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 eaa161ffe5e..47c5f9551d6 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 @@ -123,18 +123,35 @@ function insert(editor, data, {mode = "text"}) { let lastChildNode = false; if (containerLastChild.hasChildNodes()) { let tempCurrentNode = currentNode; - for (const n of [...containerLastChild.childNodes]) { - tempCurrentNode.after(n); - tempCurrentNode = n; + const children = [...containerLastChild.childNodes]; + if (insertBefore) { + children.reverse(); + } + for (const child of children) { + tempCurrentNode[insertBefore ? 'before' : 'after'](child); + tempCurrentNode = child; + } + if (insertBefore) { + currentNode = tempCurrentNode; + lastChildNode = children[0]; + } else { + lastChildNode = tempCurrentNode; } - lastChildNode = tempCurrentNode; } if (containerFirstChild.hasChildNodes()) { - for (const n of [...containerFirstChild.childNodes]) { - currentNode.after(n); + const children = [...containerFirstChild.childNodes]; + if (insertBefore) { + children.reverse(); + } + for (const n of children) { + currentNode[insertBefore ? 'before' : 'after'](n); currentNode = n; } + if (insertBefore) { + currentNode = children[0]; + insertBefore = false; + } } // If all the Html have been isolated, We force a split of the parent element diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/copyPaste.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/copyPaste.test.js index 677309d6318..7b2b355894b 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/copyPaste.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/copyPaste.test.js @@ -96,6 +96,15 @@ describe('Copy and paste', () => { }); describe('Simple text', () => { describe('range collapsed', async () => { + it('should paste a text at the beginning of a p', async () => { + await testEditor(BasicEditor, { + contentBefore: '
[]abcd
', + stepFunction: async editor => { + await pasteHtml(editor, 'x'); + }, + contentAfter: 'x[]abcd
', + }); + }); it('should paste a text in a p', async () => { await testEditor(BasicEditor, { contentBefore: 'ab[]cd
', @@ -231,6 +240,15 @@ describe('Copy and paste', () => { describe('Simple html span', () => { const simpleHtmlCharX = 'x'; describe('range collapsed', async () => { + it('should paste a text at the beginning of a p', async () => { + await testEditor(BasicEditor, { + contentBefore: '[]abcd
', + stepFunction: async editor => { + await pasteHtml(editor, simpleHtmlCharX); + }, + contentAfter: 'x[]abcd
', + }); + }); it('should paste a text in a p', async () => { await testEditor(BasicEditor, { contentBefore: 'ab[]cd
', @@ -345,6 +363,15 @@ describe('Copy and paste', () => { describe('Simple html p', () => { const simpleHtmlCharX = 'x
'; describe('range collapsed', async () => { + it('should paste a text at the beginning of a p', async () => { + await testEditor(BasicEditor, { + contentBefore: '[]abcd
', + stepFunction: async editor => { + await pasteHtml(editor, simpleHtmlCharX); + }, + contentAfter: 'x[]abcd
', + }); + }); it('should paste a text in a p', async () => { await testEditor(BasicEditor, { contentBefore: 'ab[]cd
', @@ -459,6 +486,15 @@ describe('Copy and paste', () => { describe('Complex html span', () => { const complexHtmlData = '123 4'; describe('range collapsed', async () => { + it('should paste a text at the beginning of a p', async () => { + await testEditor(BasicEditor, { + contentBefore: '[]abcd
', + stepFunction: async editor => { + await pasteHtml(editor, complexHtmlData); + }, + contentAfter: '123 4[]abcd
', + }); + }); it('should paste a text in a p', async () => { await testEditor(BasicEditor, { contentBefore: 'ab[]cd
', @@ -573,6 +609,15 @@ describe('Copy and paste', () => { describe('Complex html p', () => { const complexHtmlData = '12
34
'; describe('range collapsed', async () => { + it('should paste a text at the beginning of a p', async () => { + await testEditor(BasicEditor, { + contentBefore: '[]abcd
', + stepFunction: async editor => { + await pasteHtml(editor, complexHtmlData); + }, + contentAfter: '12
34[]abcd
', + }); + }); it('should paste a text in a p', async () => { await testEditor(BasicEditor, { contentBefore: 'ab[]cd
', @@ -700,9 +745,18 @@ describe('Copy and paste', () => { }); }); }); - describe('Complex html 3 p', () => { + describe('Complex html 3 p', () => { const complexHtmlData = '1X2
3X4
5X6
'; describe('range collapsed', async () => { + it('should paste a text at the beginning of a p', async () => { + await testEditor(BasicEditor, { + contentBefore: '[]abcd
', + stepFunction: async editor => { + await pasteHtml(editor, complexHtmlData); + }, + contentAfter: '1X2
3X4
5X6[]abcd
', + }); + }); it('should paste a text in a p', async () => { await testEditor(BasicEditor, { contentBefore: 'ab[]cd
', @@ -830,6 +884,15 @@ describe('Copy and paste', () => { describe('Complex html p+i', () => { const complexHtmlData = '12
ii
'; describe('range collapsed', async () => { + it('should paste a text at the beginning of a p', async () => { + await testEditor(BasicEditor, { + contentBefore: '[]abcd
', + stepFunction: async editor => { + await pasteHtml(editor, complexHtmlData); + }, + contentAfter: '12
ii[]abcd
', + }); + }); it('should paste a text in a p', async () => { await testEditor(BasicEditor, { contentBefore: 'ab[]cd
', @@ -955,6 +1018,15 @@ describe('Copy and paste', () => { describe('Complex html 3p+b', () => { const complexHtmlData = '123
zzz
4567
'; describe('range collapsed', async () => { + it('should paste a text at the beginning of a p', async () => { + await testEditor(BasicEditor, { + contentBefore: '[]abcd
', + stepFunction: async editor => { + await pasteHtml(editor, complexHtmlData); + }, + contentAfter: '123
zzz
4567[]abcd
', + }); + }); it('should paste a text in a p', async () => { await testEditor(BasicEditor, { contentBefore: 'ab[]cd
',