mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[REF] qweb: improve variable handling
This commit is contained in:
+15
-7
@@ -518,7 +518,8 @@ export class QWeb {
|
||||
// dynamic attributes
|
||||
if (name.startsWith("t-att-")) {
|
||||
let attName = name.slice(6);
|
||||
let formattedValue = ctx.formatExpression(ctx.getValue(value!));
|
||||
const v = ctx.getValue(value);
|
||||
let formattedValue = v.id || ctx.formatExpression(v);
|
||||
if (
|
||||
formattedValue[0] === "{" &&
|
||||
formattedValue[formattedValue.length - 1] === "}"
|
||||
@@ -623,11 +624,21 @@ export class QWeb {
|
||||
//------------------------------------------------------------------------------
|
||||
// Compilation Context
|
||||
//------------------------------------------------------------------------------
|
||||
export interface QWebExprVar {
|
||||
id: string;
|
||||
expr: string;
|
||||
}
|
||||
|
||||
export interface QWebXMLVar {
|
||||
xml: NodeList;
|
||||
}
|
||||
|
||||
export type QWebVar = QWebExprVar | QWebXMLVar;
|
||||
|
||||
export class Context {
|
||||
nextID: number = 1;
|
||||
code: string[] = [];
|
||||
variables: { [key: string]: any } = {};
|
||||
definedVariables: { [key: string]: string } = {};
|
||||
variables: { [key: string]: QWebVar } = {};
|
||||
escaping: boolean = false;
|
||||
parentNode: number | null = null;
|
||||
rootNode: number | null = null;
|
||||
@@ -744,14 +755,11 @@ export class Context {
|
||||
} else if (c.match(/\W/) && invar.length) {
|
||||
// TODO: Should check for possible spaces before dot
|
||||
if (chars[invarPos - 1] !== "." && RESERVED_WORDS.indexOf(invar) < 0) {
|
||||
if (!(invar in this.definedVariables)) {
|
||||
invar =
|
||||
WORD_REPLACEMENT[invar] ||
|
||||
(invar in this.variables &&
|
||||
this.formatExpression(this.variables[invar])) ||
|
||||
(this.variables[invar] && (<any>this.variables[invar]).id) ||
|
||||
"context['" + invar + "']";
|
||||
}
|
||||
}
|
||||
r += invar;
|
||||
invar = "";
|
||||
} else if (invar.length) {
|
||||
|
||||
+30
-27
@@ -1,4 +1,4 @@
|
||||
import { Context, QWeb, UTILS } from "./qweb_core";
|
||||
import { Context, QWeb, UTILS, QWebExprVar } from "./qweb_core";
|
||||
|
||||
/**
|
||||
* Owl QWeb Directives
|
||||
@@ -14,7 +14,6 @@ import { Context, QWeb, UTILS } from "./qweb_core";
|
||||
* - t-log
|
||||
*/
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// t-esc and t-raw
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -30,11 +29,18 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Context) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.xml instanceof NodeList) {
|
||||
for (let node of Array.from(value.xml)) {
|
||||
qweb._compileNode(<ChildNode>node, ctx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let exprID: string;
|
||||
if (typeof value === "string") {
|
||||
let exprID = value;
|
||||
if (!(value in ctx.definedVariables)) {
|
||||
exprID = `_${ctx.generateID()}`;
|
||||
ctx.addLine(`var ${exprID} = ${ctx.formatExpression(value)};`);
|
||||
} else {
|
||||
exprID = value.id;
|
||||
}
|
||||
ctx.addIf(`${exprID} || ${exprID} === 0`);
|
||||
if (!ctx.parentNode) {
|
||||
@@ -58,14 +64,8 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Context) {
|
||||
ctx.addElse();
|
||||
qweb._compileChildren(node, ctx);
|
||||
}
|
||||
|
||||
ctx.closeIf();
|
||||
return;
|
||||
}
|
||||
if (value instanceof NodeList) {
|
||||
for (let node of Array.from(value)) {
|
||||
qweb._compileNode(<ChildNode>node, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QWeb.addDirective({
|
||||
@@ -109,15 +109,21 @@ QWeb.addDirective({
|
||||
if (value) {
|
||||
const formattedValue = ctx.formatExpression(value);
|
||||
if (ctx.variables.hasOwnProperty(variable)) {
|
||||
ctx.addLine(`${ctx.variables[variable]} = ${formattedValue}`);
|
||||
ctx.addLine(
|
||||
`${(<QWebExprVar>ctx.variables[variable]).id} = ${formattedValue}`
|
||||
);
|
||||
} else {
|
||||
const varName = `_${ctx.generateID()}`;
|
||||
ctx.addLine(`var ${varName} = ${formattedValue};`);
|
||||
ctx.definedVariables[varName] = formattedValue;
|
||||
ctx.variables[variable] = varName;
|
||||
ctx.variables[variable] = {
|
||||
id: varName,
|
||||
expr: formattedValue
|
||||
};
|
||||
}
|
||||
} else {
|
||||
ctx.variables[variable] = node.childNodes;
|
||||
ctx.variables[variable] = {
|
||||
xml: node.childNodes
|
||||
};
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -189,30 +195,27 @@ QWeb.addDirective({
|
||||
tempCtx.nextID = ctx.rootContext.nextID;
|
||||
qweb._compileNode(nodeCopy, tempCtx);
|
||||
const vars = Object.assign({}, ctx.variables, tempCtx.variables);
|
||||
var definedVariables = Object.assign(
|
||||
{},
|
||||
ctx.definedVariables,
|
||||
tempCtx.definedVariables
|
||||
);
|
||||
ctx.rootContext.nextID = tempCtx.nextID;
|
||||
|
||||
// open new scope, if necessary
|
||||
const hasNewVariables = Object.keys(definedVariables).length > 0;
|
||||
const hasNewVariables = Object.keys(tempCtx.variables).length > 0;
|
||||
if (hasNewVariables) {
|
||||
ctx.addLine("{");
|
||||
ctx.indent();
|
||||
}
|
||||
|
||||
// add new variables, if any
|
||||
for (let key in definedVariables) {
|
||||
ctx.addLine(`let ${key} = ${definedVariables[key]}`);
|
||||
for (let key in tempCtx.variables) {
|
||||
const v = tempCtx.variables[key];
|
||||
if ((<QWebExprVar>v).expr) {
|
||||
ctx.addLine(`let ${(<QWebExprVar>v).id} = ${(<QWebExprVar>v).expr};`);
|
||||
}
|
||||
// todo: handle XML variables...
|
||||
}
|
||||
}
|
||||
|
||||
// compile sub template
|
||||
const subCtx = ctx
|
||||
.subContext("caller", nodeCopy)
|
||||
.subContext("variables", Object.create(vars))
|
||||
.subContext("definedVariables", Object.create(definedVariables));
|
||||
.subContext("variables", Object.create(vars));
|
||||
|
||||
qweb._compileNode(nodeTemplate.elem, subCtx);
|
||||
|
||||
|
||||
@@ -585,13 +585,13 @@ exports[`misc global 1`] = `
|
||||
c5.push({text: _6});
|
||||
}
|
||||
{
|
||||
let _11 = 'bbb'
|
||||
let _11 = 'bbb';
|
||||
var _13 = 'agüero';
|
||||
let c14 = [], p14 = {key:14,attrs:{\\"falló\\": _13},on:{}};
|
||||
var vn14 = h('Año', p14, c14);
|
||||
c1.push(vn14);
|
||||
{
|
||||
let _15 = 'aaa'
|
||||
let _15 = 'aaa';
|
||||
let c16 = [], p16 = {key:16,on:{}};
|
||||
var vn16 = h('span', p16, c16);
|
||||
c14.push(vn16);
|
||||
@@ -611,8 +611,6 @@ exports[`misc global 1`] = `
|
||||
c17.push({text: \`foo default\`});
|
||||
}
|
||||
var _19 = 'bbb';
|
||||
{
|
||||
let _19 = 'bbb'
|
||||
let c20 = [], p20 = {key:20,on:{}};
|
||||
var vn20 = h('span', p20, c20);
|
||||
c14.push(vn20);
|
||||
@@ -623,7 +621,6 @@ exports[`misc global 1`] = `
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let c21 = [], p21 = {key:21,on:{}};
|
||||
var vn21 = h('div', p21, c21);
|
||||
c1.push(vn21);
|
||||
@@ -756,12 +753,9 @@ exports[`t-call (template calling inherit context 1`] = `
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
var _2 = 1;
|
||||
{
|
||||
let _2 = 1
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
}
|
||||
}
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -773,7 +767,7 @@ exports[`t-call (template calling scoped parameters 1`] = `
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
{
|
||||
let _2 = 42
|
||||
let _2 = 42;
|
||||
c1.push({text: \`ok\`});
|
||||
}
|
||||
var _3 = context['foo'];
|
||||
@@ -800,7 +794,7 @@ exports[`t-call (template calling with unused setbody 1`] = `
|
||||
) {
|
||||
var h = this.utils.h;
|
||||
{
|
||||
let _1 = 3
|
||||
let _1 = 3;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('div', p2, c2);
|
||||
c2.push({text: \`ok\`});
|
||||
@@ -827,7 +821,7 @@ exports[`t-call (template calling with used set body 1`] = `
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
{
|
||||
let _2 = 'ok'
|
||||
let _2 = 'ok';
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user