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',