mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
+16
-5
@@ -53,9 +53,11 @@ export class Context {
|
|||||||
shouldProtectContext: boolean = false;
|
shouldProtectContext: boolean = false;
|
||||||
inLoop: boolean = false;
|
inLoop: boolean = false;
|
||||||
inPreTag: boolean = false;
|
inPreTag: boolean = false;
|
||||||
|
templateName: string;
|
||||||
|
|
||||||
constructor() {
|
constructor(name?: string) {
|
||||||
this.rootContext = this;
|
this.rootContext = this;
|
||||||
|
this.templateName = name || "noname";
|
||||||
this.addLine("let h = this.utils.h;");
|
this.addLine("let h = this.utils.h;");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +339,7 @@ export class QWeb {
|
|||||||
|
|
||||||
const mainNode = this.processedTemplates[name];
|
const mainNode = this.processedTemplates[name];
|
||||||
const isDebug = (<Element>mainNode).attributes.hasOwnProperty("t-debug");
|
const isDebug = (<Element>mainNode).attributes.hasOwnProperty("t-debug");
|
||||||
const ctx = new Context();
|
const ctx = new Context(name);
|
||||||
this._compileNode(mainNode, ctx);
|
this._compileNode(mainNode, ctx);
|
||||||
|
|
||||||
if (ctx.shouldProtectContext) {
|
if (ctx.shouldProtectContext) {
|
||||||
@@ -364,7 +366,12 @@ export class QWeb {
|
|||||||
ctx.code.join("\n")
|
ctx.code.join("\n")
|
||||||
) as CompiledTemplate<VNode>;
|
) as CompiledTemplate<VNode>;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Invalid template (or compiled code): ${e.message}`);
|
throw new Error(
|
||||||
|
`Invalid generated code while compiling template '${ctx.templateName.replace(
|
||||||
|
/`/g,
|
||||||
|
"'"
|
||||||
|
)}': ${e.message}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (isDebug) {
|
if (isDebug) {
|
||||||
console.log(
|
console.log(
|
||||||
@@ -869,15 +876,19 @@ const onDirective: Directive = {
|
|||||||
extraArgs = args.slice(1, -1);
|
extraArgs = args.slice(1, -1);
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
let error = `(function () {throw new Error('Missing handler \\'' + '${handler}' + \`\\' when evaluating template '${ctx.templateName.replace(
|
||||||
|
/`/g,
|
||||||
|
"'"
|
||||||
|
)}'\`)})()`;
|
||||||
if (extraArgs) {
|
if (extraArgs) {
|
||||||
ctx.addLine(
|
ctx.addLine(
|
||||||
`p${nodeID}.on['${eventName}'] = context['${handler}'].bind(owner, ${ctx.formatExpression(
|
`p${nodeID}.on['${eventName}'] = (context['${handler}'] || ${error}).bind(owner, ${ctx.formatExpression(
|
||||||
extraArgs
|
extraArgs
|
||||||
)});`
|
)});`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
ctx.addLine(
|
ctx.addLine(
|
||||||
`extra.handlers['${eventName}' + ${nodeID}] = extra.handlers['${eventName}' + ${nodeID}] || context['${handler}'].bind(owner);`
|
`extra.handlers['${eventName}' + ${nodeID}] = extra.handlers['${eventName}' + ${nodeID}] || (context['${handler}'] || ${error}).bind(owner);`
|
||||||
);
|
);
|
||||||
ctx.addLine(
|
ctx.addLine(
|
||||||
`p${nodeID}.on['${eventName}'] = extra.handlers['${eventName}' + ${nodeID}];`
|
`p${nodeID}.on['${eventName}'] = extra.handlers['${eventName}' + ${nodeID}];`
|
||||||
|
|||||||
@@ -987,7 +987,7 @@ exports[`t-on can bind event handler 1`] = `
|
|||||||
let h = this.utils.h;
|
let h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
extra.handlers['click' + 1] = extra.handlers['click' + 1] || context['add'].bind(owner);
|
extra.handlers['click' + 1] = extra.handlers['click' + 1] || (context['add'] || (function () {throw new Error('Missing handler \\\\'' + 'add' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner);
|
||||||
p1.on['click'] = extra.handlers['click' + 1];
|
p1.on['click'] = extra.handlers['click' + 1];
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1001,7 +1001,7 @@ exports[`t-on can bind handlers with arguments 1`] = `
|
|||||||
let h = this.utils.h;
|
let h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
p1.on['click'] = context['add'].bind(owner, 5);
|
p1.on['click'] = (context['add'] || (function () {throw new Error('Missing handler \\\\'' + 'add' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner, 5);
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -1014,7 +1014,7 @@ exports[`t-on can bind handlers with empty object (with non empty inner string 1
|
|||||||
let h = this.utils.h;
|
let h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
p1.on['click'] = context['doSomething'].bind(owner, {});
|
p1.on['click'] = (context['doSomething'] || (function () {throw new Error('Missing handler \\\\'' + 'doSomething' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner, {});
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -1027,7 +1027,7 @@ exports[`t-on can bind handlers with empty object 1`] = `
|
|||||||
let h = this.utils.h;
|
let h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
p1.on['click'] = context['doSomething'].bind(owner, {});
|
p1.on['click'] = (context['doSomething'] || (function () {throw new Error('Missing handler \\\\'' + 'doSomething' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner, {});
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -1059,7 +1059,7 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
|
|||||||
let c6 = [], p6 = {key:6,on:{}};
|
let c6 = [], p6 = {key:6,on:{}};
|
||||||
let vn6 = h('a', p6, c6);
|
let vn6 = h('a', p6, c6);
|
||||||
c5.push(vn6);
|
c5.push(vn6);
|
||||||
p6.on['click'] = context['activate'].bind(owner, context['action']);
|
p6.on['click'] = (context['activate'] || (function () {throw new Error('Missing handler \\\\'' + 'activate' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner, context['action']);
|
||||||
c6.push({text: \`link\`});
|
c6.push({text: \`link\`});
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1073,7 +1073,7 @@ exports[`t-on can bind handlers with object arguments 1`] = `
|
|||||||
let h = this.utils.h;
|
let h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
p1.on['click'] = context['add'].bind(owner, {val: 5});
|
p1.on['click'] = (context['add'] || (function () {throw new Error('Missing handler \\\\'' + 'add' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner, {val: 5});
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -1086,9 +1086,9 @@ exports[`t-on can bind two event handlers 1`] = `
|
|||||||
let h = this.utils.h;
|
let h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
extra.handlers['click' + 1] = extra.handlers['click' + 1] || context['handleClick'].bind(owner);
|
extra.handlers['click' + 1] = extra.handlers['click' + 1] || (context['handleClick'] || (function () {throw new Error('Missing handler \\\\'' + 'handleClick' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner);
|
||||||
p1.on['click'] = extra.handlers['click' + 1];
|
p1.on['click'] = extra.handlers['click' + 1];
|
||||||
extra.handlers['dblclick' + 1] = extra.handlers['dblclick' + 1] || context['handleDblClick'].bind(owner);
|
extra.handlers['dblclick' + 1] = extra.handlers['dblclick' + 1] || (context['handleDblClick'] || (function () {throw new Error('Missing handler \\\\'' + 'handleDblClick' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner);
|
||||||
p1.on['dblclick'] = extra.handlers['dblclick' + 1];
|
p1.on['dblclick'] = extra.handlers['dblclick' + 1];
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1102,7 +1102,7 @@ exports[`t-on handler is bound to proper owner 1`] = `
|
|||||||
let h = this.utils.h;
|
let h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
extra.handlers['click' + 1] = extra.handlers['click' + 1] || context['add'].bind(owner);
|
extra.handlers['click' + 1] = extra.handlers['click' + 1] || (context['add'] || (function () {throw new Error('Missing handler \\\\'' + 'add' + \`\\\\' when evaluating template 'test'\`)})()).bind(owner);
|
||||||
p1.on['click'] = extra.handlers['click' + 1];
|
p1.on['click'] = extra.handlers['click' + 1];
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
|
|||||||
@@ -107,6 +107,23 @@ describe("error handling", () => {
|
|||||||
qweb.loadTemplates("<templates><abc>></templates>");
|
qweb.loadTemplates("<templates><abc>></templates>");
|
||||||
}).toThrow("Invalid XML in template");
|
}).toThrow("Invalid XML in template");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("nice error when t-on-directive is evaluated with a missing handler", () => {
|
||||||
|
qweb.addTemplate("templatename", `<div t-on-click="somemethod"></div>`);
|
||||||
|
expect(() => qweb.render("templatename", {}, { handlers: [] })).toThrow(
|
||||||
|
"Missing handler 'somemethod' when evaluating template 'templatename'"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("error when compiled code is invalid", () => {
|
||||||
|
qweb.addTemplate(
|
||||||
|
"templatename",
|
||||||
|
`<div t-att-hey="}/^function invalid{{>'"></div>`
|
||||||
|
);
|
||||||
|
expect(() => qweb.render("templatename")).toThrow(
|
||||||
|
"Invalid generated code while compiling template 'templatename': Unexpected token }"
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("t-esc", () => {
|
describe("t-esc", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user