[FIX] qweb: correctly handle top level t-call and body

Whenever a top level t-call was made with some non empty body, Owl
complained that a template should not have more than one root node.

The reason was that the compilation context for the body of the t-call
directive was the same as the root compilation context, and it already
had a parentNode set.

To fix the issue, this commit simply use the subContext method to create
a different compilation context, which actually makes sense, because the
body of a t-call is really a different situation.  Also, as a bonus, it
slightly improves the code for the t-call directive.

closes #760
This commit is contained in:
Géry Debongnie
2020-10-19 20:30:46 +02:00
committed by aab-odoo
parent 3fbc02986c
commit 89eae191b1
3 changed files with 37 additions and 4 deletions
+1 -4
View File
@@ -267,16 +267,13 @@ QWeb.addDirective({
for (let attr of ["t-if", "t-else", "t-elif", "t-call"]) {
nodeCopy.removeAttribute(attr);
}
const parentNode = ctx.parentNode;
ctx.parentNode = "__0";
// this local scope is intended to trap c__0
ctx.addLine(`{`);
ctx.indent();
ctx.addLine("let c__0 = [];");
qweb._compileNode(nodeCopy, ctx);
qweb._compileNode(nodeCopy, ctx.subContext("parentNode", "__0"));
ctx.rootContext.shouldDefineUtils = true;
ctx.addLine("scope[utils.zero] = c__0;");
ctx.parentNode = parentNode;
ctx.dedent();
ctx.addLine(`}`);
}
@@ -1798,6 +1798,35 @@ exports[`t-call (template calling t-call allowed on a non t node 1`] = `
}"
`;
exports[`t-call (template calling t-call with body content as root of a template 1`] = `
"function anonymous(context, extra
) {
// Template name: \\"main\\"
let utils = this.constructor.utils;
let scope = Object.create(context);
let result;
let h = this.h;
let _origScope3 = scope;
scope = Object.create(scope);
scope.__access_mode__ = 'ro';
{
{
let c__0 = [];
let c4 = [], p4 = {key:4};
let vn4 = h('p', p4, c4);
c__0.push(vn4);
c4.push({text: \`antony\`});
scope[utils.zero] = c__0;
}
result = []
this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__5__'}));
result = result[0]
}
scope = _origScope3;
return result;
}"
`;
exports[`t-call (template calling t-call with t-if 1`] = `
"function anonymous(context, extra
) {
+7
View File
@@ -1096,6 +1096,13 @@ describe("t-call (template calling", () => {
expect(renderToString(qweb, "main")).toBe(expected);
});
test("t-call with body content as root of a template", () => {
qweb.addTemplate("antony", `<foo><t t-raw="0"/></foo>`);
qweb.addTemplate("main", `<t><t t-call="antony"><p>antony</p></t></t>`);
const expected = "<foo><p>antony</p></foo>";
expect(renderToString(qweb, "main")).toBe(expected);
});
test("dynamic t-call", () => {
qweb.addTemplate("foo", `<foo><t t-esc="val"/></foo>`);
qweb.addTemplate("bar", `<bar><t t-esc="val"/></bar>`);