mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] app, compiler: introduce t-out
t-out automatically escaped content when it is a string not marked with the `markup` function t-out renders the raw content if it is a Block, or if it has been marked with the `markup` funtion. t-esc has been kept since it is safe and is optimized to render text nodes. all t-raw calls are in fact the same as t-out.
This commit is contained in:
committed by
Aaron Bohy
parent
1761af9c24
commit
b902edc1be
@@ -0,0 +1,239 @@
|
||||
import {
|
||||
renderToString,
|
||||
renderToBdom,
|
||||
snapshotEverything,
|
||||
TestContext,
|
||||
makeTestFixture,
|
||||
} from "../helpers";
|
||||
import { mount, patch } from "../../src/blockdom";
|
||||
import { createBlock } from "../../src/blockdom/index";
|
||||
import { markup } from "../../src/utils";
|
||||
|
||||
snapshotEverything();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// t-out
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
describe("t-out", () => {
|
||||
let fixture: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = makeTestFixture();
|
||||
});
|
||||
|
||||
test("literal", () => {
|
||||
const template = `<span><t t-out="'ok'"/></span>`;
|
||||
expect(renderToString(template)).toBe("<span>ok</span>");
|
||||
});
|
||||
|
||||
test("literal, no outside html element", () => {
|
||||
const template = `<t t-out="'ok'"/>`;
|
||||
expect(renderToString(template)).toBe("ok");
|
||||
});
|
||||
|
||||
test("variable", () => {
|
||||
const template = `<span><t t-out="var"/></span>`;
|
||||
expect(renderToString(template, { var: "ok" })).toBe("<span>ok</span>");
|
||||
});
|
||||
|
||||
test("not escaping", () => {
|
||||
const template = `<div><t t-out="var"/></div>`;
|
||||
expect(renderToString(template, { var: markup("<ok></ok>") })).toBe("<div><ok></ok></div>");
|
||||
});
|
||||
|
||||
test("t-out and another sibling node", () => {
|
||||
const template = `<span><span>hello</span><t t-out="var"/></span>`;
|
||||
expect(renderToString(template, { var: markup("<ok>world</ok>") })).toBe(
|
||||
"<span><span>hello</span><ok>world</ok></span>"
|
||||
);
|
||||
});
|
||||
|
||||
test("t-out with comment", () => {
|
||||
const template = `<span><t t-out="var"/></span>`;
|
||||
expect(renderToString(template, { var: markup("<p>text<!-- top secret --></p>") })).toBe(
|
||||
"<span><p>text<!-- top secret --></p></span>"
|
||||
);
|
||||
});
|
||||
|
||||
test("t-out on a node with a body, as a default", () => {
|
||||
const template = `<span t-out="var">nope</span>`;
|
||||
expect(renderToString(template)).toBe("<span>nope</span>");
|
||||
});
|
||||
|
||||
test("t-out with a <t/> in body", () => {
|
||||
const template = `<t t-out="var"><t></t></t>`;
|
||||
expect(renderToString(template, { var: "coucou" })).toBe("coucou");
|
||||
});
|
||||
|
||||
test("t-out with just a t-set t-value in body", () => {
|
||||
const template = `<t t-out="var"><t t-set="a" t-value="1" /></t>`;
|
||||
expect(renderToString(template, { var: "coucou" })).toBe("coucou");
|
||||
});
|
||||
|
||||
test("t-out on a node with a dom node in body, as a default", () => {
|
||||
const template = `<span t-out="var"><div>nope</div></span>`;
|
||||
expect(renderToString(template)).toBe("<span><div>nope</div></span>");
|
||||
});
|
||||
|
||||
test("multiple calls to t-out", () => {
|
||||
const context = new TestContext();
|
||||
const sub = `
|
||||
<div>
|
||||
<t t-out="0"/>
|
||||
<div>Greeter</div>
|
||||
<t t-out="0"/>
|
||||
</div>`;
|
||||
|
||||
const main = `
|
||||
<div>
|
||||
<t t-call="sub">
|
||||
<span>coucou</span>
|
||||
</t>
|
||||
</div>`;
|
||||
|
||||
context.addTemplate("sub", sub);
|
||||
context.addTemplate("main", main);
|
||||
const expected =
|
||||
"<div><div><span>coucou</span><div>Greeter</div><span>coucou</span></div></div>";
|
||||
expect(context.renderToString("main")).toBe(expected);
|
||||
});
|
||||
|
||||
test("t-out escaped", () => {
|
||||
const template = `<span t-out="var" />`;
|
||||
expect(renderToString(template, { var: "<div>nope</div>" })).toBe(
|
||||
"<span><div>nope</div></span>"
|
||||
);
|
||||
});
|
||||
|
||||
test("t-out markedup", () => {
|
||||
const template = `<span t-out="var" />`;
|
||||
expect(renderToString(template, { var: markup("<div>nope</div>") })).toBe(
|
||||
"<span><div>nope</div></span>"
|
||||
);
|
||||
});
|
||||
|
||||
test("t-out switch escaped", () => {
|
||||
const template = `<span t-out="var" />`;
|
||||
const node = renderToBdom(template, { var: "<div>nope</div>" });
|
||||
mount(node, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<span><div>nope</div></span>");
|
||||
patch(node, renderToBdom(template, { var: "<li>yep</li>" }));
|
||||
|
||||
expect(fixture.innerHTML).toBe("<span><li>yep</li></span>");
|
||||
});
|
||||
|
||||
test("t-out switch markup", () => {
|
||||
const template = `<span t-out="var" />`;
|
||||
const node = renderToBdom(template, { var: markup("<div>nope</div>") });
|
||||
mount(node, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<span><div>nope</div></span>");
|
||||
patch(node, renderToBdom(template, { var: markup("<li>yep</li>") }));
|
||||
|
||||
expect(fixture.innerHTML).toBe("<span><li>yep</li></span>");
|
||||
});
|
||||
|
||||
test("t-out switch markup on escaped", () => {
|
||||
const template = `<span t-out="var" />`;
|
||||
const node = renderToBdom(template, { var: "<div>nope</div>" });
|
||||
mount(node, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<span><div>nope</div></span>");
|
||||
patch(node, renderToBdom(template, { var: markup("<li>yep</li>") }));
|
||||
|
||||
expect(fixture.innerHTML).toBe("<span><li>yep</li></span>");
|
||||
});
|
||||
|
||||
test("t-out switch escaped on markup", () => {
|
||||
const template = `<span t-out="var" />`;
|
||||
const node = renderToBdom(template, { var: markup("<div>nope</div>") });
|
||||
mount(node, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<span><div>nope</div></span>");
|
||||
patch(node, renderToBdom(template, { var: "<li>yep</li>" }));
|
||||
|
||||
expect(fixture.innerHTML).toBe("<span><li>yep</li></span>");
|
||||
});
|
||||
|
||||
test("t-out block", () => {
|
||||
const block = createBlock("<div>block</div>");
|
||||
const template = `<span t-out="bdom"/>`;
|
||||
expect(renderToString(template, { bdom: block() })).toBe("<span><div>block</div></span>");
|
||||
});
|
||||
|
||||
test("t-out bdom", () => {
|
||||
const template = `<div><t t-set="var"><ol>set</ol></t><span t-out="var" /></div>`;
|
||||
expect(renderToString(template)).toBe("<div><span><ol>set</ol></span></div>");
|
||||
});
|
||||
|
||||
test("t-out switch markup on bdom", () => {
|
||||
const template = `<div>
|
||||
<t t-set="bdom"><ol>set</ol></t>
|
||||
<t t-if="hasBdom">
|
||||
<span t-out="bdom" />
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span t-out="var" />
|
||||
</t>
|
||||
</div>`;
|
||||
|
||||
const node = renderToBdom(template, { hasBdom: true, var: markup("<li>yep</li>") });
|
||||
mount(node, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<div><span><ol>set</ol></span></div>");
|
||||
patch(node, renderToBdom(template, { hasBdom: false, var: markup("<li>yep</li>") }));
|
||||
|
||||
expect(fixture.innerHTML).toBe("<div><span><li>yep</li></span></div>");
|
||||
});
|
||||
|
||||
test("t-out 0", () => {
|
||||
const context = new TestContext();
|
||||
context.addTemplate("_basic-callee", `<div><t t-out="0" /></div>`);
|
||||
context.addTemplate("caller", `<div><t t-call="_basic-callee"><div>zero</div></t></div>`);
|
||||
const node = context.getTemplate("caller")({}, null, "");
|
||||
mount(node, fixture);
|
||||
expect(fixture.innerHTML).toBe("<div><div><div>zero</div></div></div>");
|
||||
});
|
||||
|
||||
test("t-out with arbitrary object", () => {
|
||||
const template = `<div t-out="var" />`;
|
||||
const node = renderToBdom(template, { var: { someKey: "someValue" } });
|
||||
expect(() => mount(node, fixture)).toThrow();
|
||||
});
|
||||
|
||||
test("t-out with arbitrary object 2", () => {
|
||||
const template = `<div t-out="var" />`;
|
||||
const node = renderToBdom(template, { var: ["someValue"] });
|
||||
expect(() => mount(node, fixture)).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("t-raw is deprecated", () => {
|
||||
test("should warn", () => {
|
||||
const template = `<div t-raw="var" />`;
|
||||
const warn = console.warn;
|
||||
const steps: string[] = [];
|
||||
console.warn = (msg: any) => steps.push(msg);
|
||||
|
||||
expect(renderToString(template, { var: "<div>escaped</div>" })).toBe(
|
||||
"<div><div>escaped</div></div>"
|
||||
);
|
||||
expect(steps).toEqual([
|
||||
't-raw has been deprecated in favor of t-out. If the value to render is not wrapped by the "markup" function, it will be escaped',
|
||||
]);
|
||||
console.warn = warn;
|
||||
});
|
||||
|
||||
test("t-out is actually called in t-raw's place", () => {
|
||||
const template = `<div t-raw="var" />`;
|
||||
const warn = console.warn;
|
||||
console.warn = (msg: any) => msg;
|
||||
|
||||
expect(renderToString(template, { var: markup("<div>raw</div>") })).toBe(
|
||||
"<div><div>raw</div></div>"
|
||||
);
|
||||
console.warn = warn;
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user