[FIX] web editor: color of whole cell should change

This commit fixes the issue of partial coloring of table cells.

Before this commit, if one colors part of the text in the cell
and then seeks to color the whole cell, the last coloring
would not apply on the previously colored text.

We do that by preventing the cell coloring to be done differently
than other elements except if we want to change the
background color.

Task-3454903

closes odoo/odoo#130646

Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
This commit is contained in:
hmai
2023-09-25 09:38:31 +00:00
parent 260577dde0
commit 8dfe8a8c6c
3 changed files with 255 additions and 114 deletions
@@ -532,7 +532,7 @@ export const editorCommands = {
node => closestElement(node).isContentEditable
);
let coloredTds = [];
if (selectedTds.length) {
if (selectedTds.length && mode === "backgroundColor") {
for (const td of selectedTds) {
colorElement(td, color, mode);
}
@@ -555,7 +555,9 @@ export const editorCommands = {
if (isEmptyBlock(range.endContainer)) {
selectionNodes.push(range.endContainer, ...descendants(range.endContainer));
}
const selectedNodes = selectionNodes.filter(node => !closestElement(node, 'table.o_selected_table'))
const selectedNodes = mode === "backgroundColor"
? selectionNodes.filter(node => !closestElement(node, 'table.o_selected_table'))
: selectionNodes;
const fonts = selectedNodes.flatMap(node => {
let font = closestElement(node, 'font') || closestElement(node, 'span');
const children = font && descendants(font);
@@ -55,7 +55,7 @@ describe('applyColor', () => {
it('should apply a background color on empty selection', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>[<br></p><p><br></p><p>]<br></p>',
stepFunction: setColor('rgb(255, 0, 0)', 'background-color'),
stepFunction: setColor('rgb(255, 0, 0)', 'backgroundColor'),
contentAfterEdit: '<p><font data-oe-zws-empty-inline="" style="background-color: rgb(255, 0, 0);">[\u200B</font></p>' +
'<p><font data-oe-zws-empty-inline="" style="background-color: rgb(255, 0, 0);">\u200B</font></p>' +
'<p><font data-oe-zws-empty-inline="" style="background-color: rgb(255, 0, 0);">]\u200B</font></p>',
@@ -97,7 +97,7 @@ describe('applyColor', () => {
<tr><td contenteditable="false">cd]</td></tr>
</tbody></table>
`),
stepFunction: setColor('rgb(255, 0, 0)', 'background-color'),
stepFunction: setColor('rgb(255, 0, 0)', 'backgroundColor'),
contentAfter: unformat(`
<table><tbody>
<tr><td style="background-color: rgb(255, 0, 0);">[]ab</td></tr>
@@ -5184,18 +5184,37 @@ X[]
describe('color', () => {
it('should apply a color to some characters and a table', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a[bc</p><table><tbody><tr>' +
'<td>a]b</td>' +
'<td>cd</td>' +
'<td>ef</td>' +
'</tr></tbody></table>',
contentBefore: unformat(`
<p>a[bc</p>
<table>
<tbody>
<tr>
<td>a]b</td>
<td>cd</td>
<td>ef</td>
</tr>
</tbody>
</table>`),
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<p>a<font style="color: aquamarine;">[bc</font></p>' +
'<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">a]b</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">ef</td>' +
'</tr></tbody></table>',
contentAfterEdit: unformat(`
<p>
a<font style="color: aquamarine;">[bc</font>
</p>
<table class="o_selected_table">
<tbody>
<tr>
<td class="o_selected_td">
<font style="color: aquamarine;">a]b</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">ef</font>
</td>
</tr>
</tbody>
</table>`),
});
});
it('should apply a color to a table and some characters', async () => {
@@ -5206,12 +5225,23 @@ X[]
'<td>e[f</td>' +
'</tr></tbody></table><p>a]bc</p>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">e[f</td>' +
'</tr></tbody></table>' +
'<p><font style="color: aquamarine;">a]</font>bc</p>',
contentAfterEdit: unformat(`
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">e[f</font>
</td>
</tr></tbody>
</table>
<p>
<font style="color: aquamarine;">a]</font>bc
</p>`),
});
});
it('should apply a color to some characters, a table and some more characters', async () => {
@@ -5224,13 +5254,26 @@ X[]
'</tr></tbody></table>' +
'<p>a]bc</p>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<p>a<font style="color: aquamarine;">[bc</font></p>' +
'<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">ef</td>' +
'</tr></tbody></table>' +
'<p><font style="color: aquamarine;">a]</font>bc</p>',
contentAfterEdit: unformat(`
<p>
a<font style="color: aquamarine;">[bc</font>
</p>
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">ef</font>
</td>
</tr></tbody>
</table>
<p>
<font style="color: aquamarine;">a]</font>bc
</p>`),
});
});
it('should apply a color to some characters, a table, some more characters and another table', async () => {
@@ -5248,18 +5291,39 @@ X[]
'<td>ef</td>' +
'</tr></tbody></table>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<p>a<font style="color: aquamarine;">[bc</font></p>' +
'<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">ef</td>' +
'</tr></tbody></table>' +
'<p><font style="color: aquamarine;">abc</font></p>' +
'<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">a]b</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">ef</td>' +
'</tr></tbody></table>',
contentAfterEdit: unformat(`
<p>
a<font style="color: aquamarine;">[bc</font>
</p>
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">ef</font>
</td>
</tr></tbody>
</table>
<p>
<font style="color: aquamarine;">abc</font>
</p>
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">a]b</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">ef</font>
</td>
</tr></tbody>
</table>`),
});
});
it('should apply a color to some characters, a table, some more characters, another table and some more characters', async () => {
@@ -5278,19 +5342,38 @@ X[]
'</tr></tbody></table>' +
'<p>a]bc</p>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<p>a<font style="color: aquamarine;">[bc</font></p>' +
'<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">ef</td>' +
'</tr></tbody></table>' +
'<p><font style="color: aquamarine;">abc</font></p>' +
'<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">ef</td>' +
'</tr></tbody></table>' +
'<p><font style="color: aquamarine;">a]</font>bc</p>',
contentAfterEdit: unformat(`
<p>
a<font style="color: aquamarine;">[bc</font>
</p>
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">ef</font>
</td>
</tr></tbody>
</table>
<p><font style="color: aquamarine;">abc</font></p>
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">ef</font>
</td>
</tr></tbody>
</table>
<p><font style="color: aquamarine;">a]</font>bc</p>`),
});
});
});
@@ -5554,11 +5637,18 @@ X[]
'<td>ef</td>' +
'</tr></tbody></table>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">a[b</td>' +
'<td class="o_selected_td" style="color: aquamarine;">c]d</td>' +
'<td>ef</td>' +
'</tr></tbody></table>',
contentAfterEdit: unformat(`
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">a[b</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">c]d</font>
</td>
<td>ef</td>
</tr></tbody>
</table>`),
});
});
it('should apply a color to a whole row', async () => {
@@ -5569,11 +5659,25 @@ X[]
'<td>e]f</td>' +
'</tr><tr><td>ab</td><td>cd</td><td>ef</td></tr></tbody></table>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<table class="o_selected_table"><tbody><tr>' +
'<td class="o_selected_td" style="color: aquamarine;">a[b</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">e]f</td>' +
'</tr><tr><td>ab</td><td>cd</td><td>ef</td></tr></tbody></table>',
contentAfterEdit: unformat(`
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">a[b</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">e]f</font>
</td>
</tr>
<tr>
<td>ab</td>
<td>cd</td>
<td>ef</td>
</tr></tbody>
</table>`),
});
});
it('should apply a color to a whole column', async () => {
@@ -5596,23 +5700,30 @@ X[]
'</tr>' +
'</tbody></table>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<table class="o_selected_table"><tbody>' +
'<tr>' +
'<td class="o_selected_td" style="color: aquamarine;">a[b</td>' +
'<td>cd</td>' +
'<td>ef</td>' +
'</tr>' +
'<tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td>cd</td>' +
'<td>ef</td>' +
'</tr>' +
'<tr>' +
'<td class="o_selected_td" style="color: aquamarine;">a]b</td>' +
'<td>cd</td>' +
'<td>ef</td>' +
'</tr>' +
'</tbody></table>',
contentAfterEdit: unformat(`
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">a[b</font>
</td>
<td>cd</td>
<td>ef</td>
</tr>
<tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td>cd</td>
<td>ef</td>
</tr>
<tr>
<td class="o_selected_td">
<font style="color: aquamarine;">a]b</font>
</td>
<td>cd</td>
<td>ef</td>
</tr></tbody>
</table>`),
});
});
it('should apply a color from (0,0) to (1,1) in a 3x3 table', async () => {
@@ -5635,23 +5746,32 @@ X[]
'</tr>' +
'</tbody></table>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<table class="o_selected_table"><tbody>' +
'<tr>' +
'<td class="o_selected_td" style="color: aquamarine;">a[b</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td>ef</td>' +
'</tr>' +
'<tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td class="o_selected_td" style="color: aquamarine;">c]d</td>' +
'<td>ef</td>' +
'</tr>' +
'<tr>' +
'<td>ab</td>' +
'<td>cd</td>' +
'<td>ef</td>' +
'</tr>' +
'</tbody></table>',
contentAfterEdit: unformat(`
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">a[b</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td>ef</td>
</tr>
<tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">c]d</font>
</td>
<td>ef</td>
</tr>
<tr>
<td>ab</td>
<td>cd</td>
<td>ef</td>
</tr></tbody>
</table>`),
});
});
it('should apply a color to a whole table', async () => {
@@ -5674,23 +5794,42 @@ X[]
'</tr>' +
'</tbody></table>',
stepFunction: async editor => editor.execCommand('applyColor', 'aquamarine', 'color'),
contentAfterEdit: '<table class="o_selected_table"><tbody>' +
'<tr>' +
'<td class="o_selected_td" style="color: aquamarine;">a[b</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">ef</td>' +
'</tr>' +
'<tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">ef</td>' +
'</tr>' +
'<tr>' +
'<td class="o_selected_td" style="color: aquamarine;">ab</td>' +
'<td class="o_selected_td" style="color: aquamarine;">cd</td>' +
'<td class="o_selected_td" style="color: aquamarine;">e]f</td>' +
'</tr>' +
'</tbody></table>',
contentAfterEdit: unformat(`
<table class="o_selected_table">
<tbody><tr>
<td class="o_selected_td">
<font style="color: aquamarine;">a[b</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">ef</font>
</td>
</tr>
<tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">ef</font>
</td>
</tr>
<tr>
<td class="o_selected_td">
<font style="color: aquamarine;">ab</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">cd</font>
</td>
<td class="o_selected_td">
<font style="color: aquamarine;">e]f</font>
</td>
</tr></tbody>
</table>`),
});
});
});