- From: Joseph Orbegoso Pea <notifications@github.com>
- Date: Sat, 11 Mar 2017 20:14:34 -0800
- To: w3c/webcomponents <webcomponents@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/webcomponents/issues/629/285921048@github.com>
Here's `childConnectedCallback` implemented on `Element.prototype.connectedCallback` (compare with the above `MutationObserver` implementation): ```js Element.prototype.connectedCallback = function() { if (this.parentElement && this.parentElement.childConnectedCallback) this.parentElement.childConnectedCallback(this) } ``` This is much simpler! Also (at least in Chrome), the order of `MutationRecords` do not always fire in the same order as the things that trigger them. This sort of problem is completely avoided with the `Element.prototype.connectedCallback` implementation. For reference, I discovered that using a single global MutationObserver rather than one per element fixes the problem of MutationRecord callbacks happening out of order. After changing my MutationObserver implementation to the following I solved a bug caused by out-of-order callbacks: ```js let childObservationHandlers = null let childObserver = null function observeChildren(ctx, onConnect, onDisconnect) { if (!childObservationHandlers) childObservationHandlers = new Map if (!childObserver) childObserver = createChildObserver() childObservationHandlers.set(ctx, {onConnect, onDisconnect}) childObserver.observe(ctx, { childList: true }) return true } function createChildObserver() { return new MutationObserver(async (changes) => { const weightsPerTarget = new Map console.log('changes', changes, performance.now()) for (const change of changes) { if (change.type != 'childList') continue if (!weightsPerTarget.has(change.target)) weightsPerTarget.set(change.target, new Map) const weights = weightsPerTarget.get(change.target) for (const addedNode of change.addedNodes) weights.set(addedNode, (weights.get(addedNode) || 0) + 1) for (const removedNode of change.removedNodes) weights.set(removedNode, (weights.get(removedNode) || 0) - 1) } for (const [target, weights] of weightsPerTarget) { const {onConnect, onDisconnect} = childObservationHandlers.get(target) for (const [node, weight] of weights) { if (weight > 0 && typeof onConnect == 'function') onConnect.call(target, node) else if (weight < 0 && typeof onDisconnect == 'function') onDisconnect.call(target, node) } } }) } ``` And... now it is even *more* complicated than the 3-line `Element.prototype.connectedCallback` version. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/w3c/webcomponents/issues/629#issuecomment-285921048
Received on Sunday, 12 March 2017 04:15:06 UTC