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 fbcdc382ac4..309e9700477 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 @@ -13,7 +13,6 @@ import './commands/align.js'; import { sanitize } from './utils/sanitize.js'; import { serializeNode, unserializeNode, serializeSelection } from './utils/serialize.js'; import { - isMacOS, closestBlock, commonParentGet, containsUnremovable, @@ -70,7 +69,10 @@ import { parseHTML, splitTextNode, isEditorTab, - isVoidElement + isMacOS, + isVoidElement, + cleanZWS, + isZWS, } from './utils/utils.js'; import { editorCommands } from './commands/commands.js'; import { Powerbox } from './powerbox/Powerbox.js'; @@ -3762,14 +3764,14 @@ export class OdooEditor extends EventTarget { // we only remove the attribute to ensure we don't break some style. // Otherwise we remove the entire inline element. for (const emptyElement of element.querySelectorAll('[data-oe-zws-empty-inline]')) { - if (emptyElement.textContent.length === 1 && emptyElement.textContent.includes('\u200B')) { + if (isZWS(emptyElement)) { if (emptyElement.classList.length > 0) { emptyElement.removeAttribute('data-oe-zws-empty-inline'); } else { emptyElement.remove(); } } else { - emptyElement.textContent = emptyElement.textContent.replace('\u200B', ''); + cleanZWS(emptyElement); emptyElement.removeAttribute('data-oe-zws-empty-inline'); } } @@ -3796,7 +3798,7 @@ export class OdooEditor extends EventTarget { // Remove Zero Width Spaces on Font awesome elements const faSelector = 'i.fa,span.fa,i.fab,span.fab,i.fad,span.fad,i.far,span.far'; for (const el of element.querySelectorAll(faSelector)) { - el.textContent = el.textContent.replace('\u200B', ''); + cleanZWS(el); } // Clean custom selections diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/sanitize.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/sanitize.js index 2b7e64d2a20..acfd0760836 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/sanitize.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/sanitize.js @@ -16,7 +16,6 @@ import { isEditorTab, isZWS, getUrlsInfosInString, - URL_REGEX, isVoidElement, } from './utils.js'; @@ -240,16 +239,17 @@ class Sanitize { ) { node.setAttribute('contenteditable', 'false'); } + if (node.firstChild) { this._parse(node.firstChild); } + // Update link URL if label is a new valid link. if (node.nodeName === 'A' && anchorEl === node) { - const linkLabel = node.textContent; - const match = linkLabel.match(URL_REGEX); - if (match && match[0] === node.textContent && !node.href.startsWith('mailto:')) { - const urlInfo = getUrlsInfosInString(linkLabel)[0]; - node.setAttribute('href', urlInfo.url); + const linkLabel = node.innerText; + const urlInfo = getUrlsInfosInString(linkLabel); + if (urlInfo.length && urlInfo[0].label === linkLabel && !node.href.startsWith('mailto:')) { + node.setAttribute('href', urlInfo[0].url); } } node = node.nextSibling; diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/utils.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/utils.js index f68c62c6974..62dc4064aef 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/utils.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/utils.js @@ -2574,3 +2574,14 @@ export function peek(arr) { export function isMacOS() { return window.navigator.userAgent.includes('Mac'); } + +/** + * Remove zero-width spaces from the provided node and its descendants. + * + * @param {Node} node + */ +export function cleanZWS(node) { + [node, ...descendants(node)] + .filter(node => node.nodeType === Node.TEXT_NODE) + .forEach(node => node.nodeValue = node.nodeValue.replace(/\u200B/g, '')); +} diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/link.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/link.test.js index 3418ac272a3..03bce980a8d 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/link.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/link.test.js @@ -239,6 +239,14 @@ describe('Link', () => { }, contentAfter: '

agoogle.comu[]b

', }); + await testEditor(BasicEditor, { + contentBefore: '

agoogle.com[]

', + stepFunction: async editor => { + await insertLineBreak(editor); + await insertText(editor, 'odoo.com') + }, + contentAfter: '

agoogle.com
odoo.com[]

', + }); }); }); describe('range not collapsed', () => {