[FIX] qweb: evaluate body of t-set immediately

This commit is contained in:
Lucas Perais (lpe)
2019-12-10 16:39:30 +01:00
committed by Géry Debongnie
parent ce9c2f8613
commit 9145799ae9
7 changed files with 453 additions and 171 deletions
+58 -30
View File
@@ -28,17 +28,14 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Compilatio
// the 'zero' magical symbol is where we can find the result of the rendering // the 'zero' magical symbol is where we can find the result of the rendering
// of the body of the t-call. // of the body of the t-call.
ctx.rootContext.shouldDefineUtils = true; ctx.rootContext.shouldDefineUtils = true;
ctx.addLine(`c${ctx.parentNode}.push(...scope[utils.zero]);`); const zeroArgs = ctx.escaping
? `{text: utils.vDomToString(scope[utils.zero])}`
: `...scope[utils.zero]`;
ctx.addLine(`c${ctx.parentNode}.push(${zeroArgs});`);
} }
return; return;
} }
if (value.xml instanceof NodeList && !value.id) {
for (let node of Array.from(value.xml)) {
qweb._compileNode(<ChildNode>node, ctx);
}
return;
}
let exprID: string; let exprID: string;
if (typeof value === "string") { if (typeof value === "string") {
exprID = `_${ctx.generateID()}`; exprID = `_${ctx.generateID()}`;
@@ -47,7 +44,15 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Compilatio
exprID = `scope.${value.id}`; exprID = `scope.${value.id}`;
} }
ctx.addIf(`${exprID} || ${exprID} === 0`); ctx.addIf(`${exprID} || ${exprID} === 0`);
if (ctx.escaping) { if (ctx.escaping) {
let protectID;
if (value.hasBody) {
protectID = ctx.startProtectScope();
ctx.addLine(
`${exprID} = ${exprID} instanceof utils.VDomArray ? utils.vDomToString(${exprID}) : ${exprID};`
);
}
if (ctx.parentTextNode) { if (ctx.parentTextNode) {
ctx.addLine(`vn${ctx.parentTextNode}.text += ${exprID};`); ctx.addLine(`vn${ctx.parentTextNode}.text += ${exprID};`);
} else if (ctx.parentNode) { } else if (ctx.parentNode) {
@@ -61,21 +66,25 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Compilatio
ctx.addLine(`result = vn${nodeID}`); ctx.addLine(`result = vn${nodeID}`);
} }
} }
if (value.hasBody) {
ctx.stopProtectScope(protectID);
}
} else { } else {
ctx.rootContext.shouldDefineUtils = true; ctx.rootContext.shouldDefineUtils = true;
if (value.hasBody) {
ctx.addLine(
`const vnodeArray = ${exprID} instanceof utils.VDomArray ? ${exprID} : utils.htmlToVDOM(${exprID});`
);
ctx.addLine(`c${ctx.parentNode}.push(...vnodeArray);`);
} else {
ctx.addLine(`c${ctx.parentNode}.push(...utils.htmlToVDOM(${exprID}));`); ctx.addLine(`c${ctx.parentNode}.push(...utils.htmlToVDOM(${exprID}));`);
} }
}
if (node.childNodes.length) { if (node.childNodes.length) {
ctx.addElse(); ctx.addElse();
qweb._compileChildren(node, ctx); qweb._compileChildren(node, ctx);
} }
if (value.xml instanceof NodeList && value.id) {
ctx.addElse();
for (let node of Array.from(value.xml)) {
qweb._compileNode(<ChildNode>node, ctx);
}
}
ctx.closeIf(); ctx.closeIf();
} }
@@ -106,25 +115,46 @@ QWeb.addDirective({
name: "set", name: "set",
extraNames: ["value"], extraNames: ["value"],
priority: 60, priority: 60,
atNodeEncounter({ node, ctx }): boolean { atNodeEncounter({ node, qweb, ctx }): boolean {
ctx.rootContext.shouldDefineScope = true; ctx.rootContext.shouldDefineScope = true;
const variable = node.getAttribute("t-set")!; const variable = node.getAttribute("t-set")!;
let value = node.getAttribute("t-value")!; let value = node.getAttribute("t-value")!;
ctx.variables[variable] = ctx.variables[variable] || {}; ctx.variables[variable] = ctx.variables[variable] || {};
let qwebvar = ctx.variables[variable]; let qwebvar = ctx.variables[variable];
const hasBody = node.hasChildNodes();
if (value) {
const formattedValue = ctx.formatExpression(value);
if (ctx.variables.hasOwnProperty(variable) && qwebvar.id) {
ctx.addLine(`${qwebvar.expr} = ${formattedValue}`);
} else {
ctx.addLine(`scope.${variable} = ${formattedValue};`);
qwebvar.id = variable; qwebvar.id = variable;
qwebvar.expr = `scope.${variable}`; qwebvar.expr = `scope.${variable}`;
if (value) {
const formattedValue = ctx.formatExpression(value);
ctx.addLine(`${qwebvar.expr} = ${formattedValue};`);
qwebvar.value = formattedValue; qwebvar.value = formattedValue;
} }
} else {
qwebvar.xml = node.childNodes; if (hasBody) {
ctx.rootContext.shouldDefineUtils = true;
if (value) {
ctx.addIf(`!(${qwebvar.expr})`);
}
const tempParentNodeID = ctx.generateID();
const _parentNode = ctx.parentNode;
ctx.parentNode = tempParentNodeID;
ctx.addLine(`const c${tempParentNodeID} = new utils.VDomArray();`);
const nodeCopy = node.cloneNode(true) as Element;
for (let attr of ["t-set", "t-value", "t-if", "t-else", "t-elif"]) {
nodeCopy.removeAttribute(attr);
}
qweb._compileNode(nodeCopy, ctx);
ctx.addLine(`${qwebvar.expr} = c${tempParentNodeID}`);
qwebvar.value = `c${tempParentNodeID}`;
qwebvar.hasBody = true;
ctx.parentNode = _parentNode;
if (value) {
ctx.closeIf();
}
} }
return true; return true;
} }
@@ -205,12 +235,12 @@ QWeb.addDirective({
// Step 3: compile t-call body if necessary // Step 3: compile t-call body if necessary
// ------------------------------------------------ // ------------------------------------------------
let hasBody = node.hasChildNodes(); let hasBody = node.hasChildNodes();
let protectID;
if (hasBody) { if (hasBody) {
// we add a sub scope to protect the ambient scope // we add a sub scope to protect the ambient scope
ctx.addLine(`{`); ctx.addLine(`{`);
ctx.indent(); ctx.indent();
ctx.addLine(`let origScope = scope;`); protectID = ctx.startProtectScope();
ctx.addLine(`scope = Object.assign(Object.create(context), scope);`);
const nodeCopy = node.cloneNode(true) as Element; const nodeCopy = node.cloneNode(true) as Element;
nodeCopy.removeAttribute("t-call"); nodeCopy.removeAttribute("t-call");
const parentNode = ctx.parentNode; const parentNode = ctx.parentNode;
@@ -229,7 +259,7 @@ QWeb.addDirective({
// Step 4: add the appropriate function call to current component // Step 4: add the appropriate function call to current component
// ------------------------------------------------ // ------------------------------------------------
const callingScope = hasBody ? 'scope' : 'Object.assign(Object.create(context), scope)'; const callingScope = hasBody ? "scope" : "Object.assign(Object.create(context), scope)";
if (ctx.parentNode) { if (ctx.parentNode) {
ctx.addLine( ctx.addLine(
`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, Object.assign({}, extra, {parentNode: c${ctx.parentNode}}));` `this.subTemplates['${subTemplate}'].call(this, ${callingScope}, Object.assign({}, extra, {parentNode: c${ctx.parentNode}}));`
@@ -247,7 +277,7 @@ QWeb.addDirective({
// Step 5: restore previous scope // Step 5: restore previous scope
// ------------------------------------------------ // ------------------------------------------------
if (hasBody) { if (hasBody) {
ctx.addLine(`scope = origScope;`); ctx.stopProtectScope(protectID);
ctx.dedent(); ctx.dedent();
ctx.addLine(`}`); ctx.addLine(`}`);
} }
@@ -279,9 +309,7 @@ QWeb.addDirective({
ctx.addLine(`_${valuesID} = Object.values(_${arrayID});`); ctx.addLine(`_${valuesID} = Object.values(_${arrayID});`);
ctx.closeIf(); ctx.closeIf();
ctx.addLine(`var _length${keysID} = _${keysID}.length;`); ctx.addLine(`var _length${keysID} = _${keysID}.length;`);
let varsID = ctx.generateID(); let varsID = ctx.startProtectScope();
ctx.addLine(`let _scope${varsID} = scope;`);
ctx.addLine(`scope = Object.assign(Object.create(context), _scope${varsID});`);
const loopVar = `i${ctx.loopNumber}`; const loopVar = `i${ctx.loopNumber}`;
ctx.addLine(`for (let ${loopVar} = 0; ${loopVar} < _length${keysID}; ${loopVar}++) {`); ctx.addLine(`for (let ${loopVar} = 0; ${loopVar} < _length${keysID}; ${loopVar}++) {`);
ctx.indent(); ctx.indent();
@@ -307,7 +335,7 @@ QWeb.addDirective({
qweb._compileNode(nodeCopy, ctx); qweb._compileNode(nodeCopy, ctx);
ctx.dedent(); ctx.dedent();
ctx.addLine("}"); ctx.addLine("}");
ctx.addLine(`scope = _scope${varsID};`); ctx.stopProtectScope(varsID);
return true; return true;
} }
}); });
+10
View File
@@ -174,4 +174,14 @@ export class CompilationContext {
let r = s.replace(/\{\{.*?\}\}/g, s => "${" + this.formatExpression(s.slice(2, -2)) + "}"); let r = s.replace(/\{\{.*?\}\}/g, s => "${" + this.formatExpression(s.slice(2, -2)) + "}");
return "`" + r + "`"; return "`" + r + "`";
} }
startProtectScope(): number {
const protectID = this.generateID();
this.rootContext.shouldDefineScope = true;
this.addLine(`const _origScope${protectID} = scope;`);
this.addLine(`scope = Object.assign(Object.create(context), scope);`);
return protectID;
}
stopProtectScope(protectID: number) {
this.addLine(`scope = _origScope${protectID};`);
}
} }
+1
View File
@@ -42,6 +42,7 @@ export interface QWebVar {
id: string; // foo id: string; // foo
expr: string; // scope.foo (local variables => only foo) expr: string; // scope.foo (local variables => only foo)
value?: string; // 1 + 3 value?: string; // 1 + 3
hasBody?: boolean;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
+16 -2
View File
@@ -87,7 +87,7 @@ interface Utils {
} }
const UTILS: Utils = { const UTILS: Utils = {
zero: Symbol('zero'), zero: Symbol("zero"),
toObj(expr) { toObj(expr) {
if (typeof expr === "string") { if (typeof expr === "string") {
expr = expr.trim(); expr = expr.trim();
@@ -106,6 +106,20 @@ const UTILS: Utils = {
shallowEqual, shallowEqual,
addNameSpace(vnode) { addNameSpace(vnode) {
addNS(vnode.data, vnode.children, vnode.sel); addNS(vnode.data, vnode.children, vnode.sel);
},
VDomArray: class VDomArray extends Array {},
vDomToString: function(vdom: VNode[]): string {
return vdom
.map(vnode => {
if (vnode.sel) {
const node = document.createElement(vnode.sel);
const result = patch(node, vnode);
return (<HTMLElement>result.elm).outerHTML;
} else {
return vnode.text;
}
})
.join();
} }
}; };
@@ -383,7 +397,7 @@ export class QWeb extends EventBus {
let code = ctx.generateCode(); let code = ctx.generateCode();
const templateName = ctx.templateName.replace(/`/g, "'").slice(0, 200); const templateName = ctx.templateName.replace(/`/g, "'").slice(0, 200);
code.unshift(` // Template name: "${templateName}"`) code.unshift(` // Template name: "${templateName}"`);
let template; let template;
try { try {
@@ -19,8 +19,8 @@ exports[`basic widget properties reconciliation alg works for t-foreach in t-for
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.section_first = i1 === 0 scope.section_first = i1 === 0
scope.section_last = i1 === _length3 - 1 scope.section_last = i1 === _length3 - 1
@@ -35,8 +35,8 @@ exports[`basic widget properties reconciliation alg works for t-foreach in t-for
_8 = Object.values(_6); _8 = Object.values(_6);
} }
var _length7 = _7.length; var _length7 = _7.length;
let _scope9 = scope; const _origScope9 = scope;
scope = Object.assign(Object.create(context), _scope9); scope = Object.assign(Object.create(context), scope);
for (let i2 = 0; i2 < _length7; i2++) { for (let i2 = 0; i2 < _length7; i2++) {
scope.blip_first = i2 === 0 scope.blip_first = i2 === 0
scope.blip_last = i2 === _length7 - 1 scope.blip_last = i2 === _length7 - 1
@@ -68,9 +68,9 @@ exports[`basic widget properties reconciliation alg works for t-foreach in t-for
} }
w10.__owl__.parentLastFiberId = extra.fiber.id; w10.__owl__.parentLastFiberId = extra.fiber.id;
} }
scope = _scope9; scope = _origScope9;
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -318,8 +318,8 @@ exports[`composition sub components with some state rendered in a loop 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.number_first = i1 === 0 scope.number_first = i1 === 0
scope.number_last = i1 === _length3 - 1 scope.number_last = i1 === _length3 - 1
@@ -352,7 +352,7 @@ exports[`composition sub components with some state rendered in a loop 1`] = `
} }
w7.__owl__.parentLastFiberId = extra.fiber.id; w7.__owl__.parentLastFiberId = extra.fiber.id;
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -983,8 +983,8 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.item_first = i1 === 0 scope.item_first = i1 === 0
scope.item_last = i1 === _length3 - 1 scope.item_last = i1 === _length3 - 1
@@ -1018,7 +1018,7 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument
} }
w7.__owl__.parentLastFiberId = extra.fiber.id; w7.__owl__.parentLastFiberId = extra.fiber.id;
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -1120,8 +1120,8 @@ exports[`t-model directive in a t-foreach 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.thing_first = i1 === 0 scope.thing_first = i1 === 0
scope.thing_last = i1 === _length3 - 1 scope.thing_last = i1 === _length3 - 1
@@ -1139,7 +1139,7 @@ exports[`t-model directive in a t-foreach 1`] = `
extra.handlers[k9] = extra.handlers[k9] || ((ev) => {expr8.f = ev.target.checked}); extra.handlers[k9] = extra.handlers[k9] || ((ev) => {expr8.f = ev.target.checked});
p8.on['input'] = extra.handlers[k9]; p8.on['input'] = extra.handlers[k9];
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -1518,8 +1518,8 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = `
_5 = Object.values(_3); _5 = Object.values(_3);
} }
var _length4 = _4.length; var _length4 = _4.length;
let _scope6 = scope; const _origScope6 = scope;
scope = Object.assign(Object.create(context), _scope6); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length4; i1++) { for (let i1 = 0; i1 < _length4; i1++) {
scope.user_first = i1 === 0 scope.user_first = i1 === 0
scope.user_last = i1 === _length4 - 1 scope.user_last = i1 === _length4 - 1
@@ -1556,7 +1556,7 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = `
} }
w9.__owl__.parentLastFiberId = extra.fiber.id; w9.__owl__.parentLastFiberId = extra.fiber.id;
} }
scope = _scope6; scope = _origScope6;
return vn1; return vn1;
}" }"
`; `;
@@ -1615,8 +1615,8 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = `
_5 = Object.values(_3); _5 = Object.values(_3);
} }
var _length4 = _4.length; var _length4 = _4.length;
let _scope6 = scope; const _origScope6 = scope;
scope = Object.assign(Object.create(context), _scope6); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length4; i1++) { for (let i1 = 0; i1 < _length4; i1++) {
scope.user_first = i1 === 0 scope.user_first = i1 === 0
scope.user_last = i1 === _length4 - 1 scope.user_last = i1 === _length4 - 1
@@ -1654,7 +1654,7 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = `
} }
w9.__owl__.parentLastFiberId = extra.fiber.id; w9.__owl__.parentLastFiberId = extra.fiber.id;
} }
scope = _scope6; scope = _origScope6;
return vn1; return vn1;
}" }"
`; `;
+295 -113
View File
@@ -397,8 +397,8 @@ exports[`foreach does not pollute the rendering context 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.item_first = i1 === 0 scope.item_first = i1 === 0
scope.item_last = i1 === _length3 - 1 scope.item_last = i1 === _length3 - 1
@@ -410,7 +410,7 @@ exports[`foreach does not pollute the rendering context 1`] = `
c1.push({text: _6}); c1.push({text: _6});
} }
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -431,8 +431,8 @@ exports[`foreach iterate on items (on a element node) 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.item_first = i1 === 0 scope.item_first = i1 === 0
scope.item_last = i1 === _length3 - 1 scope.item_last = i1 === _length3 - 1
@@ -448,7 +448,7 @@ exports[`foreach iterate on items (on a element node) 1`] = `
c7.push({text: _8}); c7.push({text: _8});
} }
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -469,8 +469,8 @@ exports[`foreach iterate on items 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.item_first = i1 === 0 scope.item_first = i1 === 0
scope.item_last = i1 === _length3 - 1 scope.item_last = i1 === _length3 - 1
@@ -494,7 +494,7 @@ exports[`foreach iterate on items 1`] = `
} }
c1.push({text: \`] \`}); c1.push({text: \`] \`});
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -515,8 +515,8 @@ exports[`foreach iterate, dict param 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.item_first = i1 === 0 scope.item_first = i1 === 0
scope.item_last = i1 === _length3 - 1 scope.item_last = i1 === _length3 - 1
@@ -540,7 +540,7 @@ exports[`foreach iterate, dict param 1`] = `
} }
c1.push({text: \`] \`}); c1.push({text: \`] \`});
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -561,8 +561,8 @@ exports[`foreach iterate, position 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.elem_first = i1 === 0 scope.elem_first = i1 === 0
scope.elem_last = i1 === _length3 - 1 scope.elem_last = i1 === _length3 - 1
@@ -583,7 +583,7 @@ exports[`foreach iterate, position 1`] = `
} }
c1.push({text: \`) \`}); c1.push({text: \`) \`});
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -604,8 +604,8 @@ exports[`foreach t-foreach in t-forach 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.number_first = i1 === 0 scope.number_first = i1 === 0
scope.number_last = i1 === _length3 - 1 scope.number_last = i1 === _length3 - 1
@@ -620,8 +620,8 @@ exports[`foreach t-foreach in t-forach 1`] = `
_8 = Object.values(_6); _8 = Object.values(_6);
} }
var _length7 = _7.length; var _length7 = _7.length;
let _scope9 = scope; const _origScope9 = scope;
scope = Object.assign(Object.create(context), _scope9); scope = Object.assign(Object.create(context), scope);
for (let i2 = 0; i2 < _length7; i2++) { for (let i2 = 0; i2 < _length7; i2++) {
scope.letter_first = i2 === 0 scope.letter_first = i2 === 0
scope.letter_last = i2 === _length7 - 1 scope.letter_last = i2 === _length7 - 1
@@ -639,9 +639,9 @@ exports[`foreach t-foreach in t-forach 1`] = `
} }
c1.push({text: \`] \`}); c1.push({text: \`] \`});
} }
scope = _scope9; scope = _origScope9;
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -662,8 +662,8 @@ exports[`foreach warn if no key in some case 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.item_first = i1 === 0 scope.item_first = i1 === 0
scope.item_last = i1 === _length3 - 1 scope.item_last = i1 === _length3 - 1
@@ -678,7 +678,7 @@ exports[`foreach warn if no key in some case 1`] = `
c6.push({text: _7}); c6.push({text: _7});
} }
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -725,8 +725,8 @@ exports[`misc global 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.value_first = i1 === 0 scope.value_first = i1 === 0
scope.value_last = i1 === _length3 - 1 scope.value_last = i1 === _length3 - 1
@@ -741,12 +741,12 @@ exports[`misc global 1`] = `
c6.push({text: _7}); c6.push({text: _7});
} }
{ {
let origScope = scope; const _origScope10 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
{ {
let origScope = scope; const _origScope13 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -754,18 +754,18 @@ exports[`misc global 1`] = `
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['_callee-uses-foo'].call(this, scope, Object.assign({}, extra, {parentNode: c__0})); this.subTemplates['_callee-uses-foo'].call(this, scope, Object.assign({}, extra, {parentNode: c__0}));
scope = origScope; scope = _origScope13;
} }
this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0})); this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0}));
scope.foo = 'bbb' scope.foo = 'bbb';
this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0})); this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0}));
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['_callee-asc'].call(this, scope, Object.assign({}, extra, {parentNode: c1})); this.subTemplates['_callee-asc'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = origScope; scope = _origScope10;
} }
} }
scope = _scope5; scope = _origScope5;
this.subTemplates['_callee-asc-toto'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1})); this.subTemplates['_callee-asc-toto'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1}));
return vn1; return vn1;
}" }"
@@ -1059,23 +1059,23 @@ exports[`t-call (template calling call with several sub nodes on same line 1`] =
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
{ {
let origScope = scope; const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
let c3 = [], p3 = {key:3};
var vn3 = h('span', p3, c3);
c__0.push(vn3);
c3.push({text: \`hey\`});
c__0.push({text: \` \`});
let c4 = [], p4 = {key:4}; let c4 = [], p4 = {key:4};
var vn4 = h('span', p4, c4); var vn4 = h('span', p4, c4);
c__0.push(vn4); c__0.push(vn4);
c4.push({text: \`yay\`}); c4.push({text: \`hey\`});
c__0.push({text: \` \`});
let c5 = [], p5 = {key:5};
var vn5 = h('span', p5, c5);
c__0.push(vn5);
c5.push({text: \`yay\`});
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1})); this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = origScope; scope = _origScope3;
} }
return vn1; return vn1;
}" }"
@@ -1106,23 +1106,23 @@ exports[`t-call (template calling cascading t-call t-raw='0' 1`] = `
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
{ {
let origScope = scope; const _origScope10 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
let c8 = [], p8 = {key:8}; let c11 = [], p11 = {key:11};
var vn8 = h('span', p8, c8); var vn11 = h('span', p11, c11);
c__0.push(vn8); c__0.push(vn11);
c8.push({text: \`hey\`}); c11.push({text: \`hey\`});
c__0.push({text: \` \`}); c__0.push({text: \` \`});
let c9 = [], p9 = {key:9}; let c12 = [], p12 = {key:12};
var vn9 = h('span', p9, c9); var vn12 = h('span', p12, c12);
c__0.push(vn9); c__0.push(vn12);
c9.push({text: \`yay\`}); c12.push({text: \`yay\`});
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1})); this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = origScope; scope = _origScope10;
} }
return vn1; return vn1;
}" }"
@@ -1191,7 +1191,7 @@ exports[`t-call (template calling recursive template, part 2 1`] = `
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
{ {
let origScope = scope; const _origScope10 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1199,7 +1199,7 @@ exports[`t-call (template calling recursive template, part 2 1`] = `
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1})); this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = origScope; scope = _origScope10;
} }
return vn1; return vn1;
}" }"
@@ -1231,8 +1231,8 @@ exports[`t-call (template calling recursive template, part 2 2`] = `
_7 = Object.values(_5); _7 = Object.values(_5);
} }
var _length6 = _6.length; var _length6 = _6.length;
let _scope8 = scope; const _origScope8 = scope;
scope = Object.assign(Object.create(context), _scope8); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length6; i1++) { for (let i1 = 0; i1 < _length6; i1++) {
scope.subtree_first = i1 === 0 scope.subtree_first = i1 === 0
scope.subtree_last = i1 === _length6 - 1 scope.subtree_last = i1 === _length6 - 1
@@ -1240,7 +1240,7 @@ exports[`t-call (template calling recursive template, part 2 2`] = `
scope.subtree = _6[i1] scope.subtree = _6[i1]
scope.subtree_value = _7[i1] scope.subtree_value = _7[i1]
{ {
let origScope = scope; const _origScope9 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1248,10 +1248,10 @@ exports[`t-call (template calling recursive template, part 2 2`] = `
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c2})); this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c2}));
scope = origScope; scope = _origScope9;
} }
} }
scope = _scope8; scope = _origScope8;
}" }"
`; `;
@@ -1265,7 +1265,7 @@ exports[`t-call (template calling recursive template, part 3 1`] = `
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
{ {
let origScope = scope; const _origScope10 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1273,7 +1273,7 @@ exports[`t-call (template calling recursive template, part 3 1`] = `
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1})); this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = origScope; scope = _origScope10;
} }
return vn1; return vn1;
}" }"
@@ -1305,8 +1305,8 @@ exports[`t-call (template calling recursive template, part 3 2`] = `
_7 = Object.values(_5); _7 = Object.values(_5);
} }
var _length6 = _6.length; var _length6 = _6.length;
let _scope8 = scope; const _origScope8 = scope;
scope = Object.assign(Object.create(context), _scope8); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length6; i1++) { for (let i1 = 0; i1 < _length6; i1++) {
scope.subtree_first = i1 === 0 scope.subtree_first = i1 === 0
scope.subtree_last = i1 === _length6 - 1 scope.subtree_last = i1 === _length6 - 1
@@ -1314,7 +1314,7 @@ exports[`t-call (template calling recursive template, part 3 2`] = `
scope.subtree = _6[i1] scope.subtree = _6[i1]
scope.subtree_value = _7[i1] scope.subtree_value = _7[i1]
{ {
let origScope = scope; const _origScope9 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1322,10 +1322,10 @@ exports[`t-call (template calling recursive template, part 3 2`] = `
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c2})); this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c2}));
scope = origScope; scope = _origScope9;
} }
} }
scope = _scope8; scope = _origScope8;
}" }"
`; `;
@@ -1339,7 +1339,7 @@ exports[`t-call (template calling scoped parameters 1`] = `
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
{ {
let origScope = scope; const _origScope2 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1347,7 +1347,7 @@ exports[`t-call (template calling scoped parameters 1`] = `
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: c1})); this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = origScope; scope = _origScope2;
} }
if (scope.foo || scope.foo === 0) { if (scope.foo || scope.foo === 0) {
c1.push({text: scope.foo}); c1.push({text: scope.foo});
@@ -1401,8 +1401,8 @@ exports[`t-call (template calling t-call with t-set inside and outside 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.v_first = i1 === 0 scope.v_first = i1 === 0
scope.v_last = i1 === _length3 - 1 scope.v_last = i1 === _length3 - 1
@@ -1411,7 +1411,7 @@ exports[`t-call (template calling t-call with t-set inside and outside 1`] = `
scope.v_value = _4[i1] scope.v_value = _4[i1]
scope.val = scope['v'].val; scope.val = scope['v'].val;
{ {
let origScope = scope; const _origScope8 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1419,10 +1419,10 @@ exports[`t-call (template calling t-call with t-set inside and outside 1`] = `
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['sub'].call(this, scope, Object.assign({}, extra, {parentNode: c1})); this.subTemplates['sub'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = origScope; scope = _origScope8;
} }
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -1463,7 +1463,7 @@ exports[`t-call (template calling with unused body 1`] = `
let result; let result;
var h = this.h; var h = this.h;
{ {
let origScope = scope; const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1473,7 +1473,7 @@ exports[`t-call (template calling with unused body 1`] = `
result = [] result = []
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result})); this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result}));
result = result[0] result = result[0]
scope = origScope; scope = _origScope3;
} }
return result; return result;
}" }"
@@ -1488,7 +1488,7 @@ exports[`t-call (template calling with unused setbody 1`] = `
let result; let result;
var h = this.h; var h = this.h;
{ {
let origScope = scope; const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1498,7 +1498,7 @@ exports[`t-call (template calling with unused setbody 1`] = `
result = [] result = []
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result})); this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result}));
result = result[0] result = result[0]
scope = origScope; scope = _origScope3;
} }
return result; return result;
}" }"
@@ -1513,7 +1513,7 @@ exports[`t-call (template calling with used body 1`] = `
let result; let result;
var h = this.h; var h = this.h;
{ {
let origScope = scope; const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1523,7 +1523,7 @@ exports[`t-call (template calling with used body 1`] = `
result = [] result = []
this.subTemplates['_callee-printsbody'].call(this, scope, Object.assign({}, extra, {parentNode: result})); this.subTemplates['_callee-printsbody'].call(this, scope, Object.assign({}, extra, {parentNode: result}));
result = result[0] result = result[0]
scope = origScope; scope = _origScope3;
} }
return result; return result;
}" }"
@@ -1539,7 +1539,7 @@ exports[`t-call (template calling with used set body 1`] = `
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('span', p1, c1); var vn1 = h('span', p1, c1);
{ {
let origScope = scope; const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope); scope = Object.assign(Object.create(context), scope);
{ {
let c__0 = []; let c__0 = [];
@@ -1547,7 +1547,7 @@ exports[`t-call (template calling with used set body 1`] = `
scope[utils.zero] = c__0; scope[utils.zero] = c__0;
} }
this.subTemplates['_callee-uses-foo'].call(this, scope, Object.assign({}, extra, {parentNode: c1})); this.subTemplates['_callee-uses-foo'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = origScope; scope = _origScope3;
} }
return vn1; return vn1;
}" }"
@@ -1621,6 +1621,59 @@ exports[`t-esc literal 1`] = `
}" }"
`; `;
exports[`t-esc t-esc is escaped 1`] = `
"function anonymous(context, extra
) {
// Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context);
var h = this.h;
let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1);
const c2 = new utils.VDomArray();
let c3 = [], p3 = {key:3};
var vn3 = h('p', p3, c3);
c2.push(vn3);
c3.push({text: \`escaped\`});
scope.var = c2
if (scope.var || scope.var === 0) {
const _origScope4 = scope;
scope = Object.assign(Object.create(context), scope);
scope.var = scope.var instanceof utils.VDomArray ? utils.vDomToString(scope.var) : scope.var;
c1.push({text: scope.var});
scope = _origScope4;
}
return vn1;
}"
`;
exports[`t-esc t-esc=0 is escaped 1`] = `
"function anonymous(context, extra
) {
// Template name: \\"testCaller\\"
let utils = this.constructor.utils;
let scope = Object.create(context);
var h = this.h;
let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1);
{
const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope);
{
let c__0 = [];
let c4 = [], p4 = {key:4};
var vn4 = h('p', p4, c4);
c__0.push(vn4);
c4.push({text: \`escaped\`});
scope[utils.zero] = c__0;
}
this.subTemplates['test'].call(this, scope, Object.assign({}, extra, {parentNode: c1}));
scope = _origScope3;
}
return vn1;
}"
`;
exports[`t-esc variable 1`] = ` exports[`t-esc variable 1`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
@@ -1930,8 +1983,8 @@ exports[`t-key t-key directive in a list 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.beer_first = i1 === 0 scope.beer_first = i1 === 0
scope.beer_last = i1 === _length3 - 1 scope.beer_last = i1 === _length3 - 1
@@ -1947,7 +2000,7 @@ exports[`t-key t-key directive in a list 1`] = `
c7.push({text: _8}); c7.push({text: _8});
} }
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -2029,8 +2082,8 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.action_first = i1 === 0 scope.action_first = i1 === 0
scope.action_last = i1 === _length3 - 1 scope.action_last = i1 === _length3 - 1
@@ -2048,7 +2101,7 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
p8.on['click'] = function (e) {if (!context.__owl__.isMounted){return}if (handler9) { handler9(e); } else { context.activate(action); }}; p8.on['click'] = function (e) {if (!context.__owl__.isMounted){return}if (handler9) { handler9(e); } else { context.activate(action); }};
c8.push({text: \`link\`}); c8.push({text: \`link\`});
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -2251,8 +2304,8 @@ exports[`t-on t-on with prevent modifier in t-foreach 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.project_first = i1 === 0 scope.project_first = i1 === 0
scope.project_last = i1 === _length3 - 1 scope.project_last = i1 === _length3 - 1
@@ -2272,7 +2325,7 @@ exports[`t-on t-on with prevent modifier in t-foreach 1`] = `
c8.push({text: _10}); c8.push({text: _10});
} }
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -2464,8 +2517,8 @@ exports[`t-ref refs in a loop 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.item_first = i1 === 0 scope.item_first = i1 === 0
scope.item_last = i1 === _length3 - 1 scope.item_last = i1 === _length3 - 1
@@ -2490,7 +2543,7 @@ exports[`t-ref refs in a loop 1`] = `
c7.push({text: _9}); c7.push({text: _9});
} }
} }
scope = _scope5; scope = _origScope5;
return vn1; return vn1;
}" }"
`; `;
@@ -2563,11 +2616,21 @@ exports[`t-set set from body literal 1`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
// Template name: \\"test\\" // Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context); let scope = Object.create(context);
let result; let result;
var h = this.h; var h = this.h;
var vn1 = {text: \`ok\`}; const c1 = new utils.VDomArray();
result = vn1; c1.push({text: \`ok\`});
scope.value = c1
if (scope.value || scope.value === 0) {
const _origScope2 = scope;
scope = Object.assign(Object.create(context), scope);
scope.value = scope.value instanceof utils.VDomArray ? utils.vDomToString(scope.value) : scope.value;
var vn3 = {text: scope.value};
result = vn3
scope = _origScope2;
}
return result; return result;
}" }"
`; `;
@@ -2576,13 +2639,23 @@ exports[`t-set set from body lookup 1`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
// Template name: \\"test\\" // Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context); let scope = Object.create(context);
var h = this.h; var h = this.h;
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
var _2 = scope['value']; const c2 = new utils.VDomArray();
if (_2 || _2 === 0) { var _3 = scope['value'];
c1.push({text: _2}); if (_3 || _3 === 0) {
c2.push({text: _3});
}
scope.stuff = c2
if (scope.stuff || scope.stuff === 0) {
const _origScope4 = scope;
scope = Object.assign(Object.create(context), scope);
scope.stuff = scope.stuff instanceof utils.VDomArray ? utils.vDomToString(scope.stuff) : scope.stuff;
c1.push({text: scope.stuff});
scope = _origScope4;
} }
return vn1; return vn1;
}" }"
@@ -2596,6 +2669,9 @@ exports[`t-set set from empty body 1`] = `
var h = this.h; var h = this.h;
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
if (scope.stuff || scope.stuff === 0) {
c1.push({text: scope.stuff});
}
return vn1; return vn1;
}" }"
`; `;
@@ -2619,17 +2695,25 @@ exports[`t-set t-set and t-if 1`] = `
exports[`t-set t-set body is evaluated immediately 1`] = ` exports[`t-set t-set body is evaluated immediately 1`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
// Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context); let scope = Object.create(context);
var h = this.h; var h = this.h;
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
scope.v1 = 'before'; scope.v1 = 'before';
scope.v1 = 'after' const c2 = new utils.VDomArray();
let c2 = [], p2 = {key:2}; let c3 = [], p3 = {key:3};
var vn2 = h('span', p2, c2); var vn3 = h('span', p3, c3);
c1.push(vn2); c2.push(vn3);
if (scope.v1 || scope.v1 === 0) { if (scope.v1 || scope.v1 === 0) {
c2.push({text: scope.v1}); c3.push({text: scope.v1});
}
scope.v2 = c2
scope.v1 = 'after';
if (scope.v2 || scope.v2 === 0) {
const vnodeArray = scope.v2 instanceof utils.VDomArray ? scope.v2 : utils.htmlToVDOM(scope.v2);
c1.push(...vnodeArray);
} }
return vn1; return vn1;
}" }"
@@ -2671,8 +2755,8 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
_4 = Object.values(_2); _4 = Object.values(_2);
} }
var _length3 = _3.length; var _length3 = _3.length;
let _scope5 = scope; const _origScope5 = scope;
scope = Object.assign(Object.create(context), _scope5); scope = Object.assign(Object.create(context), scope);
for (let i1 = 0; i1 < _length3; i1++) { for (let i1 = 0; i1 < _length3; i1++) {
scope.elem_first = i1 === 0 scope.elem_first = i1 === 0
scope.elem_last = i1 === _length3 - 1 scope.elem_last = i1 === _length3 - 1
@@ -2690,9 +2774,73 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
if (scope.v || scope.v === 0) { if (scope.v || scope.v === 0) {
c8.push({text: scope.v}); c8.push({text: scope.v});
} }
scope.v = scope['elem'] scope.v = scope['elem'];
}
scope = _origScope5;
return vn1;
}"
`;
exports[`t-set t-set with t-value (falsy) and body 1`] = `
"function anonymous(context, extra
) {
// Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context);
var h = this.h;
let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1);
scope.v3 = false;
scope.v1 = 'before';
scope.v2 = scope.v3;
if (!(scope.v2)) {
const c2 = new utils.VDomArray();
let c3 = [], p3 = {key:3};
var vn3 = h('span', p3, c3);
c2.push(vn3);
if (scope.v1 || scope.v1 === 0) {
c3.push({text: scope.v1});
}
scope.v2 = c2
}
scope.v1 = 'after';
scope.v3 = true;
if (scope.v2 || scope.v2 === 0) {
const vnodeArray = scope.v2 instanceof utils.VDomArray ? scope.v2 : utils.htmlToVDOM(scope.v2);
c1.push(...vnodeArray);
}
return vn1;
}"
`;
exports[`t-set t-set with t-value (truthy) and body 1`] = `
"function anonymous(context, extra
) {
// Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context);
var h = this.h;
let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1);
scope.v3 = 'Truthy';
scope.v1 = 'before';
scope.v2 = scope.v3;
if (!(scope.v2)) {
const c2 = new utils.VDomArray();
let c3 = [], p3 = {key:3};
var vn3 = h('span', p3, c3);
c2.push(vn3);
if (scope.v1 || scope.v1 === 0) {
c3.push({text: scope.v1});
}
scope.v2 = c2
}
scope.v1 = 'after';
scope.v3 = false;
if (scope.v2 || scope.v2 === 0) {
const vnodeArray = scope.v2 instanceof utils.VDomArray ? scope.v2 : utils.htmlToVDOM(scope.v2);
c1.push(...vnodeArray);
} }
scope = _scope5;
return vn1; return vn1;
}" }"
`; `;
@@ -2701,19 +2849,25 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 1 1`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
// Template name: \\"test\\" // Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context); let scope = Object.create(context);
var h = this.h; var h = this.h;
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
if (scope['flag']) { if (scope['flag']) {
const c2 = new utils.VDomArray();
c2.push({text: \`1\`});
scope.ourvar = c2
} }
else { else {
scope.ourvar = 0; scope.ourvar = 0;
} }
if (scope.ourvar || scope.ourvar === 0) { if (scope.ourvar || scope.ourvar === 0) {
const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope);
scope.ourvar = scope.ourvar instanceof utils.VDomArray ? utils.vDomToString(scope.ourvar) : scope.ourvar;
c1.push({text: scope.ourvar}); c1.push({text: scope.ourvar});
} else { scope = _origScope3;
c1.push({text: \`1\`});
} }
return vn1; return vn1;
}" }"
@@ -2723,19 +2877,25 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 1 2`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
// Template name: \\"test\\" // Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context); let scope = Object.create(context);
var h = this.h; var h = this.h;
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
if (scope['flag']) { if (scope['flag']) {
const c2 = new utils.VDomArray();
c2.push({text: \`1\`});
scope.ourvar = c2
} }
else { else {
scope.ourvar = 0; scope.ourvar = 0;
} }
if (scope.ourvar || scope.ourvar === 0) { if (scope.ourvar || scope.ourvar === 0) {
const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope);
scope.ourvar = scope.ourvar instanceof utils.VDomArray ? utils.vDomToString(scope.ourvar) : scope.ourvar;
c1.push({text: scope.ourvar}); c1.push({text: scope.ourvar});
} else { scope = _origScope3;
c1.push({text: \`1\`});
} }
return vn1; return vn1;
}" }"
@@ -2745,6 +2905,7 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 2 1`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
// Template name: \\"test\\" // Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context); let scope = Object.create(context);
var h = this.h; var h = this.h;
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
@@ -2753,11 +2914,16 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 2 1`] = `
scope.ourvar = 1; scope.ourvar = 1;
} }
else { else {
const c2 = new utils.VDomArray();
c2.push({text: \`0\`});
scope.ourvar = c2
} }
if (scope.ourvar || scope.ourvar === 0) { if (scope.ourvar || scope.ourvar === 0) {
const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope);
scope.ourvar = scope.ourvar instanceof utils.VDomArray ? utils.vDomToString(scope.ourvar) : scope.ourvar;
c1.push({text: scope.ourvar}); c1.push({text: scope.ourvar});
} else { scope = _origScope3;
c1.push({text: \`0\`});
} }
return vn1; return vn1;
}" }"
@@ -2767,6 +2933,7 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 2 2`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
// Template name: \\"test\\" // Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context); let scope = Object.create(context);
var h = this.h; var h = this.h;
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
@@ -2775,11 +2942,16 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 2 2`] = `
scope.ourvar = 1; scope.ourvar = 1;
} }
else { else {
const c2 = new utils.VDomArray();
c2.push({text: \`0\`});
scope.ourvar = c2
} }
if (scope.ourvar || scope.ourvar === 0) { if (scope.ourvar || scope.ourvar === 0) {
const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope);
scope.ourvar = scope.ourvar instanceof utils.VDomArray ? utils.vDomToString(scope.ourvar) : scope.ourvar;
c1.push({text: scope.ourvar}); c1.push({text: scope.ourvar});
} else { scope = _origScope3;
c1.push({text: \`0\`});
} }
return vn1; return vn1;
}" }"
@@ -2789,13 +2961,23 @@ exports[`t-set value priority 1`] = `
"function anonymous(context, extra "function anonymous(context, extra
) { ) {
// Template name: \\"test\\" // Template name: \\"test\\"
let utils = this.constructor.utils;
let scope = Object.create(context); let scope = Object.create(context);
var h = this.h; var h = this.h;
let c1 = [], p1 = {key:1}; let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1); var vn1 = h('div', p1, c1);
scope.value = 1; scope.value = 1;
if (!(scope.value)) {
const c2 = new utils.VDomArray();
c2.push({text: \`2\`});
scope.value = c2
}
if (scope.value || scope.value === 0) { if (scope.value || scope.value === 0) {
const _origScope3 = scope;
scope = Object.assign(Object.create(context), scope);
scope.value = scope.value instanceof utils.VDomArray ? utils.vDomToString(scope.value) : scope.value;
c1.push({text: scope.value}); c1.push({text: scope.value});
scope = _origScope3;
} }
return vn1; return vn1;
}" }"
+49 -2
View File
@@ -139,6 +139,17 @@ describe("t-esc", () => {
qweb.addTemplate("test", `<span t-esc="var">nope</span>`); qweb.addTemplate("test", `<span t-esc="var">nope</span>`);
expect(renderToString(qweb, "test")).toBe("<span>nope</span>"); expect(renderToString(qweb, "test")).toBe("<span>nope</span>");
}); });
test("t-esc is escaped", () => {
qweb.addTemplate("test", `<div><t t-set="var"><p>escaped</p></t><t t-esc="var"/></div>`);
const domRendered = renderToDOM(qweb, "test");
expect(domRendered.textContent).toBe("<p>escaped</p>");
});
test("t-esc=0 is escaped", () => {
qweb.addTemplate("test", `<span><t t-esc="0"/></span>`);
qweb.addTemplate("testCaller", `<div><t t-call="test"><p>escaped</p></t></div>`);
const domRendered = renderToDOM(qweb, "testCaller") as HTMLElement;
expect(domRendered.querySelector("span")!.textContent).toBe("<p>escaped</p>");
});
}); });
describe("t-raw", () => { describe("t-raw", () => {
@@ -289,10 +300,45 @@ describe("t-set", () => {
</t> </t>
<t t-set="v1" t-value="'after'"/> <t t-set="v1" t-value="'after'"/>
<t t-raw="v2"/> <t t-raw="v2"/>
</div>`
);
expect(renderToString(qweb, "test")).toBe("<div><span>before</span></div>");
});
test("t-set with t-value (falsy) and body", () => {
qweb.addTemplate(
"test",
`<div>
<t t-set="v3" t-value="false"/>
<t t-set="v1" t-value="'before'"/>
<t t-set="v2" t-value="v3">
<span><t t-esc="v1"/></span>
</t>
<t t-set="v1" t-value="'after'"/>
<t t-set="v3" t-value="true"/>
<t t-raw="v2"/>
</div>`); </div>`);
expect(renderToString(qweb, "test")).toBe("<div><span>before</span></div>"); expect(renderToString(qweb, "test")).toBe("<div><span>before</span></div>");
}); });
test("t-set with t-value (truthy) and body", () => {
qweb.addTemplate(
"test",
`<div>
<t t-set="v3" t-value="'Truthy'"/>
<t t-set="v1" t-value="'before'"/>
<t t-set="v2" t-value="v3">
<span><t t-esc="v1"/></span>
</t>
<t t-set="v1" t-value="'after'"/>
<t t-set="v3" t-value="false"/>
<t t-raw="v2"/>
</div>`);
expect(renderToString(qweb, "test")).toBe("<div>Truthy</div>");
});
}); });
describe("t-if", () => { describe("t-if", () => {
@@ -1611,11 +1657,12 @@ describe("debugging", () => {
const consoleLog = console.log; const consoleLog = console.log;
console.log = jest.fn(); console.log = jest.fn();
qweb.addTemplates(` qweb.addTemplates(`
<templates>
<p t-name="sub" t-debug="1">coucou</p> <p t-name="sub" t-debug="1">coucou</p>
<div t-name="test"> <div t-name="test">
<t t-call="sub"/> <t t-call="sub"/>
</div>` </div>
); </templates>`);
qweb.render("test"); qweb.render("test");
expect(console.log).toHaveBeenCalledTimes(1); expect(console.log).toHaveBeenCalledTimes(1);