[FIX] web_editor: merge inline elements into previous color font

Before this commit when a color was applied on a text that spans several
nodes, it was wrapping each text node in a font node to which the color
was applied. Because of this, applied gradient colors were restarting on
each text part. (e.g. before a bold section, on the bold section, after
the bold section: each had a distinctly drawn gradient)

After this commit the bold and italic nodes are considered similar to
text nodes and are wrapped inside a common font node to which the color
is applied - using the mechanism that already existed for text nodes.
Actually applied on all visible inline & inline-block elements that do
not contain a font node (and are not buttons).

task-2666200

closes odoo/odoo#109537

X-original-commit: 8c965cad4d3fdbfefbbd5caa43d8c21e3a8e064f
Signed-off-by: Arthur Detroux (ard) <ard@odoo.com>
Signed-off-by: Benoit Socias (bso) <bso@odoo.com>
This commit is contained in:
Benoit Socias
2023-01-11 09:38:53 +01:00
parent bae305fd24
commit 3ef5004c13
2 changed files with 24 additions and 2 deletions
@@ -539,8 +539,14 @@ export const editorCommands = {
} else {
font = [];
}
} else if (node.nodeType === Node.TEXT_NODE && isVisibleStr(node)) {
// Node is a visible text node: wrap it in a <font>.
} else if ((node.nodeType === Node.TEXT_NODE && isVisibleStr(node))
|| (node.nodeType === Node.ELEMENT_NODE &&
['inline', 'inline-block'].includes(getComputedStyle(node).display) &&
isVisibleStr(node.textContent) &&
!node.classList.contains('btn') &&
!node.querySelector('font'))) {
// Node is a visible text or inline node without font nor a button:
// wrap it in a <font>.
const previous = node.previousSibling;
const classRegex = mode === 'color' ? BG_CLASSES_REGEX : TEXT_CLASSES_REGEX;
if (
@@ -5658,6 +5658,22 @@ X[]
});
});
});
it('should apply a color to a slice of text containing a span', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a[b<span>c</span>d]e</p>',
stepFunction: editor => editor.execCommand('applyColor', 'rgb(255, 0, 0)', 'color'),
contentAfter: '<p>a<font style="color: rgb(255, 0, 0);">[b<span>c</span>d]</font>e</p>',
});
});
it('should distribute color to texts and to button separately', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a[b<a class="btn">c</a>d]e</p>',
stepFunction: editor => editor.execCommand('applyColor', 'rgb(255, 0, 0)', 'color'),
contentAfter: '<p>a<font style="color: rgb(255, 0, 0);">[b</font>' +
'<a class="btn"><font style="color: rgb(255, 0, 0);">c</font></a>' +
'<font style="color: rgb(255, 0, 0);">d]</font>e</p>',
});
});
});
describe('markdown', () => {