diff options
| author | Pierre Paridans <app@odoo.com> | 2021-01-19 09:39:12 +0000 |
|---|---|---|
| committer | Pierre Paridans <app@odoo.com> | 2021-01-20 10:20:05 +0000 |
| commit | 036fc78103e3d8875a5a54c797e1ba0670d02272 (patch) | |
| tree | 02e5adcfc6f2d5bfae4f66ad5f8bd02865b45887 /addons | |
| parent | 655597e9a3637abbaeffddcc78663e8733070db4 (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.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/core/dialog.js | 6 | ||||
| -rw-r--r-- | addons/web/static/tests/core/dialog_tests.js | 34 |
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(); + }); }); }); |
