From 8d62a37683928517a51b2d7ead1a52448a0b984c Mon Sep 17 00:00:00 2001
From: Andreas Kienast <a.fernandez@scripting-base.de>
Date: Thu, 13 Jun 2024 09:32:49 +0200
Subject: [PATCH] [TASK] Use code editor in styleguide examples
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Resolves: #104080
Releases: main
Change-Id: I83b5f8dfabb32b584300066ea52a97b5917ca6c4
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/84677
Tested-by: Jasmina Ließmann <minapokhalo+typo3@gmail.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Jasmina Ließmann <minapokhalo+typo3@gmail.com>
Tested-by: core-ci <typo3@b13.com>
---
 .../element/code-mirror-element.ts            |  5 +++
 .../element/code-mirror-element.js            |  7 +++-
 .../Classes/ViewHelpers/CodeViewHelper.php    | 38 ++++++++++++++++---
 3 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/Build/Sources/TypeScript/backend/code-editor/element/code-mirror-element.ts b/Build/Sources/TypeScript/backend/code-editor/element/code-mirror-element.ts
index 4f3ed7d0e534..22da9dfebe85 100644
--- a/Build/Sources/TypeScript/backend/code-editor/element/code-mirror-element.ts
+++ b/Build/Sources/TypeScript/backend/code-editor/element/code-mirror-element.ts
@@ -43,6 +43,11 @@ export class CodeMirrorElement extends LitElement {
       }
     }
 
