[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
This commit is contained in:
Benoit Socias
2022-01-31 15:33:51 +00:00
committed by qsm-odoo
parent 75c62022da
commit abbc068dbe
+9
View File
@@ -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;