From bfa3090be2344b37f30a29c36e87b5ce012a55b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Geelen=20=28sge=29?= Date: Wed, 21 Jun 2023 14:15:59 +0200 Subject: [PATCH] [FIX] web_editor: delete behavior before table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this commit: * A delete at the end of an empty block just before a table (unbreakable), nothing happened. After this commit: * A delete at the end of an empty block just before an unbreakable block, the empty paragraph should be removed and the selection put at the beginning of the unbreakable block. task-3186679 task-3252775 closes odoo/odoo#125211 closes odoo/odoo#134327 X-original-commit: 70a03c931438fd549d167deb9ad500f3fc8b6024 Signed-off-by: David Monjoie (dmo) Signed-off-by: Geelen Sébastien (sge) --- .../odoo-editor/src/commands/deleteForward.js | 12 +++++++ .../js/editor/odoo-editor/src/utils/utils.js | 2 +- .../odoo-editor/test/spec/editor.test.js | 34 +++++++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/deleteForward.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/deleteForward.js index 94657a03b35..338f5f4ded4 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/deleteForward.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/deleteForward.js @@ -24,6 +24,8 @@ import { boundariesOut, isEditorTab, isVisible, + isUnbreakable, + isEmptyBlock, isWhitespace, isVisibleTextNode, } from '../utils/utils.js'; @@ -201,6 +203,16 @@ HTMLElement.prototype.oDeleteForward = function (offset) { filterFunc, ); if (firstOutNode) { + // If next sibblings is an unbreadable node, and current node is empty, we + // delete the current node and put the selection at the beginning of the + // next sibbling. + if (nextSibling && isUnbreakable(nextSibling) && isEmptyBlock(this)) { + const restore = prepareUpdate(...boundariesOut(this)); + this.remove(); + restore(); + setSelection(firstOutNode, 0); + return; + } const [node, offset] = leftPos(firstOutNode); // If the next node is a
  • we call directly the htmlElement // oDeleteBackward : because we don't want the special cases of 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 0384598605f..eeabdf815a4 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 @@ -1309,7 +1309,7 @@ export function isUnbreakable(node) { } return ( isUnremovable(node) || // An unremovable node is always unbreakable. - ['THEAD', 'TBODY', 'TFOOT', 'TR', 'TH', 'TD', 'SECTION', 'DIV'].includes(node.tagName) || + ['TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TR', 'TH', 'TD', 'SECTION', 'DIV'].includes(node.tagName) || node.hasAttribute('t') || (node.nodeType === Node.ELEMENT_NODE && (node.nodeName === 'T' || diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/editor.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/editor.test.js index 1d55b7c778c..92821b781f4 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/editor.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/editor.test.js @@ -289,8 +289,8 @@ describe('Editor', () => { `
    abc
    `, stepFunction: deleteForward, contentAfter: `
    ` + - `
    []
    ` + - `
    abc
    `, + `
    ` + + `
    []abc
    `, }); }); it('should remove empty unbreakable', async () => { @@ -1899,6 +1899,36 @@ X[] ``, }); }); + + it('should not merge p with an unbreakable.', async () => { + await testEditor(BasicEditor, { + contentBefore: `

    ab[]

    cd
    `, + stepFunction: deleteForward, + contentAfter: `

    ab[]

    cd
    `, + }); + await testEditor(BasicEditor, { + contentBefore: `

    ab[]

    cd
    `, + stepFunction: deleteForward, + contentAfter: `

    ab[]

    cd
    `, + }); + }); + it('should delete empty p just before an unbreakable.', async () => { + await testEditor(BasicEditor, { + contentBefore: `

    []

    cd
    `, + stepFunction: deleteForward, + contentAfter: `
    []cd
    `, + }); + await testEditor(BasicEditor, { + contentBefore: `

    []

    cd
    `, + stepFunction: deleteForward, + contentAfter: `
    []cd
    `, + }); + await testEditor(BasicEditor, { + contentBefore: `

    []

    cd
    `, + stepFunction: deleteForward, + contentAfter: `
    []cd
    `, + }); + }); it('should merge the following inline text node', async () => { await testEditor(BasicEditor, { contentBefore: '

    abc

    []def',