|
@@ -33,65 +33,54 @@ export function closestDataProxy(el) {
|
|
return mergeProxies(closestDataStack(el))
|
|
return mergeProxies(closestDataStack(el))
|
|
}
|
|
}
|
|
|
|
|
|
-export function mergeProxies(objects) {
|
|
|
|
- let thisProxy = new Proxy({}, {
|
|
|
|
- ownKeys: () => {
|
|
|
|
- return Array.from(new Set(objects.flatMap(i => Object.keys(i))))
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- has: (target, name) => {
|
|
|
|
- return objects.some(obj => obj.hasOwnProperty(name))
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- get: (target, name) => {
|
|
|
|
- return (objects.find(obj => {
|
|
|
|
- if (obj.hasOwnProperty(name)) {
|
|
|
|
- let descriptor = Object.getOwnPropertyDescriptor(obj, name)
|
|
|
|
-
|
|
|
|
- // If we already bound this getter, don't rebind.
|
|
|
|
- if ((descriptor.get && descriptor.get._x_alreadyBound) || (descriptor.set && descriptor.set._x_alreadyBound)) {
|
|
|
|
- return true
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Properly bind getters and setters to this wrapper Proxy.
|
|
|
|
- if ((descriptor.get || descriptor.set) && descriptor.enumerable) {
|
|
|
|
- // Only bind user-defined getters, not our magic properties.
|
|
|
|
- let getter = descriptor.get
|
|
|
|
- let setter = descriptor.set
|
|
|
|
- let property = descriptor
|
|
|
|
-
|
|
|
|
- getter = getter && getter.bind(thisProxy)
|
|
|
|
- setter = setter && setter.bind(thisProxy)
|
|
|
|
-
|
|
|
|
- if (getter) getter._x_alreadyBound = true
|
|
|
|
- if (setter) setter._x_alreadyBound = true
|
|
|
|
-
|
|
|
|
- Object.defineProperty(obj, name, {
|
|
|
|
- ...property,
|
|
|
|
- get: getter,
|
|
|
|
- set: setter,
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return false
|
|
|
|
- }) || {})[name]
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- set: (target, name, value) => {
|
|
|
|
- let closestObjectWithKey = objects.find(obj => obj.hasOwnProperty(name))
|
|
|
|
-
|
|
|
|
- if (closestObjectWithKey) {
|
|
|
|
- closestObjectWithKey[name] = value
|
|
|
|
- } else {
|
|
|
|
- objects[objects.length - 1][name] = value
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true
|
|
|
|
- },
|
|
|
|
- })
|
|
|
|
-
|
|
|
|
- return thisProxy
|
|
|
|
|
|
+export function mergeProxies (objects) {
|
|
|
|
+ return new Proxy({ objects }, mergeProxyTrap);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+let mergeProxyTrap = {
|
|
|
|
+ ownKeys({ objects }) {
|
|
|
|
+ return Array.from(
|
|
|
|
+ new Set(objects.flatMap((i) => Object.keys(i)))
|
|
|
|
+ )
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ has({ objects }, name) {
|
|
|
|
+ if (name == Symbol.unscopables) return false;
|
|
|
|
+
|
|
|
|
+ return objects.some((obj) =>
|
|
|
|
+ Object.prototype.hasOwnProperty.call(obj, name)
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ get({ objects }, name, thisProxy) {
|
|
|
|
+ if (name == "toJSON") return collapseProxies
|
|
|
|
+
|
|
|
|
+ return Reflect.get(
|
|
|
|
+ objects.find((obj) =>
|
|
|
|
+ Object.prototype.hasOwnProperty.call(obj, name)
|
|
|
|
+ ) || {},
|
|
|
|
+ name,
|
|
|
|
+ thisProxy
|
|
|
|
+ )
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set({ objects }, name, value) {
|
|
|
|
+ return Reflect.set(
|
|
|
|
+ objects.find((obj) =>
|
|
|
|
+ Object.prototype.hasOwnProperty.call(obj, name)
|
|
|
|
+ ) || objects[objects.length-1],
|
|
|
|
+ name,
|
|
|
|
+ value
|
|
|
|
+ )
|
|
|
|
+ },
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function collapseProxies() {
|
|
|
|
+ let keys = Reflect.ownKeys(this)
|
|
|
|
+
|
|
|
|
+ return keys.reduce((acc, key) => {
|
|
|
|
+ acc[key] = Reflect.get(this, key)
|
|
|
|
+
|
|
|
|
+ return acc;
|
|
|
|
+ }, {})
|
|
}
|
|
}
|