[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) <dmo@odoo.com>
Signed-off-by: Antoine Guenet (age) <age@odoo.com>
This commit is contained in:
Antoine Guenet
2022-12-08 18:00:24 +01:00
parent 603b0ee228
commit afbe0de46f
2 changed files with 40 additions and 2 deletions
@@ -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);
@@ -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();
}