From bd110a8a8cff7958fb6d4cdb4d24bd8068fc6984 Mon Sep 17 00:00:00 2001 From: Hixie Date: Wed, 27 May 2015 11:00:40 -0700 Subject: [PATCH] [Effen] Make syncChild() support the _new_ child being null. This is needed for cases where the UINode doesn't have a list of children (so it doesn't go through the RenderNodeWrapper sync logic that removes children), but it still has multiple slots, and needs to support removing nodes from those slots. (For example, removing a drawer from a ScaffoldContainer.) Also, expose syncChild (it used to be private) so it can be overridden in descendants outside fn.dart. R=abarth@chromium.org Review URL: https://codereview.chromium.org/1158563003 --- sdk/lib/framework/fn2.dart | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sdk/lib/framework/fn2.dart b/sdk/lib/framework/fn2.dart index 4c9bf6eeb67..4f8318b39ad 100644 --- a/sdk/lib/framework/fn2.dart +++ b/sdk/lib/framework/fn2.dart @@ -93,15 +93,20 @@ abstract class UINode { } // Returns the child which should be retained as the child of this node. - UINode _syncChild(UINode node, UINode oldNode, dynamic slot) { - assert(node != null); - assert(oldNode == null || node._key == oldNode._key); + UINode syncChild(UINode node, UINode oldNode, dynamic slot) { if (node == oldNode) { - _traceSync(_SyncOperation.IDENTICAL, node._key); + _traceSync(_SyncOperation.IDENTICAL, node == null ? '*null*' : node._key); return node; // Nothing to do. Subtrees must be identical. } + if (node == null) { + // the child in this slot has gone away + removeChild(oldNode); + return null; + } + assert(oldNode == null || node._key == oldNode._key); + // TODO(rafaelw): This eagerly removes the old DOM. It may be that a // new component was built that could re-use some of it. Consider // syncing the new VDOM against the old one. @@ -141,7 +146,7 @@ abstract class ContentNode extends UINode { void _sync(UINode old, dynamic slot) { UINode oldContent = old == null ? null : (old as ContentNode).content; - content = _syncChild(content, oldContent, slot); + content = syncChild(content, oldContent, slot); assert(content.root != null); root = content.root; } @@ -441,7 +446,7 @@ abstract class OneChildListRenderNodeWrapper extends RenderNodeWrapper { UINode oldNode = null; void sync(int atIndex) { - children[atIndex] = _syncChild(currentNode, oldNode, nextSibling); + children[atIndex] = syncChild(currentNode, oldNode, nextSibling); assert(children[atIndex] != null); } @@ -899,7 +904,7 @@ abstract class Component extends UINode { _currentlyBuilding = null; _currentOrder = lastOrder; - _built = _syncChild(_built, oldBuilt, slot); + _built = syncChild(_built, oldBuilt, slot); _dirty = false; root = _built.root; assert(root != null);