From faab9ee9f6dd9ef8afba51151de32fdb69db1fd6 Mon Sep 17 00:00:00 2001 From: "Michael Mattiello (mcm)" Date: Mon, 3 Aug 2020 13:24:14 +0000 Subject: [PATCH] [FIX] web: form: prevent from calling mounted twice With this commit, the FormRenderer no longer directly extends the WidgetAdapterMixin. It doesn't need to as its parent class (the BasicRenderer) already uses it. Worse, they both called WidgetAdapterMixin.on_attach_callback, and thus mounted was called twice on Components in form views. closes odoo/odoo#55401 X-original-commit: 4c627abd310a131a4828e9ee6be451aeee4708db Signed-off-by: Aaron Bohy (aab) --- .../static/src/js/views/form/form_renderer.js | 12 +------- addons/web/static/tests/views/form_tests.js | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index 66d4c5d8bd2..2b91c5820ee 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -5,7 +5,6 @@ var BasicRenderer = require('web.BasicRenderer'); var config = require('web.config'); var core = require('web.core'); var dom = require('web.dom'); -const { WidgetAdapterMixin } = require('web.OwlCompatibility'); var viewUtils = require('web.viewUtils'); var _t = core._t; @@ -14,7 +13,7 @@ var qweb = core.qweb; // symbol used as key to set the node id on its widget const symbol = Symbol('form'); -var FormRenderer = BasicRenderer.extend(WidgetAdapterMixin, { +var FormRenderer = BasicRenderer.extend({ className: "o_form_view", events: _.extend({}, BasicRenderer.prototype.events, { 'click .o_notification_box .oe_field_translate': '_onTranslate', @@ -53,18 +52,10 @@ var FormRenderer = BasicRenderer.extend(WidgetAdapterMixin, { this._applyFormSizeClass(); return this._super.apply(this, arguments); }, - /** - * @override - */ - destroy() { - this._super(...arguments); - WidgetAdapterMixin.destroy.call(this); - }, /** * Called each time the form view is attached into the DOM */ on_attach_callback: function () { - WidgetAdapterMixin.on_attach_callback.call(this); this._isInDom = true; _.invoke(this.widgets, 'on_attach_callback'); this._super.apply(this, arguments); @@ -73,7 +64,6 @@ var FormRenderer = BasicRenderer.extend(WidgetAdapterMixin, { * Called each time the renderer is detached from the DOM. */ on_detach_callback: function () { - WidgetAdapterMixin.on_detach_callback.call(this); this._isInDom = false; this._super.apply(this, arguments); }, diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 5033c990c43..edc96a05e71 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -6,6 +6,7 @@ var BasicModel = require('web.BasicModel'); var concurrency = require('web.concurrency'); var core = require('web.core'); var fieldRegistry = require('web.field_registry'); +const fieldRegistryOwl = require('web.field_registry_owl'); var FormView = require('web.FormView'); var mixins = require('web.mixins'); var NotificationService = require('web.NotificationService'); @@ -9532,6 +9533,34 @@ QUnit.module('Views', { form.destroy(); delete widgetRegistry.map.test; }); + + QUnit.test('do not call mounted twice on children', async function (assert) { + assert.expect(3); + + class CustomFieldComponent extends fieldRegistryOwl.get('boolean') { + mounted() { + super.mounted(...arguments); + assert.step('mounted'); + } + willUnmount() { + super.willUnmount(...arguments); + assert.step('willUnmount'); + } + } + fieldRegistryOwl.add('custom', CustomFieldComponent); + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: `
`, + }); + + form.destroy(); + delete fieldRegistryOwl.map.custom; + + assert.verifySteps(['mounted', 'willUnmount']); + }); }); });