X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/74b4751a1c110b4c824b14369d3a5eea3ad5816a..refs/pull/3617/head:/resources/js/code/index.mjs diff --git a/resources/js/code/index.mjs b/resources/js/code/index.mjs index 07dcd53c2..32c25d401 100644 --- a/resources/js/code/index.mjs +++ b/resources/js/code/index.mjs @@ -1,8 +1,9 @@ import {EditorView, keymap} from "@codemirror/view"; import {copyTextToClipboard} from "../services/clipboard.js" -import {viewer, editor} from "./setups.js"; -import {createView, updateViewLanguage} from "./views.js"; +import {viewerExtensions, editorExtensions} from "./setups.js"; +import {createView} from "./views.js"; +import {SimpleEditorInterface} from "./simple-editor-interface.js"; /** * Highlight pre elements on a page @@ -45,10 +46,12 @@ function highlightElem(elem) { const ev = createView({ parent: wrapper, doc: content, - extensions: viewer(wrapper), + extensions: viewerExtensions(wrapper), }); - setMode(ev, langName, content); + const editor = new SimpleEditorInterface(ev); + editor.setMode(langName, content); + elem.remove(); addCopyIcon(ev); } @@ -86,34 +89,27 @@ function addCopyIcon(editorView) { }); } -/** - * Ge the theme to use for CodeMirror instances. - * @returns {*|string} - */ -function getTheme() { - // TODO - Remove - const darkMode = document.documentElement.classList.contains('dark-mode'); - return window.codeTheme || (darkMode ? 'darcula' : 'default'); -} - /** * Create a CodeMirror instance for showing inside the WYSIWYG editor. - * Manages a textarea element to hold code content. + * Manages a textarea element to hold code content. * @param {HTMLElement} cmContainer + * @param {ShadowRoot} shadowRoot * @param {String} content * @param {String} language - * @returns {EditorView} + * @returns {SimpleEditorInterface} */ -export function wysiwygView(cmContainer, content, language) { +export function wysiwygView(cmContainer, shadowRoot, content, language) { const ev = createView({ parent: cmContainer, doc: content, - extensions: viewer(cmContainer), + extensions: viewerExtensions(cmContainer), + root: shadowRoot, }); - setMode(ev, language, content); + const editor = new SimpleEditorInterface(ev); + editor.setMode(language, content); - return ev; + return editor; } @@ -121,36 +117,44 @@ export function wysiwygView(cmContainer, content, language) { * Create a CodeMirror instance to show in the WYSIWYG pop-up editor * @param {HTMLElement} elem * @param {String} modeSuggestion - * @returns {*} + * @returns {SimpleEditorInterface} */ export function popupEditor(elem, modeSuggestion) { const content = elem.textContent; + const config = { + parent: elem.parentElement, + doc: content, + extensions: [ + ...editorExtensions(elem.parentElement), + EditorView.updateListener.of((v) => { + if (v.docChanged) { + // textArea.value = v.state.doc.toString(); + } + }), + ], + }; - return CodeMirror(function(elt) { - elem.parentNode.insertBefore(elt, elem); - elem.style.display = 'none'; - }, { - value: content, - mode: getMode(modeSuggestion, content), - lineNumbers: true, - lineWrapping: false, - theme: getTheme() - }); + // Create editor, hide original input + const editor = new SimpleEditorInterface(createView(config)); + editor.setMode(modeSuggestion, content); + elem.style.display = 'none'; + + return editor; } /** * Create an inline editor to replace the given textarea. * @param {HTMLTextAreaElement} textArea * @param {String} mode - * @returns {EditorView} + * @returns {SimpleEditorInterface} */ export function inlineEditor(textArea, mode) { const content = textArea.value; const config = { - parent: textArea.parentNode, + parent: textArea.parentElement, doc: content, extensions: [ - ...editor(textArea.parentElement), + ...editorExtensions(textArea.parentElement), EditorView.updateListener.of((v) => { if (v.docChanged) { textArea.value = v.state.doc.toString(); @@ -161,41 +165,11 @@ export function inlineEditor(textArea, mode) { // Create editor view, hide original input const ev = createView(config); - setMode(ev, mode, content); + const editor = new SimpleEditorInterface(ev); + editor.setMode(mode, content); textArea.style.display = 'none'; - return ev; -} - -/** - * Set the language mode of a codemirror EditorView. - * - * @param {EditorView} ev - * @param {string} modeSuggestion - * @param {string} content - */ -export function setMode(ev, modeSuggestion, content) { - updateViewLanguage(ev, modeSuggestion, content); -} - -/** - * Set the content of a cm instance. - * @param cmInstance - * @param codeContent - */ -export function setContent(cmInstance, codeContent) { - cmInstance.setValue(codeContent); - setTimeout(() => { - updateLayout(cmInstance); - }, 10); -} - -/** - * Update the layout (codemirror refresh) of a cm instance. - * @param cmInstance - */ -export function updateLayout(cmInstance) { - cmInstance.refresh(); + return editor; } /** @@ -204,29 +178,29 @@ export function updateLayout(cmInstance) { * @param {function} onChange * @param {object} domEventHandlers * @param {Array} keyBindings - * @returns {*} + * @returns {EditorView} */ export function markdownEditor(elem, onChange, domEventHandlers, keyBindings) { const content = elem.textContent; const config = { - parent: elem.parentNode, + parent: elem.parentElement, doc: content, extensions: [ - ...editor(elem.parentElement), + keymap.of(keyBindings), + ...editorExtensions(elem.parentElement), EditorView.updateListener.of((v) => { onChange(v); }), EditorView.domEventHandlers(domEventHandlers), - keymap.of(keyBindings), ], }; // Emit a pre-event public event to allow tweaking of the configure before view creation. - window.$events.emitPublic(elem, 'editor-markdown-cm::pre-init', {cmEditorViewConfig: config}); + window.$events.emitPublic(elem, 'editor-markdown-cm6::pre-init', {editorViewConfig: config}); // Create editor view, hide original input const ev = createView(config); - setMode(ev, 'markdown', ''); + (new SimpleEditorInterface(ev)).setMode('markdown', ''); elem.style.display = 'none'; return ev;