X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/e711290d8b1ce06b38e0560248806e8de2077870..HEAD:/resources/js/code/index.mjs diff --git a/resources/js/code/index.mjs b/resources/js/code/index.mjs index 450592c25..a2850c06b 100644 --- a/resources/js/code/index.mjs +++ b/resources/js/code/index.mjs @@ -1,29 +1,58 @@ import {EditorView, keymap} from '@codemirror/view'; -import {copyTextToClipboard} from '../services/clipboard'; +import {copyTextToClipboard} from '../services/clipboard.ts'; import {viewerExtensions, editorExtensions} from './setups'; import {createView} from './views'; import {SimpleEditorInterface} from './simple-editor-interface'; /** - * Highlight pre elements on a page + * Add a button to a CodeMirror instance which copies the contents to the clipboard upon click. + * @param {EditorView} editorView */ -export function highlight() { - const codeBlocks = document.querySelectorAll('.page-content pre, .comment-box .content pre'); - for (const codeBlock of codeBlocks) { - highlightElem(codeBlock); - } +function addCopyIcon(editorView) { + const copyIcon = ''; + const checkIcon = ''; + const copyButton = document.createElement('button'); + copyButton.setAttribute('type', 'button'); + copyButton.classList.add('cm-copy-button'); + copyButton.innerHTML = copyIcon; + editorView.dom.appendChild(copyButton); + + const notifyTime = 620; + const transitionTime = 60; + copyButton.addEventListener('click', () => { + copyTextToClipboard(editorView.state.doc.toString()); + copyButton.classList.add('success'); + + setTimeout(() => { + copyButton.innerHTML = checkIcon; + }, transitionTime / 2); + + setTimeout(() => { + copyButton.classList.remove('success'); + }, notifyTime); + + setTimeout(() => { + copyButton.innerHTML = copyIcon; + }, notifyTime + (transitionTime / 2)); + }); } /** - * Highlight all code blocks within the given parent element - * @param {HTMLElement} parent + * @param {HTMLElement} codeElem + * @returns {String} */ -export function highlightWithin(parent) { - const codeBlocks = parent.querySelectorAll('pre'); - for (const codeBlock of codeBlocks) { - highlightElem(codeBlock); +function getDirectionFromCodeBlock(codeElem) { + let dir = ''; + const innerCodeElem = codeElem.querySelector('code'); + + if (innerCodeElem && innerCodeElem.hasAttribute('dir')) { + dir = innerCodeElem.getAttribute('dir'); + } else if (codeElem.hasAttribute('dir')) { + dir = codeElem.getAttribute('dir'); } + + return dir; } /** @@ -32,7 +61,7 @@ export function highlightWithin(parent) { */ function highlightElem(elem) { const innerCodeElem = elem.querySelector('code[class^=language-]'); - elem.innerHTML = elem.innerHTML.replace(//gi, '\n'); + elem.innerHTML = elem.innerHTML.replace(//gi, '\n'); const content = elem.textContent.trimEnd(); let langName = ''; @@ -43,7 +72,12 @@ function highlightElem(elem) { const wrapper = document.createElement('div'); elem.parentNode.insertBefore(wrapper, elem); - const ev = createView({ + const direction = getDirectionFromCodeBlock(elem); + if (direction) { + wrapper.setAttribute('dir', direction); + } + + const ev = createView('content-code-block', { parent: wrapper, doc: content, extensions: viewerExtensions(wrapper), @@ -57,36 +91,24 @@ function highlightElem(elem) { } /** - * Add a button to a CodeMirror instance which copies the contents to the clipboard upon click. - * @param {EditorView} editorView + * Highlight all code blocks within the given parent element + * @param {HTMLElement} parent */ -function addCopyIcon(editorView) { - const copyIcon = ''; - const checkIcon = ''; - const copyButton = document.createElement('button'); - copyButton.setAttribute('type', 'button'); - copyButton.classList.add('cm-copy-button'); - copyButton.innerHTML = copyIcon; - editorView.dom.appendChild(copyButton); - - const notifyTime = 620; - const transitionTime = 60; - copyButton.addEventListener('click', event => { - copyTextToClipboard(editorView.state.doc.toString()); - copyButton.classList.add('success'); - - setTimeout(() => { - copyButton.innerHTML = checkIcon; - }, transitionTime / 2); - - setTimeout(() => { - copyButton.classList.remove('success'); - }, notifyTime); +export function highlightWithin(parent) { + const codeBlocks = parent.querySelectorAll('pre'); + for (const codeBlock of codeBlocks) { + highlightElem(codeBlock); + } +} - setTimeout(() => { - copyButton.innerHTML = copyIcon; - }, notifyTime + (transitionTime / 2)); - }); +/** + * Highlight pre elements on a page + */ +export function highlight() { + const codeBlocks = document.querySelectorAll('.page-content pre, .comment-box .content pre'); + for (const codeBlock of codeBlocks) { + highlightElem(codeBlock); + } } /** @@ -99,7 +121,7 @@ function addCopyIcon(editorView) { * @returns {SimpleEditorInterface} */ export function wysiwygView(cmContainer, shadowRoot, content, language) { - const ev = createView({ + const ev = createView('content-code-block', { parent: cmContainer, doc: content, extensions: viewerExtensions(cmContainer), @@ -125,16 +147,11 @@ export function popupEditor(elem, modeSuggestion) { doc: content, extensions: [ ...editorExtensions(elem.parentElement), - EditorView.updateListener.of(v => { - if (v.docChanged) { - // textArea.value = v.state.doc.toString(); - } - }), ], }; // Create editor, hide original input - const editor = new SimpleEditorInterface(createView(config)); + const editor = new SimpleEditorInterface(createView('code-editor', config)); editor.setMode(modeSuggestion, content); elem.style.display = 'none'; @@ -163,7 +180,7 @@ export function inlineEditor(textArea, mode) { }; // Create editor view, hide original input - const ev = createView(config); + const ev = createView('code-input', config); const editor = new SimpleEditorInterface(ev); editor.setMode(mode, content); textArea.style.display = 'none'; @@ -198,7 +215,7 @@ export function markdownEditor(elem, onChange, domEventHandlers, keyBindings) { window.$events.emitPublic(elem, 'editor-markdown-cm6::pre-init', {editorViewConfig: config}); // Create editor view, hide original input - const ev = createView(config); + const ev = createView('markdown-editor', config); (new SimpleEditorInterface(ev)).setMode('markdown', ''); elem.style.display = 'none';