From a153ed42a09f8b7f5e0865112eb7d5affc22a353 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Thu, 29 Nov 2018 14:47:42 +0000 Subject: [PATCH] [FIX] website, *: properly clean website widgets * web_editor When an user saves its website, all the animations are destroyed so that a clean DOM is saved. This is particularly important for snippets like the latest post one that would crash the page if not cleaned before saving. Two cases were found where animations were not cleaned before saving and this is what this commit fixes: - When an user used the undo/redo system, all animations were lost as the DOM is recreated. - When an user duplicated a snippet, animations were not restarted on the cloned element. closes odoo/odoo#29159 --- addons/web_editor/static/src/js/editor/rte.js | 17 ++++++++ .../static/src/js/editor/snippets.editor.js | 1 + addons/website/static/src/js/menu/edit.js | 41 +++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/addons/web_editor/static/src/js/editor/rte.js b/addons/web_editor/static/src/js/editor/rte.js index 90062a02b02..911a29cef5e 100644 --- a/addons/web_editor/static/src/js/editor/rte.js +++ b/addons/web_editor/static/src/js/editor/rte.js @@ -42,7 +42,10 @@ var History = function History($editable) { $editable.removeAttr('contentEditable').removeProp('contentEditable'); } + $editable.trigger('content_will_be_destroyed'); $editable.html(oSnap.contents).scrollTop(oSnap.scrollTop); + $editable.trigger('content_was_recreated'); + $('.oe_overlay').remove(); $('.note-control-selection').hide(); @@ -276,6 +279,20 @@ var RTEWidget = Widget.extend({ var $editable = this.editable(); + // When a undo/redo is performed, the whole DOM is changed so we have + // to prepare for it (website will restart animations for example) + // TODO should be better handled + $editable.on('content_will_be_destroyed', function (ev) { + self.trigger_up('content_will_be_destroyed', { + $target: $(ev.currentTarget), + }); + }); + $editable.on('content_was_recreated', function (ev) { + self.trigger_up('content_was_recreated', { + $target: $(ev.currentTarget), + }); + }); + $editable.addClass('o_editable') .data('rte', this) .each(function () { 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 1c208956624..bc3438f6bb7 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -336,6 +336,7 @@ var SnippetEditor = Widget.extend({ } }, }); + this.trigger_up('snippet_cloned', {$target: $clone}); }, /** * Called when the overlay dimensions/positions should be recomputed. diff --git a/addons/website/static/src/js/menu/edit.js b/addons/website/static/src/js/menu/edit.js index 15e5d4cf20e..c42e2196887 100644 --- a/addons/website/static/src/js/menu/edit.js +++ b/addons/website/static/src/js/menu/edit.js @@ -15,6 +15,9 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({ edit: '_startEditMode', }), custom_events: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.custom_events || {}, { + content_will_be_destroyed: '_onContentWillBeDestroyed', + content_was_recreated: '_onContentWasRecreated', + snippet_cloned: '_onSnippetCloned', snippet_dropped: '_onSnippetDropped', }), @@ -83,6 +86,44 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({ // Handlers //-------------------------------------------------------------------------- + /** + * Called when content will be destroyed in the page. Notifies the + * WebsiteRoot that is should stop the animations. + * + * @private + * @param {OdooEvent} ev + */ + _onContentWillBeDestroyed: function (ev) { + this.trigger_up('animation_stop_demand', { + $target: ev.data.$target, + }); + }, + /** + * Called when content will be recreated in the page. Notifies the + * WebsiteRoot that is should start the animations. + * + * @private + * @param {OdooEvent} ev + */ + _onContentWasRecreated: function (ev) { + this.trigger_up('animation_start_demand', { + editableMode: true, + $target: ev.data.$target, + }); + }, + /** + * Called when a snippet is cloned in the page. Notifies the WebsiteRoot + * that is should start the animations for this snippet. + * + * @private + * @param {OdooEvent} ev + */ + _onSnippetCloned: function (ev) { + this.trigger_up('animation_start_demand', { + editableMode: true, + $target: ev.data.$target, + }); + }, /** * Called when a snippet is dropped in the page. Notifies the WebsiteRoot * that is should start the animations for this snippet.