[FIX] component: various issues while mounting manually components

The initial problem solved by this commit is that it was possible to get
into a situation where a mounting/rendering was started, then the component was
updated, but then another mounting operation begins, and it tries to
reuse the previous rendering operation, which is no longer uptodate.

The underlying issue is that Owl did not track properly the various
internal state change of a component.  These issue should be solved by
the introduction of the status enum, which currently tracks 6 possible
states:

- CREATED
- WILLSTARTED
- RENDERED
- MOUNTED
- UNMOUNTED
- DESTROYED

This status number replaces the isMounted and isDestroyed boolean flags.
It has the advantage of making sure that the component is in a
consistent state (it is no longer possible to be destroyed and mounted,
for example)

Another advantage is that it gives us an easy way to track the fact that
a component has been rendered, but is not in the DOM.  This is a subtle
situation where some various events can happen, and we need to be able
to react to that case.

Note that there is a change of behaviour: if a component is mounted in a
specific target, then before the mounting is complete, the component is
mounted in another target, we no longer reject the first mounting
operation.
This commit is contained in:
Géry Debongnie
2021-02-03 13:12:00 +01:00
committed by aab-odoo
parent 370fae4e1a
commit 0290f63ba3
15 changed files with 214 additions and 168 deletions
@@ -20,7 +20,7 @@ exports[`class and style attributes with t-component dynamic t-att-style is prop
w2 = false;
}
if (w2) {
w2.__updateProps(props2, extra.fiber, undefined).then(()=>{if (w2.__owl__.isDestroyed) {return};w2.el.style=_4;});;
w2.__updateProps(props2, extra.fiber, undefined).then(()=>{if (w2.__owl__.status === 5) {return};w2.el.style=_4;});;
let pvnode = w2.__owl__.pvnode;
c1.push(pvnode);
} else {
@@ -444,7 +444,7 @@ exports[`composition t-ref on a node, and t-on-click 2`] = `
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('click', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('click', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -579,7 +579,7 @@ exports[`other directives with t-component t-on expression captured in t-foreach
c6.push(vn7);
const otherState_8 = scope['otherState'];
const iter_8 = scope.iter;
p7.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}otherState_8.vals.push(iter_8+'_'+iter_8)};
p7.on['click'] = function (e) {if (context.__owl__.status === 5){return}otherState_8.vals.push(iter_8+'_'+iter_8)};
c7.push({text: \`expr\`});
utils.getScope(scope, 'iter').iter = scope.iter+1;
}
@@ -630,7 +630,7 @@ exports[`other directives with t-component t-on expression in t-foreach 1`] = `
c6.push(vn9);
const otherState_10 = scope['otherState'];
const val_10 = scope['val'];
p9.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}otherState_10.vals.push(val_10)};
p9.on['click'] = function (e) {if (context.__owl__.status === 5){return}otherState_10.vals.push(val_10)};
c9.push({text: \`Expr\`});
}
scope = _origScope5;
@@ -684,7 +684,7 @@ exports[`other directives with t-component t-on expression in t-foreach with t-s
const otherState_10 = scope['otherState'];
const val_10 = scope['val'];
const bossa_10 = scope.bossa;
p9.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}otherState_10.vals.push(val_10+'_'+bossa_10)};
p9.on['click'] = function (e) {if (context.__owl__.status === 5){return}otherState_10.vals.push(val_10+'_'+bossa_10)};
c9.push({text: \`Expr\`});
}
scope = _origScope5;
@@ -734,7 +734,7 @@ exports[`other directives with t-component t-on method call in t-foreach 1`] = `
let vn9 = h('button', p9, c9);
c6.push(vn9);
let args10 = [scope['val']];
p9.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['addVal'](...args10, e);};
p9.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['addVal'](...args10, e);};
c9.push({text: \`meth call\`});
}
scope = _origScope5;
@@ -770,7 +770,7 @@ exports[`other directives with t-component t-on with .capture modifier 1`] = `
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('click', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['capture'](e);}, true);}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('click', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['capture'](e);}, true);}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -812,7 +812,7 @@ exports[`other directives with t-component t-on with getter as handler 1`] = `
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
w3 = new W3(parent, props3);
parent.__owl__.cmap['__4__'] = w3.__owl__.id;
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['handler'](e);});}});});
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['handler'](e);});}});});
let pvnode = h('dummy', {key: '__4__', hook: {remove() {},destroy(vn) {w3.destroy();}}});
c1.push(pvnode);
w3.__owl__.pvnode = pvnode;
@@ -851,7 +851,7 @@ exports[`other directives with t-component t-on with handler bound to argument 1
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -890,7 +890,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -929,7 +929,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -968,7 +968,7 @@ exports[`other directives with t-component t-on with handler bound to object 1`]
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -1011,7 +1011,7 @@ exports[`other directives with t-component t-on with inline statement 1`] = `
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
w3 = new W3(parent, props3);
parent.__owl__.cmap['__4__'] = w3.__owl__.id;
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}state_5.counter++});}});});
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}state_5.counter++});}});});
let pvnode = h('dummy', {key: '__4__', hook: {remove() {},destroy(vn) {w3.destroy();}}});
c1.push(pvnode);
w3.__owl__.pvnode = pvnode;
@@ -1049,7 +1049,7 @@ exports[`other directives with t-component t-on with no handler (only modifiers)
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -1087,7 +1087,7 @@ exports[`other directives with t-component t-on with prevent and self modifiers
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();if (e.target !== vn.elm) {return}utils.getComponent(context)['onEv'](e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}e.preventDefault();if (e.target !== vn.elm) {return}utils.getComponent(context)['onEv'](e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -1125,7 +1125,7 @@ exports[`other directives with t-component t-on with self and prevent modifiers
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}if (e.target !== vn.elm) {return}e.preventDefault();utils.getComponent(context)['onEv'](e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}if (e.target !== vn.elm) {return}e.preventDefault();utils.getComponent(context)['onEv'](e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -1163,7 +1163,7 @@ exports[`other directives with t-component t-on with self modifier 1`] = `
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv1'](e);});vn.elm.addEventListener('ev-2', function (e) {if (context.__owl__.isDestroyed){return}if (e.target !== vn.elm) {return}utils.getComponent(context)['onEv2'](e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv1'](e);});vn.elm.addEventListener('ev-2', function (e) {if (context.__owl__.status === 5){return}if (e.target !== vn.elm) {return}utils.getComponent(context)['onEv2'](e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -1201,7 +1201,7 @@ exports[`other directives with t-component t-on with stop and/or prevent modifie
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
w2 = new W2(parent, props2);
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {if (context.__owl__.isDestroyed){return}e.stopPropagation();utils.getComponent(context)['onEv1'](e);});vn.elm.addEventListener('ev-2', function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();utils.getComponent(context)['onEv2'](e);});vn.elm.addEventListener('ev-3', function (e) {if (context.__owl__.isDestroyed){return}e.stopPropagation();e.preventDefault();utils.getComponent(context)['onEv3'](e);});}});});
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {if (context.__owl__.status === 5){return}e.stopPropagation();utils.getComponent(context)['onEv1'](e);});vn.elm.addEventListener('ev-2', function (e) {if (context.__owl__.status === 5){return}e.preventDefault();utils.getComponent(context)['onEv2'](e);});vn.elm.addEventListener('ev-3', function (e) {if (context.__owl__.status === 5){return}e.stopPropagation();e.preventDefault();utils.getComponent(context)['onEv3'](e);});}});});
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
c1.push(pvnode);
w2.__owl__.pvnode = pvnode;
@@ -1555,7 +1555,7 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument
if (!W6) {throw new Error('Cannot find the definition of component \\"' + componentKey6 + '\\"')}
w6 = new W6(parent, props6);
parent.__owl__.cmap[k7] = w6.__owl__.id;
let fiber = w6.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args8, e);});}});});
let fiber = w6.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args8, e);});}});});
let pvnode = h('dummy', {key: k7, hook: {remove() {},destroy(vn) {w6.destroy();}}});
c1.push(pvnode);
w6.__owl__.pvnode = pvnode;
@@ -1580,7 +1580,7 @@ exports[`t-call handlers are properly bound through a t-call 1`] = `
let vn3 = h('p', p3, c3);
c2.push(vn3);
let k4 = \`click__4__\${key0}__\`;
extra.handlers[k4] = extra.handlers[k4] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['update'](e);};
extra.handlers[k4] = extra.handlers[k4] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['update'](e);};
p3.on['click'] = extra.handlers[k4];
c3.push({text: \`lucas\`});
}"
@@ -1599,7 +1599,7 @@ exports[`t-call handlers with arguments are properly bound through a t-call 1`]
let vn3 = h('p', p3, c3);
c2.push(vn3);
let args4 = [scope['a']];
p3.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['update'](...args4, e);};
p3.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['update'](...args4, e);};
c3.push({text: \`lucas\`});
}"
`;
@@ -229,7 +229,7 @@ exports[`t-slot directive dynamic t-slot call 1`] = `
let h = this.h;
let c10 = [], p10 = {key:10,on:{}};
let vn10 = h('button', p10, c10);
extra.handlers['click__11__'] = extra.handlers['click__11__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['toggle'](e);};
extra.handlers['click__11__'] = extra.handlers['click__11__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['toggle'](e);};
p10.on['click'] = extra.handlers['click__11__'];
const slot12 = this.constructor.slots[context.__owl__.slotId + '_' + (scope['current'].slot)];
if (slot12) {
@@ -301,7 +301,7 @@ exports[`t-slot directive refs are properly bound in slots 1`] = `
let c9 = [], p9 = {key:9,on:{}};
let vn9 = h('button', p9, c9);
c8.push(vn9);
extra.handlers['click__10__'] = extra.handlers['click__10__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](e);};
extra.handlers['click__10__'] = extra.handlers['click__10__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](e);};
p9.on['click'] = extra.handlers['click__10__'];
const ref11 = \`myButton\`;
p9.hook = {
@@ -326,7 +326,7 @@ exports[`t-slot directive slots are rendered with proper context 1`] = `
let c9 = [], p9 = {key:9,on:{}};
let vn9 = h('button', p9, c9);
c8.push(vn9);
extra.handlers['click__10__'] = extra.handlers['click__10__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](e);};
extra.handlers['click__10__'] = extra.handlers['click__10__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](e);};
p9.on['click'] = extra.handlers['click__10__'];
c9.push({text: \`do something\`});
}"
+5 -5
View File
@@ -1,4 +1,4 @@
import { Component, Env } from "../../src/component/component";
import { Component, Env, STATUS } from "../../src/component/component";
import { useState } from "../../src/hooks";
import { xml } from "../../src/tags";
import { makeDeferred, makeTestEnv, makeTestFixture, nextMicroTick, nextTick } from "../helpers";
@@ -40,14 +40,14 @@ describe("async rendering", () => {
}
}
const w = new W();
expect(w.__owl__.status).toBe(STATUS.CREATED);
w.mount(fixture);
expect(w.__owl__.isDestroyed).toBe(false);
expect(w.__owl__.isMounted).toBe(false);
expect(w.__owl__.status).toBe(STATUS.WILLSTARTED);
w.destroy();
expect(w.__owl__.status).toBe(STATUS.DESTROYED);
def.resolve();
await nextTick();
expect(w.__owl__.isDestroyed).toBe(true);
expect(w.__owl__.isMounted).toBe(false);
expect(w.__owl__.status).toBe(STATUS.DESTROYED);
});
test("destroying/recreating a subwidget with different props (if start is not over)", async () => {
+12 -15
View File
@@ -1,4 +1,4 @@
import { Component, Env, mount } from "../../src/component/component";
import { Component, Env, mount, STATUS } from "../../src/component/component";
import { EventBus } from "../../src/core/event_bus";
import { useRef, useState } from "../../src/hooks";
import { QWeb } from "../../src/qweb/qweb";
@@ -1035,8 +1035,7 @@ describe("destroy method", () => {
expect(document.contains(widget.el)).toBe(true);
widget.destroy();
expect(document.contains(widget.el)).toBe(false);
expect(widget.__owl__.isMounted).toBe(false);
expect(widget.__owl__.isDestroyed).toBe(true);
expect(widget.__owl__.status).toBe(STATUS.DESTROYED);
});
test("destroying a parent also destroys its children", async () => {
@@ -1045,9 +1044,9 @@ describe("destroy method", () => {
const child = children(parent)[0];
expect(child.__owl__.isDestroyed).toBe(false);
expect(child.__owl__.status).toBe(STATUS.MOUNTED);
parent.destroy();
expect(child.__owl__.isDestroyed).toBe(true);
expect(child.__owl__.status).toBe(STATUS.DESTROYED);
});
test("destroy remove the parent/children link", async () => {
@@ -1073,17 +1072,15 @@ describe("destroy method", () => {
}
expect(fixture.innerHTML).toBe("");
const widget = new DelayedWidget();
expect(widget.__owl__.status).toBe(STATUS.CREATED);
widget.mount(fixture);
expect(widget.__owl__.isMounted).toBe(false);
expect(widget.__owl__.isDestroyed).toBe(false);
expect(widget.__owl__.status).toBe(STATUS.WILLSTARTED);
widget.destroy();
expect(widget.__owl__.isMounted).toBe(false);
expect(widget.__owl__.isDestroyed).toBe(true);
expect(widget.__owl__.status).toBe(STATUS.DESTROYED);
def.resolve();
await nextTick();
expect(widget.__owl__.isMounted).toBe(false);
expect(widget.__owl__.isDestroyed).toBe(true);
expect(widget.__owl__.status).toBe(STATUS.DESTROYED);
expect(widget.__owl__.vnode).toBe(undefined);
expect(fixture.innerHTML).toBe("");
expect(isRendered).toBe(false);
@@ -1539,7 +1536,7 @@ describe("composition", () => {
parent.state.flag = true;
await nextTick();
expect(children(parent)[0]).toBe(child);
expect(child.__owl__.isDestroyed).toBe(false);
expect(child.__owl__.status).toBe(STATUS.MOUNTED);
expect(normalize(fixture.innerHTML)).toBe(
normalize(`
<div>
@@ -2287,7 +2284,7 @@ describe("other directives with t-component", () => {
el.click();
expect(steps).toEqual(["click"]);
parent.unmount();
expect(child.__owl__.isMounted).toBe(false);
expect(child.__owl__.status).toBe(STATUS.UNMOUNTED);
el.click();
expect(steps).toEqual(["click", "click"]);
});
@@ -2361,7 +2358,7 @@ describe("other directives with t-component", () => {
expect(steps).toEqual(["click"]);
parent.state.flag = false;
await nextTick();
expect(child.__owl__.isDestroyed).toBe(true);
expect(child.__owl__.status).toBe(STATUS.DESTROYED);
el.click();
expect(steps).toEqual(["click"]);
});
@@ -2396,7 +2393,7 @@ describe("other directives with t-component", () => {
expect(steps).toEqual(["click"]);
parent.state.flag = false;
await nextTick();
expect(child.__owl__.isDestroyed).toBe(true);
expect(child.__owl__.status).toBe(STATUS.DESTROYED);
el.click();
expect(steps).toEqual(["click"]);
});
+2 -2
View File
@@ -1,4 +1,4 @@
import { Component, Env } from "../../src/component/component";
import { Component, Env, STATUS } from "../../src/component/component";
import { useState } from "../../src/hooks";
import { xml } from "../../src/tags";
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
@@ -108,7 +108,7 @@ describe("component error handling (catchError)", () => {
expect(console.error).toBeCalledTimes(0);
console.error = consoleError;
expect(app.__owl__.isDestroyed).toBe(true);
expect(app.__owl__.status).toBe(STATUS.DESTROYED);
expect(handler).toBeCalledTimes(1);
});
+38 -4
View File
@@ -404,6 +404,40 @@ describe("unmounting and remounting", () => {
expect(fixture.innerHTML).toBe("<div>P2<span>C2</span></div>");
});
test("change state while component is mounted in a fragment", async () => {
class Child1 extends Component {
static template = xml`<span>C1</span>`;
}
class Child2 extends Component {
static template = xml`<span>C2</span>`;
}
class Parent extends Component {
static components = { Child1, Child2 };
static template = xml`
<div>
<Child1 t-if="child == 'c1'"/>
<Child2 t-if="child == 'c2'"/>
</div>`;
child: string | false = false;
}
const fragment = document.createDocumentFragment();
const parent = new Parent();
await parent.mount(fragment);
expect(parent.el.outerHTML).toBe("<div></div>");
parent.child = "c1";
parent.render();
await Promise.resolve();
parent.child = "c2";
await parent.mount(fixture);
expect(fixture.innerHTML).toBe("<div><span>C2</span></div>");
});
test("unmount component during a re-rendering", async () => {
const def = makeDeferred();
class Child extends Component {
@@ -490,17 +524,17 @@ describe("unmounting and remounting", () => {
// one full tick.
await nextMicroTick();
await nextMicroTick();
expect(steps).toEqual(["1 catch"]);
expect(steps).toEqual([]);
await nextTick();
expect(fixture.innerHTML).toBe("<div></div><span></span>");
def.resolve();
await nextTick();
expect(steps).toEqual(["1 catch", "2 resolved"]);
expect(steps).toEqual(["2 resolved"]);
expect(fixture.innerHTML).toBe("<div></div><span><div>Hey</div></span>");
});
test("widget can be mounted on same target, another situation", async () => {
test("component can be mounted on same target, another situation", async () => {
const def = makeDeferred();
const steps: string[] = [];
@@ -528,8 +562,8 @@ describe("unmounting and remounting", () => {
def.resolve();
await nextTick();
expect(steps).toEqual(["1 resolved", "2 resolved"]);
expect(fixture.innerHTML).toBe("<div>Hey</div>");
expect(steps).toEqual(["1 resolved", "2 resolved"]);
});
test("mounting a destroyed widget", async () => {
+2 -2
View File
@@ -1,4 +1,4 @@
import { Env, Component } from "../src/component/component";
import { Env, Component, STATUS } from "../src/component/component";
import { scheduler } from "../src/component/scheduler";
import { EvalContext, QWeb } from "../src/qweb/qweb";
import { CompilationContext } from "../src/qweb/compilation_context";
@@ -92,7 +92,7 @@ export function renderToDOM(
if (!context.__owl__) {
// we add `__owl__` to better simulate a component as context. This is
// particularly important for event handlers added with the `t-on` directive.
context.__owl__ = { isMounted: true };
context.__owl__ = { status: STATUS.MOUNTED };
}
const vnode = qweb.render(template, context, extra);
+26 -26
View File
@@ -2727,7 +2727,7 @@ exports[`t-on can bind event handler 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['add'](e);};
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['add'](e);};
p1.on['click'] = extra.handlers['click__2__'];
c1.push({text: \`Click\`});
return vn1;
@@ -2744,7 +2744,7 @@ exports[`t-on can bind handlers with arguments 1`] = `
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
let args2 = [5];
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['add'](...args2, e);};
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['add'](...args2, e);};
c1.push({text: \`Click\`});
return vn1;
}"
@@ -2760,7 +2760,7 @@ exports[`t-on can bind handlers with empty object (with non empty inner string)
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
let args2 = [{}];
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](...args2, e);};
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](...args2, e);};
c1.push({text: \`Click\`});
return vn1;
}"
@@ -2776,7 +2776,7 @@ exports[`t-on can bind handlers with empty object 1`] = `
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
let args2 = [{}];
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](...args2, e);};
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](...args2, e);};
c1.push({text: \`Click\`});
return vn1;
}"
@@ -2815,7 +2815,7 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
let vn7 = h('a', p7, c7);
c6.push(vn7);
let args8 = [scope['action']];
p7.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['activate'](...args8, e);};
p7.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['activate'](...args8, e);};
c7.push({text: \`link\`});
}
scope = _origScope5;
@@ -2833,7 +2833,7 @@ exports[`t-on can bind handlers with object arguments 1`] = `
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
let args2 = [{val:5}];
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['add'](...args2, e);};
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['add'](...args2, e);};
c1.push({text: \`Click\`});
return vn1;
}"
@@ -2847,9 +2847,9 @@ exports[`t-on can bind two event handlers 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['handleClick'](e);};
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['handleClick'](e);};
p1.on['click'] = extra.handlers['click__2__'];
extra.handlers['dblclick__3__'] = extra.handlers['dblclick__3__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['handleDblClick'](e);};
extra.handlers['dblclick__3__'] = extra.handlers['dblclick__3__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['handleDblClick'](e);};
p1.on['dblclick'] = extra.handlers['dblclick__3__'];
c1.push({text: \`Click\`});
return vn1;
@@ -2864,7 +2864,7 @@ exports[`t-on handler is bound to proper owner 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['add'](e);};
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['add'](e);};
p1.on['click'] = extra.handlers['click__2__'];
c1.push({text: \`Click\`});
return vn1;
@@ -2883,7 +2883,7 @@ exports[`t-on t-on combined with t-esc 1`] = `
let c2 = [], p2 = {key:2,on:{}};
let vn2 = h('button', p2, c2);
c1.push(vn2);
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onClick'](e);};
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onClick'](e);};
p2.on['click'] = extra.handlers['click__3__'];
let _4 = scope['text'];
if (_4 != null) {
@@ -2905,7 +2905,7 @@ exports[`t-on t-on combined with t-raw 1`] = `
let c2 = [], p2 = {key:2,on:{}};
let vn2 = h('button', p2, c2);
c1.push(vn2);
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onClick'](e);};
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onClick'](e);};
p2.on['click'] = extra.handlers['click__3__'];
let _4 = scope['html'];
if (_4 != null) {
@@ -2923,12 +2923,12 @@ exports[`t-on t-on with .capture modifier 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('div', p1, c1);
extra.handlers['!click__2__'] = extra.handlers['!click__2__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onCapture'](e);};
extra.handlers['!click__2__'] = extra.handlers['!click__2__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onCapture'](e);};
p1.on['!click'] = extra.handlers['!click__2__'];
let c3 = [], p3 = {key:3,on:{}};
let vn3 = h('button', p3, c3);
c1.push(vn3);
extra.handlers['click__4__'] = extra.handlers['click__4__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](e);};
extra.handlers['click__4__'] = extra.handlers['click__4__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](e);};
p3.on['click'] = extra.handlers['click__4__'];
c3.push({text: \`Button\`});
return vn1;
@@ -2946,7 +2946,7 @@ exports[`t-on t-on with empty handler (only modifiers) 1`] = `
let c2 = [], p2 = {key:2,on:{}};
let vn2 = h('button', p2, c2);
c1.push(vn2);
p2.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();};
p2.on['click'] = function (e) {if (context.__owl__.status === 5){return}e.preventDefault();};
c2.push({text: \`Button\`});
return vn1;
}"
@@ -2961,7 +2961,7 @@ exports[`t-on t-on with inline statement (function call) 1`] = `
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
const state_2 = scope['state'];
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}state_2.incrementCounter(2)};
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}state_2.incrementCounter(2)};
c1.push({text: \`Click\`});
return vn1;
}"
@@ -2976,7 +2976,7 @@ exports[`t-on t-on with inline statement 1`] = `
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
const state_2 = scope['state'];
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}state_2.counter++};
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}state_2.counter++};
c1.push({text: \`Click\`});
return vn1;
}"
@@ -2991,7 +2991,7 @@ exports[`t-on t-on with inline statement, part 2 1`] = `
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
const state_2 = scope['state'];
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}state_2.flag=!state_2.flag};
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}state_2.flag=!state_2.flag};
c1.push({text: \`Toggle\`});
return vn1;
}"
@@ -3007,7 +3007,7 @@ exports[`t-on t-on with inline statement, part 3 1`] = `
let vn1 = h('button', p1, c1);
const state_2 = scope['state'];
const someFunction_2 = scope['someFunction'];
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}state_2.n=someFunction_2(3)};
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}state_2.n=someFunction_2(3)};
c1.push({text: \`Toggle\`});
return vn1;
}"
@@ -3024,7 +3024,7 @@ exports[`t-on t-on with prevent and self modifiers (order matters) 1`] = `
let c2 = [], p2 = {key:2,on:{}};
let vn2 = h('button', p2, c2);
c1.push(vn2);
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();if (e.target !== this.elm) {return}utils.getComponent(context)['onClick'](e);};
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}e.preventDefault();if (e.target !== this.elm) {return}utils.getComponent(context)['onClick'](e);};
p2.on['click'] = extra.handlers['click__3__'];
let c4 = [], p4 = {key:4};
let vn4 = h('span', p4, c4);
@@ -3045,19 +3045,19 @@ exports[`t-on t-on with prevent and/or stop modifiers 1`] = `
let c2 = [], p2 = {key:2,on:{}};
let vn2 = h('button', p2, c2);
c1.push(vn2);
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();utils.getComponent(context)['onClickPrevented'](e);};
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}e.preventDefault();utils.getComponent(context)['onClickPrevented'](e);};
p2.on['click'] = extra.handlers['click__3__'];
c2.push({text: \`Button 1\`});
let c4 = [], p4 = {key:4,on:{}};
let vn4 = h('button', p4, c4);
c1.push(vn4);
extra.handlers['click__5__'] = extra.handlers['click__5__'] || function (e) {if (context.__owl__.isDestroyed){return}e.stopPropagation();utils.getComponent(context)['onClickStopped'](e);};
extra.handlers['click__5__'] = extra.handlers['click__5__'] || function (e) {if (context.__owl__.status === 5){return}e.stopPropagation();utils.getComponent(context)['onClickStopped'](e);};
p4.on['click'] = extra.handlers['click__5__'];
c4.push({text: \`Button 2\`});
let c6 = [], p6 = {key:6,on:{}};
let vn6 = h('button', p6, c6);
c1.push(vn6);
extra.handlers['click__7__'] = extra.handlers['click__7__'] || function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();e.stopPropagation();utils.getComponent(context)['onClickPreventedAndStopped'](e);};
extra.handlers['click__7__'] = extra.handlers['click__7__'] || function (e) {if (context.__owl__.status === 5){return}e.preventDefault();e.stopPropagation();utils.getComponent(context)['onClickPreventedAndStopped'](e);};
p6.on['click'] = extra.handlers['click__7__'];
c6.push({text: \`Button 3\`});
return vn1;
@@ -3097,7 +3097,7 @@ exports[`t-on t-on with prevent modifier in t-foreach 1`] = `
let vn7 = h('a', p7, c7);
c1.push(vn7);
let args8 = [scope['project'].id];
p7.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();utils.getComponent(context)['onEdit'](...args8, e);};
p7.on['click'] = function (e) {if (context.__owl__.status === 5){return}e.preventDefault();utils.getComponent(context)['onEdit'](...args8, e);};
c7.push({text: \` Edit \`});
let _9 = scope['project'].name;
if (_9 != null) {
@@ -3121,7 +3121,7 @@ exports[`t-on t-on with self and prevent modifiers (order matters) 1`] = `
let c2 = [], p2 = {key:2,on:{}};
let vn2 = h('button', p2, c2);
c1.push(vn2);
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}if (e.target !== this.elm) {return}e.preventDefault();utils.getComponent(context)['onClick'](e);};
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}if (e.target !== this.elm) {return}e.preventDefault();utils.getComponent(context)['onClick'](e);};
p2.on['click'] = extra.handlers['click__3__'];
let c4 = [], p4 = {key:4};
let vn4 = h('span', p4, c4);
@@ -3142,7 +3142,7 @@ exports[`t-on t-on with self modifier 1`] = `
let c2 = [], p2 = {key:2,on:{}};
let vn2 = h('button', p2, c2);
c1.push(vn2);
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onClick'](e);};
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onClick'](e);};
p2.on['click'] = extra.handlers['click__3__'];
let c4 = [], p4 = {key:4};
let vn4 = h('span', p4, c4);
@@ -3151,7 +3151,7 @@ exports[`t-on t-on with self modifier 1`] = `
let c5 = [], p5 = {key:5,on:{}};
let vn5 = h('button', p5, c5);
c1.push(vn5);
extra.handlers['click__6__'] = extra.handlers['click__6__'] || function (e) {if (context.__owl__.isDestroyed){return}if (e.target !== this.elm) {return}utils.getComponent(context)['onClickSelf'](e);};
extra.handlers['click__6__'] = extra.handlers['click__6__'] || function (e) {if (context.__owl__.status === 5){return}if (e.target !== this.elm) {return}utils.getComponent(context)['onClickSelf'](e);};
p5.on['click'] = extra.handlers['click__6__'];
let c7 = [], p7 = {key:7};
let vn7 = h('span', p7, c7);
+1 -1
View File
@@ -11,7 +11,7 @@ exports[`Link component can render simple cases 1`] = `
let _6 = scope['href'];
let c7 = [], p7 = {key:7,attrs:{href: _6},class:_5,on:{}};
let vn7 = h('a', p7, c7);
extra.handlers['click__8__'] = extra.handlers['click__8__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['navigate'](e);};
extra.handlers['click__8__'] = extra.handlers['click__8__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['navigate'](e);};
p7.on['click'] = extra.handlers['click__8__'];
const slot9 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
if (slot9) {