From 934e4378d83881fb1fedfa0b201b7bf0b645b747 Mon Sep 17 00:00:00 2001 From: David Greenspan Date: Mon, 8 Jul 2013 21:03:18 -0700 Subject: [PATCH] detach, don't destroy, certain children in rebuild --- examples/unfinished/shark/client/shark.js | 6 ++++- packages/ui/dom.js | 27 ++++++++++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/examples/unfinished/shark/client/shark.js b/examples/unfinished/shark/client/shark.js index 36e038cf87..0579a964f7 100644 --- a/examples/unfinished/shark/client/shark.js +++ b/examples/unfinished/shark/client/shark.js @@ -95,6 +95,10 @@ Either = UIComponent.extend({ Meteor.startup(function () { Session.set('which', 'Span'); - var x = Either.create({isRoot: true}); + // leak `x` for fooling around in the console + x = Either.create({isRoot: true}); x.attach(document.body); + + // leak `c` + (c = _UI.Counter.create({isRoot:true})).attach(document.body); }); diff --git a/packages/ui/dom.js b/packages/ui/dom.js index 6a9ca4c8ba..6e04c62445 100644 --- a/packages/ui/dom.js +++ b/packages/ui/dom.js @@ -207,10 +207,11 @@ Component({ // Should work whether this component is detached or attached! // In other words, it may reside in an offscreen element. - var A = self.firstNode(); - var B = self.lastNode(); - var parentNode = B.parentNode; - var nextNode = B.nextSibling || null; + var firstNode = self.firstNode(); + var lastNode = self.lastNode(); + var parentNode = lastNode.parentNode; + var nextNode = lastNode.nextSibling || null; + var prevNode = firstNode.previousSibling || null; // for efficiency, do a quick check to see if we've *ever* // had children or if we are still using the prototype's @@ -222,19 +223,29 @@ Component({ var children = self.children; for (var k in children) { var child = children[k]; - if (child.isAttached || builtChildren[k]) { - // destroy first, then remove (which doesn't affect DOM) + if (builtChildren[k]) { + // destroy first, then remove + // (which doesn't affect DOM, which we will + // remove all at once) child.destroy(); self.remove(child); + } else if (child.isAttached) { + // detach the child; we don't have a good way + // of keeping this from affecting the DOM + child.detach(); } } }); } var oldNodes = []; - for (var n = A; n !== B; n = n.nextSibling) + // must be careful as call to `detach` above may have + // must with firstNode or lastNode + for (var n = prevNode ? prevNode.nextSibling : + parentNode.firstChild; + n && n !== nextNode; + n = n.nextSibling) oldNodes.push(n); - oldNodes.push(B); $(oldNodes).remove();