From ec2bc5e47c5a259d41b4f273d98ad5fbe073f89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Souk=C3=A9ina=20Bojabza?= Date: Wed, 7 Dec 2022 13:58:18 +0000 Subject: [PATCH] [FIX] web_editor: fix race condition in grid_layout tour When trying to replace an image with the media dialog, there is first a click on the image, which activates the options of the image, and then a double-click, opening the media dialog to choose the new image. However, the media dialog does not wait for the image options to be completely initialized before opening. This behaviour is in general not problematic but if it happens quickly enough, in a tour for example, it might cause a traceback. This happens because the renderings (in `_renderCustomXML`) of the image before and after replacing it happen too closely, making the first one lose the reference to the image parent. This commit fixes this issue by waiting for the options to be fully initialized before opening the media dialog, that is, by adding an empty action in the mutex and waiting for it to complete. runbot-10692 closes odoo/odoo#108738 X-original-commit: 7667ba149aaf179f430615c4aba4b963d1d167c6 Signed-off-by: Quentin Smetz (qsm) --- .../static/src/js/editor/snippets.editor.js | 8 +++++++ .../static/src/js/wysiwyg/wysiwyg.js | 21 ++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) 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 be270c36882..f2d6a2b40d5 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -2123,6 +2123,14 @@ var SnippetsMenu = Widget.extend({ // the invisible DOM list if needed. await this._updateInvisibleDOM(); }, + /** + * Public implementation of _execWithLoadingEffect. + * + * @see this._execWithLoadingEffect for parameters + */ + execWithLoadingEffect(action, contentLoading = true, delay = 500) { + return this._execWithLoadingEffect(...arguments); + }, //-------------------------------------------------------------------------- // Private diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index 171dc161046..64f2de6e444 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -308,7 +308,14 @@ const Wysiwyg = Widget.extend({ $el.selectElement(); if (!$el.parent().hasClass('o_stars')) { - self.openMediaDialog(params); + // Waiting for all the options to be initialized before + // opening the media dialog and only if the media has not + // been deleted in the meantime. + self.waitForEmptyMutexAction().then(() => { + if ($el[0].parentElement) { + self.openMediaDialog(params); + } + }); } } }); @@ -1422,6 +1429,18 @@ const Wysiwyg = Widget.extend({ getInSelection(selector) { return getInSelection(this.odooEditor.document, selector); }, + /** + * Adds an empty action in the mutex. Can be used to wait for some options + * to be initialized before doing something else. + * + * @returns {Promise} + */ + waitForEmptyMutexAction() { + if (this.snippetsMenu) { + return this.snippetsMenu.execWithLoadingEffect(() => null, false); + } + return Promise.resolve(); + }, //-------------------------------------------------------------------------- // Private