mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] compiler: handle t-set as functions
This commit is contained in:
committed by
Aaron Bohy
parent
75ad0835e9
commit
5bf47500d5
@@ -101,6 +101,25 @@ function shallowEqual(l1: any[], l2: any[]): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LazyValue {
|
||||||
|
fn: any;
|
||||||
|
ctx: any;
|
||||||
|
node: any;
|
||||||
|
constructor(fn: any, ctx: any, node: any) {
|
||||||
|
this.fn = fn;
|
||||||
|
this.ctx = capture(ctx);
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate(): any {
|
||||||
|
return this.fn(this.ctx, this.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return this.evaluate().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Safely outputs `value` as a block depending on the nature of `value`
|
* Safely outputs `value` as a block depending on the nature of `value`
|
||||||
*/
|
*/
|
||||||
@@ -113,6 +132,9 @@ export function safeOutput(value: any): ReturnType<typeof toggler> {
|
|||||||
if (value instanceof Markup) {
|
if (value instanceof Markup) {
|
||||||
safeKey = `string_safe`;
|
safeKey = `string_safe`;
|
||||||
block = html(value as string);
|
block = html(value as string);
|
||||||
|
} else if (value instanceof LazyValue) {
|
||||||
|
safeKey = `lazy_value`;
|
||||||
|
block = value.evaluate();
|
||||||
} else if (typeof value === "string") {
|
} else if (typeof value === "string") {
|
||||||
safeKey = "string_unsafe";
|
safeKey = "string_unsafe";
|
||||||
block = text(value);
|
block = text(value);
|
||||||
@@ -172,6 +194,7 @@ export const UTILS = {
|
|||||||
shallowEqual,
|
shallowEqual,
|
||||||
toNumber,
|
toNumber,
|
||||||
validateProps,
|
validateProps,
|
||||||
|
LazyValue,
|
||||||
safeOutput,
|
safeOutput,
|
||||||
bind,
|
bind,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -966,10 +966,17 @@ export class CodeGenerator {
|
|||||||
this.helpers.add("isBoundary").add("withDefault");
|
this.helpers.add("isBoundary").add("withDefault");
|
||||||
const expr = ast.value ? compileExpr(ast.value || "") : "null";
|
const expr = ast.value ? compileExpr(ast.value || "") : "null";
|
||||||
if (ast.body) {
|
if (ast.body) {
|
||||||
|
const initialTarget = this.target;
|
||||||
|
this.helpers.add("LazyValue");
|
||||||
|
let name = this.generateId("value");
|
||||||
|
const fn = new CodeTarget(name);
|
||||||
|
this.targets.push(fn);
|
||||||
|
this.target = fn;
|
||||||
const subCtx: Context = createContext(ctx);
|
const subCtx: Context = createContext(ctx);
|
||||||
const nextId = `b${BlockDescription.nextBlockId}`;
|
|
||||||
this.compileAST({ type: ASTType.Multi, content: ast.body }, subCtx);
|
this.compileAST({ type: ASTType.Multi, content: ast.body }, subCtx);
|
||||||
const value = ast.value ? (nextId ? `withDefault(${expr}, ${nextId})` : expr) : nextId;
|
this.target = initialTarget;
|
||||||
|
let value = `new LazyValue(${name}, ctx, node)`;
|
||||||
|
value = ast.value ? (value ? `withDefault(${expr}, ${value})` : expr) : value;
|
||||||
this.addLine(`ctx[\`${ast.name}\`] = ${value};`);
|
this.addLine(`ctx[\`${ast.name}\`] = ${value};`);
|
||||||
} else {
|
} else {
|
||||||
let value: string;
|
let value: string;
|
||||||
|
|||||||
@@ -114,16 +114,19 @@ exports[`t-esc t-esc is escaped 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault } = helpers;
|
let { isBoundary, withDefault, LazyValue } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
||||||
let block2 = createBlock(\`<p>escaped</p>\`);
|
let block2 = createBlock(\`<p>escaped</p>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return block2();
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
let b2 = block2();
|
ctx[\`var\`] = new LazyValue(value1, ctx, node);
|
||||||
ctx[\`var\`] = b2;
|
|
||||||
let txt1 = ctx['var'];
|
let txt1 = ctx['var'];
|
||||||
return block1([txt1]);
|
return block1([txt1]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,16 +134,19 @@ exports[`t-out t-out bdom 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault, safeOutput } = helpers;
|
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><span><block-child-0/></span></div>\`);
|
let block1 = createBlock(\`<div><span><block-child-0/></span></div>\`);
|
||||||
let block2 = createBlock(\`<ol>set</ol>\`);
|
let block2 = createBlock(\`<ol>set</ol>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return block2();
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
let b2 = block2();
|
ctx[\`var\`] = new LazyValue(value1, ctx, node);
|
||||||
ctx[\`var\`] = b2;
|
|
||||||
let b3 = safeOutput(ctx['var']);
|
let b3 = safeOutput(ctx['var']);
|
||||||
return block1([], [b3]);
|
return block1([], [b3]);
|
||||||
}
|
}
|
||||||
@@ -277,19 +280,22 @@ exports[`t-out t-out switch markup on bdom 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault, safeOutput } = helpers;
|
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
|
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
|
||||||
let block2 = createBlock(\`<ol>set</ol>\`);
|
let block2 = createBlock(\`<ol>set</ol>\`);
|
||||||
let block3 = createBlock(\`<span><block-child-0/></span>\`);
|
let block3 = createBlock(\`<span><block-child-0/></span>\`);
|
||||||
let block5 = createBlock(\`<span><block-child-0/></span>\`);
|
let block5 = createBlock(\`<span><block-child-0/></span>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return block2();
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
let b3,b5;
|
let b3,b5;
|
||||||
let b2 = block2();
|
ctx[\`bdom\`] = new LazyValue(value1, ctx, node);
|
||||||
ctx[\`bdom\`] = b2;
|
|
||||||
if (ctx['hasBdom']) {
|
if (ctx['hasBdom']) {
|
||||||
let b4 = safeOutput(ctx['bdom']);
|
let b4 = safeOutput(ctx['bdom']);
|
||||||
b3 = block3([], [b4]);
|
b3 = block3([], [b4]);
|
||||||
|
|||||||
@@ -106,15 +106,18 @@ exports[`t-set set from body lookup 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault } = helpers;
|
let { isBoundary, withDefault, LazyValue } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return text(ctx['value']);
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
let b2 = text(ctx['value']);
|
ctx[\`stuff\`] = new LazyValue(value1, ctx, node);
|
||||||
ctx[\`stuff\`] = b2;
|
|
||||||
let txt1 = ctx['stuff'];
|
let txt1 = ctx['stuff'];
|
||||||
return block1([txt1]);
|
return block1([txt1]);
|
||||||
}
|
}
|
||||||
@@ -164,18 +167,21 @@ exports[`t-set t-set body is evaluated immediately 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault, setContextValue, safeOutput } = helpers;
|
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
||||||
let block2 = createBlock(\`<span><block-text-0/></span>\`);
|
let block2 = createBlock(\`<span><block-text-0/></span>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
let txt1 = ctx['v1'];
|
||||||
|
return block2([txt1]);
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
setContextValue(ctx, \\"v1\\", 'before');
|
setContextValue(ctx, \\"v1\\", 'before');
|
||||||
let txt1 = ctx['v1'];
|
ctx[\`v2\`] = new LazyValue(value1, ctx, node);
|
||||||
let b2 = block2([txt1]);
|
|
||||||
ctx[\`v2\`] = b2;
|
|
||||||
setContextValue(ctx, \\"v1\\", 'after');
|
setContextValue(ctx, \\"v1\\", 'after');
|
||||||
let b3 = safeOutput(ctx['v2']);
|
let b3 = safeOutput(ctx['v2']);
|
||||||
return block1([], [b3]);
|
return block1([], [b3]);
|
||||||
@@ -427,17 +433,20 @@ exports[`t-set t-set with content and sub t-esc 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault } = helpers;
|
let { isBoundary, withDefault, LazyValue } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
let b3 = text(ctx['beep']);
|
||||||
|
let b4 = text(\` boop\`);
|
||||||
|
return multi([b3, b4]);
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
let b3 = text(ctx['beep']);
|
ctx[\`setvar\`] = new LazyValue(value1, ctx, node);
|
||||||
let b4 = text(\` boop\`);
|
|
||||||
let b2 = multi([b3, b4]);
|
|
||||||
ctx[\`setvar\`] = b2;
|
|
||||||
let txt1 = ctx['setvar'];
|
let txt1 = ctx['setvar'];
|
||||||
return block1([txt1]);
|
return block1([txt1]);
|
||||||
}
|
}
|
||||||
@@ -448,19 +457,22 @@ exports[`t-set t-set with t-value (falsy) and body 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault, setContextValue, safeOutput } = helpers;
|
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
||||||
let block2 = createBlock(\`<span><block-text-0/></span>\`);
|
let block2 = createBlock(\`<span><block-text-0/></span>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
let txt1 = ctx['v1'];
|
||||||
|
return block2([txt1]);
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
setContextValue(ctx, \\"v3\\", false);
|
setContextValue(ctx, \\"v3\\", false);
|
||||||
setContextValue(ctx, \\"v1\\", 'before');
|
setContextValue(ctx, \\"v1\\", 'before');
|
||||||
let txt1 = ctx['v1'];
|
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, node));
|
||||||
let b2 = block2([txt1]);
|
|
||||||
ctx[\`v2\`] = withDefault(ctx['v3'], b2);
|
|
||||||
setContextValue(ctx, \\"v1\\", 'after');
|
setContextValue(ctx, \\"v1\\", 'after');
|
||||||
setContextValue(ctx, \\"v3\\", true);
|
setContextValue(ctx, \\"v3\\", true);
|
||||||
let b3 = safeOutput(ctx['v2']);
|
let b3 = safeOutput(ctx['v2']);
|
||||||
@@ -473,19 +485,22 @@ exports[`t-set t-set with t-value (truthy) and body 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault, setContextValue, safeOutput } = helpers;
|
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
||||||
let block2 = createBlock(\`<span><block-text-0/></span>\`);
|
let block2 = createBlock(\`<span><block-text-0/></span>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
let txt1 = ctx['v1'];
|
||||||
|
return block2([txt1]);
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
setContextValue(ctx, \\"v3\\", 'Truthy');
|
setContextValue(ctx, \\"v3\\", 'Truthy');
|
||||||
setContextValue(ctx, \\"v1\\", 'before');
|
setContextValue(ctx, \\"v1\\", 'before');
|
||||||
let txt1 = ctx['v1'];
|
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, node));
|
||||||
let b2 = block2([txt1]);
|
|
||||||
ctx[\`v2\`] = withDefault(ctx['v3'], b2);
|
|
||||||
setContextValue(ctx, \\"v1\\", 'after');
|
setContextValue(ctx, \\"v1\\", 'after');
|
||||||
setContextValue(ctx, \\"v3\\", false);
|
setContextValue(ctx, \\"v3\\", false);
|
||||||
let b3 = safeOutput(ctx['v2']);
|
let b3 = safeOutput(ctx['v2']);
|
||||||
@@ -563,16 +578,19 @@ exports[`t-set value priority (with non text body 1`] = `
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault } = helpers;
|
let { isBoundary, withDefault, LazyValue } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
||||||
let block2 = createBlock(\`<span>2</span>\`);
|
let block2 = createBlock(\`<span>2</span>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return block2();
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
let b2 = block2();
|
ctx[\`value\`] = withDefault(1, new LazyValue(value1, ctx, node));
|
||||||
ctx[\`value\`] = withDefault(1, b2);
|
|
||||||
let txt1 = ctx['value'];
|
let txt1 = ctx['value'];
|
||||||
return block1([txt1]);
|
return block1([txt1]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,16 +145,19 @@ exports[`basics t-set with a body expression can be passed in props, and then t-
|
|||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
let { isBoundary, withDefault } = helpers;
|
let { isBoundary, withDefault, LazyValue } = helpers;
|
||||||
|
|
||||||
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
||||||
let block2 = createBlock(\`<p>43</p>\`);
|
let block2 = createBlock(\`<p>43</p>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return block2();
|
||||||
|
}
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
ctx = Object.create(ctx);
|
ctx = Object.create(ctx);
|
||||||
ctx[isBoundary] = 1
|
ctx[isBoundary] = 1
|
||||||
let b2 = block2();
|
ctx[\`abc\`] = new LazyValue(value1, ctx, node);
|
||||||
ctx[\`abc\`] = b2;
|
|
||||||
let b3 = component(\`Child\`, {val: ctx['abc']}, key + \`__1\`, node, ctx);
|
let b3 = component(\`Child\`, {val: ctx['abc']}, key + \`__1\`, node, ctx);
|
||||||
return block1([], [b3]);
|
return block1([], [b3]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,150 @@ exports[`t-set slot setted value (with t-set) not accessible with t-esc 2`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`t-set slots with a t-set with a component in body 1`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { capture, isBoundary, withDefault, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
|
function slot1(ctx, node, key = \\"\\") {
|
||||||
|
ctx = Object.create(ctx);
|
||||||
|
ctx[isBoundary] = 1
|
||||||
|
ctx[\`v\`] = new LazyValue(value1, ctx, node);
|
||||||
|
let b3 = text(\` in slot \`);
|
||||||
|
let b4 = safeOutput(ctx['v']);
|
||||||
|
return multi([b3, b4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return component(\`C\`, {}, key + \`__1\`, node, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
const ctx1 = capture(ctx);
|
||||||
|
return component(\`Child\`, {slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__2\`, node, ctx);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set slots with a t-set with a component in body 2`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { callSlot } = helpers;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
let b2 = text(\`Child \`);
|
||||||
|
let b3 = callSlot(ctx, node, key, 'default', false, {});
|
||||||
|
return multi([b2, b3]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set slots with a t-set with a component in body 3`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
return text(\`C\`);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set slots with an t-set with a component in body 1`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { capture, isBoundary, withDefault, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
|
let block4 = createBlock(\`<div>coffee</div>\`);
|
||||||
|
|
||||||
|
function slot1(ctx, node, key = \\"\\") {
|
||||||
|
ctx = Object.create(ctx);
|
||||||
|
ctx[isBoundary] = 1
|
||||||
|
ctx[\`v\`] = new LazyValue(value1, ctx, node);
|
||||||
|
let b5 = text(\` tea \`);
|
||||||
|
let b6 = safeOutput(ctx['v']);
|
||||||
|
return multi([b5, b6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
||||||
|
let b4 = block4();
|
||||||
|
return multi([b3, b4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
const ctx1 = capture(ctx);
|
||||||
|
return component(\`Blorg\`, {slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__2\`, node, ctx);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set slots with an t-set with a component in body 2`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { callSlot } = helpers;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
let b2 = text(\`Blorg \`);
|
||||||
|
let b3 = callSlot(ctx, node, key, 'default', false, {});
|
||||||
|
return multi([b2, b3]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set slots with an t-set with a component in body 3`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
return text(\`Child\`);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set slots with an unused t-set with a component in body 1`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { capture, isBoundary, withDefault, LazyValue } = helpers;
|
||||||
|
|
||||||
|
function slot1(ctx, node, key = \\"\\") {
|
||||||
|
ctx = Object.create(ctx);
|
||||||
|
ctx[isBoundary] = 1
|
||||||
|
ctx[\`v\`] = new LazyValue(value1, ctx, node);
|
||||||
|
return text(\` in slot \`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
const ctx1 = capture(ctx);
|
||||||
|
return component(\`Child\`, {slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__2\`, node, ctx);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set slots with an unused t-set with a component in body 2`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { callSlot } = helpers;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
let b2 = text(\`Child \`);
|
||||||
|
let b3 = callSlot(ctx, node, key, 'default', false, {});
|
||||||
|
return multi([b2, b3]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`t-set t-set can't alter component even if key in component 1`] = `
|
exports[`t-set t-set can't alter component even if key in component 1`] = `
|
||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
@@ -174,3 +318,59 @@ exports[`t-set t-set outside modified in t-if 1`] = `
|
|||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`t-set t-set with a component in body 1`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
|
let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
ctx = Object.create(ctx);
|
||||||
|
ctx[isBoundary] = 1
|
||||||
|
ctx[\`v\`] = new LazyValue(value1, ctx, node);
|
||||||
|
let b3 = safeOutput(ctx['v']);
|
||||||
|
return block1([], [b3]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set t-set with a component in body 2`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
return text(\`Child\`);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-set t-set with something in body 1`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
|
||||||
|
|
||||||
|
let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`);
|
||||||
|
let block2 = createBlock(\`<p>coucou</p>\`);
|
||||||
|
|
||||||
|
function value1(ctx, node, key = \\"\\") {
|
||||||
|
return block2();
|
||||||
|
}
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
ctx = Object.create(ctx);
|
||||||
|
ctx[isBoundary] = 1
|
||||||
|
ctx[\`v\`] = new LazyValue(value1, ctx, node);
|
||||||
|
let b3 = safeOutput(ctx['v']);
|
||||||
|
return block1([], [b3]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|||||||
@@ -156,4 +156,113 @@ describe("t-set", () => {
|
|||||||
expect(fixture.innerHTML).toBe("<div><p>source</p><div>childcalled</div><p>source</p></div>");
|
expect(fixture.innerHTML).toBe("<div><p>source</p><div>childcalled</div><p>source</p></div>");
|
||||||
expect((child as any).iter).toBe("child");
|
expect((child as any).iter).toBe("child");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("t-set with something in body", async () => {
|
||||||
|
class Comp extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<div>
|
||||||
|
<t t-set="v">
|
||||||
|
<p>coucou</p>
|
||||||
|
</t>
|
||||||
|
<div><t t-out="v"/></div>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
await mount(Comp, fixture);
|
||||||
|
|
||||||
|
expect(fixture.innerHTML).toBe("<div><div><p>coucou</p></div></div>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-set with a component in body", async () => {
|
||||||
|
class Child extends Component {
|
||||||
|
static template = xml`Child`;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Comp extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<div>
|
||||||
|
<t t-set="v">
|
||||||
|
<Child/>
|
||||||
|
</t>
|
||||||
|
<div><t t-out="v"/></div>
|
||||||
|
</div>`;
|
||||||
|
static components = { Child };
|
||||||
|
}
|
||||||
|
|
||||||
|
await mount(Comp, fixture);
|
||||||
|
|
||||||
|
expect(fixture.innerHTML).toBe("<div><div>Child</div></div>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("slots with an unused t-set with a component in body", async () => {
|
||||||
|
class Child extends Component {
|
||||||
|
static template = xml`Child <t t-slot="default"/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Comp extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<Child>
|
||||||
|
<t t-set="v">
|
||||||
|
<Child/>
|
||||||
|
</t>
|
||||||
|
in slot
|
||||||
|
</Child>`;
|
||||||
|
static components = { Child };
|
||||||
|
}
|
||||||
|
|
||||||
|
await mount(Comp, fixture);
|
||||||
|
|
||||||
|
expect(fixture.innerHTML).toBe("Child in slot ");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("slots with a t-set with a component in body", async () => {
|
||||||
|
class C extends Component {
|
||||||
|
static template = xml`C`;
|
||||||
|
}
|
||||||
|
class Child extends Component {
|
||||||
|
static template = xml`Child <t t-slot="default"/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Comp extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<Child>
|
||||||
|
<t t-set="v">
|
||||||
|
<C/>
|
||||||
|
</t>
|
||||||
|
in slot
|
||||||
|
<t t-out="v" />
|
||||||
|
</Child>`;
|
||||||
|
static components = { Child, C };
|
||||||
|
}
|
||||||
|
|
||||||
|
await mount(Comp, fixture);
|
||||||
|
|
||||||
|
expect(fixture.innerHTML).toBe("Child in slot C");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("slots with an t-set with a component in body", async () => {
|
||||||
|
class Child extends Component {
|
||||||
|
static template = xml`Child`;
|
||||||
|
}
|
||||||
|
class Blorg extends Component {
|
||||||
|
static template = xml`Blorg <t t-slot="default"/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Comp extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<Blorg>
|
||||||
|
<t t-set="v">
|
||||||
|
<Child/>
|
||||||
|
<div>coffee</div>
|
||||||
|
</t>
|
||||||
|
tea
|
||||||
|
<t t-out="v"/>
|
||||||
|
</Blorg>`;
|
||||||
|
static components = { Child, Blorg };
|
||||||
|
}
|
||||||
|
|
||||||
|
await mount(Comp, fixture);
|
||||||
|
|
||||||
|
expect(fixture.innerHTML).toBe("Blorg tea Child<div>coffee</div>");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+10
-3
@@ -78,7 +78,14 @@ export function snapshotTemplate(template: string) {
|
|||||||
expect(fn.toString()).toMatchSnapshot();
|
expect(fn.toString()).toMatchSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderToBdom(template: string, context: any = {}, node: any = {}): BDom {
|
export function renderToBdom(template: string, context: any = {}, node?: any): BDom {
|
||||||
|
if (!node) {
|
||||||
|
if (!context.__owl__) {
|
||||||
|
context.__owl__ = { component: context };
|
||||||
|
} else {
|
||||||
|
context.__owl__.component = context;
|
||||||
|
}
|
||||||
|
}
|
||||||
const fn = compile(template);
|
const fn = compile(template);
|
||||||
if (shouldSnapshot && !snapshottedTemplates.has(template)) {
|
if (shouldSnapshot && !snapshottedTemplates.has(template)) {
|
||||||
snapshottedTemplates.add(template);
|
snapshottedTemplates.add(template);
|
||||||
@@ -87,9 +94,9 @@ export function renderToBdom(template: string, context: any = {}, node: any = {}
|
|||||||
return fn(blockDom, UTILS)(context, node);
|
return fn(blockDom, UTILS)(context, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderToString(template: string, context: any = {}): string {
|
export function renderToString(template: string, context: any = {}, node?: any): string {
|
||||||
const fixture = makeTestFixture();
|
const fixture = makeTestFixture();
|
||||||
const bdom = renderToBdom(template, context);
|
const bdom = renderToBdom(template, context, node);
|
||||||
mount(bdom, fixture);
|
mount(bdom, fixture);
|
||||||
return fixture.innerHTML;
|
return fixture.innerHTML;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user