diff --git a/src/qweb/base_directives.ts b/src/qweb/base_directives.ts
index 9ac3fe46..6031e524 100644
--- a/src/qweb/base_directives.ts
+++ b/src/qweb/base_directives.ts
@@ -234,10 +234,12 @@ QWeb.addDirective({
// Step 2: compile target template in sub templates
// ------------------------------------------------
- if (!qweb.subTemplates[subTemplate]) {
- qweb.subTemplates[subTemplate] = true;
+ let subId = qweb.subTemplates[subTemplate];
+ if (!subId) {
+ subId = QWeb.nextId++;
+ qweb.subTemplates[subTemplate] = subId;
const subTemplateFn = qweb._compile(subTemplate, nodeTemplate.elem, ctx, true);
- qweb.subTemplates[subTemplate] = subTemplateFn;
+ QWeb.subTemplates[subId] = subTemplateFn;
}
// Step 3: compile t-call body if necessary
@@ -275,12 +277,16 @@ QWeb.addDirective({
const parentNode = ctx.parentNode ? `c${ctx.parentNode}` : "result";
const extra = `Object.assign({}, extra, {parentNode: ${parentNode}, parent: ${parentComponent}, key: ${key}})`;
if (ctx.parentNode) {
- ctx.addLine(`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, ${extra});`);
+ ctx.addLine(
+ `this.constructor.subTemplates['${subId}'].call(this, ${callingScope}, ${extra});`
+ );
} else {
// this is a t-call with no parentnode, we need to extract the result
ctx.rootContext.shouldDefineResult = true;
ctx.addLine(`result = []`);
- ctx.addLine(`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, ${extra});`);
+ ctx.addLine(
+ `this.constructor.subTemplates['${subId}'].call(this, ${callingScope}, ${extra});`
+ );
ctx.addLine(`result = result[0]`);
}
diff --git a/src/qweb/qweb.ts b/src/qweb/qweb.ts
index a3e94cfd..618807ec 100644
--- a/src/qweb/qweb.ts
+++ b/src/qweb/qweb.ts
@@ -212,10 +212,12 @@ export class QWeb extends EventBus {
static slots = {};
static nextSlotId = 1;
- // recursiveTemplates contains sub templates called with t-call, but which
- // ends up in recursive situations. This is very similar to the slot situation,
- // as in we need to propagate the scope.
- subTemplates = {};
+ // subTemplates are stored in two objects: a (local) mapping from a name to an
+ // id, and a (global) mapping from an id to the compiled function. This is
+ // necessary to ensure that global templates can be called with more than one
+ // QWeb instance.
+ subTemplates: {[key: string]: number} = {};
+ static subTemplates: {[id: number]: Function} = {};
isUpdating: boolean = false;
translateFn?: QWebConfig["translateFn"];
diff --git a/tests/component/__snapshots__/component.test.ts.snap b/tests/component/__snapshots__/component.test.ts.snap
index 6ea5f6d3..918198d0 100644
--- a/tests/component/__snapshots__/component.test.ts.snap
+++ b/tests/component/__snapshots__/component.test.ts.snap
@@ -1253,7 +1253,7 @@ exports[`other directives with t-component t-set can't alter from within callee
if (scope.iter != null) {
c2.push({text: scope.iter});
}
- this.subTemplates['ChildWidget'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['2'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
let c5 = [], p5 = {key:5};
let vn5 = h('p', p5, c5);
c1.push(vn5);
@@ -1289,7 +1289,7 @@ exports[`other directives with t-component t-set can't alter in t-call body 1`]
utils.getScope(scope, 'iter').iter = 'inCall';
scope[utils.zero] = c__0;
}
- this.subTemplates['ChildWidget'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__5__'}));
+ this.constructor.subTemplates['2'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__5__'}));
scope = _origScope4;
}
let c6 = [], p6 = {key:6};
@@ -1410,7 +1410,7 @@ exports[`random stuff/miscellaneous can inject values in tagged templates 1`] =
let h = this.h;
let c1 = [], p1 = {key:1};
let vn1 = h('div', p1, c1);
- this.subTemplates['__template__1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['3'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
return vn1;
}"
`;
diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts
index 96df72a2..d3dafbc6 100644
--- a/tests/component/component.test.ts
+++ b/tests/component/component.test.ts
@@ -3825,7 +3825,9 @@ describe("t-call", () => {
expect(fixture.innerHTML).toBe("
");
fixture.querySelector("p")!.click();
- expect(env.qweb.subTemplates["sub"].toString()).toMatchSnapshot();
+ const subId = env.qweb.subTemplates["sub"];
+ const subFn = QWeb.subTemplates[subId] as any;
+ expect(subFn.toString()).toMatchSnapshot();
});
test("parent is set within t-call", async () => {
@@ -3847,7 +3849,10 @@ describe("t-call", () => {
expect(fixture.innerHTML).toBe("lucas
");
expect(child.__owl__.parent).toBe(parent);
- expect(env.qweb.subTemplates["sub"].toString()).toMatchSnapshot();
+ const subId = env.qweb.subTemplates["sub"];
+ const subFn = QWeb.subTemplates[subId] as any;
+
+ expect(subFn.toString()).toMatchSnapshot();
});
test("t-call in t-foreach and children component", async () => {
@@ -3889,7 +3894,9 @@ describe("t-call", () => {
expect(fixture.innerHTML).toBe("lucas");
expect(child.__owl__.parent).toBe(parent);
- expect(env.qweb.subTemplates["sub"].toString()).toMatchSnapshot();
+ const subId = env.qweb.subTemplates["sub"];
+ const subFn = QWeb.subTemplates[subId] as any;
+ expect(subFn.toString()).toMatchSnapshot();
});
test("handlers with arguments are properly bound through a t-call", async () => {
@@ -3905,7 +3912,9 @@ describe("t-call", () => {
}
const parent = new Parent();
await parent.mount(fixture);
- expect(env.qweb.subTemplates["sub"].toString()).toMatchSnapshot();
+ const subId = env.qweb.subTemplates["sub"];
+ const subFn = QWeb.subTemplates[subId] as any;
+ expect(subFn.toString()).toMatchSnapshot();
fixture.querySelector("p")!.click();
});
diff --git a/tests/qweb/__snapshots__/qweb.test.ts.snap b/tests/qweb/__snapshots__/qweb.test.ts.snap
index b56c3230..abdc10ce 100644
--- a/tests/qweb/__snapshots__/qweb.test.ts.snap
+++ b/tests/qweb/__snapshots__/qweb.test.ts.snap
@@ -749,7 +749,7 @@ exports[`loading templates can load a few templates from a xml string 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1};
let vn1 = h('ul', p1, c1);
- this.subTemplates['items'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
return vn1;
}"
`;
@@ -803,23 +803,23 @@ exports[`misc global 1`] = `
scope[utils.zero] = c__0;
}
let k14 = \`__14__\${key1}__\`;
- this.subTemplates['_callee-uses-foo'].call(this, scope, Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k14}));
+ this.constructor.subTemplates['2'].call(this, scope, Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k14}));
scope = _origScope13;
}
let k15 = \`__15__\${key1}__\`;
- this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k15}));
+ this.constructor.subTemplates['2'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k15}));
utils.getScope(scope, 'foo').foo = 'bbb';
let k16 = \`__16__\${key1}__\`;
- this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k16}));
+ this.constructor.subTemplates['2'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k16}));
scope[utils.zero] = c__0;
}
let k17 = \`__17__\${key1}__\`;
- this.subTemplates['_callee-asc'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: k17}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: k17}));
scope = _origScope10;
}
}
scope = _origScope5;
- this.subTemplates['_callee-asc-toto'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__20__'}));
+ this.constructor.subTemplates['3'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__20__'}));
return vn1;
}"
`;
@@ -1108,25 +1108,11 @@ exports[`t-call (template calling basic caller 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1};
let vn1 = h('div', p1, c1);
- this.subTemplates['_basic-callee'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
return vn1;
}"
`;
-exports[`t-call (template calling basic caller 2`] = `
-"function anonymous(context, extra
-) {
- // Template name: \\"_basic-callee\\"
- let h = this.h;
- let c1 = extra.parentNode;
- let key0 = extra.key || \\"\\";
- let c2 = [], p2 = {key:\`\${key0}_2\`};
- let vn2 = h('span', p2, c2);
- c1.push(vn2);
- c2.push({text: \`ok\`});
-}"
-`;
-
exports[`t-call (template calling basic caller, no parent node 1`] = `
"function anonymous(context, extra
) {
@@ -1136,26 +1122,12 @@ exports[`t-call (template calling basic caller, no parent node 1`] = `
let result;
let h = this.h;
result = []
- this.subTemplates['_basic-callee'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__3__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__3__'}));
result = result[0]
return result;
}"
`;
-exports[`t-call (template calling basic caller, no parent node 2`] = `
-"function anonymous(context, extra
-) {
- // Template name: \\"_basic-callee\\"
- let h = this.h;
- let c1 = extra.parentNode;
- let key0 = extra.key || \\"\\";
- let c2 = [], p2 = {key:\`\${key0}_2\`};
- let vn2 = h('div', p2, c2);
- c1.push(vn2);
- c2.push({text: \`ok\`});
-}"
-`;
-
exports[`t-call (template calling call with several sub nodes on same line 1`] = `
"function anonymous(context, extra
) {
@@ -1182,28 +1154,14 @@ exports[`t-call (template calling call with several sub nodes on same line 1`] =
c5.push({text: \`yay\`});
scope[utils.zero] = c__0;
}
- this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__6__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__6__'}));
scope = _origScope3;
}
return vn1;
}"
`;
-exports[`t-call (template calling call with several sub nodes on same line 2`] = `
-"function anonymous(context, extra
-) {
- // Template name: \\"SubTemplate\\"
- let utils = this.constructor.utils;
- let scope = Object.create(context);
- let h = this.h;
- let c1 = extra.parentNode;
- let key0 = extra.key || \\"\\";
- let c2 = [], p2 = {key:\`\${key0}_2\`};
- let vn2 = h('div', p2, c2);
- c1.push(vn2);
- c2.push(...scope[utils.zero]);
-}"
-`;
+exports[`t-call (template calling call with several sub nodes on same line 2`] = `"1"`;
exports[`t-call (template calling cascading t-call t-raw='0' 1`] = `
"function anonymous(context, extra
@@ -1231,7 +1189,7 @@ exports[`t-call (template calling cascading t-call t-raw='0' 1`] = `
c14.push({text: \`yay\`});
scope[utils.zero] = c__0;
}
- this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__15__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__15__'}));
scope = _origScope12;
}
return vn1;
@@ -1248,7 +1206,7 @@ exports[`t-call (template calling inherit context 1`] = `
let c1 = [], p1 = {key:1};
let vn1 = h('div', p1, c1);
scope.foo = 1;
- this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__2__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__2__'}));
return vn1;
}"
`;
@@ -1267,7 +1225,7 @@ exports[`t-call (template calling recursive template, part 1 1`] = `
c1.push(vn2);
c2.push({text: \`hey\`});
if (false) {
- this.subTemplates['recursive'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__6__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__6__'}));
}
return vn1;
}"
@@ -1291,7 +1249,7 @@ exports[`t-call (template calling recursive template, part 1 2`] = `
c4.push({text: \`hey\`});
if (false) {
let k5 = \`__5__\${key0}__\`;
- this.subTemplates['recursive'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c3, parent: utils.getComponent(context), key: k5}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c3, parent: utils.getComponent(context), key: k5}));
}
}"
`;
@@ -1314,7 +1272,7 @@ exports[`t-call (template calling recursive template, part 2 1`] = `
utils.getScope(scope, 'node').node = scope['root'];
scope[utils.zero] = c__0;
}
- this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__12__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__12__'}));
scope = _origScope11;
}
return vn1;
@@ -1367,7 +1325,7 @@ exports[`t-call (template calling recursive template, part 2 2`] = `
scope[utils.zero] = c__0;
}
let k10 = \`__10__\${key0}__\${key1}__\`;
- this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c2, parent: utils.getComponent(context), key: k10}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c2, parent: utils.getComponent(context), key: k10}));
scope = _origScope9;
}
}
@@ -1393,7 +1351,7 @@ exports[`t-call (template calling recursive template, part 3 1`] = `
utils.getScope(scope, 'node').node = scope['root'];
scope[utils.zero] = c__0;
}
- this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__12__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__12__'}));
scope = _origScope11;
}
return vn1;
@@ -1446,7 +1404,7 @@ exports[`t-call (template calling recursive template, part 3 2`] = `
scope[utils.zero] = c__0;
}
let k10 = \`__10__\${key0}__\${key1}__\`;
- this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c2, parent: utils.getComponent(context), key: k10}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c2, parent: utils.getComponent(context), key: k10}));
scope = _origScope9;
}
}
@@ -1473,7 +1431,7 @@ exports[`t-call (template calling recursive template, part 4: with t-set recursi
utils.getScope(scope, 'node').node = scope['root'];
scope[utils.zero] = c__0;
}
- this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__12__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__12__'}));
scope = _origScope11;
}
return vn1;
@@ -1531,7 +1489,7 @@ exports[`t-call (template calling recursive template, part 4: with t-set recursi
scope[utils.zero] = c__0;
}
let k10 = \`__10__\${key0}__\${key1}__\`;
- this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c2, parent: utils.getComponent(context), key: k10}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c2, parent: utils.getComponent(context), key: k10}));
scope = _origScope9;
}
}
@@ -1557,7 +1515,7 @@ exports[`t-call (template calling scoped parameters 1`] = `
utils.getScope(scope, 'foo').foo = 42;
scope[utils.zero] = c__0;
}
- this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
scope = _origScope2;
}
if (scope.foo != null) {
@@ -1577,26 +1535,12 @@ exports[`t-call (template calling t-call with t-if 1`] = `
let c1 = [], p1 = {key:1};
let vn1 = h('div', p1, c1);
if (scope['flag']) {
- this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
}
return vn1;
}"
`;
-exports[`t-call (template calling t-call with t-if 2`] = `
-"function anonymous(context, extra
-) {
- // Template name: \\"sub\\"
- let h = this.h;
- let c1 = extra.parentNode;
- let key0 = extra.key || \\"\\";
- let c2 = [], p2 = {key:\`\${key0}_2\`};
- let vn2 = h('span', p2, c2);
- c1.push(vn2);
- c2.push({text: \`ok\`});
-}"
-`;
-
exports[`t-call (template calling t-call with t-set inside and outside 1`] = `
"function anonymous(context, extra
) {
@@ -1634,7 +1578,7 @@ exports[`t-call (template calling t-call with t-set inside and outside 1`] = `
scope[utils.zero] = c__0;
}
let k9 = \`__9__\${key1}__\`;
- this.subTemplates['sub'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: k9}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: k9}));
scope = _origScope8;
}
}
@@ -1653,7 +1597,7 @@ exports[`t-call (template calling t-call with t-set inside and outside. 2 1`] =
let c1 = [], p1 = {key:1};
let vn1 = h('p', p1, c1);
scope.w = 'fromwrapper';
- this.subTemplates['main'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__11__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__11__'}));
return vn1;
}"
`;
@@ -1669,7 +1613,7 @@ exports[`t-call (template calling t-call, conditional and t-set in t-call body 1
let vn1 = h('div', p1, c1);
scope.v1 = 'elif';
if (scope.v1==='if') {
- this.subTemplates['callee1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
}
else if (scope.v1==='elif') {
{
@@ -1681,7 +1625,7 @@ exports[`t-call (template calling t-call, conditional and t-set in t-call body 1
utils.getScope(scope, 'v').v = 'success';
scope[utils.zero] = c__0;
}
- this.subTemplates['callee2'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__7__'}));
+ this.constructor.subTemplates['2'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__7__'}));
scope = _origScope6;
}
}
@@ -1698,7 +1642,35 @@ exports[`t-call (template calling t-call, global templates 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1};
let vn1 = h('div', p1, c1);
- this.subTemplates['john'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
+ return vn1;
+}"
+`;
+
+exports[`t-call (template calling two different QWeb instances, and shared templates 1`] = `
+"function anonymous(context, extra
+) {
+ // Template name: \\"main\\"
+ let utils = this.constructor.utils;
+ let scope = Object.create(context);
+ let h = this.h;
+ let c1 = [], p1 = {key:1};
+ let vn1 = h('div', p1, c1);
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
+ return vn1;
+}"
+`;
+
+exports[`t-call (template calling two different QWeb instances, and shared templates 2`] = `
+"function anonymous(context, extra
+) {
+ // Template name: \\"main\\"
+ let utils = this.constructor.utils;
+ let scope = Object.create(context);
+ let h = this.h;
+ let c1 = [], p1 = {key:1};
+ let vn1 = h('div', p1, c1);
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
return vn1;
}"
`;
@@ -1721,7 +1693,7 @@ exports[`t-call (template calling with unused body 1`] = `
scope[utils.zero] = c__0;
}
result = []
- this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
result = result[0]
scope = _origScope3;
}
@@ -1747,7 +1719,7 @@ exports[`t-call (template calling with unused setbody 1`] = `
scope[utils.zero] = c__0;
}
result = []
- this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
result = result[0]
scope = _origScope3;
}
@@ -1773,7 +1745,7 @@ exports[`t-call (template calling with used body 1`] = `
scope[utils.zero] = c__0;
}
result = []
- this.subTemplates['_callee-printsbody'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
result = result[0]
scope = _origScope3;
}
@@ -1799,7 +1771,7 @@ exports[`t-call (template calling with used set body 1`] = `
utils.getScope(scope, 'foo').foo = 'ok';
scope[utils.zero] = c__0;
}
- this.subTemplates['_callee-uses-foo'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
scope = _origScope3;
}
return vn1;
@@ -1949,7 +1921,7 @@ exports[`t-esc t-esc inside t-call, with t-set outside 1`] = `
let c2 = new utils.VDomArray();
c2.push({text: \`Hi\`});
scope.v = c2
- this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__5__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__5__'}));
return vn1;
}"
`;
@@ -2018,7 +1990,7 @@ exports[`t-esc t-esc=0 is escaped 1`] = `
c4.push({text: \`escaped\`});
scope[utils.zero] = c__0;
}
- this.subTemplates['test'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__5__'}));
+ this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__5__'}));
scope = _origScope3;
}
return vn1;
@@ -2814,7 +2786,7 @@ exports[`t-on t-on with t-call 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1};
let vn1 = h('div', p1, c1);
- this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
return vn1;
}"
`;
@@ -2828,7 +2800,7 @@ exports[`t-on t-on, with arguments and t-call 1`] = `
let h = this.h;
let c1 = [], p1 = {key:1};
let vn1 = h('div', p1, c1);
- this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
+ this.constructor.subTemplates['1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
return vn1;
}"
`;
diff --git a/tests/qweb/qweb.test.ts b/tests/qweb/qweb.test.ts
index 4036633a..c8919e29 100644
--- a/tests/qweb/qweb.test.ts
+++ b/tests/qweb/qweb.test.ts
@@ -747,7 +747,7 @@ describe("t-call (template calling", () => {
qweb.addTemplate("caller", '
');
const expected = "ok
";
expect(renderToString(qweb, "caller")).toBe(expected);
- expect(qweb.subTemplates["_basic-callee"].toString()).toMatchSnapshot();
+ expect(qweb.subTemplates["_basic-callee"]).toBeTruthy();
});
test("basic caller, no parent node", () => {
@@ -755,7 +755,7 @@ describe("t-call (template calling", () => {
qweb.addTemplate("caller", '');
const expected = "ok
";
expect(renderToString(qweb, "caller")).toBe(expected);
- expect(qweb.subTemplates["_basic-callee"].toString()).toMatchSnapshot();
+ expect(qweb.subTemplates["_basic-callee"]).toBeTruthy();
});
test("t-call with t-if", () => {
@@ -763,7 +763,7 @@ describe("t-call (template calling", () => {
qweb.addTemplate("caller", '
');
const expected = "ok
";
expect(renderToString(qweb, "caller", { flag: true })).toBe(expected);
- expect(qweb.subTemplates["sub"].toString()).toMatchSnapshot();
+ expect(qweb.subTemplates["sub"]).toBeTruthy();
});
test("t-call not allowed on a non t node", () => {
@@ -898,7 +898,8 @@ describe("t-call (template calling", () => {
`);
const expected = "hey
";
expect(renderToString(qweb, "recursive")).toBe(expected);
- const recursiveFn = Object.values(qweb.subTemplates)[0] as any;
+ const subId = qweb.subTemplates["recursive"];
+ const recursiveFn = QWeb.subTemplates[subId] as any;
expect(recursiveFn.toString()).toMatchSnapshot();
});
@@ -926,7 +927,8 @@ describe("t-call (template calling", () => {
expect(renderToString(qweb, "Parent", { root }, { fiber: { vars: {}, scope: {} } })).toBe(
expected
);
- const recursiveFn = Object.values(qweb.subTemplates)[0] as any;
+ const subId = qweb.subTemplates["nodeTemplate"];
+ const recursiveFn = QWeb.subTemplates[subId] as any;
expect(recursiveFn.toString()).toMatchSnapshot();
});
@@ -953,7 +955,8 @@ describe("t-call (template calling", () => {
const expected =
"";
expect(renderToString(qweb, "Parent", { root }, { fiber: {} })).toBe(expected);
- const recursiveFn = Object.values(qweb.subTemplates)[0] as any;
+ const subId = qweb.subTemplates["nodeTemplate"];
+ const recursiveFn = QWeb.subTemplates[subId] as any;
expect(recursiveFn.toString()).toMatchSnapshot();
});
@@ -985,7 +988,8 @@ describe("t-call (template calling", () => {
const expected =
"";
expect(renderToString(qweb, "Parent", { root })).toBe(expected);
- const recursiveFn = Object.values(qweb.subTemplates)[0] as any;
+ const subId = qweb.subTemplates["nodeTemplate"];
+ const recursiveFn = QWeb.subTemplates[subId] as any;
expect(recursiveFn.toString()).toMatchSnapshot();
});
@@ -1057,6 +1061,17 @@ describe("t-call (template calling", () => {
const context = { list: [{ val: 1 }, { val: 2 }, { val: 3 }] };
expect(trim(renderToString(qweb, "wrapper", context))).toBe(expected);
});
+
+ test("two different QWeb instances, and shared templates", () => {
+ QWeb.registerTemplate("sub", `ok`);
+ QWeb.registerTemplate("main", `
`);
+
+ const qweb1 = new QWeb();
+ const qweb2 = new QWeb();
+
+ expect(renderToString(qweb1, "main")).toBe("ok
");
+ expect(renderToString(qweb2, "main")).toBe("ok
");
+ });
});
describe("foreach", () => {