diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js index 5b5270399bd..8026441f299 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js @@ -3186,7 +3186,7 @@ export class OdooEditor extends EventTarget { } if (ev.data === '`' && !closestElement(selection.anchorNode, 'code')) { // We just inserted a backtick, check if there was another - // one before. + // one in the text. const range = getDeepRange(this.editable); let textNode = range.startContainer; let offset = range.startOffset; @@ -3205,16 +3205,30 @@ export class OdooEditor extends EventTarget { sibling = textNode.nextSibling; } setSelection(textNode, offset); - const textHasOpeningTick = /`.*`/.test(textNode.textContent); - if (textHasOpeningTick) { + const textHasTwoTicks = /`.*`/.test(textNode.textContent); + if (textHasTwoTicks) { this.historyStep(); - if (offset !== textNode.textContent.length) { - splitTextNode(textNode, offset); - textNode = textNode.previousSibling; + const insertedBacktickIndex = offset - 1; + const textBeforeInsertedBacktick = textNode.textContent.substring(0, insertedBacktickIndex - 1); + let startOffset, endOffset; + const isClosingForward = textBeforeInsertedBacktick.includes('`'); + if (isClosingForward) { + // There is a backtick before the new backtick. + startOffset = textBeforeInsertedBacktick.lastIndexOf('`'); + endOffset = insertedBacktickIndex; + } else { + // There is a backtick after the new backtick. + const textAfterInsertedBacktick = textNode.textContent.substring(offset); + startOffset = insertedBacktickIndex; + endOffset = offset + textAfterInsertedBacktick.indexOf('`'); } - const openingTickOffset = textNode.textContent.substring(0, textNode.textContent.length - 1).lastIndexOf('`'); - if (openingTickOffset) { - splitTextNode(textNode, openingTickOffset); + // Split around the backticks if needed so text starts + // and ends with a backtick. + if (endOffset && endOffset < textNode.textContent.length) { + splitTextNode(textNode, endOffset + 1, DIRECTIONS.LEFT); + } + if (startOffset) { + splitTextNode(textNode, startOffset); } // Remove ticks. textNode.textContent = textNode.textContent.substring(1, textNode.textContent.length - 1); @@ -3226,9 +3240,13 @@ export class OdooEditor extends EventTarget { if (!codeElement.previousSibling || codeElement.previousSibling.nodeType !== Node.TEXT_NODE) { codeElement.before(document.createTextNode('\u200B')); } - // Move selection out of code element. - codeElement.after(document.createTextNode('\u200B')); - setSelection(codeElement.nextSibling, 1); + if (isClosingForward) { + // Move selection out of code element. + codeElement.after(document.createTextNode('\u200B')); + setSelection(codeElement.nextSibling, 1); + } else { + setSelection(codeElement.firstChild, 0); + } } } this.historyStep(); diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/editor.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/editor.test.js index dc0c171485b..1db4573a8b1 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/editor.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/editor.test.js @@ -5684,6 +5684,12 @@ X[] stepFunction: async editor => insertText(editor, '`'), contentAfter: '
\u200Bab\u200B[]cd
[]ab`cd
', + stepFunction: async editor => insertText(editor, '`'), + contentAfter: '\u200B[]abcd
abcd\u200B[]ef
ab[]cd`ef
', + stepFunction: async editor => insertText(editor, '`'), + contentAfter: 'ab[]cdef
abcd\u200B[]
ab[]cd`
', + stepFunction: async editor => insertText(editor, '`'), + contentAfter: 'ab[]cd
a`b`cd[]e`f
', stepFunction: async editor => insertText(editor, '`'), + // The closest PREVIOUS backtick is prioritary contentAfter: 'a`bcd\u200B[]e`f
ab[]cd`e`f
', + stepFunction: async editor => insertText(editor, '`'), + // If there is no previous backtick, use the closest NEXT backtick. + contentAfter: 'ab[]cde`f
ab[]c
', stepFunction: async editor => { @@ -5766,6 +5792,15 @@ X[] }, contentAfter: '\u200Bab\u200B[]c
ab[]c
', + stepFunction: async editor => { + editor.document.getSelection().anchorNode.after(document.createTextNode('`')); + insertText(editor, '`'); + }, + contentAfter: 'ab[]c