[FIX] web_editor: fix permanent loading effect on option double-click

Previously, double clicking an arrow to change the order of images in
the image-gallery snippet would cause the loading effect to permanently
stay and block the snippet editor completely. This was caused by the
fact that when clicking the arrow, the gallery snippet rebuilds itself
from scratch. After a snippet option is used (in this case, the
reordering arrow), we update the snippet overlay, and destroy
snippet-editors whose target is no longer in the DOM. When double
clicking, by the time we handle the second click, the target of the
option has been removed from the DOM, and the widget has been destroyed.
However, when we try to apply the option anyway, we trigger_up some
events (eg to refresh the public widgets) and wait for the trigger_up to
call back. Since the widget is already destroyed, it no longer has a
parent and trigger_up fails silently, never calling us back, and
blocking the mutex.

This commit fixes that by checking whether the widget is destroyed
before trying to apply the option, bailing immediately if it is the
case, and unlocking the mutex.

opw-2394953

closes odoo/odoo#63557

X-original-commit: b23dd1b20fbd656d40e2d8bc4a32a27652e50ee1
Signed-off-by: Samuel Degueldre <sdegueldre@users.noreply.github.com>
This commit is contained in:
Samuel Degueldre
2020-12-17 19:49:07 +00:00
parent 8253664223
commit e8b2b966b8
@@ -2868,6 +2868,12 @@ const SnippetOptionWidget = Widget.extend({
// Ask a mutexed snippet update according to the widget value change
const shouldRecordUndo = (!previewMode && !ev.data.isSimulatedEvent);
this.trigger_up('snippet_edition_request', {exec: async () => {
// If some previous snippet edition in the mutex removed the target from
// the DOM, the widget can be destroyed, in that case the edition request
// is now useless and can be discarded.
if (this.isDestroyed()) {
return;
}
// Filter actions that are counterbalanced by earlier/later actions
const actionQueue = this._actionQueues.get(widget).filter(({previewMode}, i, actions) => {
const prev = actions[i - 1];