diff options
| author | Samuel Degueldre <sad@odoo.com> | 2020-10-22 10:42:54 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2020-11-02 17:03:56 +0000 |
| commit | d649232e49a8bca55ba8684a605fd34068138cf6 (patch) | |
| tree | cab8a0328c5dd3bbff38647e9a7326efa17c7b99 /addons/web_editor/static/src | |
| parent | 0a23a2bb65f6e59e4db545e6736c754c55463b15 (diff) | |
[FIX] web_editor: DOM is not cleaned before saving custom snippets
Previously, when saving a custom snippet, the outerHTML of the snippet
was naively read directly and saved as a new custom snippet.
Unfortunately this completely bypasses all cleanup mechanisms that we
have before saving, such as stopping the public widgets, or creating
attachments for cropped or optimized images. This would result in weird
bugs, where public widgets would appear twice when dropping a custom
snippet containing one, as well as the creating a new attachment for any
image that was optimized or cropped before saving the custom snippet
every time it was dropped in the page again.
Unfortunately there is no good mechanism for an option to ask the editor
to clean the DOM without actually saving it, as a temporary measure, the
snippet-save option will instead save the whole page (which will clean
up the DOM) and save the custom snippet after the save, before
refreshing the page and reopening the editor, not unlike some theme
options.
task-2341612
closes odoo/odoo#61202
X-original-commit: 2fa955267a3f81495be82c4214abd8befcf1fc95
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Diffstat (limited to 'addons/web_editor/static/src')
| -rw-r--r-- | addons/web_editor/static/src/js/editor/snippets.editor.js | 6 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/editor/snippets.options.js | 54 |
2 files changed, 47 insertions, 13 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 ea9b0a8e64f..c8ac1b23cf1 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -2399,6 +2399,12 @@ var SnippetsMenu = Widget.extend({ }); }, /** + * UNUSED: used to be called when saving a custom snippet. We now save and + * reload the page when saving a custom snippet so that all the DOM cleanup + * mechanisms are run before saving. Kept for compatibility. + * + * TODO: remove in master / find a way to clean the DOM without save+reload + * * @private */ _onReloadSnippetTemplate: async function (ev) { diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 652a05571cd..d2935b8ccac 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -4,6 +4,7 @@ odoo.define('web_editor.snippets.options', function (require) { var core = require('web.core'); const {ColorpickerWidget} = require('web.Colorpicker'); const Dialog = require('web.Dialog'); +const rpc = require('web.rpc'); const time = require('web.time'); var Widget = require('web.Widget'); var ColorPaletteWidget = require('web_editor.ColorPalette').ColorPaletteWidget; @@ -4601,27 +4602,54 @@ registry.SnippetSave = SnippetOptionWidget.extend({ classes: 'btn-primary', close: true, click: async () => { - const snippetName = dialog.el.querySelector('.o_we_snippet_name_input').value; - const targetCopyEl = this.$target[0].cloneNode(true); - delete targetCopyEl.dataset.name; + const save = await new Promise(resolve => { + Dialog.confirm(this, _t("To save a snippet, we need to save all your previous modifications and reload the page."), { + buttons: [ + { + text: _t("Save and Reload"), + classes: 'btn-primary', + close: true, + click: () => resolve(true), + }, { + text: _t("Cancel"), + close: true, + click: () => resolve(false), + } + ] + }); + }); + if (!save) { + return; + } const snippetKey = this.$target[0].dataset.snippet; let thumbnailURL; this.trigger_up('snippet_thumbnail_url_request', { key: snippetKey, onSuccess: url => thumbnailURL = url, }); - await this._rpc({ - model: 'ir.ui.view', - method: 'save_snippet', - kwargs: { - 'name': snippetName, - 'arch': targetCopyEl.outerHTML, - 'template_key': this.options.snippets, - 'snippet_key': snippetKey, - 'thumbnail_url': thumbnailURL, + this.trigger_up('request_save', { + reloadEditor: true, + onSuccess: async () => { + const snippetName = dialog.el.querySelector('.o_we_snippet_name_input').value; + const targetCopyEl = this.$target[0].cloneNode(true); + delete targetCopyEl.dataset.name; + // By the time onSuccess is called after request_save, the + // current widget has been destroyed and is orphaned, so this._rpc + // will not work as it can't trigger_up. For this reason, we need + // to bypass the service provider and use the global RPC directly + await rpc.query({ + model: 'ir.ui.view', + method: 'save_snippet', + kwargs: { + 'name': snippetName, + 'arch': targetCopyEl.outerHTML, + 'template_key': this.options.snippets, + 'snippet_key': snippetKey, + 'thumbnail_url': thumbnailURL, + }, + }); }, }); - this.trigger_up('reload_snippet_template'); }, }, { text: _t("Discard"), |
