Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(439)

Side by Side Diff: sky/framework/fn.dart

Issue 987463002: Move fn.dart into /sky/framework (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/examples/stocks-fn/stocksapp.dart ('k') | sky/framework/reflect.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of fn; 5 library fn;
6
7 import 'dart:async';
8 import 'dart:collection';
9 import 'dart:sky' as sky;
10 import 'reflect.dart' as reflect;
11
12 bool _checkedMode;
13
14 bool _debugWarnings() {
15 void testFn(double i) {}
16
17 if (_checkedMode == null) {
18 _checkedMode = false;
19 try {
20 testFn('not a double');
21 } catch (ex) {
22 _checkedMode = true;
23 }
24 }
25
26 return _checkedMode;
27 }
28
29 class EventHandler {
30 final String type;
31 final sky.EventListener listener;
32
33 EventHandler(this.type, this.listener);
34 }
35
36 class EventMap {
37 final List<EventHandler> _handlers = new List<EventHandler>();
38
39 void listen(String type, sky.EventListener listener) {
40 assert(listener != null);
41 _handlers.add(new EventHandler(type, listener));
42 }
43
44 void addAll(EventMap events) {
45 _handlers.addAll(events._handlers);
46 }
47 }
48
49 class Style {
50 final String _className;
51 static final Map<String, Style> _cache = new HashMap<String, Style>();
52
53 static int nextStyleId = 1;
54
55 static String nextClassName(String styles) {
56 assert(sky.document != null);
57 String className = "style$nextStyleId";
58 nextStyleId++;
59
60 sky.Element styleNode = sky.document.createElement('style');
61 styleNode.setChild(new sky.Text(".$className { $styles }"));
62 sky.document.appendChild(styleNode);
63
64 return className;
65 }
66
67 factory Style(String styles) {
68 return _cache.putIfAbsent(styles, () {
69 return new Style._internal(nextClassName(styles));
70 });
71 }
72
73 Style._internal(this._className);
74 }
6 75
7 void _parentInsertBefore(sky.ParentNode parent, 76 void _parentInsertBefore(sky.ParentNode parent,
8 sky.Node node, 77 sky.Node node,
9 sky.Node ref) { 78 sky.Node ref) {
10 if (ref != null) { 79 if (ref != null) {
11 ref.insertBefore([node]); 80 ref.insertBefore([node]);
12 } else { 81 } else {
13 parent.appendChild(node); 82 parent.appendChild(node);
14 } 83 }
15 } 84 }
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 void _syncNode([Element old]) { 495 void _syncNode([Element old]) {
427 Anchor oldAnchor = old != null ? old as Anchor : _emptyAnchor; 496 Anchor oldAnchor = old != null ? old as Anchor : _emptyAnchor;
428 super._syncNode(oldAnchor); 497 super._syncNode(oldAnchor);
429 498
430 sky.HTMLAnchorElement skyAnchor = _root as sky.HTMLAnchorElement; 499 sky.HTMLAnchorElement skyAnchor = _root as sky.HTMLAnchorElement;
431 if (href != oldAnchor.href) { 500 if (href != oldAnchor.href) {
432 skyAnchor.href = href; 501 skyAnchor.href = href;
433 } 502 }
434 } 503 }
435 } 504 }
505
506 List<Component> _dirtyComponents = new List<Component>();
507 bool _renderScheduled = false;
508
509 void _renderDirtyComponents() {
510 Stopwatch sw = new Stopwatch()..start();
511
512 _dirtyComponents.sort((a, b) => a._order - b._order);
513 for (var comp in _dirtyComponents) {
514 comp._renderIfDirty();
515 }
516
517 _dirtyComponents.clear();
518 _renderScheduled = false;
519 sw.stop();
520 print("Render took ${sw.elapsedMicroseconds} microseconds");
521 }
522
523 void _scheduleComponentForRender(Component c) {
524 _dirtyComponents.add(c);
525
526 if (!_renderScheduled) {
527 _renderScheduled = true;
528 new Future.microtask(_renderDirtyComponents);
529 }
530 }
531
532 abstract class Component extends Node {
533 bool _dirty = true; // components begin dirty because they haven't rendered.
534 Node _rendered = null;
535 bool _removed = false;
536 final int _order;
537 static int _currentOrder = 0;
538 bool _stateful;
539 static Component _currentlyRendering;
540
541 Component({ Object key, bool stateful })
542 : _stateful = stateful != null ? stateful : false,
543 _order = _currentOrder + 1,
544 super(key:key);
545
546 void willUnmount() {}
547
548 void _remove() {
549 assert(_rendered != null);
550 assert(_root != null);
551 willUnmount();
552 _rendered._remove();
553 _rendered = null;
554 _root = null;
555 _removed = true;
556 }
557
558 // TODO(rafaelw): It seems wrong to expose DOM at all. This is presently
559 // needed to get sizing info.
560 sky.Node getRoot() => _root;
561
562 bool _sync(Node old, sky.Node host, sky.Node insertBefore) {
563 Component oldComponent = old as Component;
564
565 if (oldComponent == null || oldComponent == this) {
566 _renderInternal(host, insertBefore);
567 return false;
568 }
569
570 assert(oldComponent != null);
571 assert(_dirty);
572 assert(_rendered == null);
573
574 if (oldComponent._stateful) {
575 _stateful = false; // prevent iloop from _renderInternal below.
576
577 reflect.copyPublicFields(this, oldComponent);
578
579 oldComponent._dirty = true;
580 _dirty = false;
581
582 oldComponent._renderInternal(host, insertBefore);
583 return true; // Must retain old component
584 }
585
586 _rendered = oldComponent._rendered;
587 _renderInternal(host, insertBefore);
588 return false;
589 }
590
591 void _renderInternal(sky.Node host, sky.Node insertBefore) {
592 if (!_dirty) {
593 assert(_rendered != null);
594 return;
595 }
596
597 var oldRendered = _rendered;
598 int lastOrder = _currentOrder;
599 _currentOrder = _order;
600 _currentlyRendering = this;
601 _rendered = render();
602 _currentlyRendering = null;
603 _currentOrder = lastOrder;
604
605 _rendered.events.addAll(events);
606
607 _dirty = false;
608
609 // TODO(rafaelw): This prevents components from returning different node
610 // types as their root node at different times. Consider relaxing.
611 assert(oldRendered == null ||
612 _rendered.runtimeType == oldRendered.runtimeType);
613
614 if (_rendered._sync(oldRendered, host, insertBefore)) {
615 _rendered = oldRendered; // retain stateful component
616 }
617 _root = _rendered._root;
618 assert(_rendered._root is sky.Node);
619 }
620
621 void _renderIfDirty() {
622 assert(_rendered != null);
623 assert(!_removed);
624
625 var rendered = _rendered;
626 while (rendered is Component) {
627 rendered = rendered._rendered;
628 }
629 sky.Node root = rendered._root;
630
631 _renderInternal(root.parentNode, root.nextSibling);
632 }
633
634 void setState(Function fn()) {
635 assert(_rendered != null); // cannot setState before mounting.
636 _stateful = true;
637 fn();
638 if (_currentlyRendering != this) {
639 _dirty = true;
640 _scheduleComponentForRender(this);
641 }
642 }
643
644 Node render();
645 }
646
647 abstract class App extends Component {
648 sky.Node _host = null;
649 App()
650 : super(stateful: true) {
651
652 _host = sky.document.createElement('div');
653 sky.document.appendChild(_host);
654
655 new Future.microtask(() {
656 Stopwatch sw = new Stopwatch()..start();
657 _sync(null, _host, null);
658 assert(_root is sky.Node);
659 sw.stop();
660 print("Initial render: ${sw.elapsedMicroseconds} microseconds");
661 });
662 }
663 }
OLDNEW
« no previous file with comments | « sky/examples/stocks-fn/stocksapp.dart ('k') | sky/framework/reflect.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698