Skip to content
Snippets Groups Projects
Commit 60d1e26f authored by qsm-odoo's avatar qsm-odoo
Browse files

[FIX] web: prevent destroyed widget from calling start (2)

This completes a commit that was made for the version saas-11.3 (12.0):
https://github.com/odoo/odoo/commit/1440c8be0337c89e3d67d6d93e614c269c8689f1



Indeed, the logic was implemented for the appendTo, prependTo, etc
methods but not for the attachTo...
This could solve unknown problems in stable versions as well but was
judged too risky to merge there. Indeed, if a real problem occurs in a
stable version because of this, the condition can be added to the
related widget individually.

The problem was found in master: during website edition, the public
widgets can be restarted if an element is edited... but sometimes the
public widgets may be restarted in the same JS stack execution. The
willStart method being async, the destroy method was called before
the start method. This does not lead not any known problem with our
current widgets but will create one for a new snippet being implemented.

closes odoo/odoo#39949

Signed-off-by: default avatarAaron Bohy (aab) <aab@odoo.com>
parent 7a18176c
No related branches found
No related tags found
No related merge requests found
......@@ -204,6 +204,9 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, {
var self = this;
this.setElement(target.$el || target);
return this.willStart().then(function () {
if (self.__parentedDestroyed) {
return;
}
return self.start();
});
},
......
......@@ -452,21 +452,24 @@ QUnit.module('core', {}, function () {
QUnit.test('start is not called when widget is destroyed', function (assert) {
assert.expect(0);
var slowWillStartPromise = testUtils.makeTestPromise();
var $fix = $( "#qunit-fixture");
const $fix = $("#qunit-fixture");
var widget = new (Widget.extend({
willStart: function () {
return slowWillStartPromise;
},
// Note: willStart is always async
const MyWidget = Widget.extend({
start: function () {
throw new Error('Should not call start method');
assert.ok(false, 'Should not call start method');
},
}))();
});
const widget = new MyWidget();
widget.appendTo($fix);
widget.destroy();
slowWillStartPromise.resolve();
const divEl = document.createElement('div');
$fix[0].appendChild(divEl);
const widget2 = new MyWidget();
widget2.attachTo(divEl);
widget2.destroy();
});
QUnit.test("don't destroy twice widget's children", function (assert) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment