[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) <dmo@odoo.com>
This commit is contained in:
Nicolas Bayet
2022-08-18 13:46:45 +02:00
committed by David Monjoie
parent 7408eef971
commit 3dc3b6cc3c
2 changed files with 7 additions and 2 deletions
@@ -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);
@@ -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);