mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 38380b0b12 | |||
| 8986f06448 | |||
| 1a33d3d8e8 | |||
| 82ab18ad83 | |||
| c86bb6111a |
+85
-37
@@ -44,50 +44,88 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Compilatio
|
|||||||
} else {
|
} else {
|
||||||
exprID = `scope.${value.id}`;
|
exprID = `scope.${value.id}`;
|
||||||
}
|
}
|
||||||
ctx.addIf(`${exprID} != null`);
|
|
||||||
|
|
||||||
if (ctx.escaping) {
|
let protectID;
|
||||||
let protectID;
|
if (value.hasBody) {
|
||||||
if (value.hasBody) {
|
|
||||||
ctx.rootContext.shouldDefineUtils = true;
|
|
||||||
protectID = ctx.startProtectScope();
|
|
||||||
ctx.addLine(
|
|
||||||
`${exprID} = ${exprID} instanceof utils.VDomArray ? utils.vDomToString(${exprID}) : ${exprID};`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (ctx.parentTextNode) {
|
|
||||||
ctx.addLine(`vn${ctx.parentTextNode}.text += ${exprID};`);
|
|
||||||
} else if (ctx.parentNode) {
|
|
||||||
ctx.addLine(`c${ctx.parentNode}.push({text: ${exprID}});`);
|
|
||||||
} else {
|
|
||||||
let nodeID = ctx.generateID();
|
|
||||||
ctx.rootContext.rootNode = nodeID;
|
|
||||||
ctx.rootContext.parentTextNode = nodeID;
|
|
||||||
ctx.addLine(`let vn${nodeID} = {text: ${exprID}};`);
|
|
||||||
if (ctx.rootContext.shouldDefineResult) {
|
|
||||||
ctx.addLine(`result = vn${nodeID}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value.hasBody) {
|
|
||||||
ctx.stopProtectScope(protectID);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ctx.rootContext.shouldDefineUtils = true;
|
ctx.rootContext.shouldDefineUtils = true;
|
||||||
if (value.hasBody) {
|
protectID = ctx.startProtectScope();
|
||||||
ctx.addLine(
|
ctx.addLine(
|
||||||
`const vnodeArray = ${exprID} instanceof utils.VDomArray ? ${exprID} : utils.htmlToVDOM(${exprID});`
|
`${exprID} = ${exprID} instanceof utils.VDomArray ? utils.vDomToString(${exprID}) : ${exprID};`
|
||||||
);
|
);
|
||||||
ctx.addLine(`c${ctx.parentNode}.push(...vnodeArray);`);
|
|
||||||
} else {
|
|
||||||
ctx.addLine(`c${ctx.parentNode}.push(...utils.htmlToVDOM(${exprID}));`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (node.childNodes.length) {
|
if (node.childNodes.length) {
|
||||||
ctx.addElse();
|
// ctx.addLine(`c${ctx.parentNode}.push(...vnodeArray);`);
|
||||||
|
ctx.addIf(`!${exprID}`);
|
||||||
|
// if (node.childNodes.length) {
|
||||||
|
// ctx.addElse();
|
||||||
qweb._compileChildren(node, ctx);
|
qweb._compileChildren(node, ctx);
|
||||||
|
// }
|
||||||
|
|
||||||
|
ctx.closeIf();
|
||||||
|
}
|
||||||
|
if (ctx.parentTextNode) {
|
||||||
|
ctx.addIf(`${exprID} != null`);
|
||||||
|
ctx.addLine(`vn${ctx.parentTextNode}.text += ${exprID};`);
|
||||||
|
ctx.closeIf();
|
||||||
|
} else if (ctx.parentNode) {
|
||||||
|
ctx.rootContext.shouldDefineUtils = true;
|
||||||
|
ctx.addLine(`insertValue(c${ctx.parentNode}, ${exprID})`);
|
||||||
|
} else {
|
||||||
|
ctx.addIf(`${exprID} != null`);
|
||||||
|
|
||||||
|
let nodeID = ctx.generateID();
|
||||||
|
ctx.rootContext.rootNode = nodeID;
|
||||||
|
ctx.rootContext.parentTextNode = nodeID;
|
||||||
|
ctx.addLine(`let vn${nodeID} = {text: ${exprID}};`);
|
||||||
|
if (ctx.rootContext.shouldDefineResult) {
|
||||||
|
ctx.addLine(`result = vn${nodeID}`);
|
||||||
|
}
|
||||||
|
ctx.closeIf();
|
||||||
|
}
|
||||||
|
if (value.hasBody) {
|
||||||
|
ctx.stopProtectScope(protectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.closeIf();
|
// ctx.addIf(`${exprID} != null`);
|
||||||
|
|
||||||
|
// if (ctx.escaping) {
|
||||||
|
// let protectID;
|
||||||
|
// if (value.hasBody) {
|
||||||
|
// ctx.rootContext.shouldDefineUtils = true;
|
||||||
|
// protectID = ctx.startProtectScope();
|
||||||
|
// ctx.addLine(
|
||||||
|
// `${exprID} = ${exprID} instanceof utils.VDomArray ? utils.vDomToString(${exprID}) : ${exprID};`
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// if (ctx.parentTextNode) {
|
||||||
|
// ctx.addLine(`vn${ctx.parentTextNode}.text += ${exprID};`);
|
||||||
|
// } else if (ctx.parentNode) {
|
||||||
|
// ctx.addLine(`c${ctx.parentNode}.push({text: ${exprID}});`);
|
||||||
|
// } else {
|
||||||
|
// let nodeID = ctx.generateID();
|
||||||
|
// ctx.rootContext.rootNode = nodeID;
|
||||||
|
// ctx.rootContext.parentTextNode = nodeID;
|
||||||
|
// ctx.addLine(`let vn${nodeID} = {text: ${exprID}};`);
|
||||||
|
// if (ctx.rootContext.shouldDefineResult) {
|
||||||
|
// ctx.addLine(`result = vn${nodeID}`);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (value.hasBody) {
|
||||||
|
// ctx.stopProtectScope(protectID);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// ctx.rootContext.shouldDefineUtils = true;
|
||||||
|
// if (value.hasBody) {
|
||||||
|
// ctx.addLine(
|
||||||
|
// `const vnodeArray = ${exprID} instanceof utils.VDomArray ? ${exprID} : utils.htmlToVDOM(${exprID});`
|
||||||
|
// );
|
||||||
|
// ctx.addLine(`c${ctx.parentNode}.push(...vnodeArray);`);
|
||||||
|
// } else {
|
||||||
|
// ctx.addLine(`c${ctx.parentNode}.push(...utils.htmlToVDOM(${exprID}));`);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ctx.closeIf();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWeb.addDirective({
|
QWeb.addDirective({
|
||||||
@@ -100,6 +138,16 @@ QWeb.addDirective({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QWeb.addDirective({
|
||||||
|
name: "out",
|
||||||
|
priority: 70,
|
||||||
|
atNodeEncounter({ node, qweb, ctx }): boolean {
|
||||||
|
let value = ctx.getValue(node.getAttribute("t-out")!);
|
||||||
|
compileValueNode(value, node, qweb, ctx.subContext("escaping", true));
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
QWeb.addDirective({
|
QWeb.addDirective({
|
||||||
name: "raw",
|
name: "raw",
|
||||||
priority: 80,
|
priority: 80,
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ export class CompilationContext {
|
|||||||
this.code.unshift(" let QWeb = this.constructor;");
|
this.code.unshift(" let QWeb = this.constructor;");
|
||||||
}
|
}
|
||||||
if (this.shouldDefineUtils) {
|
if (this.shouldDefineUtils) {
|
||||||
|
this.code.unshift(" let insertValue = utils.insertValue;");
|
||||||
this.code.unshift(" let utils = this.constructor.utils;");
|
this.code.unshift(" let utils = this.constructor.utils;");
|
||||||
}
|
}
|
||||||
return this.code;
|
return this.code;
|
||||||
|
|||||||
+17
-2
@@ -1,8 +1,9 @@
|
|||||||
import { EventBus } from "../core/event_bus";
|
import { EventBus } from "../core/event_bus";
|
||||||
import { h, patch, VNode } from "../vdom/index";
|
import { h, patch, VNode } from "../vdom/index";
|
||||||
import { CompilationContext } from "./compilation_context";
|
import { CompilationContext } from "./compilation_context";
|
||||||
import { shallowEqual, escape } from "../utils";
|
import { shallowEqual, escape, _Markup } from "../utils";
|
||||||
import { addNS } from "../vdom/vdom";
|
import { addNS } from "../vdom/vdom";
|
||||||
|
import { htmlToVDOM } from "../vdom/html_to_vdom";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Owl QWeb Engine
|
* Owl QWeb Engine
|
||||||
@@ -89,6 +90,16 @@ function isComponent(obj): boolean {
|
|||||||
return obj && obj.hasOwnProperty("__owl__");
|
return obj && obj.hasOwnProperty("__owl__");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function insertValue(children: any[], value: any) {
|
||||||
|
if (value != null) {
|
||||||
|
if (value instanceof _Markup) {
|
||||||
|
children.push(...htmlToVDOM(value as any));
|
||||||
|
} else {
|
||||||
|
children.push({ text: value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class VDomArray extends Array {
|
class VDomArray extends Array {
|
||||||
toString() {
|
toString() {
|
||||||
return vDomToString(this);
|
return vDomToString(this);
|
||||||
@@ -111,6 +122,7 @@ function vDomToString(vdom: VNode[]): string {
|
|||||||
|
|
||||||
const UTILS: Utils = {
|
const UTILS: Utils = {
|
||||||
zero: Symbol("zero"),
|
zero: Symbol("zero"),
|
||||||
|
insertValue,
|
||||||
toClassObj(expr) {
|
toClassObj(expr) {
|
||||||
const result = {};
|
const result = {};
|
||||||
if (typeof expr === "string") {
|
if (typeof expr === "string") {
|
||||||
@@ -599,7 +611,10 @@ export class QWeb extends EventBus {
|
|||||||
if (!(dName in QWeb.DIRECTIVE_NAMES)) {
|
if (!(dName in QWeb.DIRECTIVE_NAMES)) {
|
||||||
throw new Error(`Unknown QWeb directive: '${attrName}'`);
|
throw new Error(`Unknown QWeb directive: '${attrName}'`);
|
||||||
}
|
}
|
||||||
if (node.tagName !== "t" && (attrName === "t-esc" || attrName === "t-raw")) {
|
if (
|
||||||
|
node.tagName !== "t" &&
|
||||||
|
(attrName === "t-esc" || attrName === "t-out" || attrName === "t-raw")
|
||||||
|
) {
|
||||||
const tNode = document.implementation.createDocument(
|
const tNode = document.implementation.createDocument(
|
||||||
"http://www.w3.org/1999/xhtml",
|
"http://www.w3.org/1999/xhtml",
|
||||||
"t",
|
"t",
|
||||||
|
|||||||
+62
-1
@@ -15,7 +15,7 @@ import { browser } from "./browser";
|
|||||||
export function whenReady(fn?: any) {
|
export function whenReady(fn?: any) {
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
if (document.readyState !== "loading") {
|
if (document.readyState !== "loading") {
|
||||||
resolve();
|
(resolve as any)();
|
||||||
} else {
|
} else {
|
||||||
document.addEventListener("DOMContentLoaded", resolve, false);
|
document.addEventListener("DOMContentLoaded", resolve, false);
|
||||||
}
|
}
|
||||||
@@ -101,3 +101,64 @@ export function shallowEqual(p1, p2): boolean {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// notable issues:
|
||||||
|
// * objects can't be negative in JS, so !!"" -> false but
|
||||||
|
// !!(new String) -> true, likewise markup
|
||||||
|
// TODO (?)
|
||||||
|
// * Markup.join / Markup#join => escapes items and returns a Markup
|
||||||
|
// * Markup#replace => automatically escapes the replacements (difficult impl)
|
||||||
|
export class _Markup extends String {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a markup object, which acts like a String but is considered safe by
|
||||||
|
* `_.escape`, and will therefore be injected as-is (without additional
|
||||||
|
* escaping) in templates. Can be used to inject dynamic HTML in templates
|
||||||
|
* (where the template itself can't), see first example.
|
||||||
|
*
|
||||||
|
* Can also be used as a *template tag*, in which case the literal content
|
||||||
|
* won't be escaped but the substitutions which are not already markup objects
|
||||||
|
* will be.
|
||||||
|
*
|
||||||
|
* ## WARNINGS:
|
||||||
|
* * A markup object is a `String` (boxed) but not a `string` (primitive), they
|
||||||
|
* typecheck differently which can be relevant.
|
||||||
|
* * To strip out the "markupness", just call `String(markup)`.
|
||||||
|
* * Most string operations (e.g. concatenation, `String#replace`, ...) will
|
||||||
|
* also strip out markupness
|
||||||
|
* * If the input is empty, returns a regular string (that way boolean tests
|
||||||
|
* work as expected).
|
||||||
|
*
|
||||||
|
* @returns a markup object
|
||||||
|
*
|
||||||
|
* @example regular function
|
||||||
|
* let h;
|
||||||
|
* if (someTest) {
|
||||||
|
* h = Markup(_t("This is a <strong>success</strong>"));
|
||||||
|
* } else {
|
||||||
|
* h = Markup(_t("Things did <strong>not</strong> work out"));
|
||||||
|
* }
|
||||||
|
* qweb.render("some_template", { message: h });
|
||||||
|
*
|
||||||
|
* @example template tag
|
||||||
|
* const escaped = "<some> text";
|
||||||
|
* const asis = Markup`some <b>text</b>`;
|
||||||
|
* const h = Markup`Regular strings get ${escaped} but markup is injected ${asis}`;
|
||||||
|
*/
|
||||||
|
export function Markup(v, ...exprs) {
|
||||||
|
if (!(v instanceof Array)) {
|
||||||
|
return v ? new _Markup(v) : "";
|
||||||
|
}
|
||||||
|
const elements = [];
|
||||||
|
let i = 0;
|
||||||
|
for (; i < exprs.length; ++i) {
|
||||||
|
elements.push(v[i], escape(exprs[i]));
|
||||||
|
}
|
||||||
|
elements.push(v[i]);
|
||||||
|
|
||||||
|
const s = elements.join("");
|
||||||
|
if (!s) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return new _Markup(s);
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,122 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`old t-esc directive escaping 1`] = `
|
||||||
|
"function anonymous(context, extra
|
||||||
|
) {
|
||||||
|
// Template name: \\"test\\"
|
||||||
|
let scope = Object.create(context);
|
||||||
|
let h = this.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
let vn1 = h('span', p1, c1);
|
||||||
|
let _2 = scope['var'];
|
||||||
|
if (_2 != null) {
|
||||||
|
c1.push({text: _2});
|
||||||
|
}
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`old t-esc directive simple dynamic value 1`] = `
|
||||||
|
"function anonymous(context, extra
|
||||||
|
) {
|
||||||
|
// Template name: \\"test\\"
|
||||||
|
let scope = Object.create(context);
|
||||||
|
let result;
|
||||||
|
let h = this.h;
|
||||||
|
let _1 = scope['text'];
|
||||||
|
if (_1 != null) {
|
||||||
|
let vn2 = {text: _1};
|
||||||
|
result = vn2
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`old t-raw directive literal 1`] = `
|
||||||
|
"function anonymous(context, extra
|
||||||
|
) {
|
||||||
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let scope = Object.create(context);
|
||||||
|
let h = this.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
let vn1 = h('span', p1, c1);
|
||||||
|
let _2 = 'ok';
|
||||||
|
if (_2 != null) {
|
||||||
|
c1.push(...utils.htmlToVDOM(_2));
|
||||||
|
}
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`old t-raw directive not escaping 1`] = `
|
||||||
|
"function anonymous(context, extra
|
||||||
|
) {
|
||||||
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let scope = Object.create(context);
|
||||||
|
let h = this.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
let vn1 = h('div', p1, c1);
|
||||||
|
let _2 = scope['var'];
|
||||||
|
if (_2 != null) {
|
||||||
|
c1.push(...utils.htmlToVDOM(_2));
|
||||||
|
}
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`old t-raw directive t-raw and another sibling node 1`] = `
|
||||||
|
"function anonymous(context, extra
|
||||||
|
) {
|
||||||
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let scope = Object.create(context);
|
||||||
|
let h = this.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
let vn1 = h('span', p1, c1);
|
||||||
|
let c2 = [], p2 = {key:2};
|
||||||
|
let vn2 = h('span', p2, c2);
|
||||||
|
c1.push(vn2);
|
||||||
|
c2.push({text: \`hello\`});
|
||||||
|
let _3 = scope['var'];
|
||||||
|
if (_3 != null) {
|
||||||
|
c1.push(...utils.htmlToVDOM(_3));
|
||||||
|
}
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`old t-raw directive t-raw with comment 1`] = `
|
||||||
|
"function anonymous(context, extra
|
||||||
|
) {
|
||||||
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let scope = Object.create(context);
|
||||||
|
let h = this.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
let vn1 = h('span', p1, c1);
|
||||||
|
let _2 = scope['var'];
|
||||||
|
if (_2 != null) {
|
||||||
|
c1.push(...utils.htmlToVDOM(_2));
|
||||||
|
}
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`old t-raw directive variable 1`] = `
|
||||||
|
"function anonymous(context, extra
|
||||||
|
) {
|
||||||
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let scope = Object.create(context);
|
||||||
|
let h = this.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
let vn1 = h('span', p1, c1);
|
||||||
|
let _2 = scope['var'];
|
||||||
|
if (_2 != null) {
|
||||||
|
c1.push(...utils.htmlToVDOM(_2));
|
||||||
|
}
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
+105
-99
@@ -2,6 +2,7 @@ import { QWeb } from "../../src/qweb/index";
|
|||||||
import { config } from "../../src/index";
|
import { config } from "../../src/index";
|
||||||
import { nextTick, normalize, renderToDOM, renderToString, trim } from "../helpers";
|
import { nextTick, normalize, renderToDOM, renderToString, trim } from "../helpers";
|
||||||
import { patch } from "../../src/vdom";
|
import { patch } from "../../src/vdom";
|
||||||
|
import { Markup } from "../../src/utils";
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Setup and helpers
|
// Setup and helpers
|
||||||
@@ -29,27 +30,27 @@ describe("static templates", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("simple dynamic value", () => {
|
test("simple dynamic value", () => {
|
||||||
qweb.addTemplate("test", '<t><t t-esc="text"/></t>');
|
qweb.addTemplate("test", '<t><t t-out="text"/></t>');
|
||||||
expect(renderToString(qweb, "test", { text: "hello vdom" })).toBe("hello vdom");
|
expect(renderToString(qweb, "test", { text: "hello vdom" })).toBe("hello vdom");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("inline template string in t-esc", () => {
|
test("inline template string in t-out", () => {
|
||||||
qweb.addTemplate("test", '<t><t t-esc="`text`"/></t>');
|
qweb.addTemplate("test", '<t><t t-out="`text`"/></t>');
|
||||||
expect(renderToString(qweb, "test")).toBe("text");
|
expect(renderToString(qweb, "test")).toBe("text");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("inline template string with content in t-esc", () => {
|
test("inline template string with content in t-out", () => {
|
||||||
qweb.addTemplate("test", '<t><t t-set="v" t-value="1"/><t t-esc="`text${v}`"/></t>');
|
qweb.addTemplate("test", '<t><t t-set="v" t-value="1"/><t t-out="`text${v}`"/></t>');
|
||||||
expect(renderToString(qweb, "test")).toBe("text1");
|
expect(renderToString(qweb, "test")).toBe("text1");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("inline template string with variable in context", () => {
|
test("inline template string with variable in context", () => {
|
||||||
qweb.addTemplate("test", '<t><t t-esc="`text ${v}`"/></t>');
|
qweb.addTemplate("test", '<t><t t-out="`text ${v}`"/></t>');
|
||||||
expect(renderToString(qweb, "test", { v: "from context" })).toBe("text from context");
|
expect(renderToString(qweb, "test", { v: "from context" })).toBe("text from context");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("simple string, with some dynamic value", () => {
|
test("simple string, with some dynamic value", () => {
|
||||||
qweb.addTemplate("test", '<t>hello <t t-esc="text"/></t>');
|
qweb.addTemplate("test", '<t>hello <t t-out="text"/></t>');
|
||||||
expect(renderToString(qweb, "test", { text: "vdom" })).toBe("hello vdom");
|
expect(renderToString(qweb, "test", { text: "vdom" })).toBe("hello vdom");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -149,47 +150,47 @@ describe("error handling", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("t-esc", () => {
|
describe("t-out", () => {
|
||||||
test("literal", () => {
|
test("literal", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-esc="'ok'"/></span>`);
|
qweb.addTemplate("test", `<span><t t-out="'ok'"/></span>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("variable", () => {
|
test("variable", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-esc="var"/></span>`);
|
qweb.addTemplate("test", `<span><t t-out="var"/></span>`);
|
||||||
expect(renderToString(qweb, "test", { var: "ok" })).toBe("<span>ok</span>");
|
expect(renderToString(qweb, "test", { var: "ok" })).toBe("<span>ok</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("escaping", () => {
|
test("escaping", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-esc="var"/></span>`);
|
qweb.addTemplate("test", `<span><t t-out="var"/></span>`);
|
||||||
expect(renderToString(qweb, "test", { var: "<ok>abc</ok>" })).toBe(
|
expect(renderToString(qweb, "test", { var: "<ok>abc</ok>" })).toBe(
|
||||||
"<span>&lt;ok&gt;abc&lt;/ok&gt;</span>"
|
"<span>&lt;ok&gt;abc&lt;/ok&gt;</span>"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("escaping on a node", () => {
|
test("escaping on a node", () => {
|
||||||
qweb.addTemplate("test", `<span t-esc="'ok'"/>`);
|
qweb.addTemplate("test", `<span t-out="'ok'"/>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("escaping on a node with a body", () => {
|
test("escaping on a node with a body", () => {
|
||||||
qweb.addTemplate("test", `<span t-esc="'ok'">nope</span>`);
|
qweb.addTemplate("test", `<span t-out="'ok'">nope</span>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("escaping on a node with a body, as a default", () => {
|
test("escaping on a node with a body, as a default", () => {
|
||||||
qweb.addTemplate("test", `<span t-esc="var">nope</span>`);
|
qweb.addTemplate("test", `<span t-out="var">nope</span>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<span>nope</span>");
|
expect(renderToString(qweb, "test")).toBe("<span>nope</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-esc is escaped", () => {
|
test("t-out is escaped", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-set="var"><p>escaped</p></t><t t-esc="var"/></div>`);
|
qweb.addTemplate("test", `<div><t t-set="var"><p>escaped</p></t><t t-out="var"/></div>`);
|
||||||
const domRendered = renderToDOM(qweb, "test");
|
const domRendered = renderToDOM(qweb, "test");
|
||||||
expect(domRendered.textContent).toBe("<p>escaped</p>");
|
expect(domRendered.textContent).toBe("<p>escaped</p>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-esc=0 is escaped", () => {
|
test("t-out=0 is escaped", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-esc="0"/></span>`);
|
qweb.addTemplate("test", `<span><t t-out="0"/></span>`);
|
||||||
qweb.addTemplate("testCaller", `<div><t t-call="test"><p>escaped</p></t></div>`);
|
qweb.addTemplate("testCaller", `<div><t t-call="test"><p>escaped</p></t></div>`);
|
||||||
const domRendered = renderToDOM(qweb, "testCaller") as HTMLElement;
|
const domRendered = renderToDOM(qweb, "testCaller") as HTMLElement;
|
||||||
expect(domRendered.querySelector("span")!.textContent).toBe("<p>escaped</p>");
|
expect(domRendered.querySelector("span")!.textContent).toBe("<p>escaped</p>");
|
||||||
@@ -200,11 +201,11 @@ describe("t-esc", () => {
|
|||||||
"test",
|
"test",
|
||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<p t-esc="v1"/>
|
<p t-out="v1"/>
|
||||||
<p t-esc="v2"/>
|
<p t-out="v2"/>
|
||||||
<p t-esc="v3"/>
|
<p t-out="v3"/>
|
||||||
<p t-esc="v4"/>
|
<p t-out="v4"/>
|
||||||
<p t-esc="v5"/>
|
<p t-out="v5"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
const vals = {
|
const vals = {
|
||||||
@@ -219,46 +220,51 @@ describe("t-esc", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-esc work with spread operator", () => {
|
test("t-out work with spread operator", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-esc="[...state.list]"/></span>`);
|
qweb.addTemplate("test", `<span><t t-out="[...state.list]"/></span>`);
|
||||||
const result = renderToString(qweb, "test", { state: { list: [1, 2] } });
|
const result = renderToString(qweb, "test", { state: { list: [1, 2] } });
|
||||||
expect(result).toBe("<span>1,2</span>");
|
expect(result).toBe("<span>1,2</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-esc inside t-call, with t-set outside", () => {
|
test("t-out inside t-call, with t-set outside", () => {
|
||||||
qweb.addTemplate("main", `<div><t t-set="v">Hi</t><t t-call="sub"/></div>`);
|
qweb.addTemplate("main", `<div><t t-set="v">Hi</t><t t-call="sub"/></div>`);
|
||||||
qweb.addTemplate("sub", `<span t-esc="v"/>`);
|
qweb.addTemplate("sub", `<span t-out="v"/>`);
|
||||||
const result = renderToString(qweb, "main");
|
const result = renderToString(qweb, "main");
|
||||||
expect(result).toBe("<div><span>Hi</span></div>");
|
expect(result).toBe("<div><span>Hi</span></div>");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("t-raw", () => {
|
describe("t-out (formerly t-raw tests)", () => {
|
||||||
test("literal", () => {
|
test("literal", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-raw="'ok'"/></span>`);
|
qweb.addTemplate("test", `<span><t t-out="'ok'"/></span>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("variable", () => {
|
test("variable", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-raw="var"/></span>`);
|
qweb.addTemplate("test", `<span><t t-out="var"/></span>`);
|
||||||
expect(renderToString(qweb, "test", { var: "ok" })).toBe("<span>ok</span>");
|
expect(renderToString(qweb, "test", { var: "ok" })).toBe("<span>ok</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("not escaping", () => {
|
test("not escaping (Markup as template function)", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-raw="var"/></div>`);
|
qweb.addTemplate("test", `<div><t t-out="var"/></div>`);
|
||||||
expect(renderToString(qweb, "test", { var: "<ok></ok>" })).toBe("<div><ok></ok></div>");
|
expect(renderToString(qweb, "test", { var: Markup`<ok></ok>` })).toBe("<div><ok></ok></div>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("not escaping (Markup as function)", () => {
|
||||||
|
qweb.addTemplate("test", `<div><t t-out="var"/></div>`);
|
||||||
|
expect(renderToString(qweb, "test", { var: Markup(`<ok></ok>`) })).toBe("<div><ok></ok></div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-raw and another sibling node", () => {
|
test("t-raw and another sibling node", () => {
|
||||||
qweb.addTemplate("test", `<span><span>hello</span><t t-raw="var"/></span>`);
|
qweb.addTemplate("test", `<span><span>hello</span><t t-raw="var"/></span>`);
|
||||||
expect(renderToString(qweb, "test", { var: "<ok>world</ok>" })).toBe(
|
expect(renderToString(qweb, "test", { var: Markup`<ok>world</ok>` })).toBe(
|
||||||
"<span><span>hello</span><ok>world</ok></span>"
|
"<span><span>hello</span><ok>world</ok></span>"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-raw with comment", () => {
|
test("t-raw with comment", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-raw="var"/></span>`);
|
qweb.addTemplate("test", `<span><t t-raw="var"/></span>`);
|
||||||
expect(renderToString(qweb, "test", { var: "<p>text<!-- top secret --></p>" })).toBe(
|
expect(renderToString(qweb, "test", { var: Markup`<p>text<!-- top secret --></p>` })).toBe(
|
||||||
"<span><p>text<!-- top secret --></p></span>"
|
"<span><p>text<!-- top secret --></p></span>"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -266,7 +272,7 @@ describe("t-raw", () => {
|
|||||||
|
|
||||||
describe("t-set", () => {
|
describe("t-set", () => {
|
||||||
test("set from attribute literal", () => {
|
test("set from attribute literal", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-set="value" t-value="'ok'"/><t t-esc="value"/></div>`);
|
qweb.addTemplate("test", `<div><t t-set="value" t-value="'ok'"/><t t-out="value"/></div>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<div>ok</div>");
|
expect(renderToString(qweb, "test")).toBe("<div>ok</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -282,12 +288,12 @@ describe("t-set", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("set from body literal", () => {
|
test("set from body literal", () => {
|
||||||
qweb.addTemplate("test", `<t><t t-set="value">ok</t><t t-esc="value"/></t>`);
|
qweb.addTemplate("test", `<t><t t-set="value">ok</t><t t-out="value"/></t>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("ok");
|
expect(renderToString(qweb, "test")).toBe("ok");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("set from attribute lookup", () => {
|
test("set from attribute lookup", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-set="stuff" t-value="value"/><t t-esc="stuff"/></div>`);
|
qweb.addTemplate("test", `<div><t t-set="stuff" t-value="value"/><t t-out="stuff"/></div>`);
|
||||||
expect(renderToString(qweb, "test", { value: "ok" })).toBe("<div>ok</div>");
|
expect(renderToString(qweb, "test", { value: "ok" })).toBe("<div>ok</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -296,8 +302,8 @@ describe("t-set", () => {
|
|||||||
"test",
|
"test",
|
||||||
`<div >
|
`<div >
|
||||||
<t t-set="v" t-value="value + ' artois'"/>
|
<t t-set="v" t-value="value + ' artois'"/>
|
||||||
<t t-esc="v"/>
|
<t t-out="v"/>
|
||||||
<t t-esc="v"/>
|
<t t-out="v"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
expect(renderToString(qweb, "test", { value: "stella" })).toBe(
|
expect(renderToString(qweb, "test", { value: "stella" })).toBe(
|
||||||
@@ -308,23 +314,23 @@ describe("t-set", () => {
|
|||||||
test("set from body lookup", () => {
|
test("set from body lookup", () => {
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"test",
|
"test",
|
||||||
`<div><t t-set="stuff"><t t-esc="value"/></t><t t-esc="stuff"/></div>`
|
`<div><t t-set="stuff"><t t-out="value"/></t><t t-out="stuff"/></div>`
|
||||||
);
|
);
|
||||||
expect(renderToString(qweb, "test", { value: "ok" })).toBe("<div>ok</div>");
|
expect(renderToString(qweb, "test", { value: "ok" })).toBe("<div>ok</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("set from empty body", () => {
|
test("set from empty body", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-set="stuff"/><t t-esc="stuff"/></div>`);
|
qweb.addTemplate("test", `<div><t t-set="stuff"/><t t-out="stuff"/></div>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<div></div>");
|
expect(renderToString(qweb, "test")).toBe("<div></div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("value priority", () => {
|
test("value priority", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-set="value" t-value="1">2</t><t t-esc="value"/></div>`);
|
qweb.addTemplate("test", `<div><t t-set="value" t-value="1">2</t><t t-out="value"/></div>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<div>1</div>");
|
expect(renderToString(qweb, "test")).toBe("<div>1</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("evaluate value expression", () => {
|
test("evaluate value expression", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-set="value" t-value="1 + 2"/><t t-esc="value"/></div>`);
|
qweb.addTemplate("test", `<div><t t-set="value" t-value="1 + 2"/><t t-out="value"/></div>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<div>3</div>");
|
expect(renderToString(qweb, "test")).toBe("<div>3</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -334,7 +340,7 @@ describe("t-set", () => {
|
|||||||
`<div>
|
`<div>
|
||||||
<t t-set="v" t-value="1"/>
|
<t t-set="v" t-value="1"/>
|
||||||
<div t-foreach="list" t-as="elem" t-key="elem_index">
|
<div t-foreach="list" t-as="elem" t-key="elem_index">
|
||||||
<span>v<t t-esc="v"/></span>
|
<span>v<t t-out="v"/></span>
|
||||||
<t t-set="v" t-value="elem"/>
|
<t t-set="v" t-value="elem"/>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
@@ -344,12 +350,12 @@ describe("t-set", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-set with content and sub t-esc", () => {
|
test("t-set with content and sub t-out", () => {
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"test",
|
"test",
|
||||||
`<div>
|
`<div>
|
||||||
<t t-set="setvar"><t t-esc="beep"/> boop</t>
|
<t t-set="setvar"><t t-out="beep"/> boop</t>
|
||||||
<t t-esc="setvar"/>
|
<t t-out="setvar"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -359,7 +365,7 @@ describe("t-set", () => {
|
|||||||
test("evaluate value expression, part 2", () => {
|
test("evaluate value expression, part 2", () => {
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"test",
|
"test",
|
||||||
`<div><t t-set="value" t-value="somevariable + 2"/><t t-esc="value"/></div>`
|
`<div><t t-set="value" t-value="somevariable + 2"/><t t-out="value"/></div>`
|
||||||
);
|
);
|
||||||
expect(renderToString(qweb, "test", { somevariable: 43 })).toBe("<div>45</div>");
|
expect(renderToString(qweb, "test", { somevariable: 43 })).toBe("<div>45</div>");
|
||||||
});
|
});
|
||||||
@@ -370,7 +376,7 @@ describe("t-set", () => {
|
|||||||
`<div>
|
`<div>
|
||||||
<t t-if="flag" t-set="ourvar">1</t>
|
<t t-if="flag" t-set="ourvar">1</t>
|
||||||
<t t-else="" t-set="ourvar" t-value="0"></t>
|
<t t-else="" t-set="ourvar" t-value="0"></t>
|
||||||
<t t-esc="ourvar"/>
|
<t t-out="ourvar"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
expect(renderToString(qweb, "test", { flag: true })).toBe("<div>1</div>");
|
expect(renderToString(qweb, "test", { flag: true })).toBe("<div>1</div>");
|
||||||
@@ -383,7 +389,7 @@ describe("t-set", () => {
|
|||||||
`<div>
|
`<div>
|
||||||
<t t-if="flag" t-set="ourvar" t-value="1"></t>
|
<t t-if="flag" t-set="ourvar" t-value="1"></t>
|
||||||
<t t-else="" t-set="ourvar">0</t>
|
<t t-else="" t-set="ourvar">0</t>
|
||||||
<t t-esc="ourvar"/>
|
<t t-out="ourvar"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
expect(renderToString(qweb, "test", { flag: true })).toBe("<div>1</div>");
|
expect(renderToString(qweb, "test", { flag: true })).toBe("<div>1</div>");
|
||||||
@@ -396,10 +402,10 @@ describe("t-set", () => {
|
|||||||
`<div>
|
`<div>
|
||||||
<t t-set="v1" t-value="'before'"/>
|
<t t-set="v1" t-value="'before'"/>
|
||||||
<t t-set="v2">
|
<t t-set="v2">
|
||||||
<span><t t-esc="v1"/></span>
|
<span><t t-out="v1"/></span>
|
||||||
</t>
|
</t>
|
||||||
<t t-set="v1" t-value="'after'"/>
|
<t t-set="v1" t-value="'after'"/>
|
||||||
<t t-raw="v2"/>
|
<t t-out="v2"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -413,7 +419,7 @@ describe("t-set", () => {
|
|||||||
<t t-set="v3" t-value="false"/>
|
<t t-set="v3" t-value="false"/>
|
||||||
<t t-set="v1" t-value="'before'"/>
|
<t t-set="v1" t-value="'before'"/>
|
||||||
<t t-set="v2" t-value="v3">
|
<t t-set="v2" t-value="v3">
|
||||||
<span><t t-esc="v1"/></span>
|
<span><t t-out="v1"/></span>
|
||||||
</t>
|
</t>
|
||||||
<t t-set="v1" t-value="'after'"/>
|
<t t-set="v1" t-value="'after'"/>
|
||||||
<t t-set="v3" t-value="true"/>
|
<t t-set="v3" t-value="true"/>
|
||||||
@@ -431,7 +437,7 @@ describe("t-set", () => {
|
|||||||
<t t-set="v3" t-value="'Truthy'"/>
|
<t t-set="v3" t-value="'Truthy'"/>
|
||||||
<t t-set="v1" t-value="'before'"/>
|
<t t-set="v1" t-value="'before'"/>
|
||||||
<t t-set="v2" t-value="v3">
|
<t t-set="v2" t-value="v3">
|
||||||
<span><t t-esc="v1"/></span>
|
<span><t t-out="v1"/></span>
|
||||||
</t>
|
</t>
|
||||||
<t t-set="v1" t-value="'after'"/>
|
<t t-set="v1" t-value="'after'"/>
|
||||||
<t t-set="v3" t-value="false"/>
|
<t t-set="v3" t-value="false"/>
|
||||||
@@ -522,13 +528,13 @@ describe("t-if", () => {
|
|||||||
expect(normalize(renderToString(qweb, "test", context))).toBe("<div>andormgtnlt</div>");
|
expect(normalize(renderToString(qweb, "test", context))).toBe("<div>andormgtnlt</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-esc with t-if", () => {
|
test("t-out with t-if", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-if="true" t-esc="'x'"/></div>`);
|
qweb.addTemplate("test", `<div><t t-if="true" t-out="'x'"/></div>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<div>x</div>");
|
expect(renderToString(qweb, "test")).toBe("<div>x</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-esc with t-elif", () => {
|
test("t-out with t-elif", () => {
|
||||||
qweb.addTemplate("test", `<div><t t-if="false">abc</t><t t-else="" t-esc="'x'"/></div>`);
|
qweb.addTemplate("test", `<div><t t-if="false">abc</t><t t-else="" t-out="'x'"/></div>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<div>x</div>");
|
expect(renderToString(qweb, "test")).toBe("<div>x</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -538,7 +544,7 @@ describe("t-if", () => {
|
|||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-set="title" t-value="'test'"/>
|
<t t-set="title" t-value="'test'"/>
|
||||||
<t t-if="title"><t t-esc="title"/></t>
|
<t t-if="title"><t t-out="title"/></t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
const result = renderToString(qweb, "test");
|
const result = renderToString(qweb, "test");
|
||||||
@@ -812,14 +818,14 @@ describe("t-call (template calling", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("with used body", () => {
|
test("with used body", () => {
|
||||||
qweb.addTemplate("_callee-printsbody", '<h1><t t-esc="0"/></h1>');
|
qweb.addTemplate("_callee-printsbody", '<h1><t t-out="0"/></h1>');
|
||||||
qweb.addTemplate("caller", '<t t-call="_callee-printsbody">ok</t>');
|
qweb.addTemplate("caller", '<t t-call="_callee-printsbody">ok</t>');
|
||||||
const expected = "<h1>ok</h1>";
|
const expected = "<h1>ok</h1>";
|
||||||
expect(renderToString(qweb, "caller")).toBe(expected);
|
expect(renderToString(qweb, "caller")).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("with used set body", () => {
|
test("with used set body", () => {
|
||||||
qweb.addTemplate("_callee-uses-foo", '<t t-esc="foo"/>');
|
qweb.addTemplate("_callee-uses-foo", '<t t-out="foo"/>');
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"caller",
|
"caller",
|
||||||
`
|
`
|
||||||
@@ -830,7 +836,7 @@ describe("t-call (template calling", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("inherit context", () => {
|
test("inherit context", () => {
|
||||||
qweb.addTemplate("_callee-uses-foo", '<t t-esc="foo"/>');
|
qweb.addTemplate("_callee-uses-foo", '<t t-out="foo"/>');
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"caller",
|
"caller",
|
||||||
`
|
`
|
||||||
@@ -849,7 +855,7 @@ describe("t-call (template calling", () => {
|
|||||||
<t t-call="_basic-callee">
|
<t t-call="_basic-callee">
|
||||||
<t t-set="foo" t-value="42"/>
|
<t t-set="foo" t-value="42"/>
|
||||||
</t>
|
</t>
|
||||||
<t t-esc="foo"/>
|
<t t-out="foo"/>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
@@ -937,7 +943,7 @@ describe("t-call (template calling", () => {
|
|||||||
</t>
|
</t>
|
||||||
</div>
|
</div>
|
||||||
<div t-name="nodeTemplate">
|
<div t-name="nodeTemplate">
|
||||||
<p><t t-esc="node.val"/></p>
|
<p><t t-out="node.val"/></p>
|
||||||
<t t-foreach="node.children or []" t-as="subtree">
|
<t t-foreach="node.children or []" t-as="subtree">
|
||||||
<t t-call="nodeTemplate">
|
<t t-call="nodeTemplate">
|
||||||
<t t-set="node" t-value="subtree"/>
|
<t t-set="node" t-value="subtree"/>
|
||||||
@@ -966,7 +972,7 @@ describe("t-call (template calling", () => {
|
|||||||
</t>
|
</t>
|
||||||
</div>
|
</div>
|
||||||
<div t-name="nodeTemplate">
|
<div t-name="nodeTemplate">
|
||||||
<p><t t-esc="node.val"/></p>
|
<p><t t-out="node.val"/></p>
|
||||||
<t t-foreach="node.children or []" t-as="subtree">
|
<t t-foreach="node.children or []" t-as="subtree">
|
||||||
<t t-call="nodeTemplate">
|
<t t-call="nodeTemplate">
|
||||||
<t t-set="node" t-value="subtree"/>
|
<t t-set="node" t-value="subtree"/>
|
||||||
@@ -996,7 +1002,7 @@ describe("t-call (template calling", () => {
|
|||||||
</div>
|
</div>
|
||||||
<div t-name="nodeTemplate">
|
<div t-name="nodeTemplate">
|
||||||
<t t-set="recursive_idx" t-value="recursive_idx + 1"/>
|
<t t-set="recursive_idx" t-value="recursive_idx + 1"/>
|
||||||
<p><t t-esc="node.val"/> <t t-esc="recursive_idx"/></p>
|
<p><t t-out="node.val"/> <t t-out="recursive_idx"/></p>
|
||||||
<t t-foreach="node.children or []" t-as="subtree">
|
<t t-foreach="node.children or []" t-as="subtree">
|
||||||
<t t-call="nodeTemplate">
|
<t t-call="nodeTemplate">
|
||||||
<t t-set="node" t-value="subtree"/>
|
<t t-set="node" t-value="subtree"/>
|
||||||
@@ -1027,7 +1033,7 @@ describe("t-call (template calling", () => {
|
|||||||
|
|
||||||
test("t-call, conditional and t-set in t-call body", () => {
|
test("t-call, conditional and t-set in t-call body", () => {
|
||||||
QWeb.registerTemplate("callee1", "<div>callee1</div>");
|
QWeb.registerTemplate("callee1", "<div>callee1</div>");
|
||||||
QWeb.registerTemplate("callee2", '<div>callee2 <t t-esc="v"/></div>');
|
QWeb.registerTemplate("callee2", '<div>callee2 <t t-out="v"/></div>');
|
||||||
QWeb.registerTemplate(
|
QWeb.registerTemplate(
|
||||||
"caller",
|
"caller",
|
||||||
`<div>
|
`<div>
|
||||||
@@ -1054,7 +1060,7 @@ describe("t-call (template calling", () => {
|
|||||||
</t>
|
</t>
|
||||||
</div>
|
</div>
|
||||||
<t t-name="sub">
|
<t t-name="sub">
|
||||||
<span t-esc="val3"/>
|
<span t-out="val3"/>
|
||||||
</t>
|
</t>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
@@ -1075,8 +1081,8 @@ describe("t-call (template calling", () => {
|
|||||||
</t>
|
</t>
|
||||||
</div>
|
</div>
|
||||||
<t t-name="sub">
|
<t t-name="sub">
|
||||||
<span t-esc="val3"/>
|
<span t-out="val3"/>
|
||||||
<t t-esc="w"/>
|
<t t-out="w"/>
|
||||||
</t>
|
</t>
|
||||||
<p t-name="wrapper"><t t-set="w" t-value="'fromwrapper'"/><t t-call="main"/></p>
|
<p t-name="wrapper"><t t-set="w" t-value="'fromwrapper'"/><t t-call="main"/></p>
|
||||||
</templates>
|
</templates>
|
||||||
@@ -1099,7 +1105,7 @@ describe("t-call (template calling", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("t-call with t-set inside and body text content", () => {
|
test("t-call with t-set inside and body text content", () => {
|
||||||
qweb.addTemplate("sub", `<p><t t-esc="val"/></p>`);
|
qweb.addTemplate("sub", `<p><t t-out="val"/></p>`);
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"main",
|
"main",
|
||||||
`
|
`
|
||||||
@@ -1121,8 +1127,8 @@ describe("t-call (template calling", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("dynamic t-call", () => {
|
test("dynamic t-call", () => {
|
||||||
qweb.addTemplate("foo", `<foo><t t-esc="val"/></foo>`);
|
qweb.addTemplate("foo", `<foo><t t-out="val"/></foo>`);
|
||||||
qweb.addTemplate("bar", `<bar><t t-esc="val"/></bar>`);
|
qweb.addTemplate("bar", `<bar><t t-out="val"/></bar>`);
|
||||||
qweb.addTemplate("main", `<div><t t-call="{{template}}"/></div>`);
|
qweb.addTemplate("main", `<div><t t-call="{{template}}"/></div>`);
|
||||||
const expected = "<div><foo>foo</foo></div>";
|
const expected = "<div><foo>foo</foo></div>";
|
||||||
expect(renderToString(qweb, "main", { template: "foo", val: "foo" })).toBe(expected);
|
expect(renderToString(qweb, "main", { template: "foo", val: "foo" })).toBe(expected);
|
||||||
@@ -1141,7 +1147,7 @@ describe("foreach", () => {
|
|||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="[3, 2, 1]" t-as="item">
|
<t t-foreach="[3, 2, 1]" t-as="item">
|
||||||
[<t t-esc="item_index"/>: <t t-esc="item"/> <t t-esc="item_value"/>]
|
[<t t-out="item_index"/>: <t t-out="item"/> <t t-out="item_value"/>]
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -1155,7 +1161,7 @@ describe("foreach", () => {
|
|||||||
"test",
|
"test",
|
||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<span t-foreach="[1, 2]" t-as="item" t-key="item"><t t-esc="item"/></span>
|
<span t-foreach="[1, 2]" t-as="item" t-key="item"><t t-out="item"/></span>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
const result = trim(renderToString(qweb, "test"));
|
const result = trim(renderToString(qweb, "test"));
|
||||||
@@ -1169,7 +1175,7 @@ describe("foreach", () => {
|
|||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="Array(5)" t-as="elem">
|
<t t-foreach="Array(5)" t-as="elem">
|
||||||
-<t t-if="elem_first"> first</t><t t-if="elem_last"> last</t> (<t t-esc="elem_index"/>)
|
-<t t-if="elem_first"> first</t><t t-if="elem_last"> last</t> (<t t-out="elem_index"/>)
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -1184,7 +1190,7 @@ describe("foreach", () => {
|
|||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="value" t-as="item">
|
<t t-foreach="value" t-as="item">
|
||||||
[<t t-esc="item_index"/>: <t t-esc="item"/> <t t-esc="item_value"/>]
|
[<t t-out="item_index"/>: <t t-out="item"/> <t t-out="item_value"/>]
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -1197,7 +1203,7 @@ describe("foreach", () => {
|
|||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"test",
|
"test",
|
||||||
`<div>
|
`<div>
|
||||||
<t t-foreach="[1]" t-as="item"><t t-esc="item"/></t>
|
<t t-foreach="[1]" t-as="item"><t t-out="item"/></t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
const context = { __owl__: {} };
|
const context = { __owl__: {} };
|
||||||
@@ -1211,7 +1217,7 @@ describe("foreach", () => {
|
|||||||
`<div>
|
`<div>
|
||||||
<t t-foreach="numbers" t-as="number">
|
<t t-foreach="numbers" t-as="number">
|
||||||
<t t-foreach="letters" t-as="letter">
|
<t t-foreach="letters" t-as="letter">
|
||||||
[<t t-esc="number"/><t t-esc="letter"/>]
|
[<t t-out="number"/><t t-out="letter"/>]
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
@@ -1227,9 +1233,9 @@ describe("foreach", () => {
|
|||||||
"test_called",
|
"test_called",
|
||||||
`<t>
|
`<t>
|
||||||
<t t-set="c" t-value="'x' + '_' + a + '_'+ b" />
|
<t t-set="c" t-value="'x' + '_' + a + '_'+ b" />
|
||||||
[<t t-esc="a" />]
|
[<t t-out="a" />]
|
||||||
[<t t-esc="b" />]
|
[<t t-out="b" />]
|
||||||
[<t t-esc="c" />]
|
[<t t-out="c" />]
|
||||||
</t>`
|
</t>`
|
||||||
);
|
);
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
@@ -1239,9 +1245,9 @@ describe("foreach", () => {
|
|||||||
<t t-foreach="letters" t-as="b">
|
<t t-foreach="letters" t-as="b">
|
||||||
<t t-call="test_called" />
|
<t t-call="test_called" />
|
||||||
</t>
|
</t>
|
||||||
<span t-esc="c"/>
|
<span t-out="c"/>
|
||||||
</t>
|
</t>
|
||||||
<span>[<t t-esc="a" />][<t t-esc="b" />][<t t-esc="c" />]</span>
|
<span>[<t t-out="a" />][<t t-out="b" />][<t t-out="c" />]</span>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
const context = { numbers: [1, 2, 3], letters: ["a", "b"] };
|
const context = { numbers: [1, 2, 3], letters: ["a", "b"] };
|
||||||
@@ -1254,9 +1260,9 @@ describe("foreach", () => {
|
|||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"test_called",
|
"test_called",
|
||||||
`<t>
|
`<t>
|
||||||
[<t t-esc="a" />]
|
[<t t-out="a" />]
|
||||||
[<t t-esc="b" />]
|
[<t t-out="b" />]
|
||||||
[<t t-esc="c" />]
|
[<t t-out="c" />]
|
||||||
</t>`
|
</t>`
|
||||||
);
|
);
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
@@ -1268,9 +1274,9 @@ describe("foreach", () => {
|
|||||||
<t t-set="c" t-value="'x' + '_' + a + '_'+ b" />
|
<t t-set="c" t-value="'x' + '_' + a + '_'+ b" />
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
<span t-esc="c"/>
|
<span t-out="c"/>
|
||||||
</t>
|
</t>
|
||||||
<span>[<t t-esc="a" />][<t t-esc="b" />][<t t-esc="c" />]</span>
|
<span>[<t t-out="a" />][<t t-out="b" />][<t t-out="c" />]</span>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
const context = { numbers: [1, 2, 3], letters: ["a", "b"] };
|
const context = { numbers: [1, 2, 3], letters: ["a", "b"] };
|
||||||
@@ -1296,7 +1302,7 @@ describe("foreach", () => {
|
|||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="[1, 2]" t-as="item">
|
<t t-foreach="[1, 2]" t-as="item">
|
||||||
<span><t t-esc="item"/></span>
|
<span><t t-out="item"/></span>
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -1312,14 +1318,14 @@ describe("foreach", () => {
|
|||||||
describe("misc", () => {
|
describe("misc", () => {
|
||||||
test("global", () => {
|
test("global", () => {
|
||||||
qweb.addTemplate("_callee-asc", `<año t-att-falló="'agüero'" t-raw="0"/>`);
|
qweb.addTemplate("_callee-asc", `<año t-att-falló="'agüero'" t-raw="0"/>`);
|
||||||
qweb.addTemplate("_callee-uses-foo", `<span t-esc="foo">foo default</span>`);
|
qweb.addTemplate("_callee-uses-foo", `<span t-out="foo">foo default</span>`);
|
||||||
qweb.addTemplate("_callee-asc-toto", `<div t-raw="toto">toto default</div>`);
|
qweb.addTemplate("_callee-asc-toto", `<div t-raw="toto">toto default</div>`);
|
||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"caller",
|
"caller",
|
||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="[4,5,6]" t-as="value">
|
<t t-foreach="[4,5,6]" t-as="value">
|
||||||
<span t-esc="value"/>
|
<span t-out="value"/>
|
||||||
<t t-call="_callee-asc">
|
<t t-call="_callee-asc">
|
||||||
<t t-call="_callee-uses-foo">
|
<t t-call="_callee-uses-foo">
|
||||||
<t t-set="foo" t-value="'aaa'"/>
|
<t t-set="foo" t-value="'aaa'"/>
|
||||||
@@ -1719,7 +1725,7 @@ describe("t-on", () => {
|
|||||||
`<div>
|
`<div>
|
||||||
<t t-foreach="projects" t-as="project">
|
<t t-foreach="projects" t-as="project">
|
||||||
<a href="#" t-key="project" t-on-click.prevent="onEdit(project.id)">
|
<a href="#" t-key="project" t-on-click.prevent="onEdit(project.id)">
|
||||||
Edit <t t-esc="project.name"/>
|
Edit <t t-out="project.name"/>
|
||||||
</a>
|
</a>
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
@@ -1767,9 +1773,9 @@ describe("t-on", () => {
|
|||||||
button.click();
|
button.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-on combined with t-esc", async () => {
|
test("t-on combined with t-out", async () => {
|
||||||
expect.assertions(3);
|
expect.assertions(3);
|
||||||
qweb.addTemplate("test", `<div><button t-on-click="onClick" t-esc="text"/></div>`);
|
qweb.addTemplate("test", `<div><button t-on-click="onClick" t-out="text"/></div>`);
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
const owner = {
|
const owner = {
|
||||||
text: "Click here",
|
text: "Click here",
|
||||||
@@ -1852,7 +1858,7 @@ describe("t-ref", () => {
|
|||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="items" t-as="item">
|
<t t-foreach="items" t-as="item">
|
||||||
<div t-ref="{{item}}" t-key="item"><t t-esc="item"/></div>
|
<div t-ref="{{item}}" t-key="item"><t t-out="item"/></div>
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -2038,7 +2044,7 @@ describe("whitespace handling", () => {
|
|||||||
|
|
||||||
describe("t-key", () => {
|
describe("t-key", () => {
|
||||||
test("can use t-key directive on a node", () => {
|
test("can use t-key directive on a node", () => {
|
||||||
qweb.addTemplate("test", `<div t-key="beer.id"><t t-esc="beer.name"/></div>`);
|
qweb.addTemplate("test", `<div t-key="beer.id"><t t-out="beer.name"/></div>`);
|
||||||
expect(renderToString(qweb, "test", { beer: { id: 12, name: "Chimay Rouge" } })).toBe(
|
expect(renderToString(qweb, "test", { beer: { id: 12, name: "Chimay Rouge" } })).toBe(
|
||||||
"<div>Chimay Rouge</div>"
|
"<div>Chimay Rouge</div>"
|
||||||
);
|
);
|
||||||
@@ -2048,7 +2054,7 @@ describe("t-key", () => {
|
|||||||
qweb.addTemplate(
|
qweb.addTemplate(
|
||||||
"test",
|
"test",
|
||||||
`<ul>
|
`<ul>
|
||||||
<li t-foreach="beers" t-as="beer" t-key="beer.id"><t t-esc="beer.name"/></li>
|
<li t-foreach="beers" t-as="beer" t-key="beer.id"><t t-out="beer.name"/></li>
|
||||||
</ul>`
|
</ul>`
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { QWeb } from "../../src/qweb/index";
|
||||||
|
import { renderToString } from "../helpers";
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Setup and helpers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// We create before each test:
|
||||||
|
// - qweb: a new QWeb instance
|
||||||
|
|
||||||
|
let qweb: QWeb;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
QWeb.TEMPLATES = {};
|
||||||
|
QWeb.nextId = 1;
|
||||||
|
qweb = new QWeb();
|
||||||
|
});
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
describe("old t-esc directive", () => {
|
||||||
|
test("simple dynamic value", () => {
|
||||||
|
qweb.addTemplate("test", '<t><t t-esc="text"/></t>');
|
||||||
|
expect(renderToString(qweb, "test", { text: "hello vdom" })).toBe("hello vdom");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("escaping", () => {
|
||||||
|
qweb.addTemplate("test", `<span><t t-esc="var"/></span>`);
|
||||||
|
expect(renderToString(qweb, "test", { var: "<ok>abc</ok>" })).toBe(
|
||||||
|
"<span>&lt;ok&gt;abc&lt;/ok&gt;</span>"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("old t-raw directive", () => {
|
||||||
|
test("literal", () => {
|
||||||
|
qweb.addTemplate("test", `<span><t t-raw="'ok'"/></span>`);
|
||||||
|
expect(renderToString(qweb, "test")).toBe("<span>ok</span>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("variable", () => {
|
||||||
|
qweb.addTemplate("test", `<span><t t-raw="var"/></span>`);
|
||||||
|
expect(renderToString(qweb, "test", { var: "ok" })).toBe("<span>ok</span>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("not escaping", () => {
|
||||||
|
qweb.addTemplate("test", `<div><t t-raw="var"/></div>`);
|
||||||
|
expect(renderToString(qweb, "test", { var: "<ok></ok>" })).toBe("<div><ok></ok></div>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-raw and another sibling node", () => {
|
||||||
|
qweb.addTemplate("test", `<span><span>hello</span><t t-raw="var"/></span>`);
|
||||||
|
expect(renderToString(qweb, "test", { var: "<ok>world</ok>" })).toBe(
|
||||||
|
"<span><span>hello</span><ok>world</ok></span>"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-raw with comment", () => {
|
||||||
|
qweb.addTemplate("test", `<span><t t-raw="var"/></span>`);
|
||||||
|
expect(renderToString(qweb, "test", { var: "<p>text<!-- top secret --></p>" })).toBe(
|
||||||
|
"<span><p>text<!-- top secret --></p></span>"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user