From f6d6da839332734ee7d6c1714c4a4cff3b22d11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Wed, 16 Oct 2019 14:51:53 +0200 Subject: [PATCH] [FIX] component: fix issues with component internal template key closes #298 --- src/component/directive.ts | 32 +- src/qweb/base_directives.ts | 15 +- src/qweb/compilation_context.ts | 2 +- tests/__snapshots__/animations.test.ts.snap | 14 +- tests/animations.test.ts | 4 +- .../__snapshots__/component.test.ts.snap | 615 ++++++++++-------- .../props_validation.test.ts.snap | 7 +- tests/component/component.test.ts | 46 ++ tests/qweb/__snapshots__/qweb.test.ts.snap | 243 ++++--- tests/qweb/qweb.test.ts | 17 + .../route_component.test.ts.snap | 8 +- 11 files changed, 610 insertions(+), 393 deletions(-) diff --git a/src/component/directive.ts b/src/component/directive.ts index 53ace04d..032ad9e0 100644 --- a/src/component/directive.ts +++ b/src/component/directive.ts @@ -243,21 +243,19 @@ QWeb.addDirective({ ctx.addLine(`let key${keyID} = 'key' + ${key};`); } ctx.addLine(`let def${defID};`); - let templateID = key - ? `key${keyID}` - : ctx.inLoop - ? ctx.currentKey - ? `String(${ctx.currentKey} + '_k_' + i + '_c_' + ${componentID} )` - : `String(-${componentID} - i)` - : String(componentID); - if (ctx.allowMultipleRoots) { - templateID = `"_slot_${templateID}"`; + + let locationExpr = `\`__${ctx.generateID()}__`; + for (let i = 0; i < ctx.loopNumber - 1; i++) { + locationExpr += `\${i${i + 1}}__`; } - if (key || ctx.inLoop) { - let id = ctx.generateID(); - ctx.addLine(`let templateId${id} = ${templateID};`); - templateID = `templateId${id}`; + if (key || ctx.currentKey) { + const k = key ? `key${keyID}` : ctx.currentKey; + ctx.addLine(`let templateId${componentID} = ${locationExpr}\` + ${k};`); + } else { + locationExpr += ctx.loopNumber ? `\${i${ctx.loopNumber}}__\`` : "`"; + ctx.addLine(`let templateId${componentID} = ${locationExpr};`); } + const templateId = `templateId${componentID}`; let ref = node.getAttribute("t-ref"); let refExpr = ""; @@ -320,7 +318,7 @@ QWeb.addDirective({ .map(function([eventName, mods, handlerName, extraArgs]) { let params = "owner"; if (extraArgs) { - if (ctx.inLoop) { + if (ctx.loopNumber) { let argId = ctx.generateID(); // we need to evaluate the arguments now, because the handler will // be set asynchronously later when the widget is ready, and the @@ -352,7 +350,7 @@ QWeb.addDirective({ } ctx.addLine( - `let w${componentID} = ${templateID} in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[${templateID}]] : false;` + `let w${componentID} = ${templateId} in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[${templateId}]] : false;` ); if (ctx.parentNode) { ctx.addLine(`let _${dummyID}_index = c${ctx.parentNode}.length;`); @@ -418,7 +416,7 @@ QWeb.addDirective({ ctx.addLine(`utils.validateProps(W${componentID}, props${componentID})`); } ctx.addLine(`w${componentID} = new W${componentID}(parent, props${componentID});`); - ctx.addLine(`parent.__owl__.cmap[${templateID}] = w${componentID}.__owl__.id;`); + ctx.addLine(`parent.__owl__.cmap[${templateId}] = w${componentID}.__owl__.id;`); // SLOTS const varDefs: string[] = []; @@ -470,7 +468,7 @@ QWeb.addDirective({ registerCode = `utils.defineProxy(vn${ctx.rootNode}, pvnode);`; } ctx.addLine( - `def${defID} = def${defID}.then(vnode=>{if (w${componentID}.__owl__.isDestroyed){return}${createHook}let pvnode=h(vnode.sel, {key: ${templateID}, hook: {insert(vn) {let nvn=w${componentID}.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;${refExpr}${transitionsInsertCode}},remove() {},destroy(vn) {${finalizeComponentCode}}}});${registerCode}w${componentID}.__owl__.pvnode = pvnode;});` + `def${defID} = def${defID}.then(vnode=>{if (w${componentID}.__owl__.isDestroyed){return}${createHook}let pvnode=h(vnode.sel, {key: ${templateId}, hook: {insert(vn) {let nvn=w${componentID}.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;${refExpr}${transitionsInsertCode}},remove() {},destroy(vn) {${finalizeComponentCode}}}});${registerCode}w${componentID}.__owl__.pvnode = pvnode;});` ); ctx.addElse(); diff --git a/src/qweb/base_directives.ts b/src/qweb/base_directives.ts index 655eccb2..c0e0b773 100644 --- a/src/qweb/base_directives.ts +++ b/src/qweb/base_directives.ts @@ -275,7 +275,7 @@ QWeb.addDirective({ priority: 10, atNodeEncounter({ node, qweb, ctx }): boolean { ctx.rootContext.shouldProtectContext = true; - ctx = ctx.subContext("inLoop", true); + ctx = ctx.subContext("loopNumber", ctx.loopNumber + 1); const elems = node.getAttribute("t-foreach")!; const name = node.getAttribute("t-as")!; let arrayID = ctx.generateID(); @@ -289,13 +289,14 @@ QWeb.addDirective({ ctx.addLine(`_${valuesID} = Object.values(_${arrayID});`); ctx.closeIf(); ctx.addLine(`var _length${keysID} = _${keysID}.length;`); - ctx.addLine(`for (let i = 0; i < _length${keysID}; i++) {`); + const loopVar = `i${ctx.loopNumber}`; + ctx.addLine(`for (let ${loopVar} = 0; ${loopVar} < _length${keysID}; ${loopVar}++) {`); ctx.indent(); - ctx.addToScope(name + "_first", "i === 0"); - ctx.addToScope(name + "_last", `i === _length${keysID} - 1`); - ctx.addToScope(name + "_index", "i"); - ctx.addToScope(name, `_${keysID}[i]`); - ctx.addToScope(name + "_value", `_${valuesID}[i]`); + ctx.addToScope(name + "_first", `${loopVar} === 0`); + ctx.addToScope(name + "_last", `${loopVar} === _length${keysID} - 1`); + ctx.addToScope(name + "_index", loopVar); + ctx.addToScope(name, `_${keysID}[${loopVar}]`); + ctx.addToScope(name + "_value", `_${valuesID}[${loopVar}]`); const nodeCopy = node.cloneNode(true); let shouldWarn = nodeCopy.tagName !== "t" && !nodeCopy.hasAttribute("t-key"); if (!shouldWarn && node.tagName === "t") { diff --git a/src/qweb/compilation_context.ts b/src/qweb/compilation_context.ts index f7ef786d..a95615e0 100644 --- a/src/qweb/compilation_context.ts +++ b/src/qweb/compilation_context.ts @@ -24,7 +24,7 @@ export class CompilationContext { shouldDefineResult: boolean = true; shouldProtectContext: boolean = false; shouldTrackScope: boolean = false; - inLoop: boolean = false; + loopNumber: number = 0; inPreTag: boolean = false; templateName: string; allowMultipleRoots: boolean = false; diff --git a/tests/__snapshots__/animations.test.ts.snap b/tests/__snapshots__/animations.test.ts.snap index 16cdb2d8..6831205f 100644 --- a/tests/__snapshots__/animations.test.ts.snap +++ b/tests/__snapshots__/animations.test.ts.snap @@ -12,7 +12,8 @@ exports[`animations t-transition combined with component 1`] = ` var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -29,9 +30,9 @@ exports[`animations t-transition combined with component 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['Child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn, 'chimay');},remove() {},destroy(vn) {let finalize = () => { + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn, 'chimay');},remove() {},destroy(vn) {let finalize = () => { w4.destroy(); }; utils.transitionRemove(vn, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); @@ -57,7 +58,8 @@ exports[`animations t-transition combined with t-component and t-if 1`] = ` if (context['state'].display) { //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -74,9 +76,9 @@ exports[`animations t-transition combined with t-component and t-if 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['Child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn, 'chimay');},remove() {},destroy(vn) {let finalize = () => { + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn, 'chimay');},remove() {},destroy(vn) {let finalize = () => { w4.destroy(); }; utils.transitionRemove(vn, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); diff --git a/tests/animations.test.ts b/tests/animations.test.ts index 851b3b3d..968e4034 100644 --- a/tests/animations.test.ts +++ b/tests/animations.test.ts @@ -251,11 +251,11 @@ describe("animations", () => { widget.state.display = false; patchNextFrame(cb => { expect(fixture.innerHTML).toBe( - '
blue
' + '
blue
' ); cb(); expect(fixture.innerHTML).toBe( - '
blue
' + '
blue
' ); def.resolve(); }); diff --git a/tests/component/__snapshots__/component.test.ts.snap b/tests/component/__snapshots__/component.test.ts.snap index 8d0ef07b..990ee0cd 100644 --- a/tests/component/__snapshots__/component.test.ts.snap +++ b/tests/component/__snapshots__/component.test.ts.snap @@ -25,7 +25,8 @@ exports[`async rendering delayed component with t-asyncroot directive 1`] = ` c1.push(vn5); //COMPONENT let def7; - let w8 = 8 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[8]] : false; + let templateId8 = \`__9__\`; + let w8 = templateId8 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId8]] : false; let _6_index = c5.length; c5.push(null); let props8 = {val:context['state'].val}; @@ -42,42 +43,43 @@ exports[`async rendering delayed component with t-asyncroot directive 1`] = ` let W8 = context.constructor.components[componentKey8] || QWeb.components[componentKey8]|| context['Child']; if (!W8) {throw new Error('Cannot find the definition of component \\"' + componentKey8 + '\\"')} w8 = new W8(parent, props8); - parent.__owl__.cmap[8] = w8.__owl__.id; + parent.__owl__.cmap[templateId8] = w8.__owl__.id; def7 = w8.__prepare(extra.fiber, undefined, undefined); - def7 = def7.then(vnode=>{if (w8.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 8, hook: {insert(vn) {let nvn=w8.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w8.destroy();}}});c5[_6_index]=pvnode;w8.__owl__.pvnode = pvnode;}); + def7 = def7.then(vnode=>{if (w8.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId8, hook: {insert(vn) {let nvn=w8.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w8.destroy();}}});c5[_6_index]=pvnode;w8.__owl__.pvnode = pvnode;}); } else { def7 = def7 || w8.__updateProps(props8, extra.fiber, undefined, undefined); def7 = def7.then(()=>{if (w8.__owl__.isDestroyed) {return};let pvnode=w8.__owl__.pvnode;c5[_6_index]=pvnode;}); } extra.promises.push(def7); //COMPONENT - let def10; - let w11 = 11 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[11]] : false; - let _9_index = c5.length; - const fiber11 = Object.assign(Object.create(extra.fiber), {patchQueue: []}); - c5.push(w11 && w11.__owl__.pvnode || null); - let props11 = {val:context['state'].val}; - if (w11 && w11.__owl__.currentFiber && !w11.__owl__.vnode) { - if (utils.shallowEqual(props11, w11.__owl__.currentFiber.props)) { - def10 = w11.__owl__.currentFiber.promise; + let def11; + let templateId12 = \`__13__\`; + let w12 = templateId12 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId12]] : false; + let _10_index = c5.length; + const fiber12 = Object.assign(Object.create(extra.fiber), {patchQueue: []}); + c5.push(w12 && w12.__owl__.pvnode || null); + let props12 = {val:context['state'].val}; + if (w12 && w12.__owl__.currentFiber && !w12.__owl__.vnode) { + if (utils.shallowEqual(props12, w12.__owl__.currentFiber.props)) { + def11 = w12.__owl__.currentFiber.promise; } else { - w11.destroy(); - w11 = false; + w12.destroy(); + w12 = false; } } - if (!w11) { - let componentKey11 = \`AsyncChild\`; - let W11 = context.constructor.components[componentKey11] || QWeb.components[componentKey11]|| context['AsyncChild']; - if (!W11) {throw new Error('Cannot find the definition of component \\"' + componentKey11 + '\\"')} - w11 = new W11(parent, props11); - parent.__owl__.cmap[11] = w11.__owl__.id; - def10 = w11.__prepare(extra.fiber, undefined, undefined); - def10 = def10.then(vnode=>{if (w11.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 11, hook: {insert(vn) {let nvn=w11.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w11.destroy();}}});c5[_9_index]=pvnode;w11.__owl__.pvnode = pvnode;}); + if (!w12) { + let componentKey12 = \`AsyncChild\`; + let W12 = context.constructor.components[componentKey12] || QWeb.components[componentKey12]|| context['AsyncChild']; + if (!W12) {throw new Error('Cannot find the definition of component \\"' + componentKey12 + '\\"')} + w12 = new W12(parent, props12); + parent.__owl__.cmap[templateId12] = w12.__owl__.id; + def11 = w12.__prepare(extra.fiber, undefined, undefined); + def11 = def11.then(vnode=>{if (w12.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId12, hook: {insert(vn) {let nvn=w12.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w12.destroy();}}});c5[_10_index]=pvnode;w12.__owl__.pvnode = pvnode;}); } else { - def10 = def10 || w11.__updateProps(props11, fiber11, undefined, undefined); - def10 = def10.then(()=>{if (w11.__owl__.isDestroyed) {return};let pvnode=w11.__owl__.pvnode;c5[_9_index]=pvnode;}); + def11 = def11 || w12.__updateProps(props12, fiber12, undefined, undefined); + def11 = def11.then(()=>{if (w12.__owl__.isDestroyed) {return};let pvnode=w12.__owl__.pvnode;c5[_10_index]=pvnode;}); } - def10.then(w11.__applyPatchQueue.bind(w11, fiber11)); + def11.then(w12.__applyPatchQueue.bind(w12, fiber12)); return vn1; }" `; @@ -107,7 +109,8 @@ exports[`async rendering fast component with t-asyncroot directive 1`] = ` c1.push(vn5); //COMPONENT let def7; - let w8 = 8 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[8]] : false; + let templateId8 = \`__9__\`; + let w8 = templateId8 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId8]] : false; let _6_index = c5.length; const fiber8 = Object.assign(Object.create(extra.fiber), {patchQueue: []}); c5.push(w8 && w8.__owl__.pvnode || null); @@ -125,41 +128,42 @@ exports[`async rendering fast component with t-asyncroot directive 1`] = ` let W8 = context.constructor.components[componentKey8] || QWeb.components[componentKey8]|| context['Child']; if (!W8) {throw new Error('Cannot find the definition of component \\"' + componentKey8 + '\\"')} w8 = new W8(parent, props8); - parent.__owl__.cmap[8] = w8.__owl__.id; + parent.__owl__.cmap[templateId8] = w8.__owl__.id; def7 = w8.__prepare(extra.fiber, undefined, undefined); - def7 = def7.then(vnode=>{if (w8.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 8, hook: {insert(vn) {let nvn=w8.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w8.destroy();}}});c5[_6_index]=pvnode;w8.__owl__.pvnode = pvnode;}); + def7 = def7.then(vnode=>{if (w8.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId8, hook: {insert(vn) {let nvn=w8.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w8.destroy();}}});c5[_6_index]=pvnode;w8.__owl__.pvnode = pvnode;}); } else { def7 = def7 || w8.__updateProps(props8, fiber8, undefined, undefined); def7 = def7.then(()=>{if (w8.__owl__.isDestroyed) {return};let pvnode=w8.__owl__.pvnode;c5[_6_index]=pvnode;}); } def7.then(w8.__applyPatchQueue.bind(w8, fiber8)); //COMPONENT - let def10; - let w11 = 11 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[11]] : false; - let _9_index = c5.length; + let def11; + let templateId12 = \`__13__\`; + let w12 = templateId12 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId12]] : false; + let _10_index = c5.length; c5.push(null); - let props11 = {val:context['state'].val}; - if (w11 && w11.__owl__.currentFiber && !w11.__owl__.vnode) { - if (utils.shallowEqual(props11, w11.__owl__.currentFiber.props)) { - def10 = w11.__owl__.currentFiber.promise; + let props12 = {val:context['state'].val}; + if (w12 && w12.__owl__.currentFiber && !w12.__owl__.vnode) { + if (utils.shallowEqual(props12, w12.__owl__.currentFiber.props)) { + def11 = w12.__owl__.currentFiber.promise; } else { - w11.destroy(); - w11 = false; + w12.destroy(); + w12 = false; } } - if (!w11) { - let componentKey11 = \`AsyncChild\`; - let W11 = context.constructor.components[componentKey11] || QWeb.components[componentKey11]|| context['AsyncChild']; - if (!W11) {throw new Error('Cannot find the definition of component \\"' + componentKey11 + '\\"')} - w11 = new W11(parent, props11); - parent.__owl__.cmap[11] = w11.__owl__.id; - def10 = w11.__prepare(extra.fiber, undefined, undefined); - def10 = def10.then(vnode=>{if (w11.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 11, hook: {insert(vn) {let nvn=w11.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w11.destroy();}}});c5[_9_index]=pvnode;w11.__owl__.pvnode = pvnode;}); + if (!w12) { + let componentKey12 = \`AsyncChild\`; + let W12 = context.constructor.components[componentKey12] || QWeb.components[componentKey12]|| context['AsyncChild']; + if (!W12) {throw new Error('Cannot find the definition of component \\"' + componentKey12 + '\\"')} + w12 = new W12(parent, props12); + parent.__owl__.cmap[templateId12] = w12.__owl__.id; + def11 = w12.__prepare(extra.fiber, undefined, undefined); + def11 = def11.then(vnode=>{if (w12.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId12, hook: {insert(vn) {let nvn=w12.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w12.destroy();}}});c5[_10_index]=pvnode;w12.__owl__.pvnode = pvnode;}); } else { - def10 = def10 || w11.__updateProps(props11, extra.fiber, undefined, undefined); - def10 = def10.then(()=>{if (w11.__owl__.isDestroyed) {return};let pvnode=w11.__owl__.pvnode;c5[_9_index]=pvnode;}); + def11 = def11 || w12.__updateProps(props12, extra.fiber, undefined, undefined); + def11 = def11.then(()=>{if (w12.__owl__.isDestroyed) {return};let pvnode=w12.__owl__.pvnode;c5[_10_index]=pvnode;}); } - extra.promises.push(def10); + extra.promises.push(def11); return vn1; }" `; @@ -189,7 +193,8 @@ exports[`async rendering t-component with t-asyncroot directive: mixed re-render c1.push(vn5); //COMPONENT let def7; - let w8 = 8 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[8]] : false; + let templateId8 = \`__9__\`; + let w8 = templateId8 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId8]] : false; let _6_index = c5.length; c5.push(null); let props8 = {val:context['state'].val}; @@ -206,42 +211,116 @@ exports[`async rendering t-component with t-asyncroot directive: mixed re-render let W8 = context.constructor.components[componentKey8] || QWeb.components[componentKey8]|| context['Child']; if (!W8) {throw new Error('Cannot find the definition of component \\"' + componentKey8 + '\\"')} w8 = new W8(parent, props8); - parent.__owl__.cmap[8] = w8.__owl__.id; + parent.__owl__.cmap[templateId8] = w8.__owl__.id; def7 = w8.__prepare(extra.fiber, undefined, undefined); - def7 = def7.then(vnode=>{if (w8.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 8, hook: {insert(vn) {let nvn=w8.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w8.destroy();}}});c5[_6_index]=pvnode;w8.__owl__.pvnode = pvnode;}); + def7 = def7.then(vnode=>{if (w8.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId8, hook: {insert(vn) {let nvn=w8.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w8.destroy();}}});c5[_6_index]=pvnode;w8.__owl__.pvnode = pvnode;}); } else { def7 = def7 || w8.__updateProps(props8, extra.fiber, undefined, undefined); def7 = def7.then(()=>{if (w8.__owl__.isDestroyed) {return};let pvnode=w8.__owl__.pvnode;c5[_6_index]=pvnode;}); } extra.promises.push(def7); //COMPONENT - let def10; - let w11 = 11 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[11]] : false; - let _9_index = c5.length; - const fiber11 = Object.assign(Object.create(extra.fiber), {patchQueue: []}); - c5.push(w11 && w11.__owl__.pvnode || null); - let props11 = {val:context['state'].val}; - if (w11 && w11.__owl__.currentFiber && !w11.__owl__.vnode) { - if (utils.shallowEqual(props11, w11.__owl__.currentFiber.props)) { - def10 = w11.__owl__.currentFiber.promise; + let def11; + let templateId12 = \`__13__\`; + let w12 = templateId12 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId12]] : false; + let _10_index = c5.length; + const fiber12 = Object.assign(Object.create(extra.fiber), {patchQueue: []}); + c5.push(w12 && w12.__owl__.pvnode || null); + let props12 = {val:context['state'].val}; + if (w12 && w12.__owl__.currentFiber && !w12.__owl__.vnode) { + if (utils.shallowEqual(props12, w12.__owl__.currentFiber.props)) { + def11 = w12.__owl__.currentFiber.promise; } else { - w11.destroy(); - w11 = false; + w12.destroy(); + w12 = false; } } - if (!w11) { - let componentKey11 = \`AsyncChild\`; - let W11 = context.constructor.components[componentKey11] || QWeb.components[componentKey11]|| context['AsyncChild']; - if (!W11) {throw new Error('Cannot find the definition of component \\"' + componentKey11 + '\\"')} - w11 = new W11(parent, props11); - parent.__owl__.cmap[11] = w11.__owl__.id; - def10 = w11.__prepare(extra.fiber, undefined, undefined); - def10 = def10.then(vnode=>{if (w11.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 11, hook: {insert(vn) {let nvn=w11.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w11.destroy();}}});c5[_9_index]=pvnode;w11.__owl__.pvnode = pvnode;}); + if (!w12) { + let componentKey12 = \`AsyncChild\`; + let W12 = context.constructor.components[componentKey12] || QWeb.components[componentKey12]|| context['AsyncChild']; + if (!W12) {throw new Error('Cannot find the definition of component \\"' + componentKey12 + '\\"')} + w12 = new W12(parent, props12); + parent.__owl__.cmap[templateId12] = w12.__owl__.id; + def11 = w12.__prepare(extra.fiber, undefined, undefined); + def11 = def11.then(vnode=>{if (w12.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId12, hook: {insert(vn) {let nvn=w12.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w12.destroy();}}});c5[_10_index]=pvnode;w12.__owl__.pvnode = pvnode;}); } else { - def10 = def10 || w11.__updateProps(props11, fiber11, undefined, undefined); - def10 = def10.then(()=>{if (w11.__owl__.isDestroyed) {return};let pvnode=w11.__owl__.pvnode;c5[_9_index]=pvnode;}); + def11 = def11 || w12.__updateProps(props12, fiber12, undefined, undefined); + def11 = def11.then(()=>{if (w12.__owl__.isDestroyed) {return};let pvnode=w12.__owl__.pvnode;c5[_10_index]=pvnode;}); + } + def11.then(w12.__applyPatchQueue.bind(w12, fiber12)); + return vn1; +}" +`; + +exports[`basic widget properties reconciliation alg works for t-foreach in t-foreach 1`] = ` +"function anonymous(context,extra +) { + let utils = this.constructor.utils; + let QWeb = this.constructor; + let parent = context; + let owner = context; + context = Object.create(context); + var h = this.h; + let c1 = [], p1 = {key:1}; + var vn1 = h('div', p1, c1); + var _2 = context['state'].s; + if (!_2) { throw new Error('QWeb error: Invalid loop expression')} + var _3 = _4 = _2; + if (!(_2 instanceof Array)) { + _3 = Object.keys(_2); + _4 = Object.values(_2); + } + var _length3 = _3.length; + for (let i1 = 0; i1 < _length3; i1++) { + context.section_first = i1 === 0; + context.section_last = i1 === _length3 - 1; + context.section_index = i1; + context.section = _3[i1]; + context.section_value = _4[i1]; + var _5 = context['section'].blips; + if (!_5) { throw new Error('QWeb error: Invalid loop expression')} + var _6 = _7 = _5; + if (!(_5 instanceof Array)) { + _6 = Object.keys(_5); + _7 = Object.values(_5); + } + var _length6 = _6.length; + for (let i2 = 0; i2 < _length6; i2++) { + context.blip_first = i2 === 0; + context.blip_last = i2 === _length6 - 1; + context.blip_index = i2; + context.blip = _6[i2]; + context.blip_value = _7[i2]; + //COMPONENT + let def9; + let templateId10 = \`__11__\${i1}__\${i2}__\`; + let w10 = templateId10 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId10]] : false; + let _8_index = c1.length; + c1.push(null); + let props10 = {blip:context['blip']}; + if (w10 && w10.__owl__.currentFiber && !w10.__owl__.vnode) { + if (utils.shallowEqual(props10, w10.__owl__.currentFiber.props)) { + def9 = w10.__owl__.currentFiber.promise; + } else { + w10.destroy(); + w10 = false; + } + } + if (!w10) { + let componentKey10 = \`Child\`; + let W10 = context.constructor.components[componentKey10] || QWeb.components[componentKey10]|| context['Child']; + if (!W10) {throw new Error('Cannot find the definition of component \\"' + componentKey10 + '\\"')} + w10 = new W10(parent, props10); + parent.__owl__.cmap[templateId10] = w10.__owl__.id; + def9 = w10.__prepare(extra.fiber, undefined, undefined); + def9 = def9.then(vnode=>{if (w10.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId10, hook: {insert(vn) {let nvn=w10.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w10.destroy();}}});c1[_8_index]=pvnode;w10.__owl__.pvnode = pvnode;}); + } else { + def9 = def9 || w10.__updateProps(props10, extra.fiber, undefined, undefined); + def9 = def9.then(()=>{if (w10.__owl__.isDestroyed) {return};let pvnode=w10.__owl__.pvnode;c1[_8_index]=pvnode;}); + } + extra.promises.push(def9); + } } - def10.then(w11.__applyPatchQueue.bind(w11, fiber11)); return vn1; }" `; @@ -258,8 +337,9 @@ exports[`class and style attributes with t-component dynamic t-att-style is prop var vn1 = h('div', p1, c1); //COMPONENT let def3; - const _5 = context['state'].style; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + const _6 = context['state'].style; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -276,12 +356,12 @@ exports[`class and style attributes with t-component dynamic t-att-style is prop let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.style = _5;}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.style = _6;}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); - def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};w4.el.style=_5;let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); + def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};w4.el.style=_6;let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); } extra.promises.push(def3); return vn1; @@ -301,10 +381,11 @@ exports[`class and style attributes with t-component t-att-class is properly add var vn1 = h('div', p1, c1); //COMPONENT let def3; - const ref5 = \`child\`; - let _6 = {'a':true}; - Object.assign(_6, {b:context['state'].b}) - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + const ref6 = \`child\`; + let _7 = {'a':true}; + Object.assign(_7, {b:context['state'].b}) + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -321,14 +402,14 @@ exports[`class and style attributes with t-component t-att-class is properly add let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['Child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;context.__owl__.refs[ref5] = w4;},remove() {},destroy(vn) {w4.destroy();delete context.__owl__.refs[ref5];}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;context.__owl__.refs[ref6] = w4;},remove() {},destroy(vn) {w4.destroy();delete context.__owl__.refs[ref6];}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); } - w4.__owl__.classObj=_6; + w4.__owl__.classObj=_7; extra.promises.push(def3); return vn1; }" @@ -360,10 +441,11 @@ exports[`class and style attributes with t-component t-att-class is properly add var vn1 = h('div', p1, c1); //COMPONENT let def3; - const ref5 = \`child\`; - let _6 = {'a':true}; - Object.assign(_6, utils.toObj(context['state'].b?'b':'')) - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + const ref6 = \`child\`; + let _7 = {'a':true}; + Object.assign(_7, utils.toObj(context['state'].b?'b':'')) + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -380,14 +462,14 @@ exports[`class and style attributes with t-component t-att-class is properly add let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['Child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;context.__owl__.refs[ref5] = w4;},remove() {},destroy(vn) {w4.destroy();delete context.__owl__.refs[ref5];}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;context.__owl__.refs[ref6] = w4;},remove() {},destroy(vn) {w4.destroy();delete context.__owl__.refs[ref6];}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); } - w4.__owl__.classObj=_6; + w4.__owl__.classObj=_7; extra.promises.push(def3); return vn1; }" @@ -418,8 +500,9 @@ exports[`class and style attributes with t-component t-att-class is properly add var vn1 = h('div', p1, c1); //COMPONENT let def3; - let _5 = {a:context['state'].a,b:context['state'].b}; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let _6 = {a:context['state'].a,b:context['state'].b}; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -436,14 +519,14 @@ exports[`class and style attributes with t-component t-att-class is properly add let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); } - w4.__owl__.classObj=_5; + w4.__owl__.classObj=_6; extra.promises.push(def3); return vn1; }" @@ -462,7 +545,8 @@ exports[`composition sub components dom state with t-keepalive is preserved 1`] if (context['state'].ok) { //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; const fiber4 = Object.assign(Object.create(extra.fiber), {patchQueue: []}); c1.push(null); @@ -480,9 +564,9 @@ exports[`composition sub components dom state with t-keepalive is preserved 1`] let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['InputWidget']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.unmount();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.unmount();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, w4.__owl__.isMounted ? extra.fiber : fiber4, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;pvnode.data.hook.insert = vn => {vn.elm.parentNode.replaceChild(w4.el,vn.elm);vn.elm=w4.el;w4.__remount();};c1[_2_index]=pvnode;}); @@ -512,17 +596,17 @@ exports[`composition sub components with some state rendered in a loop 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.number_first = i === 0; - context.number_last = i === _length3 - 1; - context.number_index = i; - context.number = _3[i]; - context.number_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.number_first = i1 === 0; + context.number_last = i1 === _length3 - 1; + context.number_index = i1; + context.number = _3[i1]; + context.number_value = _4[i1]; //COMPONENT let key8 = 'key' + context['number']; let def6; - let templateId9 = key8; - let w7 = templateId9 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId9]] : false; + let templateId7 = \`__9__\` + key8; + let w7 = templateId7 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId7]] : false; let _5_index = c1.length; c1.push(null); let props7 = {}; @@ -539,9 +623,9 @@ exports[`composition sub components with some state rendered in a loop 1`] = ` let W7 = context.constructor.components[componentKey7] || QWeb.components[componentKey7]|| context['ChildWidget']; if (!W7) {throw new Error('Cannot find the definition of component \\"' + componentKey7 + '\\"')} w7 = new W7(parent, props7); - parent.__owl__.cmap[templateId9] = w7.__owl__.id; + parent.__owl__.cmap[templateId7] = w7.__owl__.id; def6 = w7.__prepare(extra.fiber, undefined, undefined); - def6 = def6.then(vnode=>{if (w7.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId9, hook: {insert(vn) {let nvn=w7.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}});c1[_5_index]=pvnode;w7.__owl__.pvnode = pvnode;}); + def6 = def6.then(vnode=>{if (w7.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId7, hook: {insert(vn) {let nvn=w7.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}});c1[_5_index]=pvnode;w7.__owl__.pvnode = pvnode;}); } else { def6 = def6 || w7.__updateProps(props7, extra.fiber, undefined, undefined); def6 = def6.then(()=>{if (w7.__owl__.isDestroyed) {return};let pvnode=w7.__owl__.pvnode;c1[_5_index]=pvnode;}); @@ -564,7 +648,8 @@ exports[`composition t-component with dynamic value 1`] = ` var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -581,9 +666,9 @@ exports[`composition t-component with dynamic value 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -605,7 +690,8 @@ exports[`composition t-component with dynamic value 2 1`] = ` var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -622,9 +708,9 @@ exports[`composition t-component with dynamic value 2 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -646,7 +732,8 @@ exports[`dynamic t-props basic use 1`] = ` var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = Object.assign({}, context['some'].obj); @@ -663,9 +750,9 @@ exports[`dynamic t-props basic use 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['Child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -688,7 +775,8 @@ exports[`lifecycle hooks willPatch/patched hook with t-keepalive 1`] = ` if (context['state'].flag) { //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; const fiber4 = Object.assign(Object.create(extra.fiber), {patchQueue: []}); c1.push(null); @@ -706,9 +794,9 @@ exports[`lifecycle hooks willPatch/patched hook with t-keepalive 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['ChildWidget']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.unmount();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.unmount();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, w4.__owl__.isMounted ? extra.fiber : fiber4, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;pvnode.data.hook.insert = vn => {vn.elm.parentNode.replaceChild(w4.el,vn.elm);vn.elm=w4.el;w4.__remount();};c1[_2_index]=pvnode;}); @@ -731,7 +819,8 @@ exports[`other directives with t-component t-on with handler bound to argument 1 var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -748,9 +837,9 @@ exports[`other directives with t-component t-on with handler bound to argument 1 let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, 3));}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, 3));}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -772,7 +861,8 @@ exports[`other directives with t-component t-on with handler bound to empty obje var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -789,9 +879,9 @@ exports[`other directives with t-component t-on with handler bound to empty obje let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {}));}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {}));}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -813,7 +903,8 @@ exports[`other directives with t-component t-on with handler bound to empty obje var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -830,9 +921,9 @@ exports[`other directives with t-component t-on with handler bound to empty obje let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {}));}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {}));}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -854,7 +945,8 @@ exports[`other directives with t-component t-on with handler bound to object 1`] var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -871,9 +963,9 @@ exports[`other directives with t-component t-on with handler bound to object 1`] let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {val:3}));}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {val:3}));}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -895,7 +987,8 @@ exports[`other directives with t-component t-on with prevent and self modifiers var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -912,9 +1005,9 @@ exports[`other directives with t-component t-on with prevent and self modifiers let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['Child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {e.preventDefault();if (e.target !== vn.elm) {return}owner['onEv'].call(owner, e);});}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {e.preventDefault();if (e.target !== vn.elm) {return}owner['onEv'].call(owner, e);});}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -936,7 +1029,8 @@ exports[`other directives with t-component t-on with self and prevent modifiers var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -953,9 +1047,9 @@ exports[`other directives with t-component t-on with self and prevent modifiers let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (e.target !== vn.elm) {return}e.preventDefault();owner['onEv'].call(owner, e);});}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (e.target !== vn.elm) {return}e.preventDefault();owner['onEv'].call(owner, e);});}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -977,7 +1071,8 @@ exports[`other directives with t-component t-on with self modifier 1`] = ` var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -994,9 +1089,9 @@ exports[`other directives with t-component t-on with self modifier 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev-1', owner['onEv1'].bind(owner));vn.elm.addEventListener('ev-2', function (e) {if (e.target !== vn.elm) {return}owner['onEv2'].call(owner, e);});}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev-1', owner['onEv1'].bind(owner));vn.elm.addEventListener('ev-2', function (e) {if (e.target !== vn.elm) {return}owner['onEv2'].call(owner, e);});}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -1018,7 +1113,8 @@ exports[`other directives with t-component t-on with stop and/or prevent modifie var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -1035,9 +1131,9 @@ exports[`other directives with t-component t-on with stop and/or prevent modifie let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {e.stopPropagation();owner['onEv1'].call(owner, e);});vn.elm.addEventListener('ev-2', function (e) {e.preventDefault();owner['onEv2'].call(owner, e);});vn.elm.addEventListener('ev-3', function (e) {e.stopPropagation();e.preventDefault();owner['onEv3'].call(owner, e);});}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {e.stopPropagation();owner['onEv1'].call(owner, e);});vn.elm.addEventListener('ev-2', function (e) {e.preventDefault();owner['onEv2'].call(owner, e);});vn.elm.addEventListener('ev-3', function (e) {e.stopPropagation();e.preventDefault();owner['onEv3'].call(owner, e);});}};let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -1077,8 +1173,8 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = ` //COMPONENT let key5 = 'key' + 'somestring'; let def3; - let templateId6 = key5; - let w4 = templateId6 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId6]] : false; + let templateId4 = \`__6__\` + key5; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {flag:context['state'].flag}; @@ -1095,9 +1191,9 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['child']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[templateId6] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId6, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -1126,18 +1222,18 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.item_first = i === 0; - context.item_last = i === _length3 - 1; - context.item_index = i; - context.item = _3[i]; - context.item_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.item_first = i1 === 0; + context.item_last = i1 === _length3 - 1; + context.item_index = i1; + context.item = _3[i1]; + context.item_value = _4[i1]; //COMPONENT let key8 = 'key' + context['item']; let def6; - let templateId9 = key8; + let templateId7 = \`__9__\` + key8; let arg10 = context['item']; - let w7 = templateId9 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId9]] : false; + let w7 = templateId7 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId7]] : false; let _5_index = c1.length; c1.push(null); let props7 = {}; @@ -1154,9 +1250,9 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument let W7 = context.constructor.components[componentKey7] || QWeb.components[componentKey7]|| context['Child']; if (!W7) {throw new Error('Cannot find the definition of component \\"' + componentKey7 + '\\"')} w7 = new W7(parent, props7); - parent.__owl__.cmap[templateId9] = w7.__owl__.id; + parent.__owl__.cmap[templateId7] = w7.__owl__.id; def6 = w7.__prepare(extra.fiber, undefined, undefined); - def6 = def6.then(vnode=>{if (w7.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, arg10));}};let pvnode=h(vnode.sel, {key: templateId9, hook: {insert(vn) {let nvn=w7.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}});c1[_5_index]=pvnode;w7.__owl__.pvnode = pvnode;}); + def6 = def6.then(vnode=>{if (w7.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, arg10));}};let pvnode=h(vnode.sel, {key: templateId7, hook: {insert(vn) {let nvn=w7.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}});c1[_5_index]=pvnode;w7.__owl__.pvnode = pvnode;}); } else { def6 = def6 || w7.__updateProps(props7, extra.fiber, undefined, undefined); def6 = def6.then(()=>{if (w7.__owl__.isDestroyed) {return};let pvnode=w7.__owl__.pvnode;c1[_5_index]=pvnode;}); @@ -1377,7 +1473,8 @@ exports[`t-slot directive can define and call slots 1`] = ` var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {}; @@ -1394,10 +1491,10 @@ exports[`t-slot directive can define and call slots 1`] = ` let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['Dialog']; if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; w4.__owl__.slotId = 1; def3 = w4.__prepare(extra.fiber, {}, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { def3 = def3 || w4.__updateProps(props4, extra.fiber, {}, undefined); def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); @@ -1438,10 +1535,10 @@ exports[`t-slot directive can define and call slots 3`] = ` var h = this.h; let c1 = extra.parentNode; Object.assign(context, extra.fiber.scope); - let c6 = [], p6 = {key:6}; - var vn6 = h('span', p6, c6); - c1.push(vn6); - c6.push({text: \`header\`}); + let c7 = [], p7 = {key:7}; + var vn7 = h('span', p7, c7); + c1.push(vn7); + c7.push({text: \`header\`}); }" `; @@ -1451,10 +1548,10 @@ exports[`t-slot directive can define and call slots 4`] = ` var h = this.h; let c1 = extra.parentNode; Object.assign(context, extra.fiber.scope); - let c6 = [], p6 = {key:6}; - var vn6 = h('span', p6, c6); - c1.push(vn6); - c6.push({text: \`footer\`}); + let c7 = [], p7 = {key:7}; + var vn7 = h('span', p7, c7); + c1.push(vn7); + c7.push({text: \`footer\`}); }" `; @@ -1464,10 +1561,10 @@ exports[`t-slot directive content is the default slot 1`] = ` var h = this.h; let c1 = extra.parentNode; Object.assign(context, extra.fiber.scope); - let c6 = [], p6 = {key:6}; - var vn6 = h('span', p6, c6); - c1.push(vn6); - c6.push({text: \`sts rocks\`}); + let c7 = [], p7 = {key:7}; + var vn7 = h('span', p7, c7); + c1.push(vn7); + c7.push({text: \`sts rocks\`}); }" `; @@ -1487,14 +1584,14 @@ exports[`t-slot directive multiple roots are allowed in a default slot 1`] = ` var h = this.h; let c1 = extra.parentNode; Object.assign(context, extra.fiber.scope); - let c6 = [], p6 = {key:6}; - var vn6 = h('span', p6, c6); - c1.push(vn6); - c6.push({text: \`sts\`}); let c7 = [], p7 = {key:7}; var vn7 = h('span', p7, c7); c1.push(vn7); - c7.push({text: \`rocks\`}); + c7.push({text: \`sts\`}); + let c8 = [], p8 = {key:8}; + var vn8 = h('span', p8, c8); + c1.push(vn8); + c8.push({text: \`rocks\`}); }" `; @@ -1504,14 +1601,14 @@ exports[`t-slot directive multiple roots are allowed in a named slot 1`] = ` var h = this.h; let c1 = extra.parentNode; Object.assign(context, extra.fiber.scope); - let c6 = [], p6 = {key:6}; - var vn6 = h('span', p6, c6); - c1.push(vn6); - c6.push({text: \`sts\`}); let c7 = [], p7 = {key:7}; var vn7 = h('span', p7, c7); c1.push(vn7); - c7.push({text: \`rocks\`}); + c7.push({text: \`sts\`}); + let c8 = [], p8 = {key:8}; + var vn8 = h('span', p8, c8); + c1.push(vn8); + c8.push({text: \`rocks\`}); }" `; @@ -1523,24 +1620,24 @@ exports[`t-slot directive refs are properly bound in slots 1`] = ` var h = this.h; let c1 = extra.parentNode; Object.assign(context, extra.fiber.scope); - let c10 = [], p10 = {key:10,on:{}}; - var vn10 = h('button', p10, c10); - c1.push(vn10); + let c11 = [], p11 = {key:11,on:{}}; + var vn11 = h('button', p11, c11); + c1.push(vn11); if (!context['doSomething']) { throw new Error('Missing handler \\\\'' + 'doSomething' + \`\\\\' when evaluating template 'slot_footer_template'\`) } - extra.handlers['click' + 10] = extra.handlers['click' + 10] || context['doSomething'].bind(owner); - p10.on['click'] = extra.handlers['click' + 10]; - const ref11 = \`myButton\`; - p10.hook = { + extra.handlers['click' + 11] = extra.handlers['click' + 11] || context['doSomething'].bind(owner); + p11.on['click'] = extra.handlers['click' + 11]; + const ref12 = \`myButton\`; + p11.hook = { create: (_, n) => { - context.__owl__.refs[ref11] = n.elm; + context.__owl__.refs[ref12] = n.elm; }, destroy: () => { - delete context.__owl__.refs[ref11]; + delete context.__owl__.refs[ref12]; }, }; - c10.push({text: \`do something\`}); + c11.push({text: \`do something\`}); }" `; @@ -1551,15 +1648,15 @@ exports[`t-slot directive slots are rendered with proper context 1`] = ` var h = this.h; let c1 = extra.parentNode; Object.assign(context, extra.fiber.scope); - let c10 = [], p10 = {key:10,on:{}}; - var vn10 = h('button', p10, c10); - c1.push(vn10); + let c11 = [], p11 = {key:11,on:{}}; + var vn11 = h('button', p11, c11); + c1.push(vn11); if (!context['doSomething']) { throw new Error('Missing handler \\\\'' + 'doSomething' + \`\\\\' when evaluating template 'slot_footer_template'\`) } - extra.handlers['click' + 10] = extra.handlers['click' + 10] || context['doSomething'].bind(owner); - p10.on['click'] = extra.handlers['click' + 10]; - c10.push({text: \`do something\`}); + extra.handlers['click' + 11] = extra.handlers['click' + 11] || context['doSomething'].bind(owner); + p11.on['click'] = extra.handlers['click' + 11]; + c11.push({text: \`do something\`}); }" `; @@ -1602,16 +1699,16 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = ` _5 = Object.values(_3); } var _length4 = _4.length; - for (let i = 0; i < _length4; i++) { - context.user_first = i === 0; + for (let i1 = 0; i1 < _length4; i1++) { + context.user_first = i1 === 0; scope.user_first = context.user_first; - context.user_last = i === _length4 - 1; + context.user_last = i1 === _length4 - 1; scope.user_last = context.user_last; - context.user_index = i; + context.user_index = i1; scope.user_index = context.user_index; - context.user = _4[i]; + context.user = _4[i1]; scope.user = context.user; - context.user_value = _5[i]; + context.user_value = _5[i1]; scope.user_value = context.user_value; const nodeKey6 = context['user'].id let c6 = [], p6 = {key:nodeKey6}; @@ -1619,8 +1716,8 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = ` c2.push(vn6); //COMPONENT let def8; - let templateId10 = String(nodeKey6 + '_k_' + i + '_c_' + 9 ); - let w9 = templateId10 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId10]] : false; + let templateId9 = \`__10__\` + nodeKey6; + let w9 = templateId9 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId9]] : false; let _7_index = c6.length; c6.push(null); let props9 = {to:'/user/'+context['user'].id}; @@ -1637,10 +1734,10 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = ` let W9 = context.constructor.components[componentKey9] || QWeb.components[componentKey9]|| context['Link']; if (!W9) {throw new Error('Cannot find the definition of component \\"' + componentKey9 + '\\"')} w9 = new W9(parent, props9); - parent.__owl__.cmap[templateId10] = w9.__owl__.id; + parent.__owl__.cmap[templateId9] = w9.__owl__.id; w9.__owl__.slotId = 1; def8 = w9.__prepare(extra.fiber, Object.assign({}, scope), undefined); - def8 = def8.then(vnode=>{if (w9.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId10, hook: {insert(vn) {let nvn=w9.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w9.destroy();}}});c6[_7_index]=pvnode;w9.__owl__.pvnode = pvnode;}); + def8 = def8.then(vnode=>{if (w9.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId9, hook: {insert(vn) {let nvn=w9.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w9.destroy();}}});c6[_7_index]=pvnode;w9.__owl__.pvnode = pvnode;}); } else { def8 = def8 || w9.__updateProps(props9, extra.fiber, Object.assign({}, scope), undefined); def8 = def8.then(()=>{if (w9.__owl__.isDestroyed) {return};let pvnode=w9.__owl__.pvnode;c6[_7_index]=pvnode;}); @@ -1704,16 +1801,16 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = ` _5 = Object.values(_3); } var _length4 = _4.length; - for (let i = 0; i < _length4; i++) { - context.user_first = i === 0; + for (let i1 = 0; i1 < _length4; i1++) { + context.user_first = i1 === 0; scope.user_first = context.user_first; - context.user_last = i === _length4 - 1; + context.user_last = i1 === _length4 - 1; scope.user_last = context.user_last; - context.user_index = i; + context.user_index = i1; scope.user_index = context.user_index; - context.user = _4[i]; + context.user = _4[i1]; scope.user = context.user; - context.user_value = _5[i]; + context.user_value = _5[i1]; scope.user_value = context.user_value; const nodeKey6 = context['user'].id let c6 = [], p6 = {key:nodeKey6}; @@ -1722,8 +1819,8 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = ` var _7 = 'User '+context['user'].name; //COMPONENT let def9; - let templateId11 = String(nodeKey6 + '_k_' + i + '_c_' + 10 ); - let w10 = templateId11 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId11]] : false; + let templateId10 = \`__11__\` + nodeKey6; + let w10 = templateId10 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId10]] : false; let _8_index = c6.length; c6.push(null); let props10 = {to:'/user/'+context['user'].id}; @@ -1740,10 +1837,10 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = ` let W10 = context.constructor.components[componentKey10] || QWeb.components[componentKey10]|| context['Link']; if (!W10) {throw new Error('Cannot find the definition of component \\"' + componentKey10 + '\\"')} w10 = new W10(parent, props10); - parent.__owl__.cmap[templateId11] = w10.__owl__.id; + parent.__owl__.cmap[templateId10] = w10.__owl__.id; w10.__owl__.slotId = 1; def9 = w10.__prepare(extra.fiber, Object.assign({}, scope), {_7}); - def9 = def9.then(vnode=>{if (w10.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId11, hook: {insert(vn) {let nvn=w10.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w10.destroy();}}});c6[_8_index]=pvnode;w10.__owl__.pvnode = pvnode;}); + def9 = def9.then(vnode=>{if (w10.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId10, hook: {insert(vn) {let nvn=w10.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w10.destroy();}}});c6[_8_index]=pvnode;w10.__owl__.pvnode = pvnode;}); } else { def9 = def9 || w10.__updateProps(props10, extra.fiber, Object.assign({}, scope), {_7}); def9 = def9.then(()=>{if (w10.__owl__.isDestroyed) {return};let pvnode=w10.__owl__.pvnode;c6[_8_index]=pvnode;}); @@ -1780,7 +1877,8 @@ exports[`t-slot directive slots are rendered with proper context, part 4 1`] = ` var _2 = 'User '+context['state'].user.name; //COMPONENT let def4; - let w5 = 5 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[5]] : false; + let templateId5 = \`__6__\`; + let w5 = templateId5 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId5]] : false; let _3_index = c1.length; c1.push(null); let props5 = {to:'/user/'+context['state'].user.id}; @@ -1797,10 +1895,10 @@ exports[`t-slot directive slots are rendered with proper context, part 4 1`] = ` let W5 = context.constructor.components[componentKey5] || QWeb.components[componentKey5]|| context['Link']; if (!W5) {throw new Error('Cannot find the definition of component \\"' + componentKey5 + '\\"')} w5 = new W5(parent, props5); - parent.__owl__.cmap[5] = w5.__owl__.id; + parent.__owl__.cmap[templateId5] = w5.__owl__.id; w5.__owl__.slotId = 1; def4 = w5.__prepare(extra.fiber, {}, {_2}); - def4 = def4.then(vnode=>{if (w5.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 5, hook: {insert(vn) {let nvn=w5.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w5.destroy();}}});c1[_3_index]=pvnode;w5.__owl__.pvnode = pvnode;}); + def4 = def4.then(vnode=>{if (w5.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId5, hook: {insert(vn) {let nvn=w5.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w5.destroy();}}});c1[_3_index]=pvnode;w5.__owl__.pvnode = pvnode;}); } else { def4 = def4 || w5.__updateProps(props5, extra.fiber, {}, {_2}); def4 = def4.then(()=>{if (w5.__owl__.isDestroyed) {return};let pvnode=w5.__owl__.pvnode;c1[_3_index]=pvnode;}); @@ -1852,9 +1950,10 @@ exports[`top level sub widgets basic use 1`] = ` var h = this.h; //COMPONENT let def2; - let w3 = 3 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[3]] : false; - let vn4 = {}; - result = vn4; + let templateId3 = \`__4__\`; + let w3 = templateId3 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId3]] : false; + let vn5 = {}; + result = vn5; let props3 = {p:1}; if (w3 && w3.__owl__.currentFiber && !w3.__owl__.vnode) { if (utils.shallowEqual(props3, w3.__owl__.currentFiber.props)) { @@ -1869,12 +1968,12 @@ exports[`top level sub widgets basic use 1`] = ` let W3 = context.constructor.components[componentKey3] || QWeb.components[componentKey3]|| context['Child']; if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')} w3 = new W3(parent, props3); - parent.__owl__.cmap[3] = w3.__owl__.id; + parent.__owl__.cmap[templateId3] = w3.__owl__.id; def2 = w3.__prepare(extra.fiber, undefined, undefined); - def2 = def2.then(vnode=>{if (w3.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 3, hook: {insert(vn) {let nvn=w3.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}});utils.defineProxy(vn4, pvnode);w3.__owl__.pvnode = pvnode;}); + def2 = def2.then(vnode=>{if (w3.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId3, hook: {insert(vn) {let nvn=w3.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}});utils.defineProxy(vn5, pvnode);w3.__owl__.pvnode = pvnode;}); } else { def2 = def2 || w3.__updateProps(props3, extra.fiber, undefined, undefined); - def2 = def2.then(()=>{if (w3.__owl__.isDestroyed) {return};let pvnode=w3.__owl__.pvnode;utils.defineProxy(vn4, pvnode);}); + def2 = def2.then(()=>{if (w3.__owl__.isDestroyed) {return};let pvnode=w3.__owl__.pvnode;utils.defineProxy(vn5, pvnode);}); } extra.promises.push(def2); return result; @@ -1893,9 +1992,10 @@ exports[`top level sub widgets can select a sub widget 1`] = ` if (context['env'].flag) { //COMPONENT let def2; - let w3 = 3 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[3]] : false; - let vn4 = {}; - result = vn4; + let templateId3 = \`__4__\`; + let w3 = templateId3 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId3]] : false; + let vn5 = {}; + result = vn5; let props3 = {}; if (w3 && w3.__owl__.currentFiber && !w3.__owl__.vnode) { if (utils.shallowEqual(props3, w3.__owl__.currentFiber.props)) { @@ -1910,43 +2010,44 @@ exports[`top level sub widgets can select a sub widget 1`] = ` let W3 = context.constructor.components[componentKey3] || QWeb.components[componentKey3]|| context['Child']; if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')} w3 = new W3(parent, props3); - parent.__owl__.cmap[3] = w3.__owl__.id; + parent.__owl__.cmap[templateId3] = w3.__owl__.id; def2 = w3.__prepare(extra.fiber, undefined, undefined); - def2 = def2.then(vnode=>{if (w3.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 3, hook: {insert(vn) {let nvn=w3.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}});utils.defineProxy(vn4, pvnode);w3.__owl__.pvnode = pvnode;}); + def2 = def2.then(vnode=>{if (w3.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId3, hook: {insert(vn) {let nvn=w3.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}});utils.defineProxy(vn5, pvnode);w3.__owl__.pvnode = pvnode;}); } else { def2 = def2 || w3.__updateProps(props3, extra.fiber, undefined, undefined); - def2 = def2.then(()=>{if (w3.__owl__.isDestroyed) {return};let pvnode=w3.__owl__.pvnode;utils.defineProxy(vn4, pvnode);}); + def2 = def2.then(()=>{if (w3.__owl__.isDestroyed) {return};let pvnode=w3.__owl__.pvnode;utils.defineProxy(vn5, pvnode);}); } extra.promises.push(def2); } if (!context['env'].flag) { //COMPONENT - let def6; - let w7 = 7 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[7]] : false; - let vn8 = {}; - result = vn8; - let props7 = {}; - if (w7 && w7.__owl__.currentFiber && !w7.__owl__.vnode) { - if (utils.shallowEqual(props7, w7.__owl__.currentFiber.props)) { - def6 = w7.__owl__.currentFiber.promise; + let def7; + let templateId8 = \`__9__\`; + let w8 = templateId8 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId8]] : false; + let vn10 = {}; + result = vn10; + let props8 = {}; + if (w8 && w8.__owl__.currentFiber && !w8.__owl__.vnode) { + if (utils.shallowEqual(props8, w8.__owl__.currentFiber.props)) { + def7 = w8.__owl__.currentFiber.promise; } else { - w7.destroy(); - w7 = false; + w8.destroy(); + w8 = false; } } - if (!w7) { - let componentKey7 = \`OtherChild\`; - let W7 = context.constructor.components[componentKey7] || QWeb.components[componentKey7]|| context['OtherChild']; - if (!W7) {throw new Error('Cannot find the definition of component \\"' + componentKey7 + '\\"')} - w7 = new W7(parent, props7); - parent.__owl__.cmap[7] = w7.__owl__.id; - def6 = w7.__prepare(extra.fiber, undefined, undefined); - def6 = def6.then(vnode=>{if (w7.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 7, hook: {insert(vn) {let nvn=w7.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}});utils.defineProxy(vn8, pvnode);w7.__owl__.pvnode = pvnode;}); + if (!w8) { + let componentKey8 = \`OtherChild\`; + let W8 = context.constructor.components[componentKey8] || QWeb.components[componentKey8]|| context['OtherChild']; + if (!W8) {throw new Error('Cannot find the definition of component \\"' + componentKey8 + '\\"')} + w8 = new W8(parent, props8); + parent.__owl__.cmap[templateId8] = w8.__owl__.id; + def7 = w8.__prepare(extra.fiber, undefined, undefined); + def7 = def7.then(vnode=>{if (w8.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId8, hook: {insert(vn) {let nvn=w8.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w8.destroy();}}});utils.defineProxy(vn10, pvnode);w8.__owl__.pvnode = pvnode;}); } else { - def6 = def6 || w7.__updateProps(props7, extra.fiber, undefined, undefined); - def6 = def6.then(()=>{if (w7.__owl__.isDestroyed) {return};let pvnode=w7.__owl__.pvnode;utils.defineProxy(vn8, pvnode);}); + def7 = def7 || w8.__updateProps(props8, extra.fiber, undefined, undefined); + def7 = def7.then(()=>{if (w8.__owl__.isDestroyed) {return};let pvnode=w8.__owl__.pvnode;utils.defineProxy(vn10, pvnode);}); } - extra.promises.push(def6); + extra.promises.push(def7); } return result; }" diff --git a/tests/component/__snapshots__/props_validation.test.ts.snap b/tests/component/__snapshots__/props_validation.test.ts.snap index a767b2ac..2ef3ff62 100644 --- a/tests/component/__snapshots__/props_validation.test.ts.snap +++ b/tests/component/__snapshots__/props_validation.test.ts.snap @@ -16,7 +16,8 @@ exports[`props validation props are validated in dev mode (code snapshot) 1`] = var vn1 = h('div', p1, c1); //COMPONENT let def3; - let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false; + let templateId4 = \`__5__\`; + let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false; let _2_index = c1.length; c1.push(null); let props4 = {message:1}; @@ -34,9 +35,9 @@ exports[`props validation props are validated in dev mode (code snapshot) 1`] = if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')} utils.validateProps(W4, props4) w4 = new W4(parent, props4); - parent.__owl__.cmap[4] = w4.__owl__.id; + parent.__owl__.cmap[templateId4] = w4.__owl__.id; def3 = w4.__prepare(extra.fiber, undefined, undefined); - def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); } else { utils.validateProps(w4.constructor, props4) def3 = def3 || w4.__updateProps(props4, extra.fiber, undefined, undefined); diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts index a49188fe..a813e220 100644 --- a/tests/component/component.test.ts +++ b/tests/component/component.test.ts @@ -182,6 +182,52 @@ describe("basic widget properties", () => { await widget.mount(fixture); expect(fixture.innerHTML).toBe("
childchild
"); }); + + test("reconciliation alg works for t-foreach in t-foreach", async () => { + const warn = console.warn; + console.warn = () => {}; + class Child extends Component { + static template = xml`
`; + } + + class Parent extends Component { + static template = xml` +
+ + + + + +
`; + static components = { Child }; + state = { s: [{ blips: ["a1", "a2"] }, { blips: ["b1"] }] }; + } + + const widget = new Parent(env); + await widget.mount(fixture); + expect(fixture.innerHTML).toBe("
a1
a2
b1
"); + expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot(); + console.warn = warn; + }); + + test("same t-keys in two different places", async () => { + class Child extends Component { + static template = xml``; + } + + class Parent extends Component { + static template = xml` +
+
+
+
`; + static components = { Child }; + } + + const widget = new Parent(env); + await widget.mount(fixture); + expect(fixture.innerHTML).toBe("
1
2
"); + }); }); describe("lifecycle hooks", () => { diff --git a/tests/qweb/__snapshots__/qweb.test.ts.snap b/tests/qweb/__snapshots__/qweb.test.ts.snap index 382d0570..67d1be36 100644 --- a/tests/qweb/__snapshots__/qweb.test.ts.snap +++ b/tests/qweb/__snapshots__/qweb.test.ts.snap @@ -325,12 +325,12 @@ exports[`foreach does not pollute the rendering context 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.item_first = i === 0; - context.item_last = i === _length3 - 1; - context.item_index = i; - context.item = _3[i]; - context.item_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.item_first = i1 === 0; + context.item_last = i1 === _length3 - 1; + context.item_index = i1; + context.item = _3[i1]; + context.item_value = _4[i1]; var _5 = context['item']; if (_5 || _5 === 0) { c1.push({text: _5}); @@ -355,12 +355,12 @@ exports[`foreach iterate on items (on a element node) 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.item_first = i === 0; - context.item_last = i === _length3 - 1; - context.item_index = i; - context.item = _3[i]; - context.item_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.item_first = i1 === 0; + context.item_last = i1 === _length3 - 1; + context.item_index = i1; + context.item = _3[i1]; + context.item_value = _4[i1]; const nodeKey5 = context['item'] let c5 = [], p5 = {key:nodeKey5}; var vn5 = h('span', p5, c5); @@ -389,12 +389,12 @@ exports[`foreach iterate on items 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.item_first = i === 0; - context.item_last = i === _length3 - 1; - context.item_index = i; - context.item = _3[i]; - context.item_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.item_first = i1 === 0; + context.item_last = i1 === _length3 - 1; + context.item_index = i1; + context.item = _3[i1]; + context.item_value = _4[i1]; c1.push({text: \` [\`}); var _5 = context['item_index']; if (_5 || _5 === 0) { @@ -431,12 +431,12 @@ exports[`foreach iterate, dict param 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.item_first = i === 0; - context.item_last = i === _length3 - 1; - context.item_index = i; - context.item = _3[i]; - context.item_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.item_first = i1 === 0; + context.item_last = i1 === _length3 - 1; + context.item_index = i1; + context.item = _3[i1]; + context.item_value = _4[i1]; c1.push({text: \` [\`}); var _5 = context['item_index']; if (_5 || _5 === 0) { @@ -473,12 +473,12 @@ exports[`foreach iterate, position 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.elem_first = i === 0; - context.elem_last = i === _length3 - 1; - context.elem_index = i; - context.elem = _3[i]; - context.elem_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.elem_first = i1 === 0; + context.elem_last = i1 === _length3 - 1; + context.elem_index = i1; + context.elem = _3[i1]; + context.elem_value = _4[i1]; c1.push({text: \` -\`}); if (context['elem_first']) { c1.push({text: \` first\`}); @@ -497,6 +497,57 @@ exports[`foreach iterate, position 1`] = ` }" `; +exports[`foreach t-foreach in t-forach 1`] = ` +"function anonymous(context,extra +) { + context = Object.create(context); + var h = this.h; + let c1 = [], p1 = {key:1}; + var vn1 = h('div', p1, c1); + var _2 = context['numbers']; + if (!_2) { throw new Error('QWeb error: Invalid loop expression')} + var _3 = _4 = _2; + if (!(_2 instanceof Array)) { + _3 = Object.keys(_2); + _4 = Object.values(_2); + } + var _length3 = _3.length; + for (let i1 = 0; i1 < _length3; i1++) { + context.number_first = i1 === 0; + context.number_last = i1 === _length3 - 1; + context.number_index = i1; + context.number = _3[i1]; + context.number_value = _4[i1]; + var _5 = context['letters']; + if (!_5) { throw new Error('QWeb error: Invalid loop expression')} + var _6 = _7 = _5; + if (!(_5 instanceof Array)) { + _6 = Object.keys(_5); + _7 = Object.values(_5); + } + var _length6 = _6.length; + for (let i2 = 0; i2 < _length6; i2++) { + context.letter_first = i2 === 0; + context.letter_last = i2 === _length6 - 1; + context.letter_index = i2; + context.letter = _6[i2]; + context.letter_value = _7[i2]; + c1.push({text: \` [\`}); + var _8 = context['number']; + if (_8 || _8 === 0) { + c1.push({text: _8}); + } + var _9 = context['letter']; + if (_9 || _9 === 0) { + c1.push({text: _9}); + } + c1.push({text: \`] \`}); + } + } + return vn1; +}" +`; + exports[`foreach warn if no key in some case 1`] = ` "function anonymous(context,extra ) { @@ -512,12 +563,12 @@ exports[`foreach warn if no key in some case 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.item_first = i === 0; - context.item_last = i === _length3 - 1; - context.item_index = i; - context.item = _3[i]; - context.item_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.item_first = i1 === 0; + context.item_last = i1 === _length3 - 1; + context.item_index = i1; + context.item = _3[i1]; + context.item_value = _4[i1]; let c5 = [], p5 = {key:5}; var vn5 = h('span', p5, c5); c1.push(vn5); @@ -575,12 +626,12 @@ exports[`misc global 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.value_first = i === 0; - context.value_last = i === _length3 - 1; - context.value_index = i; - context.value = _3[i]; - context.value_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.value_first = i1 === 0; + context.value_last = i1 === _length3 - 1; + context.value_index = i1; + context.value = _3[i1]; + context.value_value = _4[i1]; let c5 = [], p5 = {key:5}; var vn5 = h('span', p5, c5); c1.push(vn5); @@ -940,16 +991,16 @@ exports[`t-call (template calling recursive template, part 2 1`] = ` _8 = Object.values(_6); } var _length7 = _7.length; - for (let i = 0; i < _length7; i++) { - context.subtree_first = i === 0; + for (let i1 = 0; i1 < _length7; i1++) { + context.subtree_first = i1 === 0; scope.subtree_first = context.subtree_first; - context.subtree_last = i === _length7 - 1; + context.subtree_last = i1 === _length7 - 1; scope.subtree_last = context.subtree_last; - context.subtree_index = i; + context.subtree_index = i1; scope.subtree_index = context.subtree_index; - context.subtree = _7[i]; + context.subtree = _7[i1]; scope.subtree = context.subtree; - context.subtree_value = _8[i]; + context.subtree_value = _8[i1]; scope.subtree_value = context.subtree_value; this.recursiveFns['__10'].call(this, context, Object.assign({}, extra, {parentNode: c3, fiber: {vars: {_v0: context['subtree']}, scope}})); } @@ -986,16 +1037,16 @@ exports[`t-call (template calling recursive template, part 2 2`] = ` _17 = Object.values(_15); } var _length16 = _16.length; - for (let i = 0; i < _length16; i++) { - context.subtree_first = i === 0; + for (let i1 = 0; i1 < _length16; i1++) { + context.subtree_first = i1 === 0; scope.subtree_first = context.subtree_first; - context.subtree_last = i === _length16 - 1; + context.subtree_last = i1 === _length16 - 1; scope.subtree_last = context.subtree_last; - context.subtree_index = i; + context.subtree_index = i1; scope.subtree_index = context.subtree_index; - context.subtree = _16[i]; + context.subtree = _16[i1]; scope.subtree = context.subtree; - context.subtree_value = _17[i]; + context.subtree_value = _17[i1]; scope.subtree_value = context.subtree_value; this.recursiveFns['__10'].call(this, context, Object.assign({}, extra, {parentNode: c12, fiber: {vars: {_v0: context['subtree']}, scope}})); } @@ -1031,16 +1082,16 @@ exports[`t-call (template calling recursive template, part 3 1`] = ` _8 = Object.values(_6); } var _length7 = _7.length; - for (let i = 0; i < _length7; i++) { - context.subtree_first = i === 0; + for (let i1 = 0; i1 < _length7; i1++) { + context.subtree_first = i1 === 0; scope.subtree_first = context.subtree_first; - context.subtree_last = i === _length7 - 1; + context.subtree_last = i1 === _length7 - 1; scope.subtree_last = context.subtree_last; - context.subtree_index = i; + context.subtree_index = i1; scope.subtree_index = context.subtree_index; - context.subtree = _7[i]; + context.subtree = _7[i1]; scope.subtree = context.subtree; - context.subtree_value = _8[i]; + context.subtree_value = _8[i1]; scope.subtree_value = context.subtree_value; this.recursiveFns['__10'].call(this, context, Object.assign({}, extra, {parentNode: c3, fiber: {vars: {_v0: context['subtree']}, scope}})); } @@ -1077,16 +1128,16 @@ exports[`t-call (template calling recursive template, part 3 2`] = ` _17 = Object.values(_15); } var _length16 = _16.length; - for (let i = 0; i < _length16; i++) { - context.subtree_first = i === 0; + for (let i1 = 0; i1 < _length16; i1++) { + context.subtree_first = i1 === 0; scope.subtree_first = context.subtree_first; - context.subtree_last = i === _length16 - 1; + context.subtree_last = i1 === _length16 - 1; scope.subtree_last = context.subtree_last; - context.subtree_index = i; + context.subtree_index = i1; scope.subtree_index = context.subtree_index; - context.subtree = _16[i]; + context.subtree = _16[i1]; scope.subtree = context.subtree; - context.subtree_value = _17[i]; + context.subtree_value = _17[i1]; scope.subtree_value = context.subtree_value; this.recursiveFns['__10'].call(this, context, Object.assign({}, extra, {parentNode: c12, fiber: {vars: {_v0: context['subtree']}, scope}})); } @@ -1446,12 +1497,12 @@ exports[`t-key t-key directive in a list 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.beer_first = i === 0; - context.beer_last = i === _length3 - 1; - context.beer_index = i; - context.beer = _3[i]; - context.beer_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.beer_first = i1 === 0; + context.beer_last = i1 === _length3 - 1; + context.beer_index = i1; + context.beer = _3[i1]; + context.beer_value = _4[i1]; const nodeKey5 = context['beer'].id let c5 = [], p5 = {key:nodeKey5}; var vn5 = h('li', p5, c5); @@ -1548,12 +1599,12 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.action_first = i === 0; - context.action_last = i === _length3 - 1; - context.action_index = i; - context.action = _3[i]; - context.action_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.action_first = i1 === 0; + context.action_last = i1 === _length3 - 1; + context.action_index = i1; + context.action = _3[i1]; + context.action_value = _4[i1]; const nodeKey5 = context['action_index'] let c5 = [], p5 = {key:nodeKey5}; var vn5 = h('li', p5, c5); @@ -1750,12 +1801,12 @@ exports[`t-on t-on with prevent modifier in t-foreach 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.project_first = i === 0; - context.project_last = i === _length3 - 1; - context.project_index = i; - context.project = _3[i]; - context.project_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.project_first = i1 === 0; + context.project_last = i1 === _length3 - 1; + context.project_index = i1; + context.project = _3[i1]; + context.project_value = _4[i1]; var _5 = '#'; const nodeKey6 = context['project'] let c6 = [], p6 = {key:nodeKey6,attrs:{href: _5},on:{}}; @@ -1960,12 +2011,12 @@ exports[`t-ref refs in a loop 1`] = ` _4 = Object.values(_2); } var _length3 = _3.length; - for (let i = 0; i < _length3; i++) { - context.item_first = i === 0; - context.item_last = i === _length3 - 1; - context.item_index = i; - context.item = _3[i]; - context.item_value = _4[i]; + for (let i1 = 0; i1 < _length3; i1++) { + context.item_first = i1 === 0; + context.item_last = i1 === _length3 - 1; + context.item_index = i1; + context.item = _3[i1]; + context.item_value = _4[i1]; const nodeKey5 = context['item'] let c5 = [], p5 = {key:nodeKey5}; var vn5 = h('div', p5, c5); @@ -2126,12 +2177,12 @@ exports[`t-set t-set should reuse variable if possible 1`] = ` _5 = Object.values(_3); } var _length4 = _4.length; - for (let i = 0; i < _length4; i++) { - context.elem_first = i === 0; - context.elem_last = i === _length4 - 1; - context.elem_index = i; - context.elem = _4[i]; - context.elem_value = _5[i]; + for (let i1 = 0; i1 < _length4; i1++) { + context.elem_first = i1 === 0; + context.elem_last = i1 === _length4 - 1; + context.elem_index = i1; + context.elem = _4[i1]; + context.elem_value = _5[i1]; const nodeKey6 = context['elem_index'] let c6 = [], p6 = {key:nodeKey6}; var vn6 = h('div', p6, c6); diff --git a/tests/qweb/qweb.test.ts b/tests/qweb/qweb.test.ts index b9852054..cbc5daaf 100644 --- a/tests/qweb/qweb.test.ts +++ b/tests/qweb/qweb.test.ts @@ -749,6 +749,23 @@ describe("foreach", () => { expect(Object.keys(context).length).toBe(0); }); + test("t-foreach in t-forach", () => { + qweb.addTemplate( + "test", + `
+ + + [] + + +
` + ); + const context = { numbers: [1, 2, 3], letters: ["a", "b"] }; + expect(renderToString(qweb, "test", context)).toBe( + "
[1a] [1b] [2a] [2b] [3a] [3b]
" + ); + }); + test("throws error if invalid loop expression", () => { qweb.addTemplate( "test", diff --git a/tests/router/__snapshots__/route_component.test.ts.snap b/tests/router/__snapshots__/route_component.test.ts.snap index e5eabb38..44c1fbe7 100644 --- a/tests/router/__snapshots__/route_component.test.ts.snap +++ b/tests/router/__snapshots__/route_component.test.ts.snap @@ -13,8 +13,8 @@ exports[`RouteComponent can render simple cases 1`] = ` //COMPONENT let key4 = 'key' + context['env'].router.currentRouteName; let def2; - let templateId5 = key4; - let w3 = templateId5 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId5]] : false; + let templateId3 = \`__5__\` + key4; + let w3 = templateId3 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId3]] : false; let vn6 = {}; result = vn6; let props3 = Object.assign({}, context['env'].router.currentParams); @@ -31,9 +31,9 @@ exports[`RouteComponent can render simple cases 1`] = ` let W3 = context.constructor.components[componentKey3] || QWeb.components[componentKey3]|| context['routeComponent']; if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')} w3 = new W3(parent, props3); - parent.__owl__.cmap[templateId5] = w3.__owl__.id; + parent.__owl__.cmap[templateId3] = w3.__owl__.id; def2 = w3.__prepare(extra.fiber, undefined, undefined); - def2 = def2.then(vnode=>{if (w3.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId5, hook: {insert(vn) {let nvn=w3.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}});utils.defineProxy(vn6, pvnode);w3.__owl__.pvnode = pvnode;}); + def2 = def2.then(vnode=>{if (w3.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId3, hook: {insert(vn) {let nvn=w3.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w3.destroy();}}});utils.defineProxy(vn6, pvnode);w3.__owl__.pvnode = pvnode;}); } else { def2 = def2 || w3.__updateProps(props3, extra.fiber, undefined, undefined); def2 = def2.then(()=>{if (w3.__owl__.isDestroyed) {return};let pvnode=w3.__owl__.pvnode;utils.defineProxy(vn6, pvnode);});