From 0de4d6d22342fa5a84393e5e18ff59fe42cbb876 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 27 Feb 2022 17:18:08 +0000 Subject: [PATCH] Improved WYSIWYG code block behaviour via range of fixes - Fixed issues with new code blocks breaking or acting odd due to misnamed contenteditable attribute. - Helped fix issue where code blocks may show in a strage blank state due to timing within shadow dom loading. - Fixed some function timing issues where some functions required their async predecessor to have finished. Tested rather heavily in firefox and brave. Fixes #3292 --- resources/js/components/code-editor.js | 10 ++++---- resources/js/wysiwyg/plugin-codeeditor.js | 28 +++++++++++++++++++---- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/resources/js/components/code-editor.js b/resources/js/components/code-editor.js index a8a2c0c6f..f44de813d 100644 --- a/resources/js/components/code-editor.js +++ b/resources/js/components/code-editor.js @@ -59,12 +59,10 @@ class CodeEditor { this.languageInput.value = language; this.callback = callback; - this.show(); - this.updateEditorMode(language); - - window.importVersioned('code').then(Code => { - Code.setContent(this.editor, code); - }); + this.show() + .then(() => this.updateEditorMode(language)) + .then(() => window.importVersioned('code')) + .then(Code => Code.setContent(this.editor, code)); } async show() { diff --git a/resources/js/wysiwyg/plugin-codeeditor.js b/resources/js/wysiwyg/plugin-codeeditor.js index 12b2c25fb..b0640a450 100644 --- a/resources/js/wysiwyg/plugin-codeeditor.js +++ b/resources/js/wysiwyg/plugin-codeeditor.js @@ -91,15 +91,35 @@ function defineCodeBlockCustomElement(editor) { } connectedCallback() { + const connectedTime = Date.now(); if (this.cm) { return; } + this.cleanChildContent(); + const container = this.shadowRoot.querySelector('.CodeMirrorContainer'); - importVersioned('code').then(Code => { + const renderCodeMirror = (Code) => { this.cm = Code.wysiwygView(container, this.getContent(), this.getLanguage()); + Code.updateLayout(this.cm); + }; + + window.importVersioned('code').then((Code) => { + const timeout = (Date.now() - connectedTime < 20) ? 20 : 0; + setTimeout(() => renderCodeMirror(Code), timeout); }); } + + cleanChildContent() { + const pre = this.querySelector('pre'); + if (!pre) return; + + for (const preChild of pre.childNodes) { + if (preChild.nodeName === '#text' && preChild.textContent === '') { + preChild.remove(); + } + } + } } win.customElements.define('code-block', CodeBlockElement); @@ -130,15 +150,13 @@ function register(editor, url) { } else { const textContent = editor.selection.getContent({format: 'text'}); showPopup(editor, textContent, '', (newCode, newLang) => { - const wrap = doc.createElement('code-block'); const pre = doc.createElement('pre'); const code = doc.createElement('code'); code.classList.add(`language-${newLang}`); code.innerText = newCode; pre.append(code); - wrap.append(pre); - editor.insertContent(wrap.outerHTML); + editor.insertContent(pre.outerHTML); }); } }); @@ -168,7 +186,7 @@ function register(editor, url) { editor.parser.addNodeFilter('code-block', function(elms) { for (const el of elms) { - el.attr('content-editable', 'false'); + el.attr('contenteditable', 'false'); } });