[FIX] web_editor: fix italic and underline in FF

When selecting the text content of a link
the underline and italic commands were not working in Firefox.

We re-implement the Browser command to fix this.

task-2667950

X-original-commit: 52a5b2bb692ab6712d497492f4f2fbef3a9a7874
Part-of: odoo/odoo#83895
This commit is contained in:
Sébastien Geelen (sge)
2022-02-03 11:45:55 +00:00
parent 7b29e9d70f
commit 2e2914e5fe
3 changed files with 52 additions and 9 deletions
@@ -19,6 +19,8 @@ import {
insertText,
isBlock,
isBold,
isItalic,
isUnderline,
isColorGradient,
isContentTextNode,
isShrunkBlock,
@@ -298,6 +300,16 @@ function deleteTable(editor, table) {
setSelection(p, 0);
}
function getTextNodes(editor) {
const selection = editor.document.getSelection();
if (!selection.rangeCount || selection.getRangeAt(0).collapsed) {
return null;
}
getDeepRange(editor.editable, { splitText: true, select: true, correctTripleClick: true });
return getSelectedNodes(editor.editable)
.filter(n => n.nodeType === Node.TEXT_NODE && n.nodeValue.trim().length);
}
// This is a whitelist of the commands that are implemented by the
// editor itself rather than the node prototypes. It might be
// possible to switch the conditions and test if the method exist on
@@ -355,12 +367,9 @@ export const editorCommands = {
// Formats
// -------------------------------------------------------------------------
bold: editor => {
const selection = editor.document.getSelection();
if (!selection.rangeCount || selection.getRangeAt(0).collapsed) return;
getDeepRange(editor.editable, { splitText: true, select: true, correctTripleClick: true });
const isAlreadyBold = getSelectedNodes(editor.editable)
.filter(n => n.nodeType === Node.TEXT_NODE && n.nodeValue.trim().length)
.find(n => isBold(n.parentElement));
const nodes = getTextNodes(editor);
if (!nodes) return;
const isAlreadyBold = nodes.find(n => isBold(n.parentElement));
applyInlineStyle(editor, el => {
if (isAlreadyBold) {
const block = closestBlock(el);
@@ -370,8 +379,22 @@ export const editorCommands = {
}
});
},
italic: editor => editor.document.execCommand('italic'),
underline: editor => editor.document.execCommand('underline'),
italic: editor => {
const nodes = getTextNodes(editor);
if (!nodes) return;
const isAlreadyItalic = nodes.find(n => isItalic(n.parentElement));
applyInlineStyle(editor, el => {
el.style.fontStyle = isAlreadyItalic ? 'normal' : 'italic';
});
},
underline: editor => {
const nodes = getTextNodes(editor);
if (!nodes) return;
const isAlreadyUnderline = nodes.find(n => isUnderline(n.parentElement));
applyInlineStyle(editor, el => {
el.style.textDecoration = isAlreadyUnderline ? 'none' : 'underline';
});
},
strikeThrough: editor => editor.document.execCommand('strikeThrough'),
removeFormat: editor => {
editor.document.execCommand('removeFormat');
@@ -868,6 +868,26 @@ export function isBold(node) {
const fontWeight = +getComputedStyle(closestElement(node)).fontWeight;
return fontWeight > 500 || fontWeight > +getComputedStyle(closestBlock(node)).fontWeight;
}
/**
* Return true if the given node font style equal italic
*
* @param {Node} node
* @returns {boolean}
*/
export function isItalic(node) {
const fontStyle = getComputedStyle(closestElement(node)).fontStyle;
return fontStyle === 'italic';
}
/**
* Return true if the given node text-decoration style equal underline
*
* @param {Node} node
* @returns {boolean}
*/
export function isUnderline(node) {
const textDecoration = getComputedStyle(closestElement(node)).textDecorationLine;
return textDecoration === 'underline';
}
export function isUnbreakable(node) {
if (!node || node.nodeType === Node.TEXT_NODE) {
+1 -1
View File
@@ -173,7 +173,7 @@ tour.register('rte_translator', {
}, {
content: "save new change",
trigger: 'button[data-action=save]',
extra_trigger: '#wrap.o_dirty p u',
extra_trigger: '#wrap.o_dirty p span[style="text-decoration: underline;"]',
}, {
content: "click language dropdown (4)",