| 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 library fn; | 5 library fn; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:sky' as sky; | 9 import 'dart:sky' as sky; |
| 10 import 'reflect.dart' as reflect; | 10 import 'reflect.dart' as reflect; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 | 175 |
| 176 class StyleNode extends ContentNode { | 176 class StyleNode extends ContentNode { |
| 177 final Style style; | 177 final Style style; |
| 178 | 178 |
| 179 StyleNode(UINode content, this.style): super(content); | 179 StyleNode(UINode content, this.style): super(content); |
| 180 } | 180 } |
| 181 | 181 |
| 182 /* | 182 /* |
| 183 * RenderNodes correspond to a desired state of a sky.Node. They are fully | 183 * SkyNodeWrappers correspond to a desired state of a sky.Node. They are fully |
| 184 * immutable, with one exception: A UINode which is a Component which lives with
in | 184 * immutable, with one exception: A UINode which is a Component which lives with
in |
| 185 * an WrapperNode's children list, may be replaced with the "old" instance if it | 185 * an SkyElementWrapper's children list, may be replaced with the "old" instance
if it |
| 186 * has become stateful. | 186 * has become stateful. |
| 187 */ | 187 */ |
| 188 abstract class RenderNode extends UINode { | 188 abstract class SkyNodeWrapper extends UINode { |
| 189 | 189 |
| 190 static final Map<sky.Node, RenderNode> _nodeMap = | 190 static final Map<sky.Node, SkyNodeWrapper> _nodeMap = |
| 191 new HashMap<sky.Node, RenderNode>(); | 191 new HashMap<sky.Node, SkyNodeWrapper>(); |
| 192 | 192 |
| 193 static RenderNode _getMounted(sky.Node node) => _nodeMap[node]; | 193 static SkyNodeWrapper _getMounted(sky.Node node) => _nodeMap[node]; |
| 194 | 194 |
| 195 RenderNode({ Object key }) : super(key: key); | 195 SkyNodeWrapper({ Object key }) : super(key: key); |
| 196 | 196 |
| 197 RenderNode get _emptyNode; | 197 SkyNodeWrapper get _emptyNode; |
| 198 | 198 |
| 199 sky.Node _createNode(); | 199 sky.Node _createNode(); |
| 200 | 200 |
| 201 void _sync(UINode old, sky.ParentNode host, sky.Node insertBefore) { | 201 void _sync(UINode old, sky.ParentNode host, sky.Node insertBefore) { |
| 202 if (old == null) { | 202 if (old == null) { |
| 203 _root = _createNode(); | 203 _root = _createNode(); |
| 204 _parentInsertBefore(host, _root, insertBefore); | 204 _parentInsertBefore(host, _root, insertBefore); |
| 205 old = _emptyNode; | 205 old = _emptyNode; |
| 206 } else { | 206 } else { |
| 207 _root = old._root; | 207 _root = old._root; |
| 208 } | 208 } |
| 209 | 209 |
| 210 _nodeMap[_root] = this; | 210 _nodeMap[_root] = this; |
| 211 _syncNode(old); | 211 _syncNode(old); |
| 212 } | 212 } |
| 213 | 213 |
| 214 void _syncNode(RenderNode old); | 214 void _syncNode(SkyNodeWrapper old); |
| 215 | 215 |
| 216 void _remove() { | 216 void _remove() { |
| 217 assert(_root != null); | 217 assert(_root != null); |
| 218 _root.remove(); | 218 _root.remove(); |
| 219 _nodeMap.remove(_root); | 219 _nodeMap.remove(_root); |
| 220 super._remove(); | 220 super._remove(); |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 | 223 |
| 224 typedef GestureEventListener(sky.GestureEvent e); | 224 typedef GestureEventListener(sky.GestureEvent e); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 super(content); | 304 super(content); |
| 305 | 305 |
| 306 void _handleEvent(sky.Event e) { | 306 void _handleEvent(sky.Event e) { |
| 307 sky.EventListener listener = listeners[e.type]; | 307 sky.EventListener listener = listeners[e.type]; |
| 308 if (listener != null) { | 308 if (listener != null) { |
| 309 listener(e); | 309 listener(e); |
| 310 } | 310 } |
| 311 } | 311 } |
| 312 | 312 |
| 313 static void _dispatchEvent(sky.Event e) { | 313 static void _dispatchEvent(sky.Event e) { |
| 314 UINode target = RenderNode._getMounted(e.target); | 314 UINode target = SkyNodeWrapper._getMounted(e.target); |
| 315 | 315 |
| 316 // TODO(rafaelw): StopPropagation? | 316 // TODO(rafaelw): StopPropagation? |
| 317 while (target != null) { | 317 while (target != null) { |
| 318 if (target is EventListenerNode) { | 318 if (target is EventListenerNode) { |
| 319 (target as EventListenerNode)._handleEvent(e); | 319 (target as EventListenerNode)._handleEvent(e); |
| 320 } | 320 } |
| 321 | 321 |
| 322 target = target._parent; | 322 target = target._parent; |
| 323 } | 323 } |
| 324 } | 324 } |
| 325 | 325 |
| 326 static void _ensureDocumentListener(String eventType) { | 326 static void _ensureDocumentListener(String eventType) { |
| 327 if (_registeredEvents.add(eventType)) { | 327 if (_registeredEvents.add(eventType)) { |
| 328 sky.document.addEventListener(eventType, _dispatchEvent); | 328 sky.document.addEventListener(eventType, _dispatchEvent); |
| 329 } | 329 } |
| 330 } | 330 } |
| 331 | 331 |
| 332 void _sync(UINode old, sky.ParentNode host, sky.Node insertBefore) { | 332 void _sync(UINode old, sky.ParentNode host, sky.Node insertBefore) { |
| 333 for (var type in listeners.keys) { | 333 for (var type in listeners.keys) { |
| 334 _ensureDocumentListener(type); | 334 _ensureDocumentListener(type); |
| 335 } | 335 } |
| 336 | 336 |
| 337 super._sync(old, host, insertBefore); | 337 super._sync(old, host, insertBefore); |
| 338 } | 338 } |
| 339 } | 339 } |
| 340 | 340 |
| 341 class Text extends RenderNode { | 341 class Text extends SkyNodeWrapper { |
| 342 final String data; | 342 final String data; |
| 343 | 343 |
| 344 // Text nodes are special cases of having non-unique keys (which don't need | 344 // Text nodes are special cases of having non-unique keys (which don't need |
| 345 // to be assigned as part of the API). Since they are unique in not having | 345 // to be assigned as part of the API). Since they are unique in not having |
| 346 // children, there's little point to reordering, so we always just re-assign | 346 // children, there's little point to reordering, so we always just re-assign |
| 347 // the data. | 347 // the data. |
| 348 Text(this.data) : super(key:'*text*'); | 348 Text(this.data) : super(key:'*text*'); |
| 349 | 349 |
| 350 static final Text _emptyText = new Text(null); | 350 static final Text _emptyText = new Text(null); |
| 351 | 351 |
| 352 RenderNode get _emptyNode => _emptyText; | 352 SkyNodeWrapper get _emptyNode => _emptyText; |
| 353 | 353 |
| 354 sky.Node _createNode() { | 354 sky.Node _createNode() { |
| 355 return new sky.Text(data); | 355 return new sky.Text(data); |
| 356 } | 356 } |
| 357 | 357 |
| 358 void _syncNode(RenderNode old) { | 358 void _syncNode(SkyNodeWrapper old) { |
| 359 if (old == _emptyText) | 359 if (old == _emptyText) |
| 360 return; // we set inside _createNode(); | 360 return; // we set inside _createNode(); |
| 361 | 361 |
| 362 (_root as sky.Text).data = data; | 362 (_root as sky.Text).data = data; |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 | 365 |
| 366 final List<UINode> _emptyList = new List<UINode>(); | 366 final List<UINode> _emptyList = new List<UINode>(); |
| 367 | 367 |
| 368 abstract class WrapperNode extends RenderNode { | 368 abstract class SkyElementWrapper extends SkyNodeWrapper { |
| 369 | 369 |
| 370 String get _tagName; | 370 String get _tagName; |
| 371 | 371 |
| 372 sky.Node _createNode() => sky.document.createElement(_tagName); | 372 sky.Node _createNode() => sky.document.createElement(_tagName); |
| 373 | 373 |
| 374 final List<UINode> children; | 374 final List<UINode> children; |
| 375 final Style style; | 375 final Style style; |
| 376 final String inlineStyle; | 376 final String inlineStyle; |
| 377 | 377 |
| 378 String _class; | 378 String _class; |
| 379 | 379 |
| 380 WrapperNode({ | 380 SkyElementWrapper({ |
| 381 Object key, | 381 Object key, |
| 382 List<UINode> children, | 382 List<UINode> children, |
| 383 this.style, | 383 this.style, |
| 384 this.inlineStyle | 384 this.inlineStyle |
| 385 }) : this.children = children == null ? _emptyList : children, | 385 }) : this.children = children == null ? _emptyList : children, |
| 386 super(key:key) { | 386 super(key:key) { |
| 387 | 387 |
| 388 assert(!_debugHasDuplicateIds()); | 388 assert(!_debugHasDuplicateIds()); |
| 389 } | 389 } |
| 390 | 390 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 413 } | 413 } |
| 414 | 414 |
| 415 void _ensureClass() { | 415 void _ensureClass() { |
| 416 if (_class == null) { | 416 if (_class == null) { |
| 417 List<Style> styles = new List<Style>(); | 417 List<Style> styles = new List<Style>(); |
| 418 if (style != null) { | 418 if (style != null) { |
| 419 styles.add(style); | 419 styles.add(style); |
| 420 } | 420 } |
| 421 | 421 |
| 422 UINode parent = _parent; | 422 UINode parent = _parent; |
| 423 while (parent != null && parent is! RenderNode) { | 423 while (parent != null && parent is! SkyNodeWrapper) { |
| 424 if (parent is StyleNode && (parent as StyleNode).style != null) | 424 if (parent is StyleNode && (parent as StyleNode).style != null) |
| 425 styles.add((parent as StyleNode).style); | 425 styles.add((parent as StyleNode).style); |
| 426 | 426 |
| 427 parent = parent._parent; | 427 parent = parent._parent; |
| 428 } | 428 } |
| 429 | 429 |
| 430 _class = styles.map((s) => s._className).join(' '); | 430 _class = styles.map((s) => s._className).join(' '); |
| 431 } | 431 } |
| 432 } | 432 } |
| 433 | 433 |
| 434 void _syncNode(RenderNode old) { | 434 void _syncNode(SkyNodeWrapper old) { |
| 435 WrapperNode oldWrapperNode = old as WrapperNode; | 435 SkyElementWrapper oldSkyElementWrapper = old as SkyElementWrapper; |
| 436 sky.Element root = _root as sky.Element; | 436 sky.Element root = _root as sky.Element; |
| 437 | 437 |
| 438 _ensureClass(); | 438 _ensureClass(); |
| 439 if (_class != oldWrapperNode._class && _class != '') | 439 if (_class != oldSkyElementWrapper._class && _class != '') |
| 440 root.setAttribute('class', _class); | 440 root.setAttribute('class', _class); |
| 441 | 441 |
| 442 if (inlineStyle != oldWrapperNode.inlineStyle) | 442 if (inlineStyle != oldSkyElementWrapper.inlineStyle) |
| 443 root.setAttribute('style', inlineStyle); | 443 root.setAttribute('style', inlineStyle); |
| 444 | 444 |
| 445 _syncChildren(oldWrapperNode); | 445 _syncChildren(oldSkyElementWrapper); |
| 446 } | 446 } |
| 447 | 447 |
| 448 void _syncChildren(WrapperNode oldWrapperNode) { | 448 void _syncChildren(SkyElementWrapper oldSkyElementWrapper) { |
| 449 sky.Element root = _root as sky.Element; | 449 sky.Element root = _root as sky.Element; |
| 450 assert(root != null); | 450 assert(root != null); |
| 451 | 451 |
| 452 var startIndex = 0; | 452 var startIndex = 0; |
| 453 var endIndex = children.length; | 453 var endIndex = children.length; |
| 454 | 454 |
| 455 var oldChildren = oldWrapperNode.children; | 455 var oldChildren = oldSkyElementWrapper.children; |
| 456 var oldStartIndex = 0; | 456 var oldStartIndex = 0; |
| 457 var oldEndIndex = oldChildren.length; | 457 var oldEndIndex = oldChildren.length; |
| 458 | 458 |
| 459 sky.Node nextSibling = null; | 459 sky.Node nextSibling = null; |
| 460 UINode currentNode = null; | 460 UINode currentNode = null; |
| 461 UINode oldNode = null; | 461 UINode oldNode = null; |
| 462 | 462 |
| 463 void sync(int atIndex) { | 463 void sync(int atIndex) { |
| 464 children[atIndex] = _syncChild(currentNode, oldNode, _root, nextSibling); | 464 children[atIndex] = _syncChild(currentNode, oldNode, _root, nextSibling); |
| 465 } | 465 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 // Removals | 555 // Removals |
| 556 currentNode = null; | 556 currentNode = null; |
| 557 while (oldStartIndex < oldEndIndex) { | 557 while (oldStartIndex < oldEndIndex) { |
| 558 oldNode = oldChildren[oldStartIndex]; | 558 oldNode = oldChildren[oldStartIndex]; |
| 559 _removeChild(oldNode); | 559 _removeChild(oldNode); |
| 560 advanceOldStartIndex(); | 560 advanceOldStartIndex(); |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 } | 563 } |
| 564 | 564 |
| 565 class Container extends WrapperNode { | 565 class Container extends SkyElementWrapper { |
| 566 | 566 |
| 567 String get _tagName => 'div'; | 567 String get _tagName => 'div'; |
| 568 | 568 |
| 569 static final Container _emptyContainer = new Container(); | 569 static final Container _emptyContainer = new Container(); |
| 570 | 570 |
| 571 RenderNode get _emptyNode => _emptyContainer; | 571 SkyNodeWrapper get _emptyNode => _emptyContainer; |
| 572 | 572 |
| 573 Container({ | 573 Container({ |
| 574 Object key, | 574 Object key, |
| 575 List<UINode> children, | 575 List<UINode> children, |
| 576 Style style, | 576 Style style, |
| 577 String inlineStyle | 577 String inlineStyle |
| 578 }) : super( | 578 }) : super( |
| 579 key: key, | 579 key: key, |
| 580 children: children, | 580 children: children, |
| 581 style: style, | 581 style: style, |
| 582 inlineStyle: inlineStyle | 582 inlineStyle: inlineStyle |
| 583 ); | 583 ); |
| 584 } | 584 } |
| 585 | 585 |
| 586 class Image extends WrapperNode { | 586 class Image extends SkyElementWrapper { |
| 587 | 587 |
| 588 String get _tagName => 'img'; | 588 String get _tagName => 'img'; |
| 589 | 589 |
| 590 static final Image _emptyImage = new Image(); | 590 static final Image _emptyImage = new Image(); |
| 591 | 591 |
| 592 RenderNode get _emptyNode => _emptyImage; | 592 SkyNodeWrapper get _emptyNode => _emptyImage; |
| 593 | 593 |
| 594 final String src; | 594 final String src; |
| 595 final int width; | 595 final int width; |
| 596 final int height; | 596 final int height; |
| 597 | 597 |
| 598 Image({ | 598 Image({ |
| 599 Object key, | 599 Object key, |
| 600 List<UINode> children, | 600 List<UINode> children, |
| 601 Style style, | 601 Style style, |
| 602 String inlineStyle, | 602 String inlineStyle, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 620 skyImage.src = src; | 620 skyImage.src = src; |
| 621 | 621 |
| 622 if (width != oldImage.width) | 622 if (width != oldImage.width) |
| 623 skyImage.style['width'] = '${width}px'; | 623 skyImage.style['width'] = '${width}px'; |
| 624 | 624 |
| 625 if (height != oldImage.height) | 625 if (height != oldImage.height) |
| 626 skyImage.style['height'] = '${height}px'; | 626 skyImage.style['height'] = '${height}px'; |
| 627 } | 627 } |
| 628 } | 628 } |
| 629 | 629 |
| 630 class Anchor extends WrapperNode { | 630 class Anchor extends SkyElementWrapper { |
| 631 | 631 |
| 632 String get _tagName => 'a'; | 632 String get _tagName => 'a'; |
| 633 | 633 |
| 634 static final Anchor _emptyAnchor = new Anchor(); | 634 static final Anchor _emptyAnchor = new Anchor(); |
| 635 | 635 |
| 636 UINode get _emptyNode => _emptyAnchor; | 636 UINode get _emptyNode => _emptyAnchor; |
| 637 | 637 |
| 638 final String href; | 638 final String href; |
| 639 final int width; | 639 final int width; |
| 640 final int height; | 640 final int height; |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 | 881 |
| 882 abstract class App extends Component { | 882 abstract class App extends Component { |
| 883 sky.Node _host; | 883 sky.Node _host; |
| 884 | 884 |
| 885 App() : super(stateful: true) { | 885 App() : super(stateful: true) { |
| 886 _host = sky.document.createElement('div'); | 886 _host = sky.document.createElement('div'); |
| 887 sky.document.appendChild(_host); | 887 sky.document.appendChild(_host); |
| 888 _scheduleComponentForRender(this); | 888 _scheduleComponentForRender(this); |
| 889 } | 889 } |
| 890 } | 890 } |
| OLD | NEW |