- From: Jeff Hykin <notifications@github.com>
- Date: Sat, 08 Jan 2022 17:05:42 -0800
- To: WICG/webcomponents <webcomponents@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <WICG/webcomponents/issues/951@github.com>
### TDLR: I don't think there is a way to watch all properties <br> ### Workaround #1 - Use attributes instead of properties - Use mutation observer to watch all attributes #### Downside: extremely slow, and dom updates are unnecessary <br> ### Workaround #2 - Use a proxy - Trick the browser into thinking the proxy object is a Node #### Downside: doesn't work Example: ```js const proxySymbol = Symbol.for('Proxy') const thisProxySymbol = Symbol('customObject') // monkey patching instanceof: const originalHasInstance = CustomComponent.prototype[Symbol.hasInstance] CustomComponent.prototype[Symbol.hasInstance] = (item, ...args)=>(item instanceof Object && item[thisProxySymbol])||originalHasInstance(item, ...args) const element = new CustomComponent({onConnect, onDisconnect, onAdopted, children}) const elementProxy = new Proxy(element, { defineProperty: Reflect.defineProperty, getPrototypeOf: Reflect.getPrototypeOf, ownKeys(original) { return Object.keys(original) }, get(original, key) { console.debug(`getting key:`,key) if (key == proxySymbol||key == thisProxySymbol) {return true} if (key == elementSymbol) {return original} return original[key] }, set(original, key, value) { if (key == proxySymbol||key == thisProxySymbol) {return} return original[key] = value }, }) // // attempt // elementProxy instanceof Node; // >>> true document.body.append(elementProxy) // >>> caught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node' ``` <br> ### Workaround #3 - Create a two-way link between the proxy and the element using symbols - Monkey patch all these (and I'm probably missing a few) on HTMLElement, HTMLCollection, etc - children - append - getElementById - prepend - querySelector - querySelectorAll - replaceChildren - hasChildNodes - insertBefore - removeChild - replaceChild - childNodes - firstChild - lastChild - appendChild - contains - activeElement - pointerLockElement - fullscreenElement - elementFromPoint - elementsFromPoint - getSelection - firstElementChild - lastElementChild - getRootNode - isEqualNode - isSameNode #### Downside: (other than the extreme monkey patching itself) this would still fail for things like the debugging value of `$0` that many browsers have when inspecting an element. It would return the non-proxy-wrapped element -- Reply to this email directly or view it on GitHub: https://github.com/WICG/webcomponents/issues/951 You are receiving this because you are subscribed to this thread. Message ID: <WICG/webcomponents/issues/951@github.com>
Received on Sunday, 9 January 2022 01:05:55 UTC