[FIX] web_editor: fix commands in inline

Some commands from the powerBox command bar were not working
properly in the e-shop product "terms and conditions" section.

This was due to the isolation of Odoo fields
inside the odoo editor as a all.
Those fields do not always have an editable block element
to apply the command on.

We disable some commands that should not be apear in this context.

We also remove a redundant command (separator) in website pages.

task-2962067

closes odoo/odoo#107174

X-original-commit: 3776faa178314c4df889f4c04cc3931f8bef225c
Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
This commit is contained in:
Sébastien Geelen (sge)
2022-12-07 15:32:04 +01:00
parent 13a8d7c31d
commit defce6b833
4 changed files with 66 additions and 11 deletions
@@ -446,6 +446,7 @@ export class OdooEditor extends EventTarget {
priority: 110,
description: this.options._t('Create a simple bulleted list'),
fontawesome: 'fa-list-ul',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.execCommand('toggleList', 'UL');
},
@@ -456,6 +457,7 @@ export class OdooEditor extends EventTarget {
priority: 100,
description: this.options._t('Create a list with numbering'),
fontawesome: 'fa-list-ol',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.execCommand('toggleList', 'OL');
},
@@ -466,6 +468,7 @@ export class OdooEditor extends EventTarget {
priority: 90,
description: this.options._t('Track tasks with a checklist'),
fontawesome: 'fa-check-square-o',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.execCommand('toggleList', 'CL');
},
@@ -476,26 +479,18 @@ export class OdooEditor extends EventTarget {
priority: 80,
description: this.options._t('Insert a table'),
fontawesome: 'fa-table',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.powerboxTablePicker.show();
},
},
{
category: this.options._t('Structure'),
name: this.options._t('Separator'),
priority: 40,
description: this.options._t('Insert an horizontal rule separator'),
fontawesome: 'fa-minus',
callback: () => {
this.execCommand('insertHorizontalRule');
},
},
{
category: this.options._t('Format'),
name: this.options._t('Heading 1'),
priority: 50,
description: this.options._t('Big section heading'),
fontawesome: 'fa-header',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.execCommand('setTag', 'H1');
},
@@ -506,6 +501,7 @@ export class OdooEditor extends EventTarget {
priority: 40,
description: this.options._t('Medium section heading'),
fontawesome: 'fa-header',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.execCommand('setTag', 'H2');
},
@@ -516,6 +512,7 @@ export class OdooEditor extends EventTarget {
priority: 30,
description: this.options._t('Small section heading'),
fontawesome: 'fa-header',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.execCommand('setTag', 'H3');
},
@@ -536,6 +533,7 @@ export class OdooEditor extends EventTarget {
priority: 10,
description: this.options._t('Paragraph block'),
fontawesome: 'fa-paragraph',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.execCommand('setTag', 'P');
},
@@ -567,6 +565,18 @@ export class OdooEditor extends EventTarget {
},
},
...(this.options.commands || []),
...(this.options.commands && !this.options.commands.find(c => c.title === this.options._t('Separator')) ? [
{
category: this.options._t('Structure'),
name: this.options._t('Separator'),
priority: 40,
description: this.options._t('Insert a horizontal rule separator'),
fontawesome: 'fa-minus',
isDisabled: () => !this.isSelectionInBlockRoot(),
callback: () => {
this.execCommand('insertHorizontalRule');
},
}] : []),
],
});
@@ -3456,6 +3466,26 @@ export class OdooEditor extends EventTarget {
closestElement(selection.anchorNode).isContentEditable && closestElement(selection.focusNode).isContentEditable &&
this.editable.contains(selection.anchorNode) && this.editable.contains(selection.focusNode);
}
/**
* Returns true if the current selection is in at least one block Element
* relative to the current contentEditable root.
*
* @returns {boolean}
*/
isSelectionInBlockRoot() {
const selection = this.document.getSelection();
let selectionInBlockRoot;
let currentNode = closestElement(selection.anchorNode);
while (
!currentNode.classList.contains('o_editable') &&
!currentNode.classList.contains('odoo-editor-editable') &&
!selectionInBlockRoot
) {
selectionInBlockRoot = isBlock(currentNode);
currentNode = currentNode.parentElement;
}
return !!selectionInBlockRoot;
}
/**
* @private
@@ -333,7 +333,7 @@ export class Powerbox {
} else {
const term = this._context.lastText.toLowerCase().replaceAll(/\s/g, '\\s').replaceAll('\u200B', '');
if (term.length) {
const regex = new RegExp(term.split('').map(char => char.replace(REGEX_RESERVED_CHARS, '\\$&')).join('.*'));
const regex = new RegExp(term.split('').map(char => char.replace(REGEX_RESERVED_CHARS, '\\$&')).join('.*'), 'i');
this._context.filteredCommands = this._context.commands.filter(command => (
`${command.category} ${command.name}`.toLowerCase().match(regex)
));
@@ -2031,6 +2031,7 @@ const Wysiwyg = Widget.extend({
priority: 30,
description: _t('Add a blockquote section'),
fontawesome: 'fa-quote-right',
isDisabled: () => !this.odooEditor.isSelectionInBlockRoot(),
callback: () => {
this.odooEditor.execCommand('setTag', 'blockquote');
},
@@ -2041,6 +2042,7 @@ const Wysiwyg = Widget.extend({
priority: 20,
description: _t('Add a code section'),
fontawesome: 'fa-code',
isDisabled: () => !this.odooEditor.isSelectionInBlockRoot(),
callback: () => {
this.odooEditor.execCommand('setTag', 'pre');
},
@@ -2050,6 +2052,7 @@ const Wysiwyg = Widget.extend({
name: _t('Signature'),
description: _t('Insert your signature'),
fontawesome: 'fa-pencil-square-o',
isDisabled: () => !this.odooEditor.isSelectionInBlockRoot(),
callback: async () => {
const res = await this._rpc({
model: 'res.users',
@@ -2069,6 +2072,9 @@ const Wysiwyg = Widget.extend({
fontawesome: 'fa-columns',
callback: () => this.odooEditor.execCommand('columnize', 2, editorOptions.insertParagraphAfterColumns),
isDisabled: () => {
if (!this.odooEditor.isSelectionInBlockRoot()) {
return true;
}
const anchor = this.odooEditor.document.getSelection().anchorNode;
const row = closestElement(anchor, '.o_text_columns .row');
return row && row.childElementCount === 2;
@@ -2082,6 +2088,9 @@ const Wysiwyg = Widget.extend({
fontawesome: 'fa-columns',
callback: () => this.odooEditor.execCommand('columnize', 3, editorOptions.insertParagraphAfterColumns),
isDisabled: () => {
if (!this.odooEditor.isSelectionInBlockRoot()) {
return true;
}
const anchor = this.odooEditor.document.getSelection().anchorNode;
const row = closestElement(anchor, '.o_text_columns .row');
return row && row.childElementCount === 3;
@@ -2095,6 +2104,9 @@ const Wysiwyg = Widget.extend({
fontawesome: 'fa-columns',
callback: () => this.odooEditor.execCommand('columnize', 4, editorOptions.insertParagraphAfterColumns),
isDisabled: () => {
if (!this.odooEditor.isSelectionInBlockRoot()) {
return true;
}
const anchor = this.odooEditor.document.getSelection().anchorNode;
const row = closestElement(anchor, '.o_text_columns .row');
return row && row.childElementCount === 4;
@@ -2108,6 +2120,9 @@ const Wysiwyg = Widget.extend({
fontawesome: 'fa-columns',
callback: () => this.odooEditor.execCommand('columnize', 0),
isDisabled: () => {
if (!this.odooEditor.isSelectionInBlockRoot()) {
return true;
}
const anchor = this.odooEditor.document.getSelection().anchorNode;
const row = closestElement(anchor, '.o_text_columns .row');
return !row;
@@ -524,6 +524,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 100,
description: this.env._t('Insert an alert snippet'),
fontawesome: 'fa-info',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_alert"]');
},
@@ -534,6 +535,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 90,
description: this.env._t('Insert a rating snippet'),
fontawesome: 'fa-star-half-o',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_rating"]');
},
@@ -544,6 +546,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 80,
description: this.env._t('Insert a card snippet'),
fontawesome: 'fa-sticky-note',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_card"]');
},
@@ -554,6 +557,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 70,
description: this.env._t('Insert a share snippet'),
fontawesome: 'fa-share-square-o',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_share"]');
},
@@ -564,6 +568,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 60,
description: this.env._t('Insert a text Highlight snippet'),
fontawesome: 'fa-sticky-note',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_text_highlight"]');
},
@@ -574,6 +579,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 50,
description: this.env._t('Insert a chart snippet'),
fontawesome: 'fa-bar-chart',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_chart"]');
},
@@ -584,6 +590,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 40,
description: this.env._t('Insert a progress bar snippet'),
fontawesome: 'fa-spinner',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_progress_bar"]');
},
@@ -594,6 +601,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 30,
description: this.env._t('Insert a badge snippet'),
fontawesome: 'fa-tags',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_badge"]');
},
@@ -604,6 +612,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 20,
description: this.env._t('Insert a blockquote snippet'),
fontawesome: 'fa-quote-left',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_blockquote"]');
},
@@ -614,6 +623,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
priority: 10,
description: this.env._t('Insert an horizontal separator snippet'),
fontawesome: 'fa-minus',
isDisabled: () => !this.widget.odooEditor.isSelectionInBlockRoot(),
callback: () => {
snippetCommandCallback('.oe_snippet_body[data-snippet="s_hr"]');
},