From ef11e75b704c108302985419b326d0948e730184 Mon Sep 17 00:00:00 2001 From: Antoine Guenet Date: Thu, 12 Oct 2023 10:06:00 +0200 Subject: [PATCH] [FIX] web_editor: prevent link isolation in non-editable links The link isolation mechanism should not be applied in non-editable links. It also should not be applied in Bootstrap navigation as we don't want it to behave like a list of links and not to insert non-link content between the navigation elements. Part-of: odoo/odoo#141303 --- .../src/js/editor/odoo-editor/src/OdooEditor.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) 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 f9c88b7f5b8..51599ec18ad 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 @@ -181,6 +181,8 @@ export const CLIPBOARD_WHITELISTS = { // Commands that don't require a DOM selection but take an argument instead. const SELECTIONLESS_COMMANDS = ['addRow', 'addColumn', 'removeRow', 'removeColumn', 'resetSize']; +const EDITABLE_LINK_SELECTOR = 'a:not(.nav-link):not([contenteditable="false"])'; + function defaultOptions(defaultObject, object) { const newObject = Object.assign({}, defaultObject, object); for (const [key, value] of Object.entries(object)) { @@ -1983,7 +1985,7 @@ export class OdooEditor extends EventTarget { if (!selection.isCollapsed) { return; } - const linkInSelection = getInSelection(this.document, 'a'); + const linkInSelection = getInSelection(this.document, EDITABLE_LINK_SELECTOR); const isLinkSelection = selection.anchorNode === linkInSelection; let commonAncestorContainer = selection.rangeCount && selection.getRangeAt(0).commonAncestorContainer; if (commonAncestorContainer) { @@ -1996,13 +1998,13 @@ export class OdooEditor extends EventTarget { if (!block || !this.editable.contains(block)) { block = this.editable; } - let links = [...block.querySelectorAll('a')]; + let links = [...block.querySelectorAll(EDITABLE_LINK_SELECTOR)]; // Consider the links at the edges of the sibling blocks, limiting // to the editable. if (this.editable.contains(block)) { links.push( - closestElement(previousLeaf(block, this.editable, true), 'a'), - closestElement(nextLeaf(block, this.editable, true), 'a'), + closestElement(previousLeaf(block, this.editable, true), EDITABLE_LINK_SELECTOR), + closestElement(nextLeaf(block, this.editable, true), EDITABLE_LINK_SELECTOR), ); } const offset = selection.anchorOffset; @@ -4024,7 +4026,7 @@ export class OdooEditor extends EventTarget { appliedCustomSelection = this._handleSelectionInTable(); // Handle selection/navigation at the edges of links. - const link = getInSelection(this.document, 'a'); + const link = getInSelection(this.document, EDITABLE_LINK_SELECTOR); if (link && selection.isCollapsed) { // 1. If the selection starts or ends at the end of a link // (after the end zws), move the selection after the "after" @@ -4037,8 +4039,8 @@ export class OdooEditor extends EventTarget { // The selection is at the end of the link, ie. at offset // max of the link, with no next leaf that is in the link. endZws && selection.anchorOffset === nodeSize(selection.anchorNode) && - closestElement(selection.anchorNode, 'a') === link && - closestElement(nextLeaf(selection.anchorNode, this.editable), 'a') !== link + closestElement(selection.anchorNode, EDITABLE_LINK_SELECTOR) === link && + closestElement(nextLeaf(selection.anchorNode, this.editable), EDITABLE_LINK_SELECTOR) !== link ); if (isAtEndOfLink) { let afterZws = link.nextElementSibling;