From abbc068dbe1d644e76227616577d14227269f5db Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Tue, 2 Nov 2021 14:16:07 +0000 Subject: [PATCH] [FIX] web_tour: avoid reviving destroyed tip Before this commit tips could be revived after being destroyed if a resize event occurred, because the resize was being debounced and could trigger a request to rebuild the bubble mode of the tip. After this commit the resize debounce is cancelled if the tip was destroyed in the meantime. However another unidentified reason still manages to trigger an asynchronous re-creation of the tip after destroy() is called, even though all timeouts are cleared. The following remaining sequence has been identified: - mouseenter.anchor is triggered: but this is disabled during destroy - it calls _to_info_mode() which registers the timer_in timeout: but this timeout is cleared during destroy - it calls _build_info_mode() which registers the _transitionEndTimer timeout: but this timeout is cleared during destroy - it calls _onTransitionEnd() which calls _updatePosition() which revives the tip Therefore an additional guard is added to prevent _updatePosition() from being executed if destroy() was called. Note that the mouseleave > to_bubble_mode chain being symmetrical to this one, it is likely that it could also happen. task-2728994 (was task-2675252) X-original-commit: 635675398c153e123e62dd30a35ba23a29503c70 Part-of: odoo/odoo#83692 --- addons/web_tour/static/src/js/tip.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/addons/web_tour/static/src/js/tip.js b/addons/web_tour/static/src/js/tip.js index 96b3130bc7c..8c0c337b8b9 100644 --- a/addons/web_tour/static/src/js/tip.js +++ b/addons/web_tour/static/src/js/tip.js @@ -115,6 +115,10 @@ var Tip = Widget.extend({ this.$el.toggleClass('d-none', !!this.info.hidden); this.el.classList.add('o_tooltip_visible'); core.bus.on("resize", this, _.debounce(function () { + if (this.isDestroyed()) { + // Because of the debounce, destroy() might have been called in the meantime. + return; + } if (this.tip_opened) { this._to_bubble_mode(true); } else { @@ -205,6 +209,11 @@ var Tip = Widget.extend({ if (this.info.hidden) { return; } + if (this.isDestroyed()) { + // TODO This should not be needed if the chain of events leading + // here was fully cancelled by destroy(). + return; + } let halfHeight = 0; if (this.initialPosition === 'right' || this.initialPosition === 'left') { halfHeight = this.$anchor.innerHeight() / 2;