From 08645e8e2ed1b967f9c425c428e66074ca54f6d7 Mon Sep 17 00:00:00 2001 From: Antoine Guenet Date: Fri, 3 Feb 2023 09:51:36 +0000 Subject: [PATCH] [FIX] web_editor: ensure proper live adjacent nested lists merging Sometimes, two similar adjacent elements must be merged together (eg, two `` elements with the same style, or two lists of the same type). This is done by the sanitizer, which is called on the common ancestor of the mutated nodes after each change, and on the whole editable when the document is saved. In the case of nested lists, this can cause a visible discrepancy between what is saved and what is edited: 1. In a list, say the first item contains a nested bullet list, and the second item contains a nested numbered list: `
    • ...
    1. ...
  • ` 2. Now we transform the numbered list into a bullet list: `
    • ...
    • ...
  • ` 3. The mutation happened on the second `
  • ` element so we call the sanitizer on it, and it doesn't have enough context information to merge the two `
  • ` elements, so it leaves them as is. 4. The user saves the document, and the sanitizer is called on the whole editable, which has enough context information to merge the two `
  • ` elements, so it does so, and the saved document is different from what the user sees. It is now `
    • ...
  • ` as it should have been immediately after the mutation. We solve this in a straight-forward, ad-hoc way since we currently know of no other case where this is needed, by calling the sanitizer on the parent of the first ancestor nested list of the mutated nodes, if any. closes odoo/odoo#111871 X-original-commit: 50b7b41a4573fdce8891fac5d6aa1d08c557d455 Signed-off-by: David Monjoie (dmo) --- .../src/js/editor/odoo-editor/src/OdooEditor.js | 13 +++++++++++++ .../js/editor/odoo-editor/test/spec/list.test.js | 11 +++++++++++ 2 files changed, 24 insertions(+) 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 0b31d685568..5b69160db6a 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 @@ -711,6 +711,19 @@ export class OdooEditor extends EventTarget { return false; } + // If the common ancestor is in a nested list, make sure to sanitize + // that list's parent
  • instead, so there is enough context to + // potentially merge sibling nested lists + // (eg,
      + //
      • ...
    1. + //
      • ...
    2. + //
    : these two lists should be merged together so the common + // ancestor should be the
      element). + const nestedListAncestor = closestElement(commonAncestor, '.oe-nested'); + if (nestedListAncestor && nestedListAncestor.parentElement) { + commonAncestor = nestedListAncestor.parentElement; + } + // sanitize and mark current position as sanitized sanitize(commonAncestor); this._pluginCall('sanitizeElement', [commonAncestor]); diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/list.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/list.test.js index d0ca544fbdc..fbd516d9e51 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/list.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/list.test.js @@ -315,6 +315,17 @@ describe('List', () => { `), stepFunction: toggleCheckList, + contentAfterEdit: unformat(` +
        +
      • abc
      • +
      • +
          +
        • def
        • +
        • g[]hi
        • +
        • jkl
        • +
        +
      • +
      `), contentAfter: unformat(`
      • abc