OLD | NEW |
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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 // to ensure binding is not left on attribute if property | 430 // to ensure binding is not left on attribute if property |
431 // does not update due to not changing. | 431 // does not update due to not changing. |
432 // Dart note: we include this patch: | 432 // Dart note: we include this patch: |
433 // https://github.com/Polymer/polymer/pull/319 | 433 // https://github.com/Polymer/polymer/pull/319 |
434 reflectPropertyToAttribute(property.simpleName); | 434 reflectPropertyToAttribute(property.simpleName); |
435 return bindings[name] = observer; | 435 return bindings[name] = observer; |
436 } | 436 } |
437 } | 437 } |
438 | 438 |
439 Map<String, NodeBinding> get bindings => nodeBindFallback(this).bindings; | 439 Map<String, NodeBinding> get bindings => nodeBindFallback(this).bindings; |
| 440 TemplateInstance get templateInstance => |
| 441 nodeBindFallback(this).templateInstance; |
440 | 442 |
441 void unbind(String name) => nodeBindFallback(this).unbind(name); | 443 void unbind(String name) => nodeBindFallback(this).unbind(name); |
442 | 444 |
443 void asyncUnbindAll() { | 445 void asyncUnbindAll() { |
444 if (_unbound == true) return; | 446 if (_unbound == true) return; |
445 _unbindLog.fine('[$localName] asyncUnbindAll'); | 447 _unbindLog.fine('[$localName] asyncUnbindAll'); |
446 _unbindAllJob = _runJob(_unbindAllJob, unbindAll, Duration.ZERO); | 448 _unbindAllJob = _runJob(_unbindAllJob, unbindAll, Duration.ZERO); |
447 } | 449 } |
448 | 450 |
449 void unbindAll() { | 451 void unbindAll() { |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 * custom element in which the node exists. Adding a '@' in the path directs | 733 * custom element in which the node exists. Adding a '@' in the path directs |
732 * the event binding to use the model path as the event listener. In both | 734 * the event binding to use the model path as the event listener. In both |
733 * cases, the actual listener is attached to a generic method which evaluates | 735 * cases, the actual listener is attached to a generic method which evaluates |
734 * the bound path at event execution time. | 736 * the bound path at event execution time. |
735 */ | 737 */ |
736 // from src/instance/event.js#prepareBinding | 738 // from src/instance/event.js#prepareBinding |
737 // Dart note: template_binding doesn't have the notion of prepareBinding, so | 739 // Dart note: template_binding doesn't have the notion of prepareBinding, so |
738 // we implement this by wrapping/overriding getBinding instead. | 740 // we implement this by wrapping/overriding getBinding instead. |
739 // TODO(sorvell): we're patching the syntax while evaluating | 741 // TODO(sorvell): we're patching the syntax while evaluating |
740 // event bindings. we'll move this to a better spot when that's done | 742 // event bindings. we'll move this to a better spot when that's done |
741 static getBindingWithEvents( | 743 static PrepareBindingFunction prepareBinding(String path, String name, node, |
742 model, String path, name, node, originalGetBinding) { | 744 originalPrepareBinding) { |
| 745 |
743 // if lhs an event prefix, | 746 // if lhs an event prefix, |
744 if (name is! String || !_hasEventPrefix(name)) { | 747 if (!_hasEventPrefix(name)) return originalPrepareBinding(path, name, node); |
745 return originalGetBinding(model, path, name, node); | |
746 } | |
747 | 748 |
748 // provide an event-binding callback. | 749 // provide an event-binding callback. |
749 // return (model, name, node) { | 750 return (model, node) { |
750 if (_eventsLog.isLoggable(Level.FINE)) { | 751 if (_eventsLog.isLoggable(Level.FINE)) { |
751 _eventsLog.fine('event: [$node].$name => [$model].$path())'); | 752 _eventsLog.fine('event: [$node].$name => [$model].$path())'); |
752 } | |
753 var eventName = _removeEventPrefix(name); | |
754 // TODO(sigmund): polymer.js dropped event translations. reconcile? | |
755 var translated = _eventTranslations[eventName]; | |
756 eventName = translated != null ? translated : eventName; | |
757 return node.on[eventName].listen((event) { | |
758 var ctrlr = _findController(node); | |
759 if (ctrlr is! Polymer) return; | |
760 var obj = ctrlr; | |
761 var method = path; | |
762 if (path[0] == '@') { | |
763 obj = model; | |
764 // Dart note: using getBinding gets us the result of evaluating the | |
765 // original path (without the @) as a normal expression. | |
766 method = originalGetBinding(model, path.substring(1), name, node).value; | |
767 } | 753 } |
768 var detail = event is CustomEvent ? | 754 var eventName = _removeEventPrefix(name); |
769 (event as CustomEvent).detail : null; | 755 // TODO(sigmund): polymer.js dropped event translations. reconcile? |
770 ctrlr.dispatchMethod(obj, method, [event, detail, node]); | 756 var translated = _eventTranslations[eventName]; |
771 }); | 757 eventName = translated != null ? translated : eventName; |
| 758 |
| 759 // TODO(jmesserly): returning a StreamSubscription as the model is quite |
| 760 // strange. package:template_binding doesn't have any cleanup logic to |
| 761 // handle that. |
| 762 return node.on[eventName].listen((event) { |
| 763 var ctrlr = _findController(node); |
| 764 if (ctrlr is! Polymer) return; |
| 765 var obj = ctrlr; |
| 766 var method = path; |
| 767 if (path[0] == '@') { |
| 768 obj = model; |
| 769 method = new PathObserver(model, path.substring(1)).value; |
| 770 } |
| 771 var detail = event is CustomEvent ? |
| 772 (event as CustomEvent).detail : null; |
| 773 ctrlr.dispatchMethod(obj, method, [event, detail, node]); |
| 774 }); |
| 775 }; |
772 } | 776 } |
773 | 777 |
774 // TODO(jmesserly): this won't find the correct host unless the ShadowRoot | 778 // TODO(jmesserly): this won't find the correct host unless the ShadowRoot |
775 // was created on a PolymerElement. | 779 // was created on a PolymerElement. |
776 static Polymer _findController(Node node) { | 780 static Polymer _findController(Node node) { |
777 while (node.parentNode != null) { | 781 while (node.parentNode != null) { |
778 node = node.parentNode; | 782 node = node.parentNode; |
779 } | 783 } |
780 return _shadowHost[node]; | 784 return _shadowHost[node]; |
781 } | 785 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 polymerCreated(); | 1070 polymerCreated(); |
1067 } | 1071 } |
1068 } | 1072 } |
1069 | 1073 |
1070 class _PropertyValue { | 1074 class _PropertyValue { |
1071 Object oldValue, newValue; | 1075 Object oldValue, newValue; |
1072 _PropertyValue(this.oldValue); | 1076 _PropertyValue(this.oldValue); |
1073 } | 1077 } |
1074 | 1078 |
1075 class _PolymerExpressionsWithEventDelegate extends PolymerExpressions { | 1079 class _PolymerExpressionsWithEventDelegate extends PolymerExpressions { |
1076 getBinding(model, String path, name, node) { | 1080 prepareBinding(String path, name, node) => |
1077 return Polymer.getBindingWithEvents( | 1081 Polymer.prepareBinding(path, name, node, super.prepareBinding); |
1078 model, path, name, node, super.getBinding); | |
1079 } | |
1080 } | 1082 } |
OLD | NEW |