+    :host {
+      position: relative;
+      display: block;
+    }
+
     :host([fullscreen]) {
       position: fixed;
       inset: 64px 0 0;
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/code-editor/element/code-mirror-element.js b/typo3/sysext/backend/Resources/Public/JavaScript/code-editor/element/code-mirror-element.js
index f740420c0c86..50fe9dd1715e 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/code-editor/element/code-mirror-element.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/code-editor/element/code-mirror-element.js
@@ -10,7 +10,7 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-var __decorate=function(e,t,o,r){var i,a=arguments.length,l=a<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,o,r);else for(var n=e.length-1;n>=0;n--)(i=e[n])&&(l=(a<3?i(l):a>3?i(t,o,l):i(t,o))||l);return a>3&&l&&Object.defineProperty(t,o,l),l};import{LitElement,html,css}from"lit";import{customElement,property,state}from"lit/decorators.js";import{EditorView,lineNumbers,highlightSpecialChars,drawSelection,keymap,placeholder}from"@codemirror/view";import{EditorState,Compartment}from"@codemirror/state";import{syntaxHighlighting,defaultHighlightStyle}from"@codemirror/language";import{defaultKeymap,indentWithTab}from"@codemirror/commands";import{oneDark}from"@codemirror/theme-one-dark";import{executeJavaScriptModuleInstruction,loadModule,resolveSubjectRef}from"@typo3/core/java-script-item-processor.js";import"@typo3/backend/element/spinner-element.js";let CodeMirrorElement=class extends LitElement{constructor(){super(...arguments),this.mode=null,this.addons=[],this.keymaps=[],this.lineDigits=0,this.autoheight=!1,this.nolazyload=!1,this.readonly=!1,this.fullscreen=!1,this.panel="bottom",this.editorTheme=null,this.editorView=null}render(){return html`
+var __decorate=function(e,t,o,r){var i,a=arguments.length,l=a<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,o,r);else for(var s=e.length-1;s>=0;s--)(i=e[s])&&(l=(a<3?i(l):a>3?i(t,o,l):i(t,o))||l);return a>3&&l&&Object.defineProperty(t,o,l),l};import{LitElement,html,css}from"lit";import{customElement,property,state}from"lit/decorators.js";import{EditorView,lineNumbers,highlightSpecialChars,drawSelection,keymap,placeholder}from"@codemirror/view";import{EditorState,Compartment}from"@codemirror/state";import{syntaxHighlighting,defaultHighlightStyle}from"@codemirror/language";import{defaultKeymap,indentWithTab}from"@codemirror/commands";import{oneDark}from"@codemirror/theme-one-dark";import{executeJavaScriptModuleInstruction,loadModule,resolveSubjectRef}from"@typo3/core/java-script-item-processor.js";import"@typo3/backend/element/spinner-element.js";let CodeMirrorElement=class extends LitElement{constructor(){super(...arguments),this.mode=null,this.addons=[],this.keymaps=[],this.lineDigits=0,this.autoheight=!1,this.nolazyload=!1,this.readonly=!1,this.fullscreen=!1,this.panel="bottom",this.editorTheme=null,this.editorView=null}render(){return html`
       ${this.label&&"top"===this.panel?html`<div class="codemirror-label codemirror-label-top">${this.label}</div>`:""}
       <div id="codemirror-parent" @keydown=${e=>this.onKeydown(e)}></div>
       ${this.label&&"bottom"===this.panel?html`<div class="codemirror-label codemirror-label-bottom">${this.label}</div>`:""}
@@ -22,6 +22,11 @@ var __decorate=function(e,t,o,r){var i,a=arguments.length,l=a<3?t:null===r?r=Obj
       }
     }
 
+    :host {
+      position: relative;
+      display: block;
+    }
+
     :host([fullscreen]) {
       position: fixed;
       inset: 64px 0 0;
diff --git a/typo3/sysext/styleguide/Classes/ViewHelpers/CodeViewHelper.php b/typo3/sysext/styleguide/Classes/ViewHelpers/CodeViewHelper.php
index 1f2e8801a884..06cd656220d4 100644
--- a/typo3/sysext/styleguide/Classes/ViewHelpers/CodeViewHelper.php
+++ b/typo3/sysext/styleguide/Classes/ViewHelpers/CodeViewHelper.php
@@ -17,6 +17,10 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Styleguide\ViewHelpers;
 
+use TYPO3\CMS\Backend\CodeEditor\CodeEditor;
+use TYPO3\CMS\Backend\CodeEditor\Registry\ModeRegistry;
+use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
 
 /**
@@ -36,6 +40,13 @@ final class CodeViewHelper extends AbstractViewHelper
      */
     protected $escapeChildren = false;
 
+    protected PageRenderer $pageRenderer;
+
+    public function injectPageRenderer(PageRenderer $pageRenderer): void
+    {
+        $this->pageRenderer = $pageRenderer;
+    }
+
     public function initializeArguments(): void
     {
         $this->registerArgument('language', 'string', 'the language identifier, e.g. html, php, etc.', true);
@@ -46,6 +57,10 @@ final class CodeViewHelper extends AbstractViewHelper
 
     public function render(): string
     {
+        $this->pageRenderer->loadJavaScriptModule('@typo3/backend/code-editor/element/code-mirror-element.js');
+        // Compile and register code editor configuration
+        GeneralUtility::makeInstance(CodeEditor::class)->registerConfiguration();
+
         $content = $this->renderChildren();
         $_lines = explode("\n", $content);
         $lines = [];
@@ -76,12 +91,25 @@ final class CodeViewHelper extends AbstractViewHelper
             }
         }
         if (!$this->arguments['exampleonly']) {
+            $registry = GeneralUtility::makeInstance(ModeRegistry::class);
+            if ($registry->isRegistered($this->arguments['language'])) {
+                $mode = $registry->getByFormatCode($this->arguments['language']);
+            } else {
+                $mode = $registry->getDefaultMode();
+            }
+
+            $codeMirrorConfig = [
+                'mode' => GeneralUtility::jsonEncodeForHtmlAttribute($mode->getModule(), false),
+                'readonly' => true,
+            ];
+            $attributes = [
+                'wrap' => 'off',
+            ];
+
             $markup[] = '<div class="example example--code">';
-            $markup[] = '<pre>';
-            $markup[] = '<code class="language-' . htmlspecialchars($this->arguments['language']) . '">';
-            $markup[] = htmlspecialchars($content);
-            $markup[] = '</code>';
-            $markup[] = '</pre>';
+            $markup[] = '<typo3-t3editor-codemirror ' . GeneralUtility::implodeAttributes($codeMirrorConfig, true) . '>';
+            $markup[] = '<textarea ' . GeneralUtility::implodeAttributes($attributes, true) . '>' . htmlspecialchars($content) . '</textarea>';
+            $markup[] = '</typo3-t3editor-codemirror>';
             $markup[] = '</div>';
         }
         return implode('', $markup);
-- 
GitLab