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

Side by Side Diff: pkg/polymer/lib/src/instance.dart

Issue 27518006: Practically remove boot.js, adds the initialization from the Dart side of (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of polymer; 5 part of polymer;
6 6
7 /** 7 /**
8 * Use this annotation to publish a field as an attribute. For example: 8 * Use this annotation to publish a field as an attribute. For example:
9 * 9 *
10 * class MyPlaybackElement extends PolymerElement { 10 * class MyPlaybackElement extends PolymerElement {
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 } else { 401 } else {
402 // Cannot call super.bind because of 402 // Cannot call super.bind because of
403 // https://code.google.com/p/dart/issues/detail?id=13156 403 // https://code.google.com/p/dart/issues/detail?id=13156
404 // https://code.google.com/p/dart/issues/detail?id=12456 404 // https://code.google.com/p/dart/issues/detail?id=12456
405 return TemplateElement.mdvPackage(this).bind(name, model, path); 405 return TemplateElement.mdvPackage(this).bind(name, model, path);
406 } 406 }
407 } 407 }
408 408
409 void asyncUnbindAll() { 409 void asyncUnbindAll() {
410 if (_unbound == true) return; 410 if (_unbound == true) return;
411 _unbindLog.info('[$localName] asyncUnbindAll'); 411 _unbindLog.fine('[$localName] asyncUnbindAll');
412 _unbindAllJob = job(_unbindAllJob, unbindAll, const Duration(seconds: 0)); 412 _unbindAllJob = job(_unbindAllJob, unbindAll, const Duration(seconds: 0));
413 } 413 }
414 414
415 void unbindAll() { 415 void unbindAll() {
416 if (_unbound == true) return; 416 if (_unbound == true) return;
417 417
418 unbindAllProperties(); 418 unbindAllProperties();
419 // Cannot call super.bind because of 419 // Cannot call super.bind because of
420 // https://code.google.com/p/dart/issues/detail?id=13156 420 // https://code.google.com/p/dart/issues/detail?id=13156
421 // https://code.google.com/p/dart/issues/detail?id=12456 421 // https://code.google.com/p/dart/issues/detail?id=12456
422 TemplateElement.mdvPackage(this).unbindAll(); 422 TemplateElement.mdvPackage(this).unbindAll();
423 423
424 _unbindNodeTree(shadowRoot); 424 _unbindNodeTree(shadowRoot);
425 // TODO(sjmiles): must also unbind inherited shadow roots 425 // TODO(sjmiles): must also unbind inherited shadow roots
426 _unbound = true; 426 _unbound = true;
427 } 427 }
428 428
429 void cancelUnbindAll({bool preventCascade}) { 429 void cancelUnbindAll({bool preventCascade}) {
430 if (_unbound == true) { 430 if (_unbound == true) {
431 _unbindLog.warning( 431 _unbindLog.warning(
432 '[$localName] already unbound, cannot cancel unbindAll'); 432 '[$localName] already unbound, cannot cancel unbindAll');
433 return; 433 return;
434 } 434 }
435 _unbindLog.info('[$localName] cancelUnbindAll'); 435 _unbindLog.fine('[$localName] cancelUnbindAll');
436 if (_unbindAllJob != null) { 436 if (_unbindAllJob != null) {
437 _unbindAllJob.stop(); 437 _unbindAllJob.stop();
438 _unbindAllJob = null; 438 _unbindAllJob = null;
439 } 439 }
440 440
441 // cancel unbinding our shadow tree iff we're not in the process of 441 // cancel unbinding our shadow tree iff we're not in the process of
442 // cascading our tree (as we do, for example, when the element is inserted). 442 // cascading our tree (as we do, for example, when the element is inserted).
443 if (preventCascade == true) return; 443 if (preventCascade == true) return;
444 _forNodeTree(shadowRoot, (n) { 444 _forNodeTree(shadowRoot, (n) {
445 if (n is Polymer) { 445 if (n is Polymer) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 if (publish != null) { 484 if (publish != null) {
485 publish.forEach((name, value) { 485 publish.forEach((name, value) {
486 if (observe == null || !observe.containsKey(name)) { 486 if (observe == null || !observe.containsKey(name)) {
487 observeAttributeProperty(name); 487 observeAttributeProperty(name);
488 } 488 }
489 }); 489 });
490 } 490 }
491 } 491 }
492 492
493 void _observe(String name, void callback(newValue, oldValue)) { 493 void _observe(String name, void callback(newValue, oldValue)) {
494 _observeLog.info('[$localName] watching [$name]'); 494 _observeLog.fine('[$localName] watching [$name]');
495 // TODO(jmesserly): this is a little different than the JS version so we 495 // TODO(jmesserly): this is a little different than the JS version so we
496 // can pass the oldValue, which is missing from Dart's PathObserver. 496 // can pass the oldValue, which is missing from Dart's PathObserver.
497 // This probably gives us worse performance. 497 // This probably gives us worse performance.
498 var path = new PathObserver(this, name); 498 var path = new PathObserver(this, name);
499 Object oldValue = null; 499 Object oldValue = null;
500 _registerObserver(name, path.changes.listen((_) { 500 _registerObserver(name, path.changes.listen((_) {
501 final newValue = path.value; 501 final newValue = path.value;
502 final old = oldValue; 502 final old = oldValue;
503 oldValue = newValue; 503 oldValue = newValue;
504 callback(newValue, old); 504 callback(newValue, old);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 // apply Polymer two-way reference binding 558 // apply Polymer two-way reference binding
559 _bindProperties(this, name, model, path); 559 _bindProperties(this, name, model, path);
560 560
561 /** 561 /**
562 * bind a property in A to a path in B by converting A[property] to a 562 * bind a property in A to a path in B by converting A[property] to a
563 * getter/setter pair that accesses B[...path...] 563 * getter/setter pair that accesses B[...path...]
564 */ 564 */
565 static NodeBinding _bindProperties(Polymer inA, Symbol inProperty, 565 static NodeBinding _bindProperties(Polymer inA, Symbol inProperty,
566 Object inB, String inPath) { 566 Object inB, String inPath) {
567 567
568 if (_bindLog.isLoggable(Level.INFO)) { 568 if (_bindLog.isLoggable(Level.FINE)) {
569 _bindLog.info('[$inB]: bindProperties: [$inPath] to ' 569 _bindLog.fine('[$inB]: bindProperties: [$inPath] to '
570 '[${inA.localName}].[$inProperty]'); 570 '[${inA.localName}].[$inProperty]');
571 } 571 }
572 572
573 // Dart note: normally we only reach this code when we know it's a 573 // Dart note: normally we only reach this code when we know it's a
574 // property, but if someone uses bindProperty directly they might get a 574 // property, but if someone uses bindProperty directly they might get a
575 // NoSuchMethodError either from the getField below, or from the setField 575 // NoSuchMethodError either from the getField below, or from the setField
576 // inside PolymerBinding. That doesn't seem unreasonable, but it's a slight 576 // inside PolymerBinding. That doesn't seem unreasonable, but it's a slight
577 // difference from Polymer.js behavior. 577 // difference from Polymer.js behavior.
578 578
579 // capture A's value if B's value is null or undefined, 579 // capture A's value if B's value is null or undefined,
580 // otherwise use B's value 580 // otherwise use B's value
581 var path = new PathObserver(inB, inPath); 581 var path = new PathObserver(inB, inPath);
582 if (path.value == null) { 582 if (path.value == null) {
583 path.value = reflect(inA).getField(inProperty).reflectee; 583 path.value = reflect(inA).getField(inProperty).reflectee;
584 } 584 }
585 return new _PolymerBinding(inA, inProperty, inB, inPath); 585 return new _PolymerBinding(inA, inProperty, inB, inPath);
586 } 586 }
587 587
588 /** Attach event listeners on the host (this) element. */ 588 /** Attach event listeners on the host (this) element. */
589 void addHostListeners() { 589 void addHostListeners() {
590 var events = _declaration._eventDelegates; 590 var events = _declaration._eventDelegates;
591 if (events.isEmpty) return; 591 if (events.isEmpty) return;
592 592
593 if (_eventsLog.isLoggable(Level.INFO)) { 593 if (_eventsLog.isLoggable(Level.FINE)) {
594 _eventsLog.info('[$localName] addHostListeners: $events'); 594 _eventsLog.fine('[$localName] addHostListeners: $events');
595 } 595 }
596 addNodeListeners(this, events.keys, hostEventListener); 596 addNodeListeners(this, events.keys, hostEventListener);
597 } 597 }
598 598
599 /** Attach event listeners inside a shadow [root]. */ 599 /** Attach event listeners inside a shadow [root]. */
600 void addInstanceListeners(ShadowRoot root, Element template) { 600 void addInstanceListeners(ShadowRoot root, Element template) {
601 var templateDelegates = _declaration._templateDelegates; 601 var templateDelegates = _declaration._templateDelegates;
602 if (templateDelegates == null) return; 602 if (templateDelegates == null) return;
603 var events = templateDelegates[template]; 603 var events = templateDelegates[template];
604 if (events == null) return; 604 if (events == null) return;
605 605
606 if (_eventsLog.isLoggable(Level.INFO)) { 606 if (_eventsLog.isLoggable(Level.FINE)) {
607 _eventsLog.info('[$localName] addInstanceListeners: $events'); 607 _eventsLog.fine('[$localName] addInstanceListeners: $events');
608 } 608 }
609 addNodeListeners(root, events, instanceEventListener); 609 addNodeListeners(root, events, instanceEventListener);
610 } 610 }
611 611
612 void addNodeListeners(Node node, Iterable<String> events, 612 void addNodeListeners(Node node, Iterable<String> events,
613 void listener(Event e)) { 613 void listener(Event e)) {
614 614
615 for (var name in events) { 615 for (var name in events) {
616 addNodeListener(node, name, listener); 616 addNodeListener(node, name, listener);
617 } 617 }
618 } 618 }
619 619
620 void addNodeListener(Node node, String event, void listener(Event e)) { 620 void addNodeListener(Node node, String event, void listener(Event e)) {
621 node.on[event].listen(listener); 621 node.on[event].listen(listener);
622 } 622 }
623 623
624 void hostEventListener(Event event) { 624 void hostEventListener(Event event) {
625 // TODO(jmesserly): do we need this check? It was using cancelBubble, see: 625 // TODO(jmesserly): do we need this check? It was using cancelBubble, see:
626 // https://github.com/Polymer/polymer/issues/292 626 // https://github.com/Polymer/polymer/issues/292
627 if (!event.bubbles) return; 627 if (!event.bubbles) return;
628 628
629 bool log = _eventsLog.isLoggable(Level.INFO); 629 bool log = _eventsLog.isLoggable(Level.FINE);
630 if (log) { 630 if (log) {
631 _eventsLog.info('>>> [$localName]: hostEventListener(${event.type})'); 631 _eventsLog.fine('>>> [$localName]: hostEventListener(${event.type})');
632 } 632 }
633 633
634 var h = findEventDelegate(event); 634 var h = findEventDelegate(event);
635 if (h != null) { 635 if (h != null) {
636 if (log) _eventsLog.info('[$localName] found host handler name [$h]'); 636 if (log) _eventsLog.fine('[$localName] found host handler name [$h]');
637 var detail = event is CustomEvent ? 637 var detail = event is CustomEvent ?
638 (event as CustomEvent).detail : null; 638 (event as CustomEvent).detail : null;
639 // TODO(jmesserly): cache the symbols? 639 // TODO(jmesserly): cache the symbols?
640 dispatchMethod(new Symbol(h), [event, detail, this]); 640 dispatchMethod(new Symbol(h), [event, detail, this]);
641 } 641 }
642 642
643 if (log) { 643 if (log) {
644 _eventsLog.info('<<< [$localName]: hostEventListener(${event.type})'); 644 _eventsLog.fine('<<< [$localName]: hostEventListener(${event.type})');
645 } 645 }
646 } 646 }
647 647
648 String findEventDelegate(Event event) => 648 String findEventDelegate(Event event) =>
649 _declaration._eventDelegates[_eventNameFromType(event.type)]; 649 _declaration._eventDelegates[_eventNameFromType(event.type)];
650 650
651 /** Call [methodName] method on [this] with [args], if the method exists. */ 651 /** Call [methodName] method on [this] with [args], if the method exists. */
652 // TODO(jmesserly): I removed the [node] argument as it was unused. Reconcile. 652 // TODO(jmesserly): I removed the [node] argument as it was unused. Reconcile.
653 void dispatchMethod(Symbol methodName, List args) { 653 void dispatchMethod(Symbol methodName, List args) {
654 bool log = _eventsLog.isLoggable(Level.INFO); 654 bool log = _eventsLog.isLoggable(Level.FINE);
655 if (log) _eventsLog.info('>>> [$localName]: dispatch $methodName'); 655 if (log) _eventsLog.fine('>>> [$localName]: dispatch $methodName');
656 656
657 // TODO(sigmund): consider making event listeners list all arguments 657 // TODO(sigmund): consider making event listeners list all arguments
658 // explicitly. Unless VM mirrors are optimized first, this reflectClass call 658 // explicitly. Unless VM mirrors are optimized first, this reflectClass call
659 // will be expensive once custom elements extend directly from Element (see 659 // will be expensive once custom elements extend directly from Element (see
660 // dartbug.com/11108). 660 // dartbug.com/11108).
661 var self = reflect(this); 661 var self = reflect(this);
662 var method = self.type.methods[methodName]; 662 var method = self.type.methods[methodName];
663 if (method != null) { 663 if (method != null) {
664 // This will either truncate the argument list or extend it with extra 664 // This will either truncate the argument list or extend it with extra
665 // null arguments, so it will match the signature. 665 // null arguments, so it will match the signature.
666 // TODO(sigmund): consider accepting optional arguments when we can tell 666 // TODO(sigmund): consider accepting optional arguments when we can tell
667 // them appart from named arguments (see http://dartbug.com/11334) 667 // them appart from named arguments (see http://dartbug.com/11334)
668 args.length = method.parameters.where((p) => !p.isOptional).length; 668 args.length = method.parameters.where((p) => !p.isOptional).length;
669 } 669 }
670 self.invoke(methodName, args); 670 self.invoke(methodName, args);
671 671
672 if (log) _eventsLog.info('<<< [$localName]: dispatch $methodName'); 672 if (log) _eventsLog.fine('<<< [$localName]: dispatch $methodName');
673 673
674 // TODO(jmesserly): workaround for HTML events not supporting zones. 674 // TODO(jmesserly): workaround for HTML events not supporting zones.
675 performMicrotaskCheckpoint(); 675 performMicrotaskCheckpoint();
676 } 676 }
677 677
678 void instanceEventListener(Event event) { 678 void instanceEventListener(Event event) {
679 _listenLocal(this, event); 679 _listenLocal(this, event);
680 } 680 }
681 681
682 // TODO(sjmiles): much of the below privatized only because of the vague 682 // TODO(sjmiles): much of the below privatized only because of the vague
683 // notion this code is too fiddly and we need to revisit the core feature 683 // notion this code is too fiddly and we need to revisit the core feature
684 void _listenLocal(Polymer host, Event event) { 684 void _listenLocal(Polymer host, Event event) {
685 // TODO(jmesserly): do we need this check? It was using cancelBubble, see: 685 // TODO(jmesserly): do we need this check? It was using cancelBubble, see:
686 // https://github.com/Polymer/polymer/issues/292 686 // https://github.com/Polymer/polymer/issues/292
687 if (!event.bubbles) return; 687 if (!event.bubbles) return;
688 688
689 bool log = _eventsLog.isLoggable(Level.INFO); 689 bool log = _eventsLog.isLoggable(Level.FINE);
690 if (log) _eventsLog.info('>>> [$localName]: listenLocal [${event.type}]'); 690 if (log) _eventsLog.fine('>>> [$localName]: listenLocal [${event.type}]');
691 691
692 final eventOn = '$_EVENT_PREFIX${_eventNameFromType(event.type)}'; 692 final eventOn = '$_EVENT_PREFIX${_eventNameFromType(event.type)}';
693 if (event.path == null) { 693 if (event.path == null) {
694 _listenLocalNoEventPath(host, event, eventOn); 694 _listenLocalNoEventPath(host, event, eventOn);
695 } else { 695 } else {
696 _listenLocalEventPath(host, event, eventOn); 696 _listenLocalEventPath(host, event, eventOn);
697 } 697 }
698 698
699 if (log) _eventsLog.info('<<< [$localName]: listenLocal [${event.type}]'); 699 if (log) _eventsLog.fine('<<< [$localName]: listenLocal [${event.type}]');
700 } 700 }
701 701
702 static void _listenLocalEventPath(Polymer host, Event event, String eventOn) { 702 static void _listenLocalEventPath(Polymer host, Event event, String eventOn) {
703 var c = null; 703 var c = null;
704 for (var target in event.path) { 704 for (var target in event.path) {
705 // if we hit host, stop 705 // if we hit host, stop
706 if (identical(target, host)) return; 706 if (identical(target, host)) return;
707 707
708 // find a controller for the target, unless we already found `host` 708 // find a controller for the target, unless we already found `host`
709 // as a controller 709 // as a controller
710 c = identical(c, host) ? c : _findController(target); 710 c = identical(c, host) ? c : _findController(target);
711 711
712 // if we have a controller, dispatch the event, and stop if the handler 712 // if we have a controller, dispatch the event, and stop if the handler
713 // returns true 713 // returns true
714 if (c != null && _handleEvent(c, target, event, eventOn)) { 714 if (c != null && _handleEvent(c, target, event, eventOn)) {
715 return; 715 return;
716 } 716 }
717 } 717 }
718 } 718 }
719 719
720 // TODO(sorvell): remove when ShadowDOM polyfill supports event path. 720 // TODO(sorvell): remove when ShadowDOM polyfill supports event path.
721 // Note that _findController will not return the expected controller when the 721 // Note that _findController will not return the expected controller when the
722 // event target is a distributed node. This is because we cannot traverse 722 // event target is a distributed node. This is because we cannot traverse
723 // from a composed node to a node in shadowRoot. 723 // from a composed node to a node in shadowRoot.
724 // This will be addressed via an event path api 724 // This will be addressed via an event path api
725 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21066 725 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21066
726 static void _listenLocalNoEventPath(Polymer host, Event event, 726 static void _listenLocalNoEventPath(Polymer host, Event event,
727 String eventOn) { 727 String eventOn) {
728 728
729 if (_eventsLog.isLoggable(Level.INFO)) { 729 if (_eventsLog.isLoggable(Level.FINE)) {
730 _eventsLog.info('event.path() not supported for ${event.type}'); 730 _eventsLog.fine('event.path() not supported for ${event.type}');
731 } 731 }
732 732
733 var target = event.target; 733 var target = event.target;
734 var c = null; 734 var c = null;
735 // if we hit dirt or host, stop 735 // if we hit dirt or host, stop
736 while (target != null && target != host) { 736 while (target != null && target != host) {
737 // find a controller for target `t`, unless we already found `host` 737 // find a controller for target `t`, unless we already found `host`
738 // as a controller 738 // as a controller
739 c = identical(c, host) ? c : _findController(target); 739 c = identical(c, host) ? c : _findController(target);
740 740
(...skipping 16 matching lines...) Expand all
757 } 757 }
758 758
759 static bool _handleEvent(Polymer ctrlr, Node node, Event event, 759 static bool _handleEvent(Polymer ctrlr, Node node, Event event,
760 String eventOn) { 760 String eventOn) {
761 761
762 // Note: local events are listened only in the shadow root. This dynamic 762 // Note: local events are listened only in the shadow root. This dynamic
763 // lookup is used to distinguish determine whether the target actually has a 763 // lookup is used to distinguish determine whether the target actually has a
764 // listener, and if so, to determine lazily what's the target method. 764 // listener, and if so, to determine lazily what's the target method.
765 var name = node is Element ? (node as Element).attributes[eventOn] : null; 765 var name = node is Element ? (node as Element).attributes[eventOn] : null;
766 if (name != null && _handleIfNotHandled(node, event)) { 766 if (name != null && _handleIfNotHandled(node, event)) {
767 if (_eventsLog.isLoggable(Level.INFO)) { 767 if (_eventsLog.isLoggable(Level.FINE)) {
768 _eventsLog.info('[${ctrlr.localName}] found handler name [$name]'); 768 _eventsLog.fine('[${ctrlr.localName}] found handler name [$name]');
769 } 769 }
770 var detail = event is CustomEvent ? 770 var detail = event is CustomEvent ?
771 (event as CustomEvent).detail : null; 771 (event as CustomEvent).detail : null;
772 772
773 if (node != null) { 773 if (node != null) {
774 // TODO(jmesserly): cache symbols? 774 // TODO(jmesserly): cache symbols?
775 ctrlr.dispatchMethod(new Symbol(name), [event, detail, node]); 775 ctrlr.dispatchMethod(new Symbol(name), [event, detail, node]);
776 } 776 }
777 } 777 }
778 778
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 /** 940 /**
941 * Base class for PolymerElements deriving from HtmlElement. 941 * Base class for PolymerElements deriving from HtmlElement.
942 * 942 *
943 * See [Polymer]. 943 * See [Polymer].
944 */ 944 */
945 class PolymerElement extends HtmlElement with Polymer, ObservableMixin { 945 class PolymerElement extends HtmlElement with Polymer, ObservableMixin {
946 PolymerElement.created() : super.created() { 946 PolymerElement.created() : super.created() {
947 polymerCreated(); 947 polymerCreated();
948 } 948 }
949 } 949 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698