[FIX] web: call do_hide/do_show on a destroyed widget

Before this commit, calling do_hide/do_show/do_toggle on a
widget that had been destroyed before being rendered crashed
(because this.$el was undefined).

Obviously, calling those methods in this situation is useless, but
with asynchronous code, it might happen that you call them in an
handler, and they have been destroyed meanwhile.

This commit checks if this.$el is set before accessing it to avoid
the crash.

closes odoo/odoo#65897

X-original-commit: 320c29f5b37d4f02b4d5f7b1b6ff64462b000c92
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
Aaron Bohy
2021-02-10 15:42:33 +00:00
parent 1db8e17ef7
commit d9880122db
2 changed files with 28 additions and 3 deletions
+7 -3
View File
@@ -214,13 +214,17 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, {
* Hides the widget
*/
do_hide: function () {
this.$el.addClass('o_hidden');
if (this.$el) {
this.$el.addClass('o_hidden');
}
},
/**
* Displays the widget
*/
do_show: function () {
this.$el.removeClass('o_hidden');
if (this.$el) {
this.$el.removeClass('o_hidden');
}
},
/**
* Displays or hides the widget
@@ -229,7 +233,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, {
do_toggle: function (display) {
if (_.isBoolean(display)) {
display ? this.do_show() : this.do_hide();
} else {
} else if (this.$el) {
this.$el.hasClass('o_hidden') ? this.do_show() : this.do_hide();
}
},
@@ -450,6 +450,27 @@ QUnit.module('core', {}, function () {
parent.destroy();
});
QUnit.test("calling do_hide on a widget destroyed before being rendered", async function (assert) {
assert.expect(1);
const MyWidget = Widget.extend({
willStart() {
return new Promise(() => {});
}
});
const widget = new MyWidget();
widget.appendTo(document.createDocumentFragment());
widget.destroy();
// those calls should not crash
widget.do_hide();
widget.do_show();
widget.do_toggle(true);
assert.ok(true);
});
QUnit.test('start is not called when widget is destroyed', function (assert) {
assert.expect(0);
const $fix = $("#qunit-fixture");