mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] slots: fix bad interaction between t-call and slots
The previous changes in the combine method (used to copy all the variables defined in the current scope for use in a slot) had the effect of squashing the prototype chain: instead of `Component -> Obj1 -> Obj2 -> Obj3`, the combined scope had: `Component -> Obj1'`. This has an unfortunate interaction with the way t-call is implemented, which uses the fact that we are in a subscope to add a own __access_mode__. It depends specifially on the prototype chain, and that the parent scope may have a different value for that property. But with the way combine was implemented, we lost all that subtlety since everything is squashed. In this commit, we reimplement that function in a way to make sure we keep the prototype chain structure
This commit is contained in:
+16
-2
@@ -137,12 +137,26 @@ const UTILS: Utils = {
|
||||
}
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* This method combines the current context with the variables defined in a
|
||||
* scope for use in a slot.
|
||||
*
|
||||
* The implementation is kind of tricky because we want to preserve the
|
||||
* prototype chain structure of the cloned result. So we need to traverse the
|
||||
* prototype chain, cloning each level respectively.
|
||||
*/
|
||||
combine(context, scope) {
|
||||
const clone = Object.create(context);
|
||||
let clone = context;
|
||||
const scopeStack = [];
|
||||
while (!isComponent(scope)) {
|
||||
Object.assign(clone, scope);
|
||||
scopeStack.push(scope);
|
||||
scope = scope.__proto__;
|
||||
}
|
||||
while (scopeStack.length) {
|
||||
let scope = scopeStack.pop();
|
||||
clone = Object.create(clone);
|
||||
Object.assign(clone, scope);
|
||||
}
|
||||
return clone;
|
||||
},
|
||||
shallowEqual,
|
||||
|
||||
Reference in New Issue
Block a user