fix crash in template compilation with objects in props

fix #1
This commit is contained in:
Géry Debongnie
2019-03-19 10:33:42 +01:00
parent 695636e60e
commit bd7a2bfc67
3 changed files with 117 additions and 17 deletions
+20 -17
View File
@@ -512,9 +512,28 @@ export class QWeb {
}
_formatExpression(e: string, ctx?: Context): string {
e = e.trim();
if (e in this.exprCache) {
return this.exprCache[e];
}
if (e[0] === "{" && e[e.length - 1] === "}") {
const innerExpr = e
.slice(1, -1)
.split(",")
.map(p => {
let [key, val] = p.trim().split(":");
if (key === "") {
return "";
}
if (!val) {
val = key;
}
return `${key}: ${this._formatExpression(val, ctx)}`;
})
.join(",");
return "{" + innerExpr + "}";
}
// Thanks CHM for this code...
const chars = e.split("");
let instring = "";
@@ -840,23 +859,7 @@ const widgetDirective: Directive = {
}
}
if (props) {
props = props.trim();
if (props[0] === "{" && props[props.length - 1] === "}") {
const innerProp = props
.slice(1, -1)
.split(",")
.map(p => {
let [key, val] = p.split(":");
if (!val) {
val = key;
}
return `${key}: ${qweb._formatExpression(val, ctx)}`;
})
.join(",");
props = "{" + innerProp + "}";
} else {
props = qweb._formatExpression(props);
}
props = qweb._formatExpression(props, ctx);
}
let dummyID = ctx.generateID();
let defID = ctx.generateID();
+39
View File
@@ -988,6 +988,32 @@ exports[`t-on can bind handlers with arguments 1`] = `
}"
`;
exports[`t-on can bind handlers with empty object (with non empty inner string 1`] = `
"function anonymous(context,extra
) {
let owner = context;
let h = this.utils.h;
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
p1.on['click'] = context['doSomething'].bind(owner, {});
c1.push({text: \`Click\`});
return vn1;
}"
`;
exports[`t-on can bind handlers with empty object 1`] = `
"function anonymous(context,extra
) {
let owner = context;
let h = this.utils.h;
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
p1.on['click'] = context['doSomething'].bind(owner, {});
c1.push({text: \`Click\`});
return vn1;
}"
`;
exports[`t-on can bind handlers with loop variable as argument 1`] = `
"function anonymous(context,extra
) {
@@ -1025,6 +1051,19 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
}"
`;
exports[`t-on can bind handlers with object arguments 1`] = `
"function anonymous(context,extra
) {
let owner = context;
let h = this.utils.h;
let c1 = [], p1 = {key:1,on:{}};
let vn1 = h('button', p1, c1);
p1.on['click'] = context['add'].bind(owner, {val: 5});
c1.push({text: \`Click\`});
return vn1;
}"
`;
exports[`t-on can bind two event handlers 1`] = `
"function anonymous(context,extra
) {
+58
View File
@@ -763,6 +763,64 @@ describe("t-on", () => {
expect(a).toBe(6);
});
test("can bind handlers with object arguments", () => {
qweb.addTemplate(
"test",
`<button t-on-click="add({val: 5})">Click</button>`
);
let a = 1;
const node = renderToDOM(
qweb,
"test",
{
add({ val }) {
a = a + val;
}
},
{ handlers: [] }
);
(<HTMLElement>node).click();
expect(a).toBe(6);
});
test("can bind handlers with empty object", () => {
expect.assertions(2);
qweb.addTemplate(
"test",
`<button t-on-click="doSomething({})">Click</button>`
);
const node = renderToDOM(
qweb,
"test",
{
doSomething(arg) {
expect(arg).toEqual({});
}
},
{ handlers: [] }
);
(<HTMLElement>node).click();
});
test("can bind handlers with empty object (with non empty inner string", () => {
expect.assertions(2);
qweb.addTemplate(
"test",
`<button t-on-click="doSomething({ })">Click</button>`
);
const node = renderToDOM(
qweb,
"test",
{
doSomething(arg) {
expect(arg).toEqual({});
}
},
{ handlers: [] }
);
(<HTMLElement>node).click();
});
test("can bind handlers with loop variable as argument", () => {
expect.assertions(2);
qweb.addTemplate(