[FIX] qweb: bind handlers to component

Before this commit, the handlers were bound to the current context,
which is often the component but not necessarily.  In some cases, a sub
scope can be created (with t-foreach, or slots, or t-call), and the
context is actually an object with the actual component instance it its
prototype chain, but not the component.
This commit is contained in:
Géry Debongnie
2019-12-12 11:21:49 +01:00
committed by aab-odoo
parent 4e22dbcad6
commit 0931a4dc5b
11 changed files with 208 additions and 41 deletions
+7 -1
View File
@@ -279,7 +279,13 @@ QWeb.addDirective({
}
let eventsCode = events
.map(function([name, value]) {
const { event, handler } = makeHandlerCode(ctx, name, value, false, T_COMPONENT_MODS_CODE);
const { event, handler } = makeHandlerCode(
ctx,
name,
value,
false,
T_COMPONENT_MODS_CODE
);
return `vn.elm.addEventListener('${event}', ${handler});`;
})
.join("");
+1 -1
View File
@@ -81,7 +81,7 @@ const STATIC_TOKEN_MAP: { [key: string]: TKind } = {
// note that the space after typeof is relevant. It makes sure that the formatted
// expression has a space after typeof
const OPERATORS = ".,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=".split(",");
const OPERATORS = ".,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;".split(",");
type Tokenizer = (expr: string) => Token | false;
+4 -2
View File
@@ -55,13 +55,15 @@ export function makeHandlerCode(
// then generate code
if (isMethodCall) {
ctx.rootContext.shouldDefineUtils = true;
const comp = `utils.getComponent(context)`;
if (args) {
let argId = ctx.generateID();
ctx.addLine(`let args${argId} = [${ctx.formatExpression(args)}];`);
code = `context['${name}'](...args${argId}, e);`;
code = `${comp}['${name}'](...args${argId}, e);`;
putInCache = false;
} else {
code = `context['${name}'](e);`;
code = `${comp}['${name}'](e);`;
}
} else {
// if we get here, then it is an expression
+6
View File
@@ -120,6 +120,12 @@ const UTILS: Utils = {
}
})
.join();
},
getComponent(obj) {
while (obj && !obj.hasOwnProperty("__owl__")) {
obj = obj.__proto__;
}
return obj;
}
};