[FIX] web_tour: make tour system more resilient
The tour system is based on many assumptions, some of those not being true all the time. In practice, it works most of the time, but when some slight changes occurs, we may observe undeterministic behavior. This was actually the case in a dev branch working on assets: the order of some files was changed, and it caused crashes in various tours. This helped us identify two issues in the Tip class: - the Tip class may be destroyed before it is completely started (so, the destroy method should not assume that the code in start was called - the attach_to method should not resolve if the tip was destroyed meanwhile. This is critical, because some code uses that promise to act on the widget. This commit fixes both of these issues. closes odoo/odoo#67896 X-original-commit: b88b634a0363a55411290e54e37806cfec1b2de5 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
@@ -57,12 +57,15 @@ var Tip = Widget.extend({
|
||||
* Attaches the tip to the provided $anchor and $altAnchor.
|
||||
* $altAnchor is an alternative trigger that can consume the step. The tip is
|
||||
* however only displayed on the $anchor.
|
||||
*
|
||||
* Note that the returned promise stays pending if the Tip widget was
|
||||
* destroyed in the meantime.
|
||||
*
|
||||
* @param {jQuery} $anchor the node on which the tip should be placed
|
||||
* @param {jQuery} $altAnchor an alternative node that can consume the step
|
||||
* @return {Promise}
|
||||
*/
|
||||
attach_to: function ($anchor, $altAnchor) {
|
||||
attach_to: async function ($anchor, $altAnchor) {
|
||||
this._setupAnchor($anchor, $altAnchor);
|
||||
|
||||
this.is_anchor_fixed_position = this.$anchor.css("position") === "fixed";
|
||||
@@ -70,7 +73,10 @@ var Tip = Widget.extend({
|
||||
// The body never needs to have the o_tooltip_parent class. It is a
|
||||
// safe place to put the tip in the DOM at initialization and be able
|
||||
// to compute its dimensions and reposition it if required.
|
||||
return this.appendTo(document.body);
|
||||
await this.appendTo(document.body);
|
||||
if (this.isDestroyed()) {
|
||||
return new Promise(() => {});
|
||||
}
|
||||
},
|
||||
start() {
|
||||
this.$tooltip_overlay = this.$(".o_tooltip_overlay");
|
||||
@@ -131,8 +137,12 @@ var Tip = Widget.extend({
|
||||
$el.removeClass("o_tooltip_parent");
|
||||
}
|
||||
};
|
||||
_removeParentClass(this.$ideal_location);
|
||||
_removeParentClass(this.$furtherIdealLocation);
|
||||
if (this.$el && this.$ideal_location) {
|
||||
_removeParentClass(this.$ideal_location);
|
||||
}
|
||||
if (this.$el && this.$furtherIdealLocation) {
|
||||
_removeParentClass(this.$furtherIdealLocation);
|
||||
}
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
@@ -392,9 +402,15 @@ var Tip = Widget.extend({
|
||||
return $consumeEventAnchors;
|
||||
},
|
||||
_unbind_anchor_events: function () {
|
||||
this.$anchor.off(".anchor");
|
||||
this.$consumeEventAnchors.off(".anchor");
|
||||
this.$scrolableElement.off('.Tip');
|
||||
if (this.$anchor) {
|
||||
this.$anchor.off(".anchor");
|
||||
}
|
||||
if (this.$consumeEventAnchors) {
|
||||
this.$consumeEventAnchors.off(".anchor");
|
||||
}
|
||||
if (this.$scrolableElement) {
|
||||
this.$scrolableElement.off('.Tip');
|
||||
}
|
||||
},
|
||||
_get_spaced_inverted_position: function (position) {
|
||||
if (position === "right") return "left+" + this.info.space;
|
||||
|
||||
Reference in New Issue
Block a user