diff --git a/resources/js/code/index.mjs b/resources/js/code/index.mjs index ab31e3f74..d2ea12a4c 100644 --- a/resources/js/code/index.mjs +++ b/resources/js/code/index.mjs @@ -38,6 +38,23 @@ function addCopyIcon(editorView) { }); } +/** + * @param {HTMLElement} codeElem + * @returns {String} + */ +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; +} + /** * Add code highlighting to a single element. * @param {HTMLElement} elem @@ -48,16 +65,14 @@ function highlightElem(elem) { const content = elem.textContent.trimEnd(); let langName = ''; - let innerCodeDirection = ''; if (innerCodeElem !== null) { langName = innerCodeElem.className.replace('language-', ''); - innerCodeDirection = innerCodeElem.getAttribute('dir'); } const wrapper = document.createElement('div'); elem.parentNode.insertBefore(wrapper, elem); - const direction = innerCodeDirection || elem.getAttribute('dir') || ''; + const direction = getDirectionFromCodeBlock(elem); if (direction) { wrapper.setAttribute('dir', direction); } diff --git a/resources/js/components/code-editor.js b/resources/js/components/code-editor.js index 1c68c2048..091c3483f 100644 --- a/resources/js/components/code-editor.js +++ b/resources/js/components/code-editor.js @@ -129,7 +129,7 @@ export class CodeEditor extends Component { this.hide(); } - async open(code, language, saveCallback, cancelCallback) { + async open(code, language, direction, saveCallback, cancelCallback) { this.languageInput.value = language; this.saveCallback = saveCallback; this.cancelCallback = cancelCallback; @@ -137,6 +137,7 @@ export class CodeEditor extends Component { await this.show(); this.languageInputChange(language); this.editor.setContent(code); + this.setDirection(direction); } async show() { @@ -156,6 +157,15 @@ export class CodeEditor extends Component { }); } + setDirection(direction) { + const target = this.editorInput.parentElement; + if (direction) { + target.setAttribute('dir', direction); + } else { + target.removeAttribute('dir'); + } + } + hide() { this.getPopup().hide(); this.addHistory(); diff --git a/resources/js/wysiwyg/plugin-codeeditor.js b/resources/js/wysiwyg/plugin-codeeditor.js index f86760214..c01a7eca0 100644 --- a/resources/js/wysiwyg/plugin-codeeditor.js +++ b/resources/js/wysiwyg/plugin-codeeditor.js @@ -6,13 +6,14 @@ function elemIsCodeBlock(elem) { * @param {Editor} editor * @param {String} code * @param {String} language + * @param {String} direction * @param {function(string, string)} callback (Receives (code: string,language: string) */ -function showPopup(editor, code, language, callback) { +function showPopup(editor, code, language, direction, callback) { /** @var {CodeEditor} codeEditor * */ const codeEditor = window.$components.first('code-editor'); const bookMark = editor.selection.getBookmark(); - codeEditor.open(code, language, (newCode, newLang) => { + codeEditor.open(code, language, direction, (newCode, newLang) => { callback(newCode, newLang); editor.focus(); editor.selection.moveToBookmark(bookMark); @@ -27,7 +28,8 @@ function showPopup(editor, code, language, callback) { * @param {CodeBlockElement} codeBlock */ function showPopupForCodeBlock(editor, codeBlock) { - showPopup(editor, codeBlock.getContent(), codeBlock.getLanguage(), (newCode, newLang) => { + const direction = codeBlock.getAttribute('dir') || ''; + showPopup(editor, codeBlock.getContent(), codeBlock.getLanguage(), direction, (newCode, newLang) => { codeBlock.setContent(newCode, newLang); }); } @@ -179,13 +181,17 @@ function register(editor) { showPopupForCodeBlock(editor, selectedNode); } else { const textContent = editor.selection.getContent({format: 'text'}); - showPopup(editor, textContent, '', (newCode, newLang) => { + const direction = document.dir === 'rtl' ? 'ltr' : ''; + showPopup(editor, textContent, '', direction, (newCode, newLang) => { const pre = doc.createElement('pre'); const code = doc.createElement('code'); code.classList.add(`language-${newLang}`); code.innerText = newCode; - pre.append(code); + if (direction) { + pre.setAttribute('dir', direction); + } + pre.append(code); editor.insertContent(pre.outerHTML); }); } @@ -205,7 +211,8 @@ function register(editor) { contenteditable: 'false', }); - const direction = el.attr('dir'); + const childCodeBlock = el.children().filter(child => child.name === 'code')[0] || null; + const direction = el.attr('dir') || (childCodeBlock && childCodeBlock.attr('dir')) || ''; if (direction) { wrapper.attr('dir', direction); } diff --git a/resources/sass/_components.scss b/resources/sass/_components.scss index ae899357c..fc4ddeba4 100644 --- a/resources/sass/_components.scss +++ b/resources/sass/_components.scss @@ -182,7 +182,7 @@ flex: 0; .popup-title { color: #FFF; - margin-right: auto; + margin-inline-end: auto; padding: 8px $-m; } &.flex-container-row {