From 03dd2513b5a35fd5745f10a183dfff0b62ba9685 Mon Sep 17 00:00:00 2001 From: Kamen Zhekov Date: Thu, 17 Feb 2022 09:56:15 +0000 Subject: [PATCH] [FIX] web_editor, website: fix website editor as restricted editor When assigned the role of restricted editor, there are many ways to break the web_editor when trying to do actions that should be unavailable. There is a traceback for the following scenarios under some circumstances (mainly because of pages without editable areas or features without the proper access rights): - Drag and dropping snippet when Restricted Editor. - Clicking on product when Restricted Editor in /shop. - Clicking on product image on specific product page. - Clicking on user name (e.g. Marc Demo). - Clicking on menu items or logo. - Clicking on a blog's image in /blog. - Clicking on a blog's image on specific blog page. - Clicking on calendar's image in /calendar. There is now no longer a traceback which makes the editor crash or freeze. This mimics the behavior in other cases where the editor does not show a traceback, but there is no message indicating that the action is unauthorized. When accessing a menu that cannot be edited, the "Edit the menu" button is not shown to the restricted editor. task-2747895 opw-3164176 closes odoo/odoo#118116 X-original-commit: 15c85e4f9f967ee04af3cdeb766d280a2c00731e Signed-off-by: Quentin Smetz (qsm) Co-authored-by: Benjamin Vray Co-authored-by: qsm-odoo --- .../static/src/js/editor/snippets.editor.js | 11 +++++++- .../wysiwyg_adapter/wysiwyg_adapter.js | 4 ++- .../src/js/widgets/link_popover_widget.js | 28 ++++++++++++++----- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 99349cbf151..36e2d8b26cf 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -157,7 +157,15 @@ var SnippetEditor = Widget.extend({ init: function (parent, target, templateOptions, $editable, options) { this._super.apply(this, arguments); this.options = options; - this.$editable = $editable; + // This is possible to have a snippet editor not inside an editable area + // (data-no-check="true") and it is possible to not have editable areas + // at all (restricted editor), in that case we just suppose this is the + // body so related code can still be executed without crash (as we still + // need to instantiate instances of editors even if nothing is really + // editable (data-no-check="true" / navigation options / ...)). + // TODO this should probably be reviewed in master: do we need a + // reference to the editable area? There should be workarounds. + this.$editable = $editable && $editable.length ? $editable : $(document.body); this.ownerDocument = this.$editable[0].ownerDocument; this.$body = $(this.ownerDocument.body); this.$target = $(target); @@ -3166,6 +3174,7 @@ var SnippetsMenu = Widget.extend({ const smoothScrollOptions = this._getScrollOptions({ jQueryDraggableOptions: { handle: '.oe_snippet_thumbnail:not(.o_we_already_dragging)', + cancel: '.oe_snippet.o_disabled', helper: function () { const dragSnip = this.cloneNode(true); dragSnip.querySelectorAll('.o_delete_btn, .o_rename_btn').forEach( 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 ab9f8553190..2070b1ea9a6 100644 --- a/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js +++ b/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js @@ -343,7 +343,9 @@ export class WysiwygAdapterComponent extends ComponentAdapter { * @private */ _addEditorMessages() { - const $wrap = this.$editable.find('.oe_structure.oe_empty, [data-oe-type="html"]'); + const $wrap = this.$editable + .find('.oe_structure.oe_empty, [data-oe-type="html"]') + .filter(':o_editable'); this.$editorMessageElement = $wrap.not('[data-editor-message]') .attr('data-editor-message-default', true) .attr('data-editor-message', this.env._t('DRAG BUILDING BLOCKS HERE')); diff --git a/addons/website/static/src/js/widgets/link_popover_widget.js b/addons/website/static/src/js/widgets/link_popover_widget.js index 2d55c804b4f..1b357472e1c 100644 --- a/addons/website/static/src/js/widgets/link_popover_widget.js +++ b/addons/website/static/src/js/widgets/link_popover_widget.js @@ -29,14 +29,28 @@ const NavbarLinkPopoverWidget = weWidgets.LinkPopoverWidget.extend({ * * @override */ - start() { + async start() { + const _super = this._super.bind(this); + + this.isWebsiteDesigner = await this._rpc({ + 'model': 'res.users', + 'method': 'has_group', + 'args': ['website.group_website_designer'], + }); + const $removeLink = this.$('.o_we_remove_link'); // remove link has no sense on navbar menu links, instead show edit menu - const $anchor = $('', { - href: '#', class: 'ms-2 js_edit_menu', title: _t('Edit Menu'), - 'data-bs-placement': 'top', 'data-bs-toggle': 'tooltip', - }).append($('', {class: 'fa fa-sitemap'})); - this.$('.o_we_remove_link').replaceWith($anchor); - return this._super(...arguments); + if (this.isWebsiteDesigner) { + const $anchor = $('', { + href: '#', class: 'ms-2 js_edit_menu', title: _t('Edit Menu'), + 'data-bs-placement': 'top', 'data-bs-toggle': 'tooltip', + }).append($('', {class: 'fa fa-sitemap'})); + $removeLink.replaceWith($anchor); + } else { + this.$('.o_we_edit_link').remove(); + $removeLink.remove(); + } + + return _super(...arguments); }, //--------------------------------------------------------------------------