diff --git a/src/component/directive.ts b/src/component/directive.ts index 2d517319..ed293df9 100644 --- a/src/component/directive.ts +++ b/src/component/directive.ts @@ -443,7 +443,7 @@ QWeb.addDirective({ ); ctx.addLine(`const fiber = w${componentID}.__owl__.currentFiber;`); ctx.addLine( - `def${defID}.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; ${createHook}});` + `def${defID}.then(function () { if (fiber.isCompleted) { w${componentID}.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; ${createHook}});` ); if (registerCode) { ctx.addLine(registerCode); diff --git a/tests/__snapshots__/animations.test.ts.snap b/tests/__snapshots__/animations.test.ts.snap index 23f9bc14..3647b7a3 100644 --- a/tests/__snapshots__/animations.test.ts.snap +++ b/tests/__snapshots__/animations.test.ts.snap @@ -35,7 +35,7 @@ exports[`animations t-transition combined with component 1`] = ` }; utils.transitionRemove(vn, 'chimay', finalize);}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -80,7 +80,7 @@ exports[`animations t-transition combined with t-component and t-if 1`] = ` }; utils.transitionRemove(vn, 'chimay', finalize);}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } diff --git a/tests/component/__snapshots__/component.test.ts.snap b/tests/component/__snapshots__/component.test.ts.snap index 9bfff75a..c797c165 100644 --- a/tests/component/__snapshots__/component.test.ts.snap +++ b/tests/component/__snapshots__/component.test.ts.snap @@ -61,7 +61,7 @@ exports[`basic widget properties reconciliation alg works for t-foreach in t-for let def8 = w9.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k10, hook: {insert(vn) { let nvn=w9.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w9.destroy();}}}); const fiber = w9.__owl__.currentFiber; - def8.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def8.then(function () { if (fiber.isCompleted) { w9.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w9.__owl__.pvnode = pvnode; } @@ -105,7 +105,7 @@ exports[`class and style attributes with t-component dynamic t-att-style is prop let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.style = _6;}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.style = _6;}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -150,7 +150,7 @@ exports[`class and style attributes with t-component t-att-class is properly add let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;context.__owl__.refs[ref6] = w3;},remove() {},destroy(vn) {w3.destroy();delete context.__owl__.refs[ref6];}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -210,7 +210,7 @@ exports[`class and style attributes with t-component t-att-class is properly add let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;context.__owl__.refs[ref6] = w3;},remove() {},destroy(vn) {w3.destroy();delete context.__owl__.refs[ref6];}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -282,7 +282,7 @@ exports[`composition sub components with some state rendered in a loop 1`] = ` let def6 = w7.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k8, hook: {insert(vn) { let nvn=w7.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}}); const fiber = w7.__owl__.currentFiber; - def6.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def6.then(function () { if (fiber.isCompleted) { w7.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w7.__owl__.pvnode = pvnode; } @@ -324,7 +324,7 @@ exports[`composition t-component with dynamic value 1`] = ` let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -365,7 +365,7 @@ exports[`composition t-component with dynamic value 2 1`] = ` let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -406,7 +406,7 @@ exports[`dynamic t-props basic use 1`] = ` let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -451,7 +451,7 @@ exports[`other directives with t-component t-on with getter as handler 1`] = ` let def3 = w4.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k5, hook: {insert(vn) { let nvn=w4.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}}); const fiber = w4.__owl__.currentFiber; - def3.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['handler'];if (fn) { fn.call(owner, e); } else { owner.handler; }});}};}); + def3.then(function () { if (fiber.isCompleted) { w4.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['handler'];if (fn) { fn.call(owner, e); } else { owner.handler; }});}};}); c1.push(pvnode); w4.__owl__.pvnode = pvnode; } @@ -492,7 +492,7 @@ exports[`other directives with t-component t-on with handler bound to argument 1 let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, 3, e); } else { owner.onEv; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, 3, e); } else { owner.onEv; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -533,7 +533,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, {}, e); } else { owner.onEv; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, {}, e); } else { owner.onEv; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -574,7 +574,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, {}, e); } else { owner.onEv; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, {}, e); } else { owner.onEv; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -615,7 +615,7 @@ exports[`other directives with t-component t-on with handler bound to object 1`] let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, {val:3}, e); } else { owner.onEv; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, {val:3}, e); } else { owner.onEv; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -660,7 +660,7 @@ exports[`other directives with t-component t-on with inline statement 1`] = ` let def3 = w4.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k5, hook: {insert(vn) { let nvn=w4.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}}); const fiber = w4.__owl__.currentFiber; - def3.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['state.counter++'];if (fn) { fn.call(owner, e); } else { owner.state.counter++; }});}};}); + def3.then(function () { if (fiber.isCompleted) { w4.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['state.counter++'];if (fn) { fn.call(owner, e); } else { owner.state.counter++; }});}};}); c1.push(pvnode); w4.__owl__.pvnode = pvnode; } @@ -701,7 +701,7 @@ exports[`other directives with t-component t-on with no handler (only modifiers) let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, e); } else { owner.onEv; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, e); } else { owner.onEv; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -742,7 +742,7 @@ exports[`other directives with t-component t-on with prevent and self modifiers let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {e.preventDefault();if (e.target !== vn.elm) {return}const fn = owner['onEv'];if (fn) { fn.call(owner, e); } else { owner.onEv; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {e.preventDefault();if (e.target !== vn.elm) {return}const fn = owner['onEv'];if (fn) { fn.call(owner, e); } else { owner.onEv; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -783,7 +783,7 @@ exports[`other directives with t-component t-on with self and prevent modifiers let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (e.target !== vn.elm) {return}e.preventDefault();const fn = owner['onEv'];if (fn) { fn.call(owner, e); } else { owner.onEv; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (e.target !== vn.elm) {return}e.preventDefault();const fn = owner['onEv'];if (fn) { fn.call(owner, e); } else { owner.onEv; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -824,7 +824,7 @@ exports[`other directives with t-component t-on with self modifier 1`] = ` let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {const fn = owner['onEv1'];if (fn) { fn.call(owner, e); } else { owner.onEv1; }});vn.elm.addEventListener('ev-2', function (e) {if (e.target !== vn.elm) {return}const fn = owner['onEv2'];if (fn) { fn.call(owner, e); } else { owner.onEv2; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {const fn = owner['onEv1'];if (fn) { fn.call(owner, e); } else { owner.onEv1; }});vn.elm.addEventListener('ev-2', function (e) {if (e.target !== vn.elm) {return}const fn = owner['onEv2'];if (fn) { fn.call(owner, e); } else { owner.onEv2; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -865,7 +865,7 @@ exports[`other directives with t-component t-on with stop and/or prevent modifie let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {e.stopPropagation();const fn = owner['onEv1'];if (fn) { fn.call(owner, e); } else { owner.onEv1; }});vn.elm.addEventListener('ev-2', function (e) {e.preventDefault();const fn = owner['onEv2'];if (fn) { fn.call(owner, e); } else { owner.onEv2; }});vn.elm.addEventListener('ev-3', function (e) {e.stopPropagation();e.preventDefault();const fn = owner['onEv3'];if (fn) { fn.call(owner, e); } else { owner.onEv3; }});}};}); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {e.stopPropagation();const fn = owner['onEv1'];if (fn) { fn.call(owner, e); } else { owner.onEv1; }});vn.elm.addEventListener('ev-2', function (e) {e.preventDefault();const fn = owner['onEv2'];if (fn) { fn.call(owner, e); } else { owner.onEv2; }});vn.elm.addEventListener('ev-3', function (e) {e.stopPropagation();e.preventDefault();const fn = owner['onEv3'];if (fn) { fn.call(owner, e); } else { owner.onEv3; }});}};}); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -925,7 +925,7 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = ` let def3 = w4.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k5, hook: {insert(vn) { let nvn=w4.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}}); const fiber = w4.__owl__.currentFiber; - def3.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def3.then(function () { if (fiber.isCompleted) { w4.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w4.__owl__.pvnode = pvnode; } @@ -983,7 +983,7 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument let def6 = w7.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k8, hook: {insert(vn) { let nvn=w7.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}}); const fiber = w7.__owl__.currentFiber; - def6.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, arg10, e); } else { owner.onEv; }});}};}); + def6.then(function () { if (fiber.isCompleted) { w7.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, arg10, e); } else { owner.onEv; }});}};}); c1.push(pvnode); w7.__owl__.pvnode = pvnode; } @@ -1284,7 +1284,7 @@ exports[`t-slot directive can define and call slots 1`] = ` let def2 = w3.__prepare(extra.fiber, {}, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } @@ -1530,7 +1530,7 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = ` let def8 = w9.__prepare(extra.fiber, Object.assign({}, scope), undefined, sibling); let pvnode = h('dummy', {key: k10, hook: {insert(vn) { let nvn=w9.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w9.destroy();}}}); const fiber = w9.__owl__.currentFiber; - def8.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def8.then(function () { if (fiber.isCompleted) { w9.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c7.push(pvnode); w9.__owl__.pvnode = pvnode; } @@ -1634,7 +1634,7 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = ` let def9 = w10.__prepare(extra.fiber, Object.assign({}, scope), {_8}, sibling); let pvnode = h('dummy', {key: k11, hook: {insert(vn) { let nvn=w10.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w10.destroy();}}}); const fiber = w10.__owl__.currentFiber; - def9.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def9.then(function () { if (fiber.isCompleted) { w10.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c7.push(pvnode); w10.__owl__.pvnode = pvnode; } @@ -1692,7 +1692,7 @@ exports[`t-slot directive slots are rendered with proper context, part 4 1`] = ` let def3 = w4.__prepare(extra.fiber, {}, {_2}, sibling); let pvnode = h('dummy', {key: k5, hook: {insert(vn) { let nvn=w4.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}}); const fiber = w4.__owl__.currentFiber; - def3.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def3.then(function () { if (fiber.isCompleted) { w4.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w4.__owl__.pvnode = pvnode; } @@ -1767,7 +1767,7 @@ exports[`top level sub widgets basic use 1`] = ` let def1 = w2.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k3, hook: {insert(vn) { let nvn=w2.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w2.destroy();}}}); const fiber = w2.__owl__.currentFiber; - def1.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def1.then(function () { if (fiber.isCompleted) { w2.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); utils.defineProxy(vn5, pvnode); w2.__owl__.pvnode = pvnode; } @@ -1810,7 +1810,7 @@ exports[`top level sub widgets can select a sub widget 1`] = ` let def1 = w2.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k3, hook: {insert(vn) { let nvn=w2.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w2.destroy();}}}); const fiber = w2.__owl__.currentFiber; - def1.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def1.then(function () { if (fiber.isCompleted) { w2.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); utils.defineProxy(vn5, pvnode); w2.__owl__.pvnode = pvnode; } @@ -1840,7 +1840,7 @@ exports[`top level sub widgets can select a sub widget 1`] = ` let def6 = w7.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k8, hook: {insert(vn) { let nvn=w7.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}}); const fiber = w7.__owl__.currentFiber; - def6.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def6.then(function () { if (fiber.isCompleted) { w7.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); utils.defineProxy(vn10, pvnode); w7.__owl__.pvnode = pvnode; } diff --git a/tests/component/__snapshots__/props_validation.test.ts.snap b/tests/component/__snapshots__/props_validation.test.ts.snap index 4c1d6b50..17dd7e5b 100644 --- a/tests/component/__snapshots__/props_validation.test.ts.snap +++ b/tests/component/__snapshots__/props_validation.test.ts.snap @@ -32,7 +32,7 @@ exports[`props validation props are validated in dev mode (code snapshot) 1`] = let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); c1.push(pvnode); w3.__owl__.pvnode = pvnode; } diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts index a8b100ad..80ebc8bd 100644 --- a/tests/component/component.test.ts +++ b/tests/component/component.test.ts @@ -975,6 +975,41 @@ describe("destroy method", () => { await nextTick(); expect(fixture.innerHTML).toBe("
12
"); }); + + test("destroying a widget before being mounted (2)", async () => { + const def = makeDeferred(); + const steps: string[] = []; + class Child extends Component { + static template = xml``; + willStart() { + steps.push("willStart"); + return def; + } + __destroy(parent) { + steps.push("__destroy"); + super.__destroy(parent); + } + } + class Parent extends Component { + static template = xml`
`; + static components = { Child }; + state = useState({ flag: true }); + } + + const parent = new Parent(); + const prom = parent.mount(fixture); + await nextTick(); // wait for Child to be instantiated + parent.state.flag = false; + await prom; + expect(fixture.innerHTML).toBe("
"); + // we can't easily detect that we have to destroy the component before + // willStart is resolved. However, willStart should have no side-effect + // (like dispatching an action), so it's probably fine + expect(steps).toEqual(["willStart"]); + def.resolve(); + await nextTick(); + expect(steps).toEqual(["willStart", "__destroy"]); + }); }); describe("composition", () => { diff --git a/tests/router/__snapshots__/route_component.test.ts.snap b/tests/router/__snapshots__/route_component.test.ts.snap index a2c896e4..140af816 100644 --- a/tests/router/__snapshots__/route_component.test.ts.snap +++ b/tests/router/__snapshots__/route_component.test.ts.snap @@ -35,7 +35,7 @@ exports[`RouteComponent can render simple cases 1`] = ` let def2 = w3.__prepare(extra.fiber, undefined, undefined, sibling); let pvnode = h('dummy', {key: k4, hook: {insert(vn) { let nvn=w3.__mount(fiber, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}}); const fiber = w3.__owl__.currentFiber; - def2.then(function () {if (fiber.isCompleted) {return;} const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); + def2.then(function () { if (fiber.isCompleted) { w3.destroy(); return; } const vnode = fiber.vnode; pvnode.sel = vnode.sel; }); utils.defineProxy(vn6, pvnode); w3.__owl__.pvnode = pvnode; }