From f36306c8ff5c963cfd4f77ae11ec247a25478351 Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Mon, 25 Apr 2022 13:20:18 +0000 Subject: [PATCH] [FIX] web: fix ComponentWrapper lifecycle on out-of-DOM updates Previously, updating a component that was mounted out of the DOM would rerender it and patch it. In owl 1, patched was not called when a component was mounted outside of the document. This caused crashes when something done in onPatched depended on something done in onMounted (as mounted is also not called when not it the DOM, which was handled correctly by the compatibility layer). This commit fixes that by ignoring requests to render a component that is not yet in the DOM as a new render will be initiated anyway when mounting the component in the document for real. closes odoo/odoo#89935 X-original-commit: fc6a843abe52cfee084ed476f00a12a8ba1d1669 Signed-off-by: Lucas Perais (lpe) Signed-off-by: Samuel Degueldre --- addons/web/static/src/legacy/js/owl_compatibility.js | 3 +++ .../web/static/tests/legacy/owl_compatibility_tests.js | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/legacy/js/owl_compatibility.js b/addons/web/static/src/legacy/js/owl_compatibility.js index 2dbc895aa32..cd9eb32836e 100644 --- a/addons/web/static/src/legacy/js/owl_compatibility.js +++ b/addons/web/static/src/legacy/js/owl_compatibility.js @@ -626,6 +626,9 @@ odoo.define('web.OwlCompatibility', function (require) { } render() { + if (this.status !== "mounted") { + return; + } if (this.renderProm) { this.node.render(true); return this.renderProm; diff --git a/addons/web/static/tests/legacy/owl_compatibility_tests.js b/addons/web/static/tests/legacy/owl_compatibility_tests.js index 89df699aea6..8296fd01041 100644 --- a/addons/web/static/tests/legacy/owl_compatibility_tests.js +++ b/addons/web/static/tests/legacy/owl_compatibility_tests.js @@ -1060,7 +1060,7 @@ odoo.define('web.OwlCompatibilityTests', function (require) { }); QUnit.test("lifecycle mount in fragment", async function (assert) { - assert.expect(17); + assert.expect(18); class MyChildComponent extends LegacyComponent { setup() { @@ -1077,8 +1077,8 @@ odoo.define('web.OwlCompatibilityTests', function (require) { MyComponent.components = { MyChildComponent }; const MyWidget = WidgetAdapter.extend({ start() { - let component = new ComponentWrapper(this, MyComponent, {}); - return component.mount(this.el); + this.component = new ComponentWrapper(this, MyComponent, {}); + return this.component.mount(this.el); } }); @@ -1097,6 +1097,9 @@ odoo.define('web.OwlCompatibilityTests', function (require) { "onRendered MyChildComponent", ]); + await widget.component.update({}); + assert.verifySteps([]); // Out of DOM: shouldn't do anything. + widget.$el.appendTo(target); widget.on_attach_callback(); assert.verifySteps([