From 165c32be915862c25bb0a9b90eb0b5c2c62958f8 Mon Sep 17 00:00:00 2001 From: John Messerly Date: Tue, 23 Sep 2014 14:02:59 -0700 Subject: [PATCH] create a unique observer for each ShadowRoot or Document so detached nodes with shadow roots can be collected --- src/Observer.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/Observer.js b/src/Observer.js index 61d764f..232354a 100644 --- a/src/Observer.js +++ b/src/Observer.js @@ -246,10 +246,7 @@ function watchShadow(node) { } function watchRoot(root) { - if (!root.__watched) { - observe(root); - root.__watched = true; - } + observe(root); } function handler(mutations) { @@ -294,18 +291,32 @@ function handler(mutations) { logFlags.dom && console.groupEnd(); }; -var observer = new MutationObserver(handler); +function takeRecords(node) { + // If the optional node is not supplied, assume we mean the whole document. + if (node === undefined) node = document; + + // Find the root of the tree, which will be an Document or ShadowRoot. + while (node.parentNode) { + node = node.parentNode; + } -function takeRecords() { - // TODO(sjmiles): ask Raf why we have to call handler ourselves - handler(observer.takeRecords()); - takeMutations(); + var observer = node.__observer; + if (observer) { + handler(observer.takeRecords()); + takeMutations(); + } } var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); function observe(inRoot) { + if (inRoot.__observer) return; + + // For each ShadowRoot, we create a new MutationObserver, so the root can be + // garbage collected once all references to the `inRoot` node are gone. + var observer = new MutationObserver(handler); observer.observe(inRoot, {childList: true, subtree: true}); + inRoot.__observer = observer; } function observeDocument(doc) {