From 1a91bd9ea506dcdf1c720df33acf525f60c88772 Mon Sep 17 00:00:00 2001 From: dhba-odoo Date: Wed, 17 May 2023 06:30:43 +0000 Subject: [PATCH] [FIX] web_editor: word tables are broken because of formatting spaces. Before this commit: When format styles were applied to the word table, it would break table. After this commit: Now, when format styles are applied to a word table, the style will be applied to it without breaking the table. task-3165767 closes odoo/odoo#129356 X-original-commit: 0b06ba23aa111f6a85929abe8018b6b18da79873 Signed-off-by: David Monjoie (dmo) --- .../odoo-editor/src/commands/commands.js | 6 +- .../js/editor/odoo-editor/src/utils/utils.js | 2 +- .../editor/odoo-editor/test/spec/list.test.js | 324 ++++++++++++++++++ 3 files changed, 330 insertions(+), 2 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/commands.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/commands.js index f7747440ae2..2bd8c37ce20 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/commands.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/commands.js @@ -490,7 +490,11 @@ export const editorCommands = { const li = new Set(); const blocks = new Set(); - for (const node of getTraversedNodes(editor.editable)) { + const selectedBlocks = getTraversedNodes(editor.editable); + const deepestSelectedBlocks = selectedBlocks.filter(block => ( + !descendants(block).some(descendant => selectedBlocks.includes(descendant)) + )); + for (const node of deepestSelectedBlocks) { if (node.nodeType === Node.TEXT_NODE && isWhitespace(node) && closestElement(node).isContentEditable) { node.remove(); } else { 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 032a88b761a..adac7549470 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 @@ -1023,7 +1023,7 @@ export const formatSelection = (editor, formatName, {applyStyle, formatProps} = } const selectedTextNodes = getSelectedNodes(editor.editable) - .filter(n => n.nodeType === Node.TEXT_NODE && closestElement(n).isContentEditable); + .filter(n => n.nodeType === Node.TEXT_NODE && closestElement(n).isContentEditable && (isVisibleTextNode(n) || isZWS(n))); const formatSpec = formatsSpecs[formatName]; for (const selectedTextNode of selectedTextNodes) { 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 5ba40e784fa..c56e771a26e 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 @@ -59,6 +59,59 @@ describe('List', () => { '', }); }); + it('should turn an empty paragraph of multiple table cells into a list', async () => { + await testEditor(BasicEditor, { + contentBefore: unformat(` + + + + + + + + + + + + + +
[





]
+ `), + stepFunction: toggleUnorderedList, + contentAfterEdit: unformat(` + + + + + + + + + + + + + +
[






]
+ `), + contentAfter: unformat(` + + + + + + + + + + + + + +
[]






+ `), + }); + }); }); describe('Remove', () => { it('should turn an empty list into a paragraph', async () => { @@ -137,6 +190,59 @@ describe('List', () => { `), }); }); + it('should turn an list of multiple table cells into a empty paragraph', async () => { + await testEditor(BasicEditor, { + contentBefore: unformat(` + + + + + + + + + + + + + +
[






]
+ `), + stepFunction: toggleUnorderedList, + contentAfterEdit: unformat(` + + + + + + + + + + + + + +
[







]
+ `), + contentAfter: unformat(` + + + + + + + + + + + + + +
[]







+ `), + }); + }); }); describe('Transform', () => { it('should turn an empty ordered list into an unordered list', async () => { @@ -194,6 +300,59 @@ describe('List', () => { '
  1. ab cd ef[]gh
', }); }); + it('should turn an empty paragraph of multiple table cells into a list', async () => { + await testEditor(BasicEditor, { + contentBefore: unformat(` + + + + + + + + + + + + + +
[





]
+ `), + stepFunction: toggleOrderedList, + contentAfterEdit: unformat(` + + + + + + + + + + + + + +
[






]
+ `), + contentAfter: unformat(` + + + + + + + + + + + + + +
[]






+ `), + }); + }); }); describe('Remove', () => { it('should turn an empty list into a paragraph', async () => { @@ -233,6 +392,59 @@ describe('List', () => { '

ab cd ef[]gh

', }); }); + it('should turn an list of multiple table cells into a empty paragraph', async () => { + await testEditor(BasicEditor, { + contentBefore: unformat(` + + + + + + + + + + + + + +
[






]
+ `), + stepFunction: toggleOrderedList, + contentAfterEdit: unformat(` + + + + + + + + + + + + + +
[







]
+ `), + contentAfter: unformat(` + + + + + + + + + + + + + +
[]







+ `), + }); + }); }); }); describe('Checklist', () => { @@ -401,6 +613,65 @@ describe('List', () => { }, }); }); + it('should turn an empty paragraph of multiple table cells into a checklist', async () => { + await testEditor(BasicEditor, { + removeCheckIds: true, + contentBefore: unformat(` + + + + + + + + + + + + + +
[





]
+ `), + stepFunction: editor => { + toggleCheckList(editor); + for (const li of editor.editable.querySelectorAll('li[id^=checkId-]')) { + li.removeAttribute('id'); + } + }, + contentAfterEdit: unformat(` + + + + + + + + + + + + + +
[






]
+ `), + contentAfter: unformat(` + + + + + + + + + + + + + +
[]






+ `), + }); + }); }); describe('Remove', () => { it('should turn an empty list into a paragraph', async () => { @@ -483,6 +754,59 @@ describe('List', () => { `), }); }); + it('should turn an list of multiple table cells into a empty paragraph', async () => { + await testEditor(BasicEditor, { + contentBefore: unformat(` + + + + + + + + + + + + + +
[






]
+ `), + stepFunction: toggleCheckList, + contentAfterEdit: unformat(` + + + + + + + + + + + + + +
[







]
+ `), + contentAfter: unformat(` + + + + + + + + + + + + + +
[]







+ `), + }); + }); }); }); });