From 3dc3b6cc3c2020f8eb4ff9ccf4f397748bad267c Mon Sep 17 00:00:00 2001 From: Nicolas Bayet Date: Thu, 11 Aug 2022 10:08:41 +0000 Subject: [PATCH] [FIX] web_editor: don't observe changes that cancel each others Before this commit, if the mutation records would contain records that would cancel each others, those change would be listened and considered. For instance: - Mutation 1: Adding ID on element A - Mutation 2: Removing ID on element A When processing the mutation records, it is useless to consider those 2 as the Id of the element A is the same before and after the mutation. This led to multiple issues, especially in case where some elements have the same branding (and are thus the same field/xpath). In such cases, the editor is replicating the changes made on one of them to the others to keep the "same" fields sync'd. For instance, if you go on an event page and try to modify a date, the change will be replicated at multiple place in the page which are actually the same t-field. When replicating those changes, somehow the jQuery Sizzle ID changes were listened, leading to infinite loop of mutation observer. Step to reproduce: - Install website - Go to any page and enter edit mode - Click on the navbar and in the right panel select Vertical header - Activate the CTA option in that navbar right panel (should already be) - Click on the CTA button - Try to edit the URL in the right panel or any link option (style etc) The changes will be ignored as the button's section is being re-rendered every 50ms infinitely. On chrome you can easily see it by watching the DOM in the dev tool. The section will blink again and again, hinting about DOM change. opw-2893480 closes odoo/odoo#98331 X-original-commit: 97c712e81692661fc9bc65e0810abc4dc017ed87 Signed-off-by: David Monjoie (dmo) --- .../static/src/js/editor/odoo-editor/src/OdooEditor.js | 2 +- addons/web_editor/static/src/js/wysiwyg/wysiwyg.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 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 76dc6a61234..a64224993ae 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 @@ -672,7 +672,7 @@ export class OdooEditor extends EventTarget { } } observerFlush() { - this.observerApply(this.observer.takeRecords()); + this.observerApply(this.filterMutationRecords(this.observer.takeRecords())); } observerActive(label) { this._observerUnactiveLabels.delete(label); diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index 864de2b3615..42c257be833 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -1047,7 +1047,12 @@ const Wysiwyg = Widget.extend({ if ($node.hasClass('o_editable_date_field_format_changed')) { $nodes.addClass('o_editable_date_field_format_changed'); } - $nodes.html($node.html()); + const html = $node.html(); + for (const node of $nodes) { + if (node.innerHTML !== html) { + node.innerHTML = html; + } + } this._observeOdooFieldChanges(); }); observer.observe(field, observerOptions);