From 0c2015ee0e414c8c703f41b19a01de6691257c4e Mon Sep 17 00:00:00 2001 From: Antoine Guenet Date: Mon, 28 Nov 2022 16:46:47 +0000 Subject: [PATCH] [FIX] web_editor: prevent closestElement traceback with comment nodes Comment nodes don't have a `closest` method so when passing one to `closestElement`, the method crashed. ---- Step to reproduce in website: - Go to debug mode and to website app - Click on configuration > websites - Select a website and in the `custom_code_footer` field add an HTML comment - Go to the website and try to enter edit mode -> Crash The same error will be visible if you simply enter edit mode and drag & drop the "Code" snippet and enter an HTML comment inside it. ----- Step to reproduce in marketing automation: - Install marketing automation - Click on a campaign > Add a new activity - On the mail template field, type something > Create and edit - Select plain text -> `element.closest is not a function` ---- task-3083797 opw-3081323 opw-3081278 closes odoo/odoo#107486 X-original-commit: 3a9177dd6a6f12f75d0df8146b692e3486f2467c Signed-off-by: David Monjoie (dmo) --- .../src/js/editor/odoo-editor/src/OdooEditor.js | 13 +++++++++---- .../src/js/editor/odoo-editor/src/utils/utils.js | 13 +++++++------ 2 files changed, 16 insertions(+), 10 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 4091e18fef7..82f4f5e8b19 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 @@ -1885,7 +1885,7 @@ export class OdooEditor extends EventTarget { } if (joinWith) { const el = closestElement(joinWith); - fillEmpty(el); + el && fillEmpty(el); } } @@ -3462,9 +3462,14 @@ export class OdooEditor extends EventTarget { */ isSelectionInEditable(selection) { selection = selection || this.document.getSelection(); - return selection && selection.anchorNode && - closestElement(selection.anchorNode).isContentEditable && closestElement(selection.focusNode).isContentEditable && - this.editable.contains(selection.anchorNode) && this.editable.contains(selection.focusNode); + if (selection && selection.anchorNode && selection.focusNode) { + const anchorElement = closestElement(selection.anchorNode); + const focusElement = closestElement(selection.focusNode); + return anchorElement && anchorElement.isContentEditable && focusElement && focusElement.isContentEditable && + this.editable.contains(selection.anchorNode) && this.editable.contains(selection.focusNode); + } else { + return false; + } } /** * Returns true if the current selection is in at least one block Element 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 ac4af60e681..ac24ec1df5a 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 @@ -284,16 +284,17 @@ export function getFurthestUneditableParent(node, parentLimit) { * * @param {Node} node * @param {string} [selector=undefined] - * @param {boolean} [restrictToEditable=false] * @returns {HTMLElement} */ export function closestElement(node, selector) { - const element = node.nodeType === Node.TEXT_NODE ? node.parentElement : node; - if (selector && element) { - const elementFound = element.closest(selector); - return elementFound && elementFound.querySelector('.odoo-editor-editable') ? null : elementFound; + let element = node; + while (element && element.nodeType !== Node.ELEMENT_NODE) { + element = element.parentNode; } - return selector && element ? element.closest(selector) : element || node; + if (element && selector) { + element = element.closest(selector); + } + return element && element.querySelector('.odoo-editor-editable') ? null : element; } /**