| Index: sky/sdk/lib/widgets/widget.dart
|
| diff --git a/sky/sdk/lib/widgets/widget.dart b/sky/sdk/lib/widgets/widget.dart
|
| index 6c9a3449186fe04ed1272ba0a40b15f8e11337ce..53c059e992ef7a4fa3e73a5858062c4d0f2fea23 100644
|
| --- a/sky/sdk/lib/widgets/widget.dart
|
| +++ b/sky/sdk/lib/widgets/widget.dart
|
| @@ -106,8 +106,10 @@ abstract class Widget {
|
| bool _retainStatefulNodeIfPossible(Widget old) => false;
|
|
|
| void _sync(Widget old, dynamic slot);
|
| - // 'slot' is the identifier that the parent RenderObjectWrapper uses to know
|
| - // where to put this descendant
|
| + void updateSlot(dynamic newSlot);
|
| + // 'slot' is the identifier that the ancestor RenderObjectWrapper uses to know
|
| + // where to put this descendant. If you just defer to a child, then make sure
|
| + // to pass them the slot.
|
|
|
| Widget findAncestor(Type targetType) {
|
| var ancestor = _parent;
|
| @@ -186,10 +188,23 @@ abstract class Widget {
|
| return newNode;
|
| }
|
|
|
| - String toString() {
|
| + String toString([String prefix = '', String startPrefix = '']) {
|
| + String childrenString = '';
|
| + List<Widget> children = new List<Widget>();
|
| + walkChildren(children.add);
|
| + if (children.length > 0) {
|
| + Widget lastChild = children.removeLast();
|
| + String nextStartPrefix = prefix + ' +-';
|
| + String nextPrefix = prefix + ' | ';
|
| + for (Widget child in children)
|
| + childrenString += child.toString(nextPrefix, nextStartPrefix);
|
| + String lastStartPrefix = prefix + ' \'-';
|
| + String lastPrefix = prefix + ' ';
|
| + childrenString += lastChild.toString(lastPrefix, lastStartPrefix);
|
| + }
|
| if (key == null)
|
| - return '$runtimeType(unkeyed)';
|
| - return '$runtimeType("$key")';
|
| + return '$startPrefix$runtimeType(unkeyed)\n$childrenString';
|
| + return '$startPrefix$runtimeType("$key")\n$childrenString';
|
| }
|
|
|
| }
|
| @@ -210,7 +225,8 @@ abstract class TagNode extends Widget {
|
| Widget child;
|
|
|
| void walkChildren(WidgetTreeWalker walker) {
|
| - walker(child);
|
| + if (child != null)
|
| + walker(child);
|
| }
|
|
|
| void _sync(Widget old, dynamic slot) {
|
| @@ -222,6 +238,10 @@ abstract class TagNode extends Widget {
|
| assert(_root == root); // in case a subclass reintroduces it
|
| }
|
|
|
| + void updateSlot(dynamic newSlot) {
|
| + child.updateSlot(newSlot);
|
| + }
|
| +
|
| void remove() {
|
| if (child != null)
|
| removeChild(child);
|
| @@ -374,6 +394,17 @@ abstract class Component extends Widget {
|
| Widget _built;
|
| dynamic _slot; // cached slot from the last time we were synced
|
|
|
| + void updateSlot(dynamic newSlot) {
|
| + _slot = newSlot;
|
| + if (_built != null)
|
| + _built.updateSlot(newSlot);
|
| + }
|
| +
|
| + void walkChildren(WidgetTreeWalker walker) {
|
| + if (_built != null)
|
| + walker(_built);
|
| + }
|
| +
|
| void didMount() {
|
| assert(!_disqualifiedFromEverAppearingAgain);
|
| super.didMount();
|
| @@ -459,7 +490,7 @@ abstract class Component extends Widget {
|
| assert(_built == null || old == null);
|
| assert(!_disqualifiedFromEverAppearingAgain);
|
|
|
| - _slot = slot;
|
| + updateSlot(slot);
|
|
|
| var oldBuilt;
|
| if (old == null) {
|
| @@ -490,7 +521,6 @@ abstract class Component extends Widget {
|
| assert(!_disqualifiedFromEverAppearingAgain);
|
| if (!_dirty || !_mounted)
|
| return;
|
| -
|
| assert(root != null);
|
| _sync(null, _slot);
|
| }
|
| @@ -618,6 +648,13 @@ abstract class RenderObjectWrapper extends Widget {
|
| syncRenderObject(old);
|
| }
|
|
|
| + void updateSlot(dynamic newSlot) {
|
| + // We never use the slot except during sync(), in which
|
| + // case our parent is handing it to us anyway.
|
| + // We don't need to propagate this to our children, since
|
| + // we give them their own slots for them to fit into us.
|
| + }
|
| +
|
| void syncRenderObject(RenderObjectWrapper old) {
|
| ParentData parentData = null;
|
| Widget ancestor = parent;
|
| @@ -675,7 +712,8 @@ abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper {
|
| Widget get child => _child;
|
|
|
| void walkChildren(WidgetTreeWalker walker) {
|
| - walker(child);
|
| + if (child != null)
|
| + walker(child);
|
| }
|
|
|
| void syncRenderObject(RenderObjectWrapper old) {
|
| @@ -789,6 +827,8 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
|
| children[atIndex] = syncChild(currentNode, oldNode, nextSibling);
|
| assert(children[atIndex] != null);
|
| assert(children[atIndex].parent == this);
|
| + if (atIndex > 0)
|
| + children[atIndex-1].updateSlot(children[atIndex].root);
|
| }
|
|
|
| // Scan backwards from end of list while nodes can be directly synced
|
|
|