From 59e1bdff221f4a099f6000eb9884f84f772c38bb Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Wed, 17 Jan 2018 14:31:35 +0100 Subject: [PATCH] [FIX] web_editor, website: properly clean snippets before saving /!\ Partial backport of https://github.com/odoo/odoo/commit/0a31cb9b4ae461119ecafdd05c5b979621ffb039 /!\ Should not be forward-ported Before the websitepocalypse introduced in 11.0 (saas-17), when saving a page in the editor, every `cleanForSave` method of snippet options were called, even for snippet options which were not initialized (so if a snippet was left unchanged before saving, the related `cleanForSave` methods were called anyway). This behavior was bad code and did not make much sense and was so removed with the websitepocalypse (see https://github.com/odoo/odoo/commit/2972976962617d4b8a0113bae58c640ab41cdff8#diff-4c580abda3220e45c6b3f6bdcf77c733L415) Unfortunatly, the behavior was necessary given the states of our snippet options. Indeed, for the "latest posts" snippet, the `cleanForSave` method removes the entire snippet content (as it is dynamically loaded). The dynamic loading is performed by the snippet *animation*... and removing the dynamic content should logically be done by the animation too... which is the case. The problem is that animations are not stopped before the editor is saved. This behavior was only implemented in saas-11.1 (for future version 12.0) with commit https://github.com/odoo/odoo/commit/0a31cb9b4ae461119ecafdd05c5b979621ffb039 As a stable fix for 11.0, part of the mentioned commit is backported here and some specific `cleanForSave` will be reviewed as animations if necessary. Note: `cleanForSave` made useless by this commit are left anyway as this is a stable fix. See https://github.com/odoo/odoo/issues/22089 --- .../static/src/js/editor/snippets.editor.js | 1 + .../static/src/js/content/website_root.js | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) 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 5f721fd4805..1c208956624 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -622,6 +622,7 @@ var SnippetsMenu = Widget.extend({ * - Remove the 'contentEditable' attributes */ cleanForSave: function () { + this.trigger_up('ready_to_clean_for_save'); _.each(this.snippetEditors, function (snippetEditor) { snippetEditor.cleanForSave(); }); diff --git a/addons/website/static/src/js/content/website_root.js b/addons/website/static/src/js/content/website_root.js index aaa45e45c18..ab1de2ea357 100644 --- a/addons/website/static/src/js/content/website_root.js +++ b/addons/website/static/src/js/content/website_root.js @@ -43,8 +43,16 @@ var WebsiteRoot = BodyManager.extend({ }), custom_events: _.extend({}, BodyManager.prototype.custom_events || {}, { animation_start_demand: '_onAnimationStartDemand', + ready_to_clean_for_save: '_onAnimationStopDemand', }), + /** + * @constructor + */ + init: function () { + this._super.apply(this, arguments); + this.animations = []; + }, /** * @override */ @@ -108,6 +116,7 @@ var WebsiteRoot = BodyManager.extend({ * registry has been instantiated outside of the class and is simply * returned here. * + * @private * @override */ _getRegistry: function () { @@ -118,6 +127,7 @@ var WebsiteRoot = BodyManager.extend({ * `selector` key of one of the registered animations * (@see Animation.selector). * + * @private * @param {boolean} [editableMode=false] - true if the page is in edition mode * @param {jQuery} [$from] * only initialize the animations whose `selector` matches the @@ -138,9 +148,11 @@ var WebsiteRoot = BodyManager.extend({ var $snippet = $(el); var animation = $snippet.data('snippet-view'); if (animation) { + self.animations = _.without(self.animations, animation); animation.destroy(); } animation = new Animation(self, editableMode); + self.animations.push(animation); $snippet.data('snippet-view', animation); return animation.attachTo($snippet); }); @@ -148,6 +160,18 @@ var WebsiteRoot = BodyManager.extend({ }); return $.when.apply($, defs); }, + /** + * Destroys all animation instances. Especially needed before saving while + * in edition mode for example. + * + * @private + */ + _stopAnimations: function () { + _.each(this.animations, function (animation) { + animation.destroy(); + }); + this.animations = []; + }, //-------------------------------------------------------------------------- // Handlers @@ -165,6 +189,15 @@ var WebsiteRoot = BodyManager.extend({ .done(ev.data.onSuccess) .fail(ev.data.onFailure); }, + /** + * Called when the root is notified that the animations have to be + * stopped. + * + * @private + */ + _onAnimationStopDemand: function () { + this._stopAnimations(); + }, /** * @todo review * @private