mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] compiler: compile named slot in t-component in named slot
Previously, if a t-set-slot was inside a t-component itself inside a t-set-slot the parser would crash, because the slot is removed from the template before compiling its content, causing a further check's assumption to be broken (the t-set-slot remains connected to the component's xml node)
This commit is contained in:
committed by
Géry Debongnie
parent
b7c37ca69a
commit
a53e42518f
@@ -740,14 +740,14 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
|
|||||||
// be ignored)
|
// be ignored)
|
||||||
let el = slotNode.parentElement!;
|
let el = slotNode.parentElement!;
|
||||||
let isInSubComponent = false;
|
let isInSubComponent = false;
|
||||||
while (el !== clone) {
|
while (el && el !== clone) {
|
||||||
if (el!.hasAttribute("t-component") || el!.tagName[0] === el!.tagName[0].toUpperCase()) {
|
if (el!.hasAttribute("t-component") || el!.tagName[0] === el!.tagName[0].toUpperCase()) {
|
||||||
isInSubComponent = true;
|
isInSubComponent = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
el = el.parentElement!;
|
el = el.parentElement!;
|
||||||
}
|
}
|
||||||
if (isInSubComponent) {
|
if (isInSubComponent || !el) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1066,6 +1066,45 @@ exports[`slots multiple slots containing components 3`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`slots named slot inside named slot in t-component 1`] = `
|
||||||
|
"function anonymous(app, bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
|
||||||
|
let { capture, markRaw } = helpers;
|
||||||
|
const comp1 = app.createComponent(null, false, true, false, []);
|
||||||
|
const comp2 = app.createComponent(\`Child\`, true, true, false, []);
|
||||||
|
|
||||||
|
function slot1(ctx, node, key = \\"\\") {
|
||||||
|
const b2 = text(\` outer \`);
|
||||||
|
const ctx2 = capture(ctx);
|
||||||
|
const Comp1 = ctx['Child'];
|
||||||
|
const b4 = toggler(Comp1, comp1({slots: markRaw({'brol': {__render: slot2.bind(this), __ctx: ctx2}})}, (Comp1).name + key + \`__1\`, node, this, Comp1));
|
||||||
|
return multi([b2, b4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function slot2(ctx, node, key = \\"\\") {
|
||||||
|
return text(ctx['value']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
const ctx1 = capture(ctx);
|
||||||
|
return comp2({slots: markRaw({'brol': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__2\`, node, this, null);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`slots named slot inside named slot in t-component 2`] = `
|
||||||
|
"function anonymous(app, bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
|
||||||
|
let { callSlot } = helpers;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
return callSlot(ctx, node, key, 'brol', false, {});
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`slots named slot inside slot 1`] = `
|
exports[`slots named slot inside slot 1`] = `
|
||||||
"function anonymous(app, bdom, helpers
|
"function anonymous(app, bdom, helpers
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1673,6 +1673,31 @@ describe("slots", () => {
|
|||||||
expect(fixture.innerHTML).toBe("<div><div><p>Ablip</p><div><p>Bblip</p></div></div></div>");
|
expect(fixture.innerHTML).toBe("<div><div><p>Ablip</p><div><p>Bblip</p></div></div></div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("named slot inside named slot in t-component", async () => {
|
||||||
|
class Child extends Component {
|
||||||
|
static template = xml`<t t-slot="brol"/>`;
|
||||||
|
}
|
||||||
|
class Parent extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<Child>
|
||||||
|
<t t-set-slot="brol">
|
||||||
|
outer
|
||||||
|
<t t-component="Child">
|
||||||
|
<t t-set-slot="brol">
|
||||||
|
<t t-esc="value"/>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</Child>`;
|
||||||
|
static components = { Child };
|
||||||
|
Child = Child;
|
||||||
|
value = "inner";
|
||||||
|
}
|
||||||
|
await mount(Parent, fixture);
|
||||||
|
|
||||||
|
expect(fixture.innerHTML).toBe(" outer inner");
|
||||||
|
});
|
||||||
|
|
||||||
test("can render only empty slot", async () => {
|
test("can render only empty slot", async () => {
|
||||||
class Parent extends Component {
|
class Parent extends Component {
|
||||||
static template = xml`<t t-slot="default"/>`;
|
static template = xml`<t t-slot="default"/>`;
|
||||||
|
|||||||
Reference in New Issue
Block a user