[FIX] qweb: properly handle subtemplates in shared templates

With QWeb, we can register globally templates (using the xml tag or
the registerTemplate function). However, these templates, once
compiled, can generate sub template compiled functions. Before this
commit, these sub functions were local to a specific instance.

This means that creating a new QWeb instance and rendering a global
parent template would crash, since it was unable to find the actual sub
function.

This commit fixes the issue: the sub functions are now shared
statically, but with a unique ID, so we do not have issues with sub
functions having a same name in different QWeb instance.

closes #701
This commit is contained in:
Géry Debongnie
2020-05-25 10:33:14 +02:00
committed by aab-odoo
parent 4b961cbffe
commit 85318b3ae6
6 changed files with 118 additions and 114 deletions
+11 -5
View File
@@ -234,10 +234,12 @@ QWeb.addDirective({
// Step 2: compile target template in sub templates
// ------------------------------------------------
if (!qweb.subTemplates[subTemplate]) {
qweb.subTemplates[subTemplate] = true;
let subId = qweb.subTemplates[subTemplate];
if (!subId) {
subId = QWeb.nextId++;
qweb.subTemplates[subTemplate] = subId;
const subTemplateFn = qweb._compile(subTemplate, nodeTemplate.elem, ctx, true);
qweb.subTemplates[subTemplate] = subTemplateFn;
QWeb.subTemplates[subId] = subTemplateFn;
}
// Step 3: compile t-call body if necessary
@@ -275,12 +277,16 @@ QWeb.addDirective({
const parentNode = ctx.parentNode ? `c${ctx.parentNode}` : "result";
const extra = `Object.assign({}, extra, {parentNode: ${parentNode}, parent: ${parentComponent}, key: ${key}})`;
if (ctx.parentNode) {
ctx.addLine(`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, ${extra});`);
ctx.addLine(
`this.constructor.subTemplates['${subId}'].call(this, ${callingScope}, ${extra});`
);
} else {
// this is a t-call with no parentnode, we need to extract the result
ctx.rootContext.shouldDefineResult = true;
ctx.addLine(`result = []`);
ctx.addLine(`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, ${extra});`);
ctx.addLine(
`this.constructor.subTemplates['${subId}'].call(this, ${callingScope}, ${extra});`
);
ctx.addLine(`result = result[0]`);
}