mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] qweb: properly handle lists in inline expressions
Before this commit, Owl inline expressions with a list with multiple
elements such as [a,b,c] was transformed into
[scope['a'], b: scope['b'], scope['c']]
instead of
[scope['a'], scope['b'], scope['c']]
This is due to a previous commit adding support for short object
descriptions such as {a,b}.
To fix this means that we have to keep track of the current group type
for the expression, which is done by using a stack.
This commit is contained in:
@@ -257,16 +257,33 @@ export function compileExprToArray(expr: string, scope: { [key: string]: QWebVar
|
|||||||
const tokens = tokenize(expr);
|
const tokens = tokenize(expr);
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
let stack = []; // to track last opening [ or {
|
||||||
|
|
||||||
while (i < tokens.length) {
|
while (i < tokens.length) {
|
||||||
let token = tokens[i];
|
let token = tokens[i];
|
||||||
let prevToken = tokens[i - 1];
|
let prevToken = tokens[i - 1];
|
||||||
let nextToken = tokens[i + 1];
|
let nextToken = tokens[i + 1];
|
||||||
|
let groupType = stack[stack.length - 1];
|
||||||
|
|
||||||
|
switch (token.type) {
|
||||||
|
case "LEFT_BRACE":
|
||||||
|
case "LEFT_BRACKET":
|
||||||
|
stack.push(token.type);
|
||||||
|
break;
|
||||||
|
case "RIGHT_BRACE":
|
||||||
|
case "RIGHT_BRACKET":
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
let isVar = token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value);
|
let isVar = token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value);
|
||||||
if (token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value)) {
|
if (token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value)) {
|
||||||
if (prevToken) {
|
if (prevToken) {
|
||||||
// normalize missing tokens: {a} should be equivalent to {a:a}
|
// normalize missing tokens: {a} should be equivalent to {a:a}
|
||||||
if (isLeftSeparator(prevToken) && isRightSeparator(nextToken)) {
|
if (
|
||||||
|
groupType === "LEFT_BRACE" &&
|
||||||
|
isLeftSeparator(prevToken) &&
|
||||||
|
isRightSeparator(nextToken)
|
||||||
|
) {
|
||||||
tokens.splice(i + 1, 0, { type: "COLON", value: ":" }, { ...token });
|
tokens.splice(i + 1, 0, { type: "COLON", value: ":" }, { ...token });
|
||||||
nextToken = tokens[i + 1];
|
nextToken = tokens[i + 1];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,6 +207,17 @@ describe("expression evaluation", () => {
|
|||||||
expect(compileExpr("{a,b:3,c}", {})).toBe("{a:scope['a'],b:3,c:scope['c']}");
|
expect(compileExpr("{a,b:3,c}", {})).toBe("{a:scope['a'],b:3,c:scope['c']}");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("works with short object description and lists ", () => {
|
||||||
|
expect(compileExpr("[a, b]", {})).toBe("[scope['a'],scope['b']]");
|
||||||
|
expect(compileExpr("[a, b, c]", {})).toBe("[scope['a'],scope['b'],scope['c']]");
|
||||||
|
expect(compileExpr("[a, {b, c},d]", {})).toBe(
|
||||||
|
"[scope['a'],{b:scope['b'],c:scope['c']},scope['d']]"
|
||||||
|
);
|
||||||
|
expect(compileExpr("{a:[b, {c, d: e}]}", {})).toBe(
|
||||||
|
"{a:[scope['b'],{c:scope['c'],d:scope['e']}]}"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("template strings", () => {
|
test("template strings", () => {
|
||||||
expect(compileExpr("`hey`", {})).toBe("`hey`");
|
expect(compileExpr("`hey`", {})).toBe("`hey`");
|
||||||
expect(compileExpr("`hey ${you}`", {})).toBe("`hey ${scope['you']}`");
|
expect(compileExpr("`hey ${you}`", {})).toBe("`hey ${scope['you']}`");
|
||||||
|
|||||||
Reference in New Issue
Block a user