UNPKG

@wordpress/interactivity

Version:

Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.

59 lines (55 loc) 2.45 kB
const contextObjectToProxy = new WeakMap(); const contextObjectToFallback = new WeakMap(); const contextProxies = new WeakSet(); const descriptor = Reflect.getOwnPropertyDescriptor; // TODO: Use the proxy registry to avoid multiple proxies on the same object. const contextHandlers = { get: (target, key) => { const fallback = contextObjectToFallback.get(target); // Always subscribe to prop changes in the current context. const currentProp = target[key]; /* * Return the value from `target` if it exists, or from `fallback` * otherwise. This way, in the case the property doesn't exist either in * `target` or `fallback`, it also subscribes to changes in the parent * context. */ return key in target ? currentProp : fallback[key]; }, set: (target, key, value) => { const fallback = contextObjectToFallback.get(target); // If the property exists in the current context, modify it. Otherwise, // add it to the current context. const obj = key in target || !(key in fallback) ? target : fallback; obj[key] = value; return true; }, ownKeys: target => [...new Set([...Object.keys(contextObjectToFallback.get(target)), ...Object.keys(target)])], getOwnPropertyDescriptor: (target, key) => descriptor(target, key) || descriptor(contextObjectToFallback.get(target), key), has: (target, key) => Reflect.has(target, key) || Reflect.has(contextObjectToFallback.get(target), key) }; /** * Wraps a context object with a proxy to reproduce the context stack. The proxy * uses the passed `inherited` context as a fallback to look up for properties * that don't exist in the given context. Also, updated properties are modified * where they are defined, or added to the main context when they don't exist. * * @param current Current context. * @param inherited Inherited context, used as fallback. * * @return The wrapped context object. */ export const proxifyContext = (current, inherited = {}) => { if (contextProxies.has(current)) { throw Error('This object cannot be proxified.'); } // Update the fallback object reference when it changes. contextObjectToFallback.set(current, inherited); if (!contextObjectToProxy.has(current)) { const proxy = new Proxy(current, contextHandlers); contextObjectToProxy.set(current, proxy); contextProxies.add(proxy); } return contextObjectToProxy.get(current); }; //# sourceMappingURL=context.js.map