Skip to content

Commit

Permalink
WYSIWYG: Added text direction support for code editor popup
Browse files Browse the repository at this point in the history
Editor popup will now reflect the direction of the opened code block.
This also updates in-editor codemirror instances to correcly reflect/use
the direction if set on the inner code elem.

This also defaults new code blocks, when in RTL languages, to be started
in LTR, which can then be changed via in-editor direction controls if
needed. This is on the assumption that most code will be LTR (could not
find much examples of RTL code use).

Fixes #4943
  • Loading branch information
ssddanbrown committed May 3, 2024
1 parent 4c1c315 commit f9e0873
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 11 deletions.
21 changes: 18 additions & 3 deletions resources/js/code/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
Expand Down
12 changes: 11 additions & 1 deletion resources/js/components/code-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,15 @@ 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;

await this.show();
this.languageInputChange(language);
this.editor.setContent(code);
this.setDirection(direction);
}

async show() {
Expand All @@ -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();
Expand Down
19 changes: 13 additions & 6 deletions resources/js/wysiwyg/plugin-codeeditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
});
}
Expand Down Expand Up @@ -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);
});
}
Expand All @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
flex: 0;
.popup-title {
color: #FFF;
margin-right: auto;
margin-inline-end: auto;
padding: 8px $-m;
}
&.flex-container-row {
Expand Down

0 comments on commit f9e0873

Please sign in to comment.