summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorPierre Paridans <app@odoo.com>2021-01-19 09:39:12 +0000
committerPierre Paridans <app@odoo.com>2021-01-20 10:20:05 +0000
commit036fc78103e3d8875a5a54c797e1ba0670d02272 (patch)
tree02e5adcfc6f2d5bfae4f66ad5f8bd02865b45887 /addons
parent655597e9a3637abbaeffddcc78663e8733070db4 (diff)
[FIX] web: Dialog widget should always call on_{attach|detach}_callback
Before this commit, the `on_attach_callback` and `on_detach_callback` callbacks are not called all the time on the `Dialog` widget when it's attached/detached to the DOM. Relying on those callbacks could result in unpredictable behaviours. To be more precise, the `on_attach_callback` isn't executed on a regular Dialog#open() call. But Dialog spawned by the ActionManager will execute it. This difference prevents from properly binding those callbacks later on through an extend or include of the Dialog widget as we have no way to know if they have already been called or not (e.g. which can result in calling them twice). This commit normalize this situation by ensuring that the `on_attach_callback` and `on_detach_callback` callbacks are properly called by the Dialog widget and allows any extension of this widget to rely on them. Therefore the ActionManager is adapted accordingly. opw-2438534 closes odoo/odoo#64780 Related: odoo/enterprise#15849 Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/web/static/src/js/chrome/action_manager.js2
-rw-r--r--addons/web/static/src/js/core/dialog.js6
-rw-r--r--addons/web/static/tests/core/dialog_tests.js34
3 files changed, 41 insertions, 1 deletions
diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js
index bdcc93e022a..6cb86030fe3 100644
--- a/addons/web/static/src/js/chrome/action_manager.js
+++ b/addons/web/static/src/js/chrome/action_manager.js
@@ -396,7 +396,7 @@ var ActionManager = Widget.extend({
widget.setParent(dialog);
dom.append(dialog.$el, widget.$el, {
in_DOM: true,
- callbacks: [{widget: dialog}, {widget: controller.widget}],
+ callbacks: [{widget: controller.widget}],
});
widget.renderButtons(dialog.$footer);
dialog.rebindButtonBehavior();
diff --git a/addons/web/static/src/js/core/dialog.js b/addons/web/static/src/js/core/dialog.js
index eb567750584..70d92b41386 100644
--- a/addons/web/static/src/js/core/dialog.js
+++ b/addons/web/static/src/js/core/dialog.js
@@ -72,6 +72,9 @@ var Dialog = Widget.extend({
this._opened = new Promise(function (resolve) {
self._openedResolver = resolve;
});
+ if (this.on_attach_callback) {
+ this._opened = this.opened(this.on_attach_callback);
+ }
options = _.defaults(options || {}, {
title: _t('Odoo'), subtitle: '',
size: 'large',
@@ -256,6 +259,9 @@ var Dialog = Widget.extend({
$('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal has disappeared
if (this.$modal) {
+ if (this.on_detach_callback) {
+ this.on_detach_callback();
+ }
this.$modal.modal('hide');
this.$modal.remove();
}
diff --git a/addons/web/static/tests/core/dialog_tests.js b/addons/web/static/tests/core/dialog_tests.js
index c51239a01bb..abb1cb43251 100644
--- a/addons/web/static/tests/core/dialog_tests.js
+++ b/addons/web/static/tests/core/dialog_tests.js
@@ -124,6 +124,40 @@ QUnit.module('core', {}, function () {
parent.destroy();
});
+
+ QUnit.test("Ensure on_attach_callback and on_detach_callback are properly called", async function (assert) {
+ assert.expect(4);
+
+ const TestDialog = Dialog.extend({
+ on_attach_callback() {
+ assert.step('on_attach_callback');
+ },
+ on_detach_callback() {
+ assert.step('on_detach_callback');
+ },
+ });
+
+ const parent = await createEmptyParent();
+ const dialog = new TestDialog(parent, {
+ buttons: [
+ {
+ text: "Close",
+ classes: 'btn-primary',
+ close: true,
+ },
+ ],
+ $content: $('<main/>'),
+ }).open();
+
+ await dialog.opened();
+
+ assert.verifySteps(['on_attach_callback']);
+
+ await testUtils.dom.click($('.modal[role="dialog"] .btn-primary'));
+ assert.verifySteps(['on_detach_callback']);
+
+ parent.destroy();
+ });
});
});