| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'dart:sky' as sky; | 7 import 'dart:sky' as sky; |
| 8 | 8 |
| 9 import 'package:sky/mojo/activity.dart' as activity; | 9 import 'package:sky/mojo/activity.dart' as activity; |
| 10 | 10 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 } | 200 } |
| 201 | 201 |
| 202 assert(oldNode == null || (oldNode.mounted == false && oldNode.parent == nul
l)); | 202 assert(oldNode == null || (oldNode.mounted == false && oldNode.parent == nul
l)); |
| 203 assert(!newNode.mounted); | 203 assert(!newNode.mounted); |
| 204 newNode.setParent(this); | 204 newNode.setParent(this); |
| 205 newNode._sync(oldNode, slot); | 205 newNode._sync(oldNode, slot); |
| 206 assert(newNode.root is RenderObject); | 206 assert(newNode.root is RenderObject); |
| 207 return newNode; | 207 return newNode; |
| 208 } | 208 } |
| 209 | 209 |
| 210 @override |
| 210 String toString([String prefix = '', String startPrefix = '']) { | 211 String toString([String prefix = '', String startPrefix = '']) { |
| 211 String childrenString = ''; | 212 String childrenString = ''; |
| 212 List<Widget> children = new List<Widget>(); | 213 List<Widget> children = new List<Widget>(); |
| 213 walkChildren(children.add); | 214 walkChildren(children.add); |
| 214 if (children.length > 0) { | 215 if (children.length > 0) { |
| 215 Widget lastChild = children.removeLast(); | 216 Widget lastChild = children.removeLast(); |
| 216 String nextStartPrefix = prefix + ' +-'; | 217 String nextStartPrefix = prefix + ' +-'; |
| 217 String nextPrefix = prefix + ' | '; | 218 String nextPrefix = prefix + ' | '; |
| 218 for (Widget child in children) | 219 for (Widget child in children) |
| 219 childrenString += child.toString(nextPrefix, nextStartPrefix); | 220 childrenString += child.toString(nextPrefix, nextStartPrefix); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 239 | 240 |
| 240 TagNode(Widget child, { String key }) | 241 TagNode(Widget child, { String key }) |
| 241 : this.child = child, super(key: key); | 242 : this.child = child, super(key: key); |
| 242 | 243 |
| 243 // TODO(jackson): Remove this workaround for limitation of Dart mixins | 244 // TODO(jackson): Remove this workaround for limitation of Dart mixins |
| 244 TagNode._withKey(Widget child, String key) | 245 TagNode._withKey(Widget child, String key) |
| 245 : this.child = child, super._withKey(key); | 246 : this.child = child, super._withKey(key); |
| 246 | 247 |
| 247 Widget child; | 248 Widget child; |
| 248 | 249 |
| 250 @override |
| 249 void walkChildren(WidgetTreeWalker walker) { | 251 void walkChildren(WidgetTreeWalker walker) { |
| 250 if (child != null) | 252 if (child != null) |
| 251 walker(child); | 253 walker(child); |
| 252 } | 254 } |
| 253 | 255 |
| 256 @override |
| 254 void _sync(Widget old, dynamic slot) { | 257 void _sync(Widget old, dynamic slot) { |
| 255 Widget oldChild = old == null ? null : (old as TagNode).child; | 258 Widget oldChild = old == null ? null : (old as TagNode).child; |
| 256 child = syncChild(child, oldChild, slot); | 259 child = syncChild(child, oldChild, slot); |
| 257 assert(child.parent == this); | 260 assert(child.parent == this); |
| 258 assert(child.root != null); | 261 assert(child.root != null); |
| 259 _root = child.root; | 262 _root = child.root; |
| 260 assert(_root == root); // in case a subclass reintroduces it | 263 assert(_root == root); // in case a subclass reintroduces it |
| 261 } | 264 } |
| 262 | 265 |
| 266 @override |
| 263 void updateSlot(dynamic newSlot) { | 267 void updateSlot(dynamic newSlot) { |
| 264 child.updateSlot(newSlot); | 268 child.updateSlot(newSlot); |
| 265 } | 269 } |
| 266 | 270 |
| 271 @override |
| 267 void remove() { | 272 void remove() { |
| 268 if (child != null) | 273 if (child != null) |
| 269 removeChild(child); | 274 removeChild(child); |
| 270 super.remove(); | 275 super.remove(); |
| 271 } | 276 } |
| 272 | 277 |
| 278 @override |
| 273 void detachRoot() { | 279 void detachRoot() { |
| 274 if (child != null) | 280 if (child != null) |
| 275 child.detachRoot(); | 281 child.detachRoot(); |
| 276 } | 282 } |
| 277 | 283 |
| 278 } | 284 } |
| 279 | 285 |
| 280 class ParentDataNode extends TagNode { | 286 class ParentDataNode extends TagNode { |
| 281 ParentDataNode(Widget child, this.parentData, { String key }) | 287 ParentDataNode(Widget child, this.parentData, { String key }) |
| 282 : super(child, key: key); | 288 : super(child, key: key); |
| 283 final ParentData parentData; | 289 final ParentData parentData; |
| 284 } | 290 } |
| 285 | 291 |
| 286 abstract class Inherited extends TagNode { | 292 abstract class Inherited extends TagNode { |
| 287 | 293 |
| 288 Inherited({ String key, Widget child }) : super._withKey(child, key); | 294 Inherited({ String key, Widget child }) : super._withKey(child, key); |
| 289 | 295 |
| 296 @override |
| 290 void _sync(Widget old, dynamic slot) { | 297 void _sync(Widget old, dynamic slot) { |
| 291 if (old != null && syncShouldNotify(old)) { | 298 if (old != null && syncShouldNotify(old)) { |
| 292 final Type ourRuntimeType = runtimeType; | 299 final Type ourRuntimeType = runtimeType; |
| 293 void notifyChildren(Widget child) { | 300 void notifyChildren(Widget child) { |
| 294 if (child is Component && | 301 if (child is Component && |
| 295 child._dependencies != null && | 302 child._dependencies != null && |
| 296 child._dependencies.contains(ourRuntimeType)) | 303 child._dependencies.contains(ourRuntimeType)) |
| 297 child._dependenciesChanged(); | 304 child._dependenciesChanged(); |
| 298 if (child.runtimeType != ourRuntimeType) | 305 if (child.runtimeType != ourRuntimeType) |
| 299 child.walkChildren(notifyChildren); | 306 child.walkChildren(notifyChildren); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 super._withKey(key); | 413 super._withKey(key); |
| 407 | 414 |
| 408 static Component _currentlyBuilding; | 415 static Component _currentlyBuilding; |
| 409 bool get _isBuilding => _currentlyBuilding == this; | 416 bool get _isBuilding => _currentlyBuilding == this; |
| 410 | 417 |
| 411 bool _dirty = true; | 418 bool _dirty = true; |
| 412 | 419 |
| 413 Widget _built; | 420 Widget _built; |
| 414 dynamic _slot; // cached slot from the last time we were synced | 421 dynamic _slot; // cached slot from the last time we were synced |
| 415 | 422 |
| 423 @override |
| 416 void updateSlot(dynamic newSlot) { | 424 void updateSlot(dynamic newSlot) { |
| 417 _slot = newSlot; | 425 _slot = newSlot; |
| 418 if (_built != null) | 426 if (_built != null) |
| 419 _built.updateSlot(newSlot); | 427 _built.updateSlot(newSlot); |
| 420 } | 428 } |
| 421 | 429 |
| 430 @override |
| 422 void walkChildren(WidgetTreeWalker walker) { | 431 void walkChildren(WidgetTreeWalker walker) { |
| 423 if (_built != null) | 432 if (_built != null) |
| 424 walker(_built); | 433 walker(_built); |
| 425 } | 434 } |
| 426 | 435 |
| 436 @override |
| 427 void remove() { | 437 void remove() { |
| 428 assert(_built != null); | 438 assert(_built != null); |
| 429 assert(root != null); | 439 assert(root != null); |
| 430 removeChild(_built); | 440 removeChild(_built); |
| 431 _built = null; | 441 _built = null; |
| 432 super.remove(); | 442 super.remove(); |
| 433 } | 443 } |
| 434 | 444 |
| 445 @override |
| 435 void detachRoot() { | 446 void detachRoot() { |
| 436 assert(_built != null); | 447 assert(_built != null); |
| 437 assert(root != null); | 448 assert(root != null); |
| 438 _built.detachRoot(); | 449 _built.detachRoot(); |
| 439 } | 450 } |
| 440 | 451 |
| 441 Set<Type> _dependencies; | 452 Set<Type> _dependencies; |
| 442 Inherited inheritedOfType(Type targetType) { | 453 Inherited inheritedOfType(Type targetType) { |
| 443 if (_dependencies == null) | 454 if (_dependencies == null) |
| 444 _dependencies = new Set<Type>(); | 455 _dependencies = new Set<Type>(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 461 final int _order; | 472 final int _order; |
| 462 static int _currentOrder = 0; | 473 static int _currentOrder = 0; |
| 463 | 474 |
| 464 // There are three cases here: | 475 // There are three cases here: |
| 465 // 1) Building for the first time: | 476 // 1) Building for the first time: |
| 466 // assert(_built == null && old == null) | 477 // assert(_built == null && old == null) |
| 467 // 2) Re-building (because a dirty flag got set): | 478 // 2) Re-building (because a dirty flag got set): |
| 468 // assert(_built != null && old == null) | 479 // assert(_built != null && old == null) |
| 469 // 3) Syncing against an old version | 480 // 3) Syncing against an old version |
| 470 // assert(_built == null && old != null) | 481 // assert(_built == null && old != null) |
| 482 @override |
| 471 void _sync(Component old, dynamic slot) { | 483 void _sync(Component old, dynamic slot) { |
| 472 assert(_built == null || old == null); | 484 assert(_built == null || old == null); |
| 473 | 485 |
| 474 updateSlot(slot); | 486 updateSlot(slot); |
| 475 | 487 |
| 476 var oldBuilt; | 488 var oldBuilt; |
| 477 if (old == null) { | 489 if (old == null) { |
| 478 oldBuilt = _built; | 490 oldBuilt = _built; |
| 479 } else { | 491 } else { |
| 480 assert(_built == null); | 492 assert(_built == null); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 Widget build(); | 527 Widget build(); |
| 516 | 528 |
| 517 } | 529 } |
| 518 | 530 |
| 519 abstract class StatefulComponent extends Component { | 531 abstract class StatefulComponent extends Component { |
| 520 | 532 |
| 521 StatefulComponent({ String key }) : super(key: key); | 533 StatefulComponent({ String key }) : super(key: key); |
| 522 | 534 |
| 523 bool _disqualifiedFromEverAppearingAgain = false; | 535 bool _disqualifiedFromEverAppearingAgain = false; |
| 524 | 536 |
| 537 @override |
| 525 void didMount() { | 538 void didMount() { |
| 526 assert(!_disqualifiedFromEverAppearingAgain); | 539 assert(!_disqualifiedFromEverAppearingAgain); |
| 527 super.didMount(); | 540 super.didMount(); |
| 528 } | 541 } |
| 529 | 542 |
| 543 @override |
| 530 void _buildIfDirty() { | 544 void _buildIfDirty() { |
| 531 assert(!_disqualifiedFromEverAppearingAgain); | 545 assert(!_disqualifiedFromEverAppearingAgain); |
| 532 super._buildIfDirty(); | 546 super._buildIfDirty(); |
| 533 } | 547 } |
| 534 | 548 |
| 549 @override |
| 535 void _sync(Widget old, dynamic slot) { | 550 void _sync(Widget old, dynamic slot) { |
| 536 assert(!_disqualifiedFromEverAppearingAgain); | 551 assert(!_disqualifiedFromEverAppearingAgain); |
| 537 super._sync(old, slot); | 552 super._sync(old, slot); |
| 538 } | 553 } |
| 539 | 554 |
| 555 @override |
| 540 Widget syncChild(Widget node, Widget oldNode, dynamic slot) { | 556 Widget syncChild(Widget node, Widget oldNode, dynamic slot) { |
| 541 assert(!_disqualifiedFromEverAppearingAgain); | 557 assert(!_disqualifiedFromEverAppearingAgain); |
| 542 return super.syncChild(node, oldNode, slot); | 558 return super.syncChild(node, oldNode, slot); |
| 543 } | 559 } |
| 544 | 560 |
| 561 @override |
| 545 bool retainStatefulNodeIfPossible(StatefulComponent newNode) { | 562 bool retainStatefulNodeIfPossible(StatefulComponent newNode) { |
| 546 assert(!_disqualifiedFromEverAppearingAgain); | 563 assert(!_disqualifiedFromEverAppearingAgain); |
| 547 assert(newNode != null); | 564 assert(newNode != null); |
| 548 assert(runtimeType == newNode.runtimeType); | 565 assert(runtimeType == newNode.runtimeType); |
| 549 assert(key == newNode.key); | 566 assert(key == newNode.key); |
| 550 assert(_built != null); | 567 assert(_built != null); |
| 551 newNode._disqualifiedFromEverAppearingAgain = true; | 568 newNode._disqualifiedFromEverAppearingAgain = true; |
| 552 | 569 |
| 553 newNode._built = _built; | 570 newNode._built = _built; |
| 554 _built = null; | 571 _built = null; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 | 688 |
| 672 RenderObjectWrapper _ancestor; | 689 RenderObjectWrapper _ancestor; |
| 673 void insertChildRoot(RenderObjectWrapper child, dynamic slot); | 690 void insertChildRoot(RenderObjectWrapper child, dynamic slot); |
| 674 void detachChildRoot(RenderObjectWrapper child); | 691 void detachChildRoot(RenderObjectWrapper child); |
| 675 | 692 |
| 676 void retainStatefulRenderObjectWrapper(RenderObjectWrapper newNode) { | 693 void retainStatefulRenderObjectWrapper(RenderObjectWrapper newNode) { |
| 677 newNode._root = _root; | 694 newNode._root = _root; |
| 678 newNode._ancestor = _ancestor; | 695 newNode._ancestor = _ancestor; |
| 679 } | 696 } |
| 680 | 697 |
| 698 @override |
| 681 void _sync(RenderObjectWrapper old, dynamic slot) { | 699 void _sync(RenderObjectWrapper old, dynamic slot) { |
| 682 // TODO(abarth): We should split RenderObjectWrapper into two pieces so that | 700 // TODO(abarth): We should split RenderObjectWrapper into two pieces so that |
| 683 // RenderViewObject doesn't need to inherit all this code it | 701 // RenderViewObject doesn't need to inherit all this code it |
| 684 // doesn't need. | 702 // doesn't need. |
| 685 assert(parent != null || this is RenderViewWrapper); | 703 assert(parent != null || this is RenderViewWrapper); |
| 686 if (old == null) { | 704 if (old == null) { |
| 687 _root = createNode(); | 705 _root = createNode(); |
| 688 assert(_root != null); | 706 assert(_root != null); |
| 689 _ancestor = findAncestorRenderObjectWrapper(); | 707 _ancestor = findAncestorRenderObjectWrapper(); |
| 690 if (_ancestor is RenderObjectWrapper) | 708 if (_ancestor is RenderObjectWrapper) |
| 691 _ancestor.insertChildRoot(this, slot); | 709 _ancestor.insertChildRoot(this, slot); |
| 692 } else { | 710 } else { |
| 693 assert(old is RenderObjectWrapper); | 711 assert(old is RenderObjectWrapper); |
| 694 _root = old.root; | 712 _root = old.root; |
| 695 _ancestor = old._ancestor; | 713 _ancestor = old._ancestor; |
| 696 assert(_root != null); | 714 assert(_root != null); |
| 697 } | 715 } |
| 698 assert(_root == root); // in case a subclass reintroduces it | 716 assert(_root == root); // in case a subclass reintroduces it |
| 699 assert(root != null); | 717 assert(root != null); |
| 700 assert(mounted); | 718 assert(mounted); |
| 701 _nodeMap[root] = this; | 719 _nodeMap[root] = this; |
| 702 syncRenderObject(old); | 720 syncRenderObject(old); |
| 703 } | 721 } |
| 704 | 722 |
| 723 @override |
| 705 void updateSlot(dynamic newSlot) { | 724 void updateSlot(dynamic newSlot) { |
| 706 // We never use the slot except during sync(), in which | 725 // We never use the slot except during sync(), in which |
| 707 // case our parent is handing it to us anyway. | 726 // case our parent is handing it to us anyway. |
| 708 // We don't need to propagate this to our children, since | 727 // We don't need to propagate this to our children, since |
| 709 // we give them their own slots for them to fit into us. | 728 // we give them their own slots for them to fit into us. |
| 710 } | 729 } |
| 711 | 730 |
| 712 void syncRenderObject(RenderObjectWrapper old) { | 731 void syncRenderObject(RenderObjectWrapper old) { |
| 713 ParentData parentData = null; | 732 ParentData parentData = null; |
| 714 Widget ancestor = parent; | 733 Widget ancestor = parent; |
| 715 while (ancestor != null && ancestor is! RenderObjectWrapper) { | 734 while (ancestor != null && ancestor is! RenderObjectWrapper) { |
| 716 if (ancestor is ParentDataNode && ancestor.parentData != null) { | 735 if (ancestor is ParentDataNode && ancestor.parentData != null) { |
| 717 if (parentData != null) | 736 if (parentData != null) |
| 718 parentData.merge(ancestor.parentData); // this will throw if the types
aren't the same | 737 parentData.merge(ancestor.parentData); // this will throw if the types
aren't the same |
| 719 else | 738 else |
| 720 parentData = ancestor.parentData; | 739 parentData = ancestor.parentData; |
| 721 } | 740 } |
| 722 ancestor = ancestor.parent; | 741 ancestor = ancestor.parent; |
| 723 } | 742 } |
| 724 if (parentData != null) { | 743 if (parentData != null) { |
| 725 assert(root.parentData != null); | 744 assert(root.parentData != null); |
| 726 root.parentData.merge(parentData); // this will throw if the types aren't
appropriate | 745 root.parentData.merge(parentData); // this will throw if the types aren't
appropriate |
| 727 if (parent.root != null) | 746 if (parent.root != null) |
| 728 parent.root.markNeedsLayout(); | 747 parent.root.markNeedsLayout(); |
| 729 } | 748 } |
| 730 } | 749 } |
| 731 | 750 |
| 751 @override |
| 732 void remove() { | 752 void remove() { |
| 733 assert(root != null); | 753 assert(root != null); |
| 734 _nodeMap.remove(root); | 754 _nodeMap.remove(root); |
| 735 super.remove(); | 755 super.remove(); |
| 736 } | 756 } |
| 737 | 757 |
| 758 @override |
| 738 void detachRoot() { | 759 void detachRoot() { |
| 739 assert(_ancestor != null); | 760 assert(_ancestor != null); |
| 740 assert(root != null); | 761 assert(root != null); |
| 741 _ancestor.detachChildRoot(this); | 762 _ancestor.detachChildRoot(this); |
| 742 } | 763 } |
| 743 | 764 |
| 744 } | 765 } |
| 745 | 766 |
| 746 abstract class LeafRenderObjectWrapper extends RenderObjectWrapper { | 767 abstract class LeafRenderObjectWrapper extends RenderObjectWrapper { |
| 747 | 768 |
| 748 LeafRenderObjectWrapper({ String key }) : super(key: key); | 769 LeafRenderObjectWrapper({ String key }) : super(key: key); |
| 749 | 770 |
| 771 @override |
| 750 void insertChildRoot(RenderObjectWrapper child, dynamic slot) { | 772 void insertChildRoot(RenderObjectWrapper child, dynamic slot) { |
| 751 assert(false); | 773 assert(false); |
| 752 } | 774 } |
| 753 | 775 |
| 776 @override |
| 754 void detachChildRoot(RenderObjectWrapper child) { | 777 void detachChildRoot(RenderObjectWrapper child) { |
| 755 assert(false); | 778 assert(false); |
| 756 } | 779 } |
| 757 | 780 |
| 758 } | 781 } |
| 759 | 782 |
| 760 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { | 783 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { |
| 761 | 784 |
| 762 OneChildRenderObjectWrapper({ String key, Widget child }) | 785 OneChildRenderObjectWrapper({ String key, Widget child }) |
| 763 : _child = child, super(key: key); | 786 : _child = child, super(key: key); |
| 764 | 787 |
| 765 Widget _child; | 788 Widget _child; |
| 766 Widget get child => _child; | 789 Widget get child => _child; |
| 767 | 790 |
| 791 @override |
| 768 void walkChildren(WidgetTreeWalker walker) { | 792 void walkChildren(WidgetTreeWalker walker) { |
| 769 if (child != null) | 793 if (child != null) |
| 770 walker(child); | 794 walker(child); |
| 771 } | 795 } |
| 772 | 796 |
| 797 @override |
| 773 void syncRenderObject(RenderObjectWrapper old) { | 798 void syncRenderObject(RenderObjectWrapper old) { |
| 774 super.syncRenderObject(old); | 799 super.syncRenderObject(old); |
| 775 Widget oldChild = old == null ? null : (old as OneChildRenderObjectWrapper).
child; | 800 Widget oldChild = old == null ? null : (old as OneChildRenderObjectWrapper).
child; |
| 776 Widget newChild = child; | 801 Widget newChild = child; |
| 777 _child = syncChild(newChild, oldChild, null); | 802 _child = syncChild(newChild, oldChild, null); |
| 778 assert((newChild == null && child == null) || (newChild != null && child.par
ent == this)); | 803 assert((newChild == null && child == null) || (newChild != null && child.par
ent == this)); |
| 779 assert(oldChild == null || child == oldChild || oldChild.parent == null); | 804 assert(oldChild == null || child == oldChild || oldChild.parent == null); |
| 780 } | 805 } |
| 781 | 806 |
| 807 @override |
| 782 void insertChildRoot(RenderObjectWrapper child, dynamic slot) { | 808 void insertChildRoot(RenderObjectWrapper child, dynamic slot) { |
| 783 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 809 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 784 assert(root is RenderObjectWithChildMixin); | 810 assert(root is RenderObjectWithChildMixin); |
| 785 assert(slot == null); | 811 assert(slot == null); |
| 786 root.child = child.root; | 812 root.child = child.root; |
| 787 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer | 813 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer |
| 788 } | 814 } |
| 789 | 815 |
| 816 @override |
| 790 void detachChildRoot(RenderObjectWrapper child) { | 817 void detachChildRoot(RenderObjectWrapper child) { |
| 791 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 818 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 792 assert(root is RenderObjectWithChildMixin); | 819 assert(root is RenderObjectWithChildMixin); |
| 793 assert(root.child == child.root); | 820 assert(root.child == child.root); |
| 794 root.child = null; | 821 root.child = null; |
| 795 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer | 822 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer |
| 796 } | 823 } |
| 797 | 824 |
| 825 @override |
| 798 void remove() { | 826 void remove() { |
| 799 if (child != null) | 827 if (child != null) |
| 800 removeChild(child); | 828 removeChild(child); |
| 801 super.remove(); | 829 super.remove(); |
| 802 } | 830 } |
| 803 } | 831 } |
| 804 | 832 |
| 805 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { | 833 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { |
| 806 | 834 |
| 807 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes | 835 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes |
| 808 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c
alls | 836 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c
alls |
| 809 | 837 |
| 810 MultiChildRenderObjectWrapper({ String key, List<Widget> children }) | 838 MultiChildRenderObjectWrapper({ String key, List<Widget> children }) |
| 811 : this.children = children == null ? const [] : children, | 839 : this.children = children == null ? const [] : children, |
| 812 super(key: key) { | 840 super(key: key) { |
| 813 assert(!_debugHasDuplicateIds()); | 841 assert(!_debugHasDuplicateIds()); |
| 814 } | 842 } |
| 815 | 843 |
| 816 final List<Widget> children; | 844 final List<Widget> children; |
| 817 | 845 |
| 846 @override |
| 818 void walkChildren(WidgetTreeWalker walker) { | 847 void walkChildren(WidgetTreeWalker walker) { |
| 819 for (Widget child in children) | 848 for (Widget child in children) |
| 820 walker(child); | 849 walker(child); |
| 821 } | 850 } |
| 822 | 851 |
| 852 @override |
| 823 void insertChildRoot(RenderObjectWrapper child, dynamic slot) { | 853 void insertChildRoot(RenderObjectWrapper child, dynamic slot) { |
| 824 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 854 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 825 assert(slot == null || slot is RenderObject); | 855 assert(slot == null || slot is RenderObject); |
| 826 assert(root is ContainerRenderObjectMixin); | 856 assert(root is ContainerRenderObjectMixin); |
| 827 root.add(child.root, before: slot); | 857 root.add(child.root, before: slot); |
| 828 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer | 858 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer |
| 829 } | 859 } |
| 830 | 860 |
| 861 @override |
| 831 void detachChildRoot(RenderObjectWrapper child) { | 862 void detachChildRoot(RenderObjectWrapper child) { |
| 832 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 863 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 833 assert(root is ContainerRenderObjectMixin); | 864 assert(root is ContainerRenderObjectMixin); |
| 834 assert(child.root.parent == root); | 865 assert(child.root.parent == root); |
| 835 root.remove(child.root); | 866 root.remove(child.root); |
| 836 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer | 867 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer |
| 837 } | 868 } |
| 838 | 869 |
| 870 @override |
| 839 void remove() { | 871 void remove() { |
| 840 assert(children != null); | 872 assert(children != null); |
| 841 for (var child in children) { | 873 for (var child in children) { |
| 842 assert(child != null); | 874 assert(child != null); |
| 843 removeChild(child); | 875 removeChild(child); |
| 844 } | 876 } |
| 845 super.remove(); | 877 super.remove(); |
| 846 } | 878 } |
| 847 | 879 |
| 848 bool _debugHasDuplicateIds() { | 880 bool _debugHasDuplicateIds() { |
| 849 var idSet = new HashSet<String>(); | 881 var idSet = new HashSet<String>(); |
| 850 for (var child in children) { | 882 for (var child in children) { |
| 851 assert(child != null); | 883 assert(child != null); |
| 852 if (child.key == null) | 884 if (child.key == null) |
| 853 continue; // when these nodes are reordered, we just reassign the data | 885 continue; // when these nodes are reordered, we just reassign the data |
| 854 | 886 |
| 855 if (!idSet.add(child.key)) { | 887 if (!idSet.add(child.key)) { |
| 856 throw '''If multiple keyed nodes exist as children of another node, they
must have unique keys. $this has duplicate child key "${child.key}".'''; | 888 throw '''If multiple keyed nodes exist as children of another node, they
must have unique keys. $this has duplicate child key "${child.key}".'''; |
| 857 } | 889 } |
| 858 } | 890 } |
| 859 return false; | 891 return false; |
| 860 } | 892 } |
| 861 | 893 |
| 894 @override |
| 862 void syncRenderObject(MultiChildRenderObjectWrapper old) { | 895 void syncRenderObject(MultiChildRenderObjectWrapper old) { |
| 863 super.syncRenderObject(old); | 896 super.syncRenderObject(old); |
| 864 | 897 |
| 865 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 898 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 866 if (root is! ContainerRenderObjectMixin) | 899 if (root is! ContainerRenderObjectMixin) |
| 867 return; | 900 return; |
| 868 | 901 |
| 869 var startIndex = 0; | 902 var startIndex = 0; |
| 870 var endIndex = children.length; | 903 var endIndex = children.length; |
| 871 | 904 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 | 1032 |
| 1000 WidgetSkyBinding({ RenderView renderViewOverride: null }) | 1033 WidgetSkyBinding({ RenderView renderViewOverride: null }) |
| 1001 : super(renderViewOverride: renderViewOverride); | 1034 : super(renderViewOverride: renderViewOverride); |
| 1002 | 1035 |
| 1003 static void initWidgetSkyBinding({ RenderView renderViewOverride: null }) { | 1036 static void initWidgetSkyBinding({ RenderView renderViewOverride: null }) { |
| 1004 if (SkyBinding.instance == null) | 1037 if (SkyBinding.instance == null) |
| 1005 new WidgetSkyBinding(renderViewOverride: renderViewOverride); | 1038 new WidgetSkyBinding(renderViewOverride: renderViewOverride); |
| 1006 assert(SkyBinding.instance is WidgetSkyBinding); | 1039 assert(SkyBinding.instance is WidgetSkyBinding); |
| 1007 } | 1040 } |
| 1008 | 1041 |
| 1042 @override |
| 1009 void dispatchEvent(sky.Event event, HitTestResult result) { | 1043 void dispatchEvent(sky.Event event, HitTestResult result) { |
| 1010 assert(SkyBinding.instance == this); | 1044 assert(SkyBinding.instance == this); |
| 1011 super.dispatchEvent(event, result); | 1045 super.dispatchEvent(event, result); |
| 1012 for (HitTestEntry entry in result.path.reversed) { | 1046 for (HitTestEntry entry in result.path.reversed) { |
| 1013 Widget target = RenderObjectWrapper._getMounted(entry.target); | 1047 Widget target = RenderObjectWrapper._getMounted(entry.target); |
| 1014 if (target == null) | 1048 if (target == null) |
| 1015 continue; | 1049 continue; |
| 1016 RenderObject targetRoot = target.root; | 1050 RenderObject targetRoot = target.root; |
| 1017 while (target != null && target.root == targetRoot) { | 1051 while (target != null && target.root == targetRoot) { |
| 1018 if (target is Listener) | 1052 if (target is Listener) |
| 1019 target._handleEvent(event); | 1053 target._handleEvent(event); |
| 1020 target = target._parent; | 1054 target = target._parent; |
| 1021 } | 1055 } |
| 1022 } | 1056 } |
| 1023 } | 1057 } |
| 1024 | 1058 |
| 1025 } | 1059 } |
| 1026 | 1060 |
| 1027 abstract class App extends StatefulComponent { | 1061 abstract class App extends StatefulComponent { |
| 1028 | 1062 |
| 1029 App({ String key }) : super(key: key); | 1063 App({ String key }) : super(key: key); |
| 1030 | 1064 |
| 1031 void _handleEvent(sky.Event event) { | 1065 void _handleEvent(sky.Event event) { |
| 1032 if (event.type == 'back') | 1066 if (event.type == 'back') |
| 1033 onBack(); | 1067 onBack(); |
| 1034 } | 1068 } |
| 1035 | 1069 |
| 1070 @override |
| 1036 void didMount() { | 1071 void didMount() { |
| 1037 super.didMount(); | 1072 super.didMount(); |
| 1038 SkyBinding.instance.addEventListener(_handleEvent); | 1073 SkyBinding.instance.addEventListener(_handleEvent); |
| 1039 } | 1074 } |
| 1040 | 1075 |
| 1076 @override |
| 1041 void didUnmount() { | 1077 void didUnmount() { |
| 1042 super.didUnmount(); | 1078 super.didUnmount(); |
| 1043 SkyBinding.instance.removeEventListener(_handleEvent); | 1079 SkyBinding.instance.removeEventListener(_handleEvent); |
| 1044 } | 1080 } |
| 1045 | 1081 |
| 1082 @override |
| 1046 void syncFields(Component source) { } | 1083 void syncFields(Component source) { } |
| 1047 | 1084 |
| 1048 // Override this to handle back button behavior in your app | 1085 // Override this to handle back button behavior in your app |
| 1049 // Call super.onBack() to finish the activity | 1086 // Call super.onBack() to finish the activity |
| 1050 void onBack() { | 1087 void onBack() { |
| 1051 activity.finishCurrentActivity(); | 1088 activity.finishCurrentActivity(); |
| 1052 } | 1089 } |
| 1053 } | 1090 } |
| 1054 | 1091 |
| 1055 abstract class AbstractWidgetRoot extends StatefulComponent { | 1092 abstract class AbstractWidgetRoot extends StatefulComponent { |
| 1056 | 1093 |
| 1057 AbstractWidgetRoot() { | 1094 AbstractWidgetRoot() { |
| 1058 _mounted = true; | 1095 _mounted = true; |
| 1059 _scheduleComponentForRender(this); | 1096 _scheduleComponentForRender(this); |
| 1060 } | 1097 } |
| 1061 | 1098 |
| 1099 @override |
| 1062 void syncFields(AbstractWidgetRoot source) { | 1100 void syncFields(AbstractWidgetRoot source) { |
| 1063 assert(false); | 1101 assert(false); |
| 1064 // if we get here, it implies that we have a parent | 1102 // if we get here, it implies that we have a parent |
| 1065 } | 1103 } |
| 1066 | 1104 |
| 1105 @override |
| 1067 void _buildIfDirty() { | 1106 void _buildIfDirty() { |
| 1068 assert(_dirty); | 1107 assert(_dirty); |
| 1069 assert(_mounted); | 1108 assert(_mounted); |
| 1070 assert(parent == null); | 1109 assert(parent == null); |
| 1071 _sync(null, null); | 1110 _sync(null, null); |
| 1072 } | 1111 } |
| 1073 | 1112 |
| 1074 } | 1113 } |
| 1075 | 1114 |
| 1076 class RenderViewWrapper extends OneChildRenderObjectWrapper { | 1115 class RenderViewWrapper extends OneChildRenderObjectWrapper { |
| 1077 RenderViewWrapper({ String key, Widget child }) : super(key: key, child: child
); | 1116 RenderViewWrapper({ String key, Widget child }) : super(key: key, child: child
); |
| 1117 |
| 1118 @override |
| 1078 RenderView get root => super.root; | 1119 RenderView get root => super.root; |
| 1120 |
| 1121 @override |
| 1079 RenderView createNode() => SkyBinding.instance.renderView; | 1122 RenderView createNode() => SkyBinding.instance.renderView; |
| 1080 } | 1123 } |
| 1081 | 1124 |
| 1082 class AppContainer extends AbstractWidgetRoot { | 1125 class AppContainer extends AbstractWidgetRoot { |
| 1083 AppContainer(this.app) { | 1126 AppContainer(this.app) { |
| 1084 assert(SkyBinding.instance is WidgetSkyBinding); | 1127 assert(SkyBinding.instance is WidgetSkyBinding); |
| 1085 } | 1128 } |
| 1086 final App app; | 1129 final App app; |
| 1130 |
| 1131 @override |
| 1087 Widget build() => new RenderViewWrapper(child: app); | 1132 Widget build() => new RenderViewWrapper(child: app); |
| 1088 } | 1133 } |
| 1089 | 1134 |
| 1090 void runApp(App app, { RenderView renderViewOverride, bool enableProfilingLoop:
false }) { | 1135 void runApp(App app, { RenderView renderViewOverride, bool enableProfilingLoop:
false }) { |
| 1091 WidgetSkyBinding.initWidgetSkyBinding(renderViewOverride: renderViewOverride); | 1136 WidgetSkyBinding.initWidgetSkyBinding(renderViewOverride: renderViewOverride); |
| 1092 new AppContainer(app); | 1137 new AppContainer(app); |
| 1093 if (enableProfilingLoop) { | 1138 if (enableProfilingLoop) { |
| 1094 new Timer.periodic(const Duration(milliseconds: 20), (_) { | 1139 new Timer.periodic(const Duration(milliseconds: 20), (_) { |
| 1095 app.scheduleBuild(); | 1140 app.scheduleBuild(); |
| 1096 }); | 1141 }); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1118 _container = value; | 1163 _container = value; |
| 1119 if (root != null) { | 1164 if (root != null) { |
| 1120 _container.child = root; | 1165 _container.child = root; |
| 1121 assert(_container.child == root); | 1166 assert(_container.child == root); |
| 1122 } | 1167 } |
| 1123 } | 1168 } |
| 1124 } | 1169 } |
| 1125 | 1170 |
| 1126 final Builder builder; | 1171 final Builder builder; |
| 1127 | 1172 |
| 1173 @override |
| 1128 void _buildIfDirty() { | 1174 void _buildIfDirty() { |
| 1129 super._buildIfDirty(); | 1175 super._buildIfDirty(); |
| 1130 if (root.parent == null) { | 1176 if (root.parent == null) { |
| 1131 // we haven't attached it yet | 1177 // we haven't attached it yet |
| 1132 assert(_container.child == null); | 1178 assert(_container.child == null); |
| 1133 _container.child = root; | 1179 _container.child = root; |
| 1134 } | 1180 } |
| 1135 assert(root.parent == _container); | 1181 assert(root.parent == _container); |
| 1136 } | 1182 } |
| 1137 | 1183 |
| 1184 @override |
| 1138 Widget build() => builder(); | 1185 Widget build() => builder(); |
| 1139 } | 1186 } |
| OLD | NEW |