mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
wip
This commit is contained in:
+61
-41
@@ -44,50 +44,70 @@ 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) {
|
if (ctx.parentTextNode) {
|
||||||
let protectID;
|
ctx.addIf(`${exprID} != null`);
|
||||||
if (value.hasBody) {
|
ctx.addLine(`vn${ctx.parentTextNode}.text += ${exprID};`);
|
||||||
ctx.rootContext.shouldDefineUtils = true;
|
ctx.closeIf();
|
||||||
protectID = ctx.startProtectScope();
|
} else if (ctx.parentNode) {
|
||||||
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) {
|
ctx.addLine(`insertValue(c${ctx.parentNode}, ${exprID})`);
|
||||||
ctx.addLine(
|
} else {
|
||||||
`const vnodeArray = ${exprID} instanceof utils.VDomArray ? ${exprID} : utils.htmlToVDOM(${exprID});`
|
ctx.addIf(`${exprID} != null`);
|
||||||
);
|
|
||||||
ctx.addLine(`c${ctx.parentNode}.push(...vnodeArray);`);
|
|
||||||
} else {
|
|
||||||
ctx.addLine(`c${ctx.parentNode}.push(...utils.htmlToVDOM(${exprID}));`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (node.childNodes.length) {
|
|
||||||
ctx.addElse();
|
|
||||||
qweb._compileChildren(node, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.closeIf();
|
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();
|
||||||
|
}
|
||||||
|
// 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}));`);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (node.childNodes.length) {
|
||||||
|
// ctx.addElse();
|
||||||
|
// qweb._compileChildren(node, ctx);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ctx.closeIf();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWeb.addDirective({
|
QWeb.addDirective({
|
||||||
|
|||||||
@@ -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-out" || 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",
|
||||||
|
|||||||
+42
-47
@@ -102,68 +102,63 @@ export function shallowEqual(p1, p2): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const escapeMethod = Symbol('html')
|
|
||||||
|
|
||||||
// notable issues:
|
// notable issues:
|
||||||
// * objects can't be negative in JS, so !!"" -> false but
|
// * objects can't be negative in JS, so !!"" -> false but
|
||||||
// !!(new String) -> true, likewise markup
|
// !!(new String) -> true, likewise markup
|
||||||
// TODO (?)
|
// TODO (?)
|
||||||
// * Markup.join / Markup#join => escapes items and returns a Markup
|
// * Markup.join / Markup#join => escapes items and returns a Markup
|
||||||
// * Markup#replace => automatically escapes the replacements (difficult impl)
|
// * Markup#replace => automatically escapes the replacements (difficult impl)
|
||||||
class _Markup extends String {
|
export class _Markup extends String {}
|
||||||
[escapeMethod]() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a markup object, which acts like a String but is considered safe by
|
* Returns a markup object, which acts like a String but is considered safe by
|
||||||
* `_.escape`, and will therefore be injected as-is (without additional
|
* `_.escape`, and will therefore be injected as-is (without additional
|
||||||
* escaping) in templates. Can be used to inject dynamic HTML in templates
|
* escaping) in templates. Can be used to inject dynamic HTML in templates
|
||||||
* (where the template itself can't), see first example.
|
* (where the template itself can't), see first example.
|
||||||
*
|
*
|
||||||
* Can also be used as a *template tag*, in which case the literal content
|
* 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
|
* won't be escaped but the substitutions which are not already markup objects
|
||||||
* will be.
|
* will be.
|
||||||
*
|
*
|
||||||
* ## WARNINGS:
|
* ## WARNINGS:
|
||||||
* * A markup object is a `String` (boxed) but not a `string` (primitive), they
|
* * A markup object is a `String` (boxed) but not a `string` (primitive), they
|
||||||
* typecheck differently which can be relevant.
|
* typecheck differently which can be relevant.
|
||||||
* * To strip out the "markupness", just call `String(markup)`.
|
* * To strip out the "markupness", just call `String(markup)`.
|
||||||
* * Most string operations (e.g. concatenation, `String#replace`, ...) will
|
* * Most string operations (e.g. concatenation, `String#replace`, ...) will
|
||||||
* also strip out markupness
|
* also strip out markupness
|
||||||
* * If the input is empty, returns a regular string (that way boolean tests
|
* * If the input is empty, returns a regular string (that way boolean tests
|
||||||
* work as expected).
|
* work as expected).
|
||||||
*
|
*
|
||||||
* @returns a markup object
|
* @returns a markup object
|
||||||
*
|
*
|
||||||
* @example regular function
|
* @example regular function
|
||||||
* let h;
|
* let h;
|
||||||
* if (someTest) {
|
* if (someTest) {
|
||||||
* h = Markup(_t("This is a <strong>success</strong>"));
|
* h = Markup(_t("This is a <strong>success</strong>"));
|
||||||
* } else {
|
* } else {
|
||||||
* h = Markup(_t("Things did <strong>not</strong> work out"));
|
* h = Markup(_t("Things did <strong>not</strong> work out"));
|
||||||
* }
|
* }
|
||||||
* qweb.render("some_template", { message: h });
|
* qweb.render("some_template", { message: h });
|
||||||
*
|
*
|
||||||
* @example template tag
|
* @example template tag
|
||||||
* const escaped = "<some> text";
|
* const escaped = "<some> text";
|
||||||
* const asis = Markup`some <b>text</b>`;
|
* const asis = Markup`some <b>text</b>`;
|
||||||
* const h = Markup`Regular strings get ${escaped} but markup is injected ${asis}`;
|
* const h = Markup`Regular strings get ${escaped} but markup is injected ${asis}`;
|
||||||
*/
|
*/
|
||||||
export function Markup(v, ...exprs) {
|
export function Markup(v, ...exprs) {
|
||||||
if (!(v instanceof Array)) {
|
if (!(v instanceof Array)) {
|
||||||
return v ? new _Markup(v) : '';
|
return v ? new _Markup(v) : "";
|
||||||
}
|
}
|
||||||
const elements = [];
|
const elements = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for(; i < exprs.length; ++i) {
|
for (; i < exprs.length; ++i) {
|
||||||
elements.push(v[i], escape(exprs[i]));
|
elements.push(v[i], escape(exprs[i]));
|
||||||
}
|
}
|
||||||
elements.push(v[i]);
|
elements.push(v[i]);
|
||||||
|
|
||||||
const s = elements.join('');
|
const s = elements.join("");
|
||||||
if (!s) { return '' }
|
if (!s) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return new _Markup(s);
|
return new _Markup(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3064,14 +3064,14 @@ exports[`t-out (formerly t-raw tests) not escaping 1`] = `
|
|||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
// Template name: \\"test\\"
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let insertValue = utils.insertValue;
|
||||||
let scope = Object.create(context);
|
let scope = Object.create(context);
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
let _2 = scope['var'];
|
let _2 = scope['var'];
|
||||||
if (_2 != null) {
|
insertValue(c1, _2)
|
||||||
c1.push({text: _2});
|
|
||||||
}
|
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -3181,14 +3181,14 @@ exports[`t-out escaping 1`] = `
|
|||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
// Template name: \\"test\\"
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let insertValue = utils.insertValue;
|
||||||
let scope = Object.create(context);
|
let scope = Object.create(context);
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('span', p1, c1);
|
let vn1 = h('span', p1, c1);
|
||||||
let _2 = scope['var'];
|
let _2 = scope['var'];
|
||||||
if (_2 != null) {
|
insertValue(c1, _2)
|
||||||
c1.push({text: _2});
|
|
||||||
}
|
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -3197,14 +3197,14 @@ exports[`t-out escaping on a node 1`] = `
|
|||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
// Template name: \\"test\\"
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let insertValue = utils.insertValue;
|
||||||
let scope = Object.create(context);
|
let scope = Object.create(context);
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('span', p1, c1);
|
let vn1 = h('span', p1, c1);
|
||||||
let _2 = 'ok';
|
let _2 = 'ok';
|
||||||
if (_2 != null) {
|
insertValue(c1, _2)
|
||||||
c1.push({text: _2});
|
|
||||||
}
|
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -3213,16 +3213,14 @@ exports[`t-out escaping on a node with a body 1`] = `
|
|||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
// Template name: \\"test\\"
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let insertValue = utils.insertValue;
|
||||||
let scope = Object.create(context);
|
let scope = Object.create(context);
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('span', p1, c1);
|
let vn1 = h('span', p1, c1);
|
||||||
let _2 = 'ok';
|
let _2 = 'ok';
|
||||||
if (_2 != null) {
|
insertValue(c1, _2)
|
||||||
c1.push({text: _2});
|
|
||||||
} else {
|
|
||||||
c1.push({text: \`nope\`});
|
|
||||||
}
|
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -3231,16 +3229,14 @@ exports[`t-out escaping on a node with a body, as a default 1`] = `
|
|||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
// Template name: \\"test\\"
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let insertValue = utils.insertValue;
|
||||||
let scope = Object.create(context);
|
let scope = Object.create(context);
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('span', p1, c1);
|
let vn1 = h('span', p1, c1);
|
||||||
let _2 = scope['var'];
|
let _2 = scope['var'];
|
||||||
if (_2 != null) {
|
insertValue(c1, _2)
|
||||||
c1.push({text: _2});
|
|
||||||
} else {
|
|
||||||
c1.push({text: \`nope\`});
|
|
||||||
}
|
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -3249,14 +3245,14 @@ exports[`t-out literal 1`] = `
|
|||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
// Template name: \\"test\\"
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let insertValue = utils.insertValue;
|
||||||
let scope = Object.create(context);
|
let scope = Object.create(context);
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('span', p1, c1);
|
let vn1 = h('span', p1, c1);
|
||||||
let _2 = 'ok';
|
let _2 = 'ok';
|
||||||
if (_2 != null) {
|
insertValue(c1, _2)
|
||||||
c1.push({text: _2});
|
|
||||||
}
|
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -3357,14 +3353,14 @@ exports[`t-out variable 1`] = `
|
|||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
// Template name: \\"test\\"
|
// Template name: \\"test\\"
|
||||||
|
let utils = this.constructor.utils;
|
||||||
|
let insertValue = utils.insertValue;
|
||||||
let scope = Object.create(context);
|
let scope = Object.create(context);
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('span', p1, c1);
|
let vn1 = h('span', p1, c1);
|
||||||
let _2 = scope['var'];
|
let _2 = scope['var'];
|
||||||
if (_2 != null) {
|
insertValue(c1, _2)
|
||||||
c1.push({text: _2});
|
|
||||||
}
|
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ describe("error handling", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("t-out", () => {
|
describe.only("t-out", () => {
|
||||||
test("literal", () => {
|
test("literal", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-out="'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>");
|
||||||
@@ -178,7 +178,7 @@ describe("t-out", () => {
|
|||||||
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.only("escaping on a node with a body, as a default", () => {
|
||||||
qweb.addTemplate("test", `<span t-out="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>");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,36 +32,35 @@ describe("old t-esc directive", () => {
|
|||||||
"<span>&lt;ok&gt;abc&lt;/ok&gt;</span>"
|
"<span>&lt;ok&gt;abc&lt;/ok&gt;</span>"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("old t-raw directive", () => {
|
describe("old t-raw directive", () => {
|
||||||
test("literal", () => {
|
test("literal", () => {
|
||||||
qweb.addTemplate("test", `<span><t t-raw="'ok'"/></span>`);
|
qweb.addTemplate("test", `<span><t t-raw="'ok'"/></span>`);
|
||||||
expect(renderToString(qweb, "test")).toBe("<span>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>"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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