From 04f10fbf64e01503aeec40f533ff9c4d7bac44d0 Mon Sep 17 00:00:00 2001 From: Hixie Date: Thu, 4 Jun 2015 10:39:34 -0700 Subject: [PATCH] Fix the crash when the drawer is hidden. The root cause of the crash was threefold: - you can't enumerate enums, in dart; you have to enumerate their values. - RenderNodeWrapper was trying to call remove(child.root) on its root, but that's not something that all RenderNodes have - when a RenderNode was deparented, its relayoutSubtreeRoot wasn't removed, so the node ended up in an inconsistent state regarding its parent tree R=abarth@chromium.org Review URL: https://codereview.chromium.org/1151573020 --- sdk/lib/framework/components2/scaffold.dart | 2 +- sdk/lib/framework/fn2.dart | 30 ++++++++++++--------- sdk/lib/framework/rendering/node.dart | 9 ++++--- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/sdk/lib/framework/components2/scaffold.dart b/sdk/lib/framework/components2/scaffold.dart index 2f600fcdcc9..ff2d697fd60 100644 --- a/sdk/lib/framework/components2/scaffold.dart +++ b/sdk/lib/framework/components2/scaffold.dart @@ -48,7 +48,7 @@ class RenderScaffold extends RenderBox { ScaffoldSlots remove(RenderBox child) { assert(child != null); - for (ScaffoldSlots slot in ScaffoldSlots) { + for (ScaffoldSlots slot in ScaffoldSlots.values) { if (_slots[slot] == child) { this[slot] = null; return slot; diff --git a/sdk/lib/framework/fn2.dart b/sdk/lib/framework/fn2.dart index 77fde9afa16..a3adb268742 100644 --- a/sdk/lib/framework/fn2.dart +++ b/sdk/lib/framework/fn2.dart @@ -317,11 +317,6 @@ abstract class RenderNodeWrapper extends UINode { } } - void removeChild(UINode node) { - root.remove(node.root); - super.removeChild(node); - } - void _remove() { assert(root != null); _nodeMap.remove(root); @@ -334,20 +329,25 @@ abstract class OneChildRenderNodeWrapper extends RenderNodeWrapper { OneChildRenderNodeWrapper({ this.child, Object key }) : super(key: key); - void insert(RenderNodeWrapper child, dynamic slot) { - assert(slot == null); - root.child = child.root; - } - void syncRenderNode(RenderNodeWrapper old) { super.syncRenderNode(old); UINode oldChild = old == null ? null : (old as OneChildRenderNodeWrapper).child; syncChild(child, oldChild, null); } + void insert(RenderNodeWrapper child, dynamic slot) { + assert(slot == null); + root.child = child.root; + } + + void removeChild(UINode node) { + root.child = null; + super.removeChild(node); + } + void _remove() { - assert(child != null); - removeChild(child); + if (child != null) + removeChild(child); super._remove(); } } @@ -436,6 +436,12 @@ abstract class OneChildListRenderNodeWrapper extends RenderNodeWrapper { root.add(child.root, before: slot); } + void removeChild(UINode node) { + assert(root is ContainerRenderNodeMixin); + root.remove(node.root); + super.removeChild(node); + } + void _remove() { assert(children != null); for (var child in children) { diff --git a/sdk/lib/framework/rendering/node.dart b/sdk/lib/framework/rendering/node.dart index 07cf57cdfa4..81ad8242021 100644 --- a/sdk/lib/framework/rendering/node.dart +++ b/sdk/lib/framework/rendering/node.dart @@ -55,12 +55,18 @@ abstract class RenderNode extends AbstractNode { assert(child != null); setParentData(child); super.adoptChild(child); + markNeedsLayout(); } void dropChild(RenderNode child) { // only for use by subclasses assert(child != null); assert(child.parentData != null); child.parentData.detach(); + if (child._relayoutSubtreeRoot != child) { + child._relayoutSubtreeRoot = null; + child._needsLayout = true; + } super.dropChild(child); + markNeedsLayout(); } static List _nodesNeedingLayout = new List(); @@ -231,7 +237,6 @@ abstract class RenderNodeWithChildMixin { _child = value; if (_child != null) adoptChild(_child); - markNeedsLayout(); } void attachChildren() { if (_child != null) @@ -336,7 +341,6 @@ abstract class ContainerRenderNodeMixin