mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[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:
+3
-2
@@ -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;
|
||||
},
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user