[IMP] qweb: reintroduce t-tag directive

will not be compatible with t-model directive !
This commit is contained in:
Bruno Boi
2021-11-09 15:16:37 +01:00
committed by Aaron Bohy
parent 7c04cc425e
commit df2d6b6a0e
9 changed files with 289 additions and 34 deletions
+27 -8
View File
@@ -54,6 +54,7 @@ class BlockDescription {
varName: string;
blockName: string;
dynamicTagName: string | null = null;
isRoot: boolean = false;
hasDynamicChildren: boolean = false;
children: BlockDescription[] = [];
@@ -95,6 +96,9 @@ class BlockDescription {
if (hasChildren) {
params += ", [" + this.children.map((c) => c.varName).join(", ") + "]";
}
if (this.dynamicTagName) {
return `toggler(${this.dynamicTagName}, ${this.blockName}(${this.dynamicTagName})(${params}))`;
}
return `${this.blockName}(${params})`;
} else if (this.type === "list") {
return `list(c_block${this.id})`;
@@ -304,7 +308,14 @@ export class QWebCompiler {
this.addLine(``);
for (let block of this.blocks) {
if (block.dom) {
this.addLine(`let ${block.blockName} = createBlock(\`${block.asXmlString()}\`);`);
let xmlString = block.asXmlString();
if (block.dynamicTagName) {
xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`);
xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`);
this.addLine(`let ${block.blockName} = tag => createBlock(\`${xmlString}\`);`);
} else {
this.addLine(`let ${block.blockName} = createBlock(\`${xmlString}\`);`);
}
}
}
}
@@ -514,11 +525,19 @@ export class QWebCompiler {
compileTDomNode(ast: ASTDomNode, ctx: Context) {
let { block, forceNewBlock } = ctx;
const isNewBlock = !block || forceNewBlock;
const isNewBlock = !block || forceNewBlock || ast.dynamicTag !== null;
let codeIdx = this.target.code.length;
if (isNewBlock) {
if (ast.dynamicTag && ctx.block) {
this.insertAnchor(ctx.block!);
}
block = this.createBlock(block, "block", ctx);
this.blocks.push(block);
if (ast.dynamicTag) {
const tagExpr = this.generateId("tag");
this.addLine(`let ${tagExpr} = ${compileExpr(ast.dynamicTag)};`);
block.dynamicTagName = tagExpr;
}
}
// attributes
const attrs: { [key: string]: string } = {};
@@ -989,12 +1008,6 @@ export class QWebCompiler {
propString = propVar;
}
let keyArg = `key + \`${key}\``;
if (ctx.tKeyExpr) {
keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
}
let blockArgs = `${expr}, ${propString}, ${keyArg}, node, ctx`;
// slots
const hasSlot = !!Object.keys(ast.slots).length;
let slotDef: string;
@@ -1034,6 +1047,12 @@ export class QWebCompiler {
// todo: check the forcenewblock condition
this.insertAnchor(block);
}
let keyArg = `key + \`${key}\``;
if (ctx.tKeyExpr) {
keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
}
const blockArgs = `${expr}, ${propString}, ${keyArg}, node, ctx`;
let blockExpr = `component(${blockArgs})`;
if (Object.keys(extraArgs).length) {
this.shouldDefineAssign = true;
+4 -3
View File
@@ -25,9 +25,10 @@
// Misc types, constants and helpers
//------------------------------------------------------------------------------
const RESERVED_WORDS = "true,false,NaN,null,undefined,debugger,console,window,in,instanceof,new,function,return,this,eval,void,Math,RegExp,Array,Object,Date".split(
","
);
const RESERVED_WORDS =
"true,false,NaN,null,undefined,debugger,console,window,in,instanceof,new,function,return,this,eval,void,Math,RegExp,Array,Object,Date".split(
","
);
const WORD_REPLACEMENT: { [key: string]: string } = Object.assign(Object.create(null), {
and: "&&",
+10 -11
View File
@@ -35,6 +35,7 @@ export interface ASTComment {
export interface ASTDomNode {
type: ASTType.DomNode;
tag: string;
dynamicTag: string | null;
attrs: { [key: string]: string };
content: AST[];
ref: string | null;
@@ -289,7 +290,12 @@ const hasBracketsAtTheEnd = /\[[^\[]+\]\s*$/;
function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
const { tagName } = node;
if (tagName === "t") {
let dynamicTag = null;
if (node.hasAttribute("t-tag")) {
dynamicTag = node.getAttribute("t-tag");
node.removeAttribute("t-tag");
}
if (tagName === "t" && !dynamicTag) {
return null;
}
const children: AST[] = [];
@@ -373,6 +379,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
return {
type: ASTType.DomNode,
tag: tagName,
dynamicTag,
attrs,
on,
ref,
@@ -404,13 +411,9 @@ function parseTEscNode(node: Element, ctx: ParsingContext): AST | null {
}
if (ast && ast.type === ASTType.DomNode) {
return {
type: ASTType.DomNode,
tag: ast.tag,
attrs: ast.attrs,
on: ast.on,
...ast,
ref,
content: [tesc],
model: ast.model,
};
}
if (ast && ast.type === ASTType.TComponent) {
@@ -443,13 +446,9 @@ function parseTRawNode(node: Element, ctx: ParsingContext): AST | null {
if (ast && ast.type === ASTType.DomNode) {
tRaw.body = ast.content.length ? ast.content : null;
return {
type: ASTType.DomNode,
tag: ast.tag,
attrs: ast.attrs,
on: ast.on,
...ast,
ref,
content: [tRaw],
model: ast.model,
};
}