[FIX] components: capture context in prop expressions

This commit is contained in:
Samuel Degueldre
2021-11-22 12:04:58 +01:00
committed by Aaron Bohy
parent c0cf2c9e3d
commit 7143dd3ff5
16 changed files with 202 additions and 134 deletions
@@ -1130,10 +1130,9 @@ exports[`rendering component again in next microtick 2`] = `
return function template(ctx, node, key = \\"\\") {
let b2;
const v1 = ctx['onClick'];
let d1 = [v1, ctx];
let d1 = [ctx['onClick'], ctx];
if (ctx['env'].config.flag) {
b2 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
}
return block1([d1], [b2]);
}
@@ -23,15 +23,40 @@ exports[`event handling handler receive the event as argument 2`] = `
let block1 = createBlock(\`<span block-handler-0=\\"click\\"><block-child-0/><block-text-1/></span>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['inc'];
let d1 = [v1, ctx];
let b2 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
let d1 = [ctx['inc'], ctx];
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let d2 = ctx['state'].value;
return block1([d1, d2], [b2]);
}
}"
`;
exports[`event handling objects from scope are properly captured by t-on 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div class=\\"item\\" block-handler-0=\\"click\\"/>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item'];
const v1 = ctx['onClick'];
const v2 = ctx['item'];
let d1 = [ev=>v1(v2.val,ev), ctx];
c_block2[i1] = withKey(block3([d1]), key1);
}
let b2 = list(c_block2);
return block1([], [b2]);
}
}"
`;
exports[`event handling support for callable expression in event handler 1`] = `
"function anonymous(bdom, helpers
) {
@@ -42,8 +67,7 @@ exports[`event handling support for callable expression in event handler 1`] = `
return function template(ctx, node, key = \\"\\") {
let d1 = ctx['state'].value;
const v1 = ctx['obj'];
let d2 = [v1.onInput, ctx];
let d2 = [ctx['obj'].onInput, ctx];
return block1([d1, d2]);
}
}"
@@ -130,8 +130,7 @@ exports[`basics sub widget is interactive 1`] = `
let block1 = createBlock(\`<span><button block-handler-0=\\"click\\">click</button>child<block-text-1/></span>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['inc'];
let d1 = [v1, ctx];
let d1 = [ctx['inc'], ctx];
let d2 = ctx['state'].val;
return block1([d1, d2]);
}
@@ -540,8 +540,7 @@ exports[`lifecycle hooks onWillRender 1`] = `
let block1 = createBlock(\`<button block-handler-0=\\"click\\"><block-text-1/></button>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['increment'];
let d1 = [v1, ctx];
let d1 = [ctx['increment'], ctx];
let d2 = ctx['state'].value;
return block1([d1, d2]);
}
@@ -30,6 +30,42 @@ exports[`basics accept ES6-like syntax for props (with getters) 2`] = `
}"
`;
exports[`basics arrow functions as prop correctly capture their scope 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
let block1 = createBlock(\`<button block-handler-0=\\"click\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let d1 = [ctx['props'].onClick, ctx];
return block1([d1]);
}
}"
`;
exports[`basics arrow functions as prop correctly capture their scope 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['items']);
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1];
let key1 = ctx['item'].val;
const v1 = ctx['onClick'];
const v2 = ctx['item'];
c_block1[i1] = withKey(component(\`Child\`, {onClick: ev=>v1(v2.val,ev)}, key + \`__3__\${key1}\`, node, ctx), key1);
}
return list(c_block1);
}
}"
`;
exports[`basics explicit object prop 1`] = `
"function anonymous(bdom, helpers
) {
@@ -43,8 +43,7 @@ exports[`refs refs are properly bound in slots 2`] = `
const slot3 = ctx => (node, key) => {
const refs = ctx.__owl__.refs
const v4 = ctx['doSomething'];
let d2 = [v4, ctx];
let d2 = [ctx['doSomething'], ctx];
let d3 = (el) => refs[\`myButton\`] = el;
return block2([d2, d3]);
}
@@ -389,10 +389,9 @@ exports[`slots dynamic t-slot call 1`] = `
let block1 = createBlock(\`<button block-handler-0=\\"click\\"><block-child-0/></button>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['toggle'];
let d1 = [v1, ctx];
const slot2 = (ctx['current'].slot);
let b2 = toggler(slot2, callSlot(ctx, node, key, slot2));
let d1 = [ctx['toggle'], ctx];
const slot1 = (ctx['current'].slot);
let b2 = toggler(slot1, callSlot(ctx, node, key, slot1));
return block1([d1], [b2]);
}
}"
@@ -436,14 +435,13 @@ exports[`slots dynamic t-slot call with default 1`] = `
let block1 = createBlock(\`<button block-handler-0=\\"click\\"><block-child-0/></button>\`);
const defaultSlot2 = ctx => {
const defaultSlot1 = ctx => {
return text(\` owl \`);
}
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['toggle'];
let d1 = [v1, ctx];
let b3 = callSlot(ctx, node, key, (ctx['current'].slot), defaultSlot2, true);
let d1 = [ctx['toggle'], ctx];
let b3 = callSlot(ctx, node, key, (ctx['current'].slot), defaultSlot1, true);
return block1([d1], [b3]);
}
}"
@@ -1262,15 +1260,14 @@ exports[`slots slot are properly rendered if inner props are changed 3`] = `
let block1 = createBlock(\`<div><button block-handler-0=\\"click\\">Inc[<block-text-1/>]</button><block-child-0/></div>\`);
const slot3 = ctx => (node, key) => {
return component(\`SomeComponent\`, {val: ctx['state'].val}, key + \`__4\`, node, ctx);
const slot2 = ctx => (node, key) => {
return component(\`SomeComponent\`, {val: ctx['state'].val}, key + \`__3\`, node, ctx);
}
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['inc'];
let d1 = [v1, ctx];
let d1 = [ctx['inc'], ctx];
let d2 = ctx['state'].val;
let b3 = assign(component(\`GenericComponent\`, {}, key + \`__2\`, node, ctx), {slots: {'default': slot3(ctx)}});
let b3 = assign(component(\`GenericComponent\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([d1, d2], [b3]);
}
}"
@@ -1301,8 +1298,7 @@ exports[`slots slot content is bound to caller 2`] = `
let block1 = createBlock(\`<button block-handler-0=\\"click\\">some text</button>\`);
const slot2 = ctx => (node, key) => {
const v3 = ctx['inc'];
let d1 = [v3, ctx];
let d1 = [ctx['inc'], ctx];
return block1([d1]);
}
@@ -1472,8 +1468,7 @@ exports[`slots slots are rendered with proper context 2`] = `
let block2 = createBlock(\`<button block-handler-0=\\"click\\">do something</button>\`);
const slot3 = ctx => (node, key) => {
const v4 = ctx['doSomething'];
let d2 = [v4, ctx];
let d2 = [ctx['doSomething'], ctx];
return block2([d2]);
}
@@ -2083,8 +2078,7 @@ exports[`slots t-slot scope context 2`] = `
let block1 = createBlock(\`<div block-handler-0=\\"click\\"><block-child-0/></div>\`);
const slot2 = ctx => (node, key) => {
const v3 = ctx['onClick'];
let d1 = [v3, ctx];
let d1 = [ctx['onClick'], ctx];
let b2 = callSlot(ctx, node, key, 'default');
return block1([d1], [b2]);
}
@@ -52,8 +52,7 @@ exports[`t-call handlers are properly bound through a t-call 1`] = `
let block1 = createBlock(\`<p block-handler-0=\\"click\\">lucas</p>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['update'];
let d1 = [v1, ctx];
let d1 = [ctx['update'], ctx];
return block1([d1]);
}
}"
@@ -117,11 +117,10 @@ exports[`t-model directive can also define t-on directive on same event, part 1
let block1 = createBlock(\`<div><input block-handler-0=\\"input\\" block-attribute-1=\\"value\\" block-handler-2=\\"input\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['onInput'];
let d1 = [v1, ctx];
const bExpr2 = ctx['state'];
let d1 = [ctx['onInput'], ctx];
const bExpr1 = ctx['state'];
let d2 = ctx['state']['text'];
let d3 = [(ev) => { bExpr2['text'] = ev.target.value; }];
let d3 = [(ev) => { bExpr1['text'] = ev.target.value; }];
return block1([d1, d2, d3]);
}
}"
@@ -136,21 +135,18 @@ exports[`t-model directive can also define t-on directive on same event, part 2
let block1 = createBlock(\`<div><input type=\\"radio\\" id=\\"one\\" value=\\"One\\" block-handler-0=\\"click\\" block-attribute-1=\\"checked\\" block-handler-2=\\"click\\"/><input type=\\"radio\\" id=\\"two\\" value=\\"Two\\" block-handler-3=\\"click\\" block-attribute-4=\\"checked\\" block-handler-5=\\"click\\"/><input type=\\"radio\\" id=\\"three\\" value=\\"Three\\" block-handler-6=\\"click\\" block-attribute-7=\\"checked\\" block-handler-8=\\"click\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['onClick'];
let d1 = [v1, ctx];
const bExpr2 = ctx['state'];
let d1 = [ctx['onClick'], ctx];
const bExpr1 = ctx['state'];
let d2 = ctx['state']['choice'] === 'One';
let d3 = [(ev) => { bExpr2['choice'] = ev.target.value; }];
const v3 = ctx['onClick'];
let d4 = [v3, ctx];
const bExpr4 = ctx['state'];
let d3 = [(ev) => { bExpr1['choice'] = ev.target.value; }];
let d4 = [ctx['onClick'], ctx];
const bExpr2 = ctx['state'];
let d5 = ctx['state']['choice'] === 'Two';
let d6 = [(ev) => { bExpr4['choice'] = ev.target.value; }];
const v5 = ctx['onClick'];
let d7 = [v5, ctx];
const bExpr6 = ctx['state'];
let d6 = [(ev) => { bExpr2['choice'] = ev.target.value; }];
let d7 = [ctx['onClick'], ctx];
const bExpr3 = ctx['state'];
let d8 = ctx['state']['choice'] === 'Three';
let d9 = [(ev) => { bExpr6['choice'] = ev.target.value; }];
let d9 = [(ev) => { bExpr3['choice'] = ev.target.value; }];
return block1([d1, d2, d3, d4, d5, d6, d7, d8, d9]);
}
}"
@@ -130,8 +130,7 @@ exports[`t-on t-on on destroyed components 1`] = `
let block1 = createBlock(\`<div block-handler-0=\\"click\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['onClick'];
let d1 = [v1, ctx];
let d1 = [ctx['onClick'], ctx];
return block1([d1]);
}
}"