diff --git a/src/qweb/extensions.ts b/src/qweb/extensions.ts index d3918a46..c3176c1a 100644 --- a/src/qweb/extensions.ts +++ b/src/qweb/extensions.ts @@ -206,7 +206,7 @@ QWeb.addDirective({ ctx.addLine(`result = {}`); } ctx.addLine( - `slot${slotKey}.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: ${parentNode}, vars: extra.vars, parent: owner}));` + `slot${slotKey}.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: ${parentNode}, vars: extra.vars, parent: extra.parent || owner}));` ); if (!ctx.parentNode) { ctx.addLine(`utils.defineProxy(result, ${parentNode}[0]);`); diff --git a/tests/component/__snapshots__/component.test.ts.snap b/tests/component/__snapshots__/component.test.ts.snap index eedf9e73..0b3c1ad5 100644 --- a/tests/component/__snapshots__/component.test.ts.snap +++ b/tests/component/__snapshots__/component.test.ts.snap @@ -1341,14 +1341,14 @@ exports[`t-slot directive can define and call slots 2`] = ` c8.push(vn9); const slot10 = this.constructor.slots[context.__owl__.slotId + '_' + 'header']; if (slot10) { - slot10.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c9, vars: extra.vars, parent: owner})); + slot10.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c9, vars: extra.vars, parent: extra.parent || owner})); } let c11 = [], p11 = {key:11}; var vn11 = h('div', p11, c11); c8.push(vn11); const slot12 = this.constructor.slots[context.__owl__.slotId + '_' + 'footer']; if (slot12) { - slot12.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c11, vars: extra.vars, parent: owner})); + slot12.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c11, vars: extra.vars, parent: extra.parent || owner})); } return vn8; }" @@ -1489,7 +1489,7 @@ exports[`t-slot directive slots are rendered with proper context, part 2 1`] = ` var vn14 = h('a', p14, c14); const slot15 = this.constructor.slots[context.__owl__.slotId + '_' + 'default']; if (slot15) { - slot15.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c14, vars: extra.vars, parent: owner})); + slot15.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c14, vars: extra.vars, parent: extra.parent || owner})); } return vn14; }" @@ -1589,7 +1589,7 @@ exports[`t-slot directive slots are rendered with proper context, part 3 1`] = ` var vn14 = h('a', p14, c14); const slot15 = this.constructor.slots[context.__owl__.slotId + '_' + 'default']; if (slot15) { - slot15.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c14, vars: extra.vars, parent: owner})); + slot15.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c14, vars: extra.vars, parent: extra.parent || owner})); } return vn14; }" @@ -1745,7 +1745,7 @@ exports[`t-slot directive template can just return a slot 1`] = ` if (slot10) { let children11= [] result = {} - slot10.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: children11, vars: extra.vars, parent: owner})); + slot10.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: children11, vars: extra.vars, parent: extra.parent || owner})); utils.defineProxy(result, children11[0]); } return result; diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts index 2a3d255a..20ef345b 100644 --- a/tests/component/component.test.ts +++ b/tests/component/component.test.ts @@ -4069,6 +4069,37 @@ describe("t-slot directive", () => { expect(childrenChildren[0]).toBeInstanceOf(GrandChild); }); + test("nested slots: evaluation context and parented relationship", async () => { + let slot; + class Slot extends Component { + static template = xml``; + constructor(parent, props) { + super(parent, props); + slot = this; + } + } + class GrandChild extends Component { + static template = xml`
`; + } + class Child extends Component { + static components = { GrandChild }; + static template = xml` + + + `; + } + class Parent extends Component { + static components = { Child, Slot }; + static template = xml``; + state = useState({ val: 3 }); + } + const parent = new Parent(); + await parent.mount(fixture); + + expect(fixture.innerHTML).toBe("
3
"); + expect(slot.__owl__.parent).toBeInstanceOf(GrandChild); + }); + test("slot are properly rendered if inner props are changed", async () => { env.qweb.addTemplates(` diff --git a/tests/router/__snapshots__/link.test.ts.snap b/tests/router/__snapshots__/link.test.ts.snap index f184b404..b10fc996 100644 --- a/tests/router/__snapshots__/link.test.ts.snap +++ b/tests/router/__snapshots__/link.test.ts.snap @@ -14,7 +14,7 @@ exports[`Link component can render simple cases 1`] = ` p8.on['click'] = extra.handlers['click' + 8]; const slot9 = this.constructor.slots[context.__owl__.slotId + '_' + 'default']; if (slot9) { - slot9.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c8, vars: extra.vars, parent: owner})); + slot9.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c8, vars: extra.vars, parent: extra.parent || owner})); } return vn8; }"