Skip to content

Commit 5b2cfaa

Browse files
committed
[IMP] qweb: t-call with params
1 parent fb7d25b commit 5b2cfaa

File tree

5 files changed

+136
-3
lines changed

5 files changed

+136
-3
lines changed

src/compiler/code_generator.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
ASTMulti,
1616
ASTSlot,
1717
ASTTCall,
18+
ASTTCall2,
1819
ASTTCallBlock,
1920
ASTTEsc,
2021
ASTText,
@@ -500,6 +501,8 @@ export class CodeGenerator {
500501
return this.compileMulti(ast, ctx);
501502
case ASTType.TCall:
502503
return this.compileTCall(ast, ctx);
504+
case ASTType.TCall2:
505+
return this.compileTCall2(ast, ctx);
503506
case ASTType.TCallBlock:
504507
return this.compileTCallBlock(ast, ctx);
505508
case ASTType.TSet:
@@ -1092,6 +1095,65 @@ export class CodeGenerator {
10921095
return block.varName;
10931096
}
10941097

1098+
compileTCall2(ast: ASTTCall2, ctx: Context): string {
1099+
let { block, forceNewBlock } = ctx;
1100+
const ctxVar = ctx.ctxVar || "ctx";
1101+
1102+
debugger;
1103+
1104+
const attrs = ast.attrs
1105+
? this.formatPropObject(ast.attrs, ast.attrsTranslationCtx, ctx.translationCtx) // should use ctxVar
1106+
: [];
1107+
let ctxString = `{${attrs.join(",")}}`;
1108+
if (ast.context) {
1109+
const dynCtxVar = generateId("ctx");
1110+
this.addLine(`let ${dynCtxVar} = ${compileExpr(ast.context)};`);
1111+
ctxString = `Object.assign({}, ${dynCtxVar}${attrs.length ? ", " + ctxString : ""})`;
1112+
}
1113+
1114+
const isDynamic = INTERP_REGEXP.test(ast.name);
1115+
const subTemplate = isDynamic ? interpolate(ast.name) : "`" + ast.name + "`";
1116+
if (block && !forceNewBlock) {
1117+
this.insertAnchor(block);
1118+
}
1119+
block = this.createBlock(block, "multi", ctx);
1120+
if (ast.body) {
1121+
this.addLine(`${ctxVar} = Object.create(${ctxVar});`);
1122+
this.addLine(`${ctxVar}[isBoundary] = 1;`);
1123+
this.helpers.add("isBoundary");
1124+
const subCtx = createContext(ctx, { ctxVar });
1125+
const bl = this.compileMulti({ type: ASTType.Multi, content: ast.body }, subCtx);
1126+
if (bl) {
1127+
this.helpers.add("zero");
1128+
this.addLine(`${ctxVar}[zero] = ${bl};`);
1129+
}
1130+
}
1131+
1132+
const key = this.generateComponentKey();
1133+
if (isDynamic) {
1134+
const templateVar = generateId("template");
1135+
if (!this.staticDefs.find((d) => d.id === "call")) {
1136+
this.staticDefs.push({ id: "call", expr: `app.callTemplate.bind(app)` });
1137+
}
1138+
this.define(templateVar, subTemplate);
1139+
this.insertBlock(`call(this, ${templateVar}, ${ctxString}, node, ${key})`, block!, {
1140+
...ctx,
1141+
forceNewBlock: !block,
1142+
});
1143+
} else {
1144+
const id = generateId(`callTemplate_`);
1145+
this.staticDefs.push({ id, expr: `app.getTemplate(${subTemplate})` });
1146+
this.insertBlock(`${id}.call(this, ${ctxString}, node, ${key})`, block!, {
1147+
...ctx,
1148+
forceNewBlock: !block,
1149+
});
1150+
}
1151+
if (ast.body && !ctx.isLast) {
1152+
this.addLine(`${ctxVar} = ${ctxVar}.__proto__;`);
1153+
}
1154+
return block.varName;
1155+
}
1156+
10951157
compileTCallBlock(ast: ASTTCallBlock, ctx: Context): string {
10961158
let { block, forceNewBlock } = ctx;
10971159
if (block) {

src/compiler/parser.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const enum ASTType {
1818
TIf,
1919
TSet,
2020
TCall,
21+
TCall2,
2122
TOut,
2223
TForEach,
2324
TKey,
@@ -130,6 +131,15 @@ export interface ASTTCall extends BaseAST {
130131
context: string | null;
131132
}
132133

134+
export interface ASTTCall2 extends BaseAST {
135+
type: ASTType.TCall2;
136+
name: string;
137+
attrs: Attrs | null;
138+
attrsTranslationCtx: Attrs | null;
139+
body: AST[] | null;
140+
context: string | null;
141+
}
142+
133143
interface SlotDefinition {
134144
content: AST | null;
135145
scope: string | null;
@@ -200,6 +210,7 @@ export type AST =
200210
| ASTTif
201211
| ASTTSet
202212
| ASTTCall
213+
| ASTTCall2
203214
| ASTTOut
204215
| ASTTForEach
205216
| ASTTKey
@@ -664,11 +675,34 @@ function parseTCall(node: Element, ctx: ParsingContext): AST | null {
664675
};
665676
}
666677
}
667-
const body = parseChildren(node, ctx);
668678

679+
const body = parseChildren(node, ctx);
680+
let attrs: Attrs | null = null;
681+
let attrsTranslationCtx: Attrs | null = null;
682+
for (let attributeName of node.getAttributeNames()) {
683+
const value = node.getAttribute(attributeName)!;
684+
if (attributeName.startsWith("t-translation-context-")) {
685+
const attrName = attributeName.slice(22);
686+
attrsTranslationCtx = attrsTranslationCtx || {};
687+
attrsTranslationCtx[attrName] = value;
688+
} else {
689+
attrs = attrs || {};
690+
attrs[attributeName] = value;
691+
}
692+
}
693+
if (!attrs && !attrsTranslationCtx) {
694+
return {
695+
type: ASTType.TCall,
696+
name: subTemplate,
697+
body: body.length ? body : null,
698+
context,
699+
};
700+
}
669701
return {
670-
type: ASTType.TCall,
702+
type: ASTType.TCall2,
671703
name: subTemplate,
704+
attrs,
705+
attrsTranslationCtx,
672706
body: body.length ? body : null,
673707
context,
674708
};

tests/compiler/__snapshots__/t_call.test.ts.snap

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,33 @@ exports[`t-call (template calling) t-call on a div with t-call-context 2`] = `
826826
}"
827827
`;
828828

829+
exports[`t-call (template calling) t-call with attributes 1`] = `
830+
"function anonymous(app, bdom, helpers
831+
) {
832+
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
833+
const callTemplate_1 = app.getTemplate(\`sub\`);
834+
835+
return function template(ctx, node, key = \\"\\") {
836+
return callTemplate_1.call(this, {'v1': ctx['val1'],'v2': ctx['val2']}, node, key + \`__1\`);
837+
}
838+
}"
839+
`;
840+
841+
exports[`t-call (template calling) t-call with attributes 2`] = `
842+
"function anonymous(app, bdom, helpers
843+
) {
844+
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
845+
846+
let block1 = createBlock(\`<span><block-text-0/><block-text-1/></span>\`);
847+
848+
return function template(ctx, node, key = \\"\\") {
849+
let txt1 = ctx['v1'];
850+
let txt2 = ctx['v2'];
851+
return block1([txt1, txt2]);
852+
}
853+
}"
854+
`;
855+
829856
exports[`t-call (template calling) t-call with body content as root of a template 1`] = `
830857
"function anonymous(app, bdom, helpers
831858
) {

tests/compiler/parser.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ describe("qweb parser", () => {
14931493
scope: null,
14941494
},
14951495
},
1496-
type: 11,
1496+
type: ASTType.TComponent,
14971497
});
14981498
});
14991499

tests/compiler/t_call.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,4 +538,14 @@ describe("t-call (template calling)", () => {
538538

539539
expect(context.renderToString("main")).toBe("grandchild<p>Some content...</p>");
540540
});
541+
542+
test("t-call with attributes", () => {
543+
const context = new TestContext();
544+
context.addTemplate("sub", `<span><t t-esc="v1"/><t t-esc="v2"/></span>`);
545+
context.addTemplate("main", `<t t-call="sub" v1="val1" v2="val2"/>`);
546+
547+
expect(context.renderToString("main", { val1: "abc", val2: "def" })).toBe(
548+
"<span>abcdef</span>"
549+
);
550+
});
541551
});

0 commit comments

Comments
 (0)