diff --git a/src/qweb/qweb.ts b/src/qweb/qweb.ts index 2edc3b0c..2de45442 100644 --- a/src/qweb/qweb.ts +++ b/src/qweb/qweb.ts @@ -139,8 +139,9 @@ const UTILS: Utils = { }, combine(context, scope) { const clone = Object.create(context); - for (let k in scope) { - clone[k] = scope[k]; + while (!isComponent(scope)) { + Object.assign(clone, scope); + scope = scope.__proto__; } return clone; }, diff --git a/tests/component/slots.test.ts b/tests/component/slots.test.ts index b95bcaae..54297cdc 100644 --- a/tests/component/slots.test.ts +++ b/tests/component/slots.test.ts @@ -1257,4 +1257,50 @@ describe("t-slot directive", () => { `
` ); }); + + test("t-slot scope context", async () => { + expect.assertions(1); + + class Wrapper extends Component { + static template = xml``; + } + + let dialog; + + class Dialog extends Component { + static template = xml` + +
+ +
+
+ `; + + static components = { Wrapper }; + + setup() { + dialog = this; + } + + onClick(ev) { + // we do not use expect(this).toBe(dialog) here because if it fails, it + // may blow up jest because it then tries to compute a diff, which is + // infinite if there is a cycle + expect(this === dialog).toBe(true); + } + } + + class Parent extends Component { + static template = xml` + + + `; + static components = { Dialog }; + } + + await mount(Parent, { target: fixture }); + + document.querySelector("button").click(); + await nextTick(); + }); });