From defce6b8339862c0efd355823142bad3ca81f90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Geelen=20=28sge=29?= Date: Fri, 2 Dec 2022 14:19:17 +0000 Subject: [PATCH] [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) --- .../js/editor/odoo-editor/src/OdooEditor.js | 50 +++++++++++++++---- .../odoo-editor/src/powerbox/Powerbox.js | 2 +- .../static/src/js/wysiwyg/wysiwyg.js | 15 ++++++ .../wysiwyg_adapter/wysiwyg_adapter.js | 10 ++++ 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js index 01944fc4174..4091e18fef7 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js @@ -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 diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/powerbox/Powerbox.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/powerbox/Powerbox.js index b351ed3b81b..4f1173806a5 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/powerbox/Powerbox.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/powerbox/Powerbox.js @@ -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) )); diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index 85a2544af46..28fbe9485f4 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -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; diff --git a/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js b/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js index 4b80f01cb21..834d5a6087f 100644 --- a/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js +++ b/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js @@ -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"]'); },