From fb05e0f554dbd3e94bef990d665ae0ff515bdea2 Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Tue, 23 Mar 2021 12:56:42 +0000 Subject: [PATCH] [FIX] web_editor: fix race condition in option selection Previously, when selecting certain options, especially ones which had slow updateUI methods, the selected value was sometimes reset to its previous value. This was caused by a race condition in which, when a snippet option updated its value, it would wait for options on the parent snippet editors to update all of their options' UI, but it incorrectly only waited for *one* of the snippet editors to finish instead of waiting for all of them. This commit fixes that by stopping the event propagation and triggering a new event that will let the direct parent know when all parent editors are done updating their options' UI before signalling that the UI update is done. task-2487578 closes odoo/odoo#68341 X-original-commit: 7623a0c771495cd41bf40af37c0d2b6e4beb7cdc Signed-off-by: Quentin Smetz (qsm) Co-authored-by: Arthur Detroux --- .../static/src/js/editor/snippets.editor.js | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 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 968f53c96c7..4b87155fbdb 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -856,18 +856,32 @@ var SnippetEditor = Widget.extend({ * @param {OdooEvent} ev */ _onSnippetOptionUpdate: async function (ev) { - const proms1 = Object.keys(this.styles).map(key => { - return this.styles[key].updateUI({ - noVisibility: true, + if (ev.target === this) { + return; + } + ev.stopPropagation(); + const updateOptionsUI = async () => { + const proms1 = Object.keys(this.styles).map(key => { + return this.styles[key].updateUI({ + noVisibility: true, + }); }); - }); - await Promise.all(proms1); - - const proms2 = Object.keys(this.styles).map(key => { - return this.styles[key].updateUIVisibility(); - }); - await Promise.all(proms2); + await Promise.all(proms1); + const proms2 = Object.keys(this.styles).map(key => { + return this.styles[key].updateUIVisibility(); + }); + await Promise.all(proms2); + }; + // Wait for the current editor's option UI updates and the parent ones + await Promise.all([ + updateOptionsUI(), + new Promise(resolve => { + this.trigger_up('snippet_option_update', Object.assign({}, ev.data, { + onSuccess: () => resolve(), + })); + }), + ]); ev.data.onSuccess(); }, /** @@ -941,6 +955,7 @@ var SnippetsMenu = Widget.extend({ 'snippet_editor_destroyed': '_onSnippetEditorDestroyed', 'snippet_removed': '_onSnippetRemoved', 'snippet_cloned': '_onSnippetCloned', + 'snippet_option_update': '_onSnippetOptionUpdate', 'snippet_option_visibility_update': '_onSnippetOptionVisibilityUpdate', 'snippet_thumbnail_url_request': '_onSnippetThumbnailURLRequest', 'reload_snippet_dropzones': '_disableUndroppableSnippets', @@ -2673,6 +2688,14 @@ var SnippetsMenu = Widget.extend({ this._disableUndroppableSnippets(); this._updateInvisibleDOM(); }, + /** + * @private + * @param {OdooEvent} ev + */ + _onSnippetOptionUpdate: function (ev) { + ev.stopPropagation(); + ev.data.onSuccess(); + }, /** * @private * @param {OdooEvent} ev