[FIX] slots: make sure handlers are properly bound to component

In some situations (a slot inside a slot), the combine method was
wrongly copying all properties of the scope into the context, which
caused the event handling system to wrongly use a subobject as component
(since it detects the fact that __owl__ is a own property_).
Consequently, we could have very subtle issue with some properties being
shadowed by a sub object.
This commit is contained in:
Géry Debongnie
2021-07-07 10:31:37 +02:00
committed by aab-odoo
parent 9cfafc30b5
commit ea3c6f7bf0
2 changed files with 49 additions and 2 deletions
+3 -2
View File
@@ -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;
},
+46
View File
@@ -1257,4 +1257,50 @@ describe("t-slot directive", () => {
`<div><div class="slotted"><div class="slot"><div class="child"></div></div></div></div>`
);
});
test("t-slot scope context", async () => {
expect.assertions(1);
class Wrapper extends Component {
static template = xml`<t t-slot="default"/>`;
}
let dialog;
class Dialog extends Component {
static template = xml`
<Wrapper>
<div t-on-click="onClick">
<t t-slot="default" />
</div>
</Wrapper>
`;
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`
<Dialog>
<button>The Button</button>
</Dialog>`;
static components = { Dialog };
}
await mount(Parent, { target: fixture });
document.querySelector("button").click();
await nextTick();
});
});