From afbe0de46f09ebc6ef4e46810e3b87a7620f186a Mon Sep 17 00:00:00 2001 From: Antoine Guenet Date: Tue, 15 Nov 2022 10:52:29 +0000 Subject: [PATCH] [FIX] web_editor: paste a full table after copying custom-selected table With the tables' custom selection in the editor, copy-pasting from a table became awkward. This ensures that copying (from) a table in the editor guarantees a valid table on paste. task-3061274 closes odoo/odoo#107544 X-original-commit: 9730a1f1e0053cc9633faaf0ffb424ae373bbc38 Signed-off-by: David Monjoie (dmo) Signed-off-by: Antoine Guenet (age) --- .../js/editor/odoo-editor/src/OdooEditor.js | 38 +++++++++++++++++++ .../odoo-editor/src/commands/commands.js | 4 +- 2 files changed, 40 insertions(+), 2 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 82f4f5e8b19..c3d8fd11335 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 @@ -3245,6 +3245,44 @@ export class OdooEditor extends EventTarget { list.replaceChildren(...rangeContent.childNodes); rangeContent = list; } + if (rangeContent.firstChild.nodeName === 'TR' || rangeContent.firstChild.nodeName === 'TD') { + // We enter this case only if selection is within single table. + const table = closestElement(range.commonAncestorContainer, 'table'); + const tableClone = table.cloneNode(true); + // A table is considered fully selected if it is nested inside a + // cell that is itself selected, or if all its own cells are + // selected. + const isTableFullySelected = + table.parentElement && closestElement(table.parentElement, 'td.o_selected_td') || + [...table.querySelectorAll('td')] + .filter(td => closestElement(td, 'table') === table) + .every(td => td.classList.contains('o_selected_td')); + if (!isTableFullySelected(table)) { + for (const td of tableClone.querySelectorAll('td:not(.o_selected_td)')) { + if (closestElement(td, 'table') === tableClone) { // ignore nested + td.remove(); + } + } + for (const tr of tableClone.querySelectorAll('tr:not(:has(td))')) { + if (closestElement(tr, 'table') === tableClone) { // ignore nested + tr.remove(); + } + } + } + // If it is fully selected, clone the whole table rather than + // just its rows. + rangeContent = tableClone; + } + if (rangeContent.firstChild.nodeName === 'TABLE') { + // Make sure the full leading table is copied. + rangeContent.firstChild.after(closestElement(range.startContainer, 'table').cloneNode(true)); + rangeContent.firstChild.remove(); + } + if (rangeContent.lastChild.nodeName === 'TABLE') { + // Make sure the full trailing table is copied. + rangeContent.lastChild.before(closestElement(range.endContainer, 'table').cloneNode(true)); + rangeContent.lastChild.remove(); + } const dataHtmlElement = document.createElement('data'); dataHtmlElement.append(rangeContent); 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 9e452ce1253..1439d579283 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 @@ -183,12 +183,12 @@ export const editorCommands = { container.replaceChildren(...p.childNodes); } else if (container.childElementCount > 1) { // Grab the content of the first child block and isolate it. - if (isBlock(container.firstChild)) { + if (isBlock(container.firstChild) && container.firstChild.nodeName !== 'TABLE') { containerFirstChild.replaceChildren(...container.firstElementChild.childNodes); container.firstElementChild.remove(); } // Grab the content of the last child block and isolate it. - if (isBlock(container.lastChild)) { + if (isBlock(container.lastChild) && container.lastChild.nodeName !== 'TABLE') { containerLastChild.replaceChildren(...container.lastElementChild.childNodes); container.lastElementChild.remove(); }