From a42ca8f3ba74c608dd5fd31f69148ca01d9eb2e4 Mon Sep 17 00:00:00 2001 From: dhba Date: Fri, 23 Feb 2024 11:59:52 +0000 Subject: [PATCH] [FIX] web_editor: issue with copy paste Before this commit: When attempting to copy a button that is a direct child of a div tag, the div was unintentionally copied along with the button, leading to additional space upon pasting, along with the background color. After this commit: Now, only the button will be copied and pasted task-3764652 closes odoo/odoo#158975 X-original-commit: b27b9ca18da9b1c39906f8a374418105c2e9c487 Signed-off-by: David Monjoie (dmo) --- .../src/js/editor/odoo-editor/src/OdooEditor.js | 16 +++++++++++++--- .../odoo-editor/test/spec/copyPaste.test.js | 12 ++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) 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 4d35fd64bf5f4..ec7da9719abf8 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 @@ -3899,9 +3899,13 @@ export class OdooEditor extends EventTarget { const ancestorsList = [commonAncestorElement, ...ancestors(commonAncestorElement, blockEl)]; // Wrap rangeContent with clones of their ancestors to keep the styles. for (const ancestor of ancestorsList) { - const clone = ancestor.cloneNode(); - clone.append(...rangeContent.childNodes); - rangeContent.appendChild(clone); + // Keep the formatting by keeping inline ancestors and paragraph + // related ones like headings etc. + if (!isBlock(ancestor) || paragraphRelatedElements.includes(ancestor.nodeName)) { + const clone = ancestor.cloneNode(); + clone.append(...rangeContent.childNodes); + rangeContent.appendChild(clone); + } } } const dataHtmlElement = document.createElement('data'); @@ -4928,6 +4932,12 @@ export class OdooEditor extends EventTarget { this._applyCommand("insert", text); } else if (odooEditorHtml) { const fragment = parseHTML(this.document, odooEditorHtml); + const selector = this.options.renderingClasses.map(c => `.${c}`).join(','); + if (selector) { + for (const element of fragment.querySelectorAll(selector)) { + element.classList.remove(...this.options.renderingClasses); + } + } // Instantiate DOMPurify with the correct window. this.DOMPurify ??= DOMPurify(this.document.defaultView); this.DOMPurify.sanitize(fragment, { IN_PLACE: true }); 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 770f59c60d7a5..72fd4e1e1036a 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 @@ -100,8 +100,8 @@ describe('Copy', () => { const clipboardData = new DataTransfer(); triggerEvent(editor.editable, 'copy', { clipboardData }); window.chai.expect(clipboardData.getData('text/plain')).to.be.equal('First'); - window.chai.expect(clipboardData.getData('text/html')).to.be.equal('
  • First
  • '); - window.chai.expect(clipboardData.getData('text/odoo-editor')).to.be.equal('
  • First
  • '); + window.chai.expect(clipboardData.getData('text/html')).to.be.equal('First'); + window.chai.expect(clipboardData.getData('text/odoo-editor')).to.be.equal('First'); }, }); await testEditor(BasicEditor, { @@ -110,8 +110,8 @@ describe('Copy', () => { const clipboardData = new DataTransfer(); triggerEvent(editor.editable, 'copy', { clipboardData }); window.chai.expect(clipboardData.getData('text/plain')).to.be.equal('List'); - window.chai.expect(clipboardData.getData('text/html')).to.be.equal('
  • List
  • '); - window.chai.expect(clipboardData.getData('text/odoo-editor')).to.be.equal('
  • List
  • '); + window.chai.expect(clipboardData.getData('text/html')).to.be.equal('List'); + window.chai.expect(clipboardData.getData('text/odoo-editor')).to.be.equal('List'); }, }); await testEditor(BasicEditor, { @@ -120,8 +120,8 @@ describe('Copy', () => { const clipboardData = new DataTransfer(); triggerEvent(editor.editable, 'copy', { clipboardData }); window.chai.expect(clipboardData.getData('text/plain')).to.be.equal('First'); - window.chai.expect(clipboardData.getData('text/html')).to.be.equal('
  • First
  • '); - window.chai.expect(clipboardData.getData('text/odoo-editor')).to.be.equal('
  • First
  • '); + window.chai.expect(clipboardData.getData('text/html')).to.be.equal('First'); + window.chai.expect(clipboardData.getData('text/odoo-editor')).to.be.equal('First'); }, }); })