mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] qweb/component: refactoring of scoping/variables/slots
This commit is a significant refactoring of the internal of QWeb. It simplifies the way variables/scoping and slots interact together. The main idea is that we use a simple scope object instead of a context/var/scope object. This commit also implement the actual correct QWeb semantic for the t-call directive with a sub body. Before, we simply extracted the variables from the body and injected them at the top of the sub template. We now simply compile the body before the sub template. This is a joint work with Lucas (lpe). closes #541 closes #544 closes #545 closes #557 closes #556
This commit is contained in:
+89
-3
@@ -278,6 +278,21 @@ describe("t-set", () => {
|
||||
expect(renderToString(qweb, "test", { flag: true })).toBe("<div>1</div>");
|
||||
expect(renderToString(qweb, "test", { flag: false })).toBe("<div>0</div>");
|
||||
});
|
||||
|
||||
test("t-set body is evaluated immediately", () => {
|
||||
qweb.addTemplate(
|
||||
"test",
|
||||
`<div>
|
||||
<t t-set="v1" t-value="'before'"/>
|
||||
<t t-set="v2">
|
||||
<span><t t-esc="v1"/></span>
|
||||
</t>
|
||||
<t t-set="v1" t-value="'after'"/>
|
||||
<t t-raw="v2"/>
|
||||
</div>`);
|
||||
|
||||
expect(renderToString(qweb, "test")).toBe("<div><span>before</span></div>");
|
||||
});
|
||||
});
|
||||
|
||||
describe("t-if", () => {
|
||||
@@ -598,10 +613,19 @@ describe("attributes", () => {
|
||||
|
||||
describe("t-call (template calling", () => {
|
||||
test("basic caller", () => {
|
||||
qweb.addTemplate("_basic-callee", "<span>ok</span>");
|
||||
qweb.addTemplate("caller", '<div><t t-call="_basic-callee"/></div>');
|
||||
const expected = "<div><span>ok</span></div>";
|
||||
expect(renderToString(qweb, "caller")).toBe(expected);
|
||||
expect(qweb.subTemplates["_basic-callee"].toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("basic caller, no parent node", () => {
|
||||
qweb.addTemplate("_basic-callee", "<div>ok</div>");
|
||||
qweb.addTemplate("caller", '<t t-call="_basic-callee"/>');
|
||||
const expected = "<div>ok</div>";
|
||||
expect(renderToString(qweb, "caller")).toBe(expected);
|
||||
expect(qweb.subTemplates["_basic-callee"].toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-call with t-if", () => {
|
||||
@@ -609,6 +633,7 @@ describe("t-call (template calling", () => {
|
||||
qweb.addTemplate("caller", '<div><t t-if="flag" t-call="sub"/></div>');
|
||||
const expected = "<div><span>ok</span></div>";
|
||||
expect(renderToString(qweb, "caller", { flag: true })).toBe(expected);
|
||||
expect(qweb.subTemplates["sub"].toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-call not allowed on a non t node", () => {
|
||||
@@ -693,6 +718,7 @@ describe("t-call (template calling", () => {
|
||||
`);
|
||||
const expected = "<div><div><span>hey</span> <span>yay</span></div></div>";
|
||||
expect(renderToString(qweb, "main")).toBe(expected);
|
||||
expect(qweb.subTemplates["SubTemplate"].toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("cascading t-call t-raw='0'", () => {
|
||||
@@ -742,7 +768,7 @@ describe("t-call (template calling", () => {
|
||||
`);
|
||||
const expected = "<div><span>hey</span></div>";
|
||||
expect(renderToString(qweb, "recursive")).toBe(expected);
|
||||
const recursiveFn = Object.values(qweb.recursiveFns)[0] as any;
|
||||
const recursiveFn = Object.values(qweb.subTemplates)[0] as any;
|
||||
expect(recursiveFn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -770,7 +796,7 @@ describe("t-call (template calling", () => {
|
||||
expect(renderToString(qweb, "Parent", { root }, { fiber: { vars: {}, scope: {} } })).toBe(
|
||||
expected
|
||||
);
|
||||
const recursiveFn = Object.values(qweb.recursiveFns)[0] as any;
|
||||
const recursiveFn = Object.values(qweb.subTemplates)[0] as any;
|
||||
expect(recursiveFn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -797,7 +823,7 @@ describe("t-call (template calling", () => {
|
||||
const expected =
|
||||
"<div><div><p>a</p><div><p>b</p><div><p>d</p></div></div><div><p>c</p></div></div></div>";
|
||||
expect(renderToString(qweb, "Parent", { root }, { fiber: {} })).toBe(expected);
|
||||
const recursiveFn = Object.values(qweb.recursiveFns)[0] as any;
|
||||
const recursiveFn = Object.values(qweb.subTemplates)[0] as any;
|
||||
expect(recursiveFn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -807,6 +833,51 @@ describe("t-call (template calling", () => {
|
||||
const expected = "<div><span>desk</span></div>";
|
||||
expect(trim(renderToString(qweb, "abcd"))).toBe(expected);
|
||||
});
|
||||
|
||||
test("t-call with t-set inside and outside", () => {
|
||||
qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="main">
|
||||
<t t-foreach="list" t-as="v">
|
||||
<t t-set="val" t-value="v.val"/>
|
||||
<t t-call="sub">
|
||||
<t t-set="val3" t-value="val*3"/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<t t-name="sub">
|
||||
<span t-esc="val3"/>
|
||||
</t>
|
||||
</templates>
|
||||
`);
|
||||
const expected = "<div><span>3</span><span>6</span><span>9</span></div>";
|
||||
const context = { list: [{ val: 1 }, { val: 2 }, { val: 3 }] };
|
||||
expect(trim(renderToString(qweb, "main", context))).toBe(expected);
|
||||
});
|
||||
|
||||
test("t-call with t-set inside and outside. 2", () => {
|
||||
qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="main">
|
||||
<t t-foreach="list" t-as="v">
|
||||
<t t-set="val" t-value="v.val"/>
|
||||
<t t-call="sub">
|
||||
<t t-set="val3" t-value="val*3"/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<t t-name="sub">
|
||||
<span t-esc="val3"/>
|
||||
<t t-esc="w"/>
|
||||
</t>
|
||||
<p t-name="wrapper"><t t-set="w" t-value="'fromwrapper'"/><t t-call="main"/></p>
|
||||
</templates>
|
||||
`);
|
||||
const expected =
|
||||
"<p><div><span>3</span>fromwrapper<span>6</span>fromwrapper<span>9</span>fromwrapper</div></p>";
|
||||
const context = { list: [{ val: 1 }, { val: 2 }, { val: 3 }] };
|
||||
expect(trim(renderToString(qweb, "wrapper", context))).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("foreach", () => {
|
||||
@@ -1536,6 +1607,21 @@ describe("debugging", () => {
|
||||
console.log = consoleLog;
|
||||
});
|
||||
|
||||
test("t-debug on sub template", () => {
|
||||
const consoleLog = console.log;
|
||||
console.log = jest.fn();
|
||||
qweb.addTemplates(`
|
||||
<p t-name="sub" t-debug="1">coucou</p>
|
||||
<div t-name="test">
|
||||
<t t-call="sub"/>
|
||||
</div>`
|
||||
);
|
||||
qweb.render("test");
|
||||
|
||||
expect(console.log).toHaveBeenCalledTimes(1);
|
||||
console.log = consoleLog;
|
||||
});
|
||||
|
||||
test("t-log", () => {
|
||||
const consoleLog = console.log;
|
||||
console.log = jest.fn();
|
||||
|
||||
Reference in New Issue
Block a user