| 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 /// Code from declaration/events.js | 5 /// Code from declaration/events.js |
| 6 part of polymer; | 6 part of polymer; |
| 7 | 7 |
| 8 /// An extension of [polymer_expressions.PolymerExpressions] that adds support | 8 /// An extension of [polymer_expressions.PolymerExpressions] that adds support |
| 9 /// for binding events using `on-eventName` using [PolymerEventBindings]. | 9 /// for binding events using `on-eventName` using [PolymerEventBindings]. |
| 10 // TODO(jmesserly): the JS layering is a bit odd, with polymer-dev implementing | 10 // TODO(jmesserly): the JS layering is a bit odd, with polymer-dev implementing |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 | 75 |
| 76 prepareEventBinding(String path, String name, Node node) { | 76 prepareEventBinding(String path, String name, Node node) { |
| 77 if (!_hasEventPrefix(name)) return null; | 77 if (!_hasEventPrefix(name)) return null; |
| 78 | 78 |
| 79 var eventType = _removeEventPrefix(name); | 79 var eventType = _removeEventPrefix(name); |
| 80 var translated = _eventTranslations[eventType]; | 80 var translated = _eventTranslations[eventType]; |
| 81 eventType = translated != null ? translated : eventType; | 81 eventType = translated != null ? translated : eventType; |
| 82 | 82 |
| 83 return (model, node, oneTime) { | 83 return (model, node, oneTime) { |
| 84 var handler = getEventHandler(null, node, path); | 84 var handler = getEventHandler(null, node, path); |
| 85 node.addEventListener(eventType, handler); | 85 var sub = node.on[eventType].listen(handler); |
| 86 | 86 |
| 87 if (oneTime) return null; | 87 if (oneTime) return null; |
| 88 return new _EventBindable(node, eventType, handler, path); | 88 return new _EventBindable(sub, path); |
| 89 }; | 89 }; |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 class _EventBindable extends Bindable { | 94 class _EventBindable extends Bindable { |
| 95 final Node _node; | 95 final StreamSubscription _sub; |
| 96 final String _eventType; | |
| 97 final Function _handler; | |
| 98 final String _path; | 96 final String _path; |
| 99 | 97 |
| 100 _EventBindable(this._node, this._eventType, this._handler, this._path); | 98 _EventBindable(this._sub, this._path); |
| 101 | 99 |
| 102 // TODO(rafaelw): This is really pointless work. Aside from the cost | 100 // TODO(rafaelw): This is really pointless work. Aside from the cost |
| 103 // of these allocations, NodeBind is going to setAttribute back to its | 101 // of these allocations, NodeBind is going to setAttribute back to its |
| 104 // current value. Fixing this would mean changing the TemplateBinding | 102 // current value. Fixing this would mean changing the TemplateBinding |
| 105 // binding delegate API. | 103 // binding delegate API. |
| 106 get value => '{{ $_path }}'; | 104 get value => '{{ $_path }}'; |
| 107 | 105 |
| 108 open(callback) => value; | 106 open(callback) => value; |
| 109 | 107 |
| 110 void close() => _node.removeEventListener(_eventType, _handler); | 108 void close() { |
| 109 if (_sub != null) { |
| 110 _sub.cancel(); |
| 111 _sub = null; |
| 112 } |
| 113 } |
| 111 } | 114 } |
| 112 | 115 |
| 113 | 116 |
| 114 /// Attribute prefix used for declarative event handlers. | 117 /// Attribute prefix used for declarative event handlers. |
| 115 const _EVENT_PREFIX = 'on-'; | 118 const _EVENT_PREFIX = 'on-'; |
| 116 | 119 |
| 117 /// Whether an attribute declares an event. | 120 /// Whether an attribute declares an event. |
| 118 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX); | 121 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX); |
| 119 | 122 |
| 120 String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length); | 123 String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 148 return map; | 151 return map; |
| 149 }(); | 152 }(); |
| 150 | 153 |
| 151 // Dart note: we need this function because we have additional renames JS does | 154 // Dart note: we need this function because we have additional renames JS does |
| 152 // not have. The JS renames are simply case differences, whereas we have ones | 155 // not have. The JS renames are simply case differences, whereas we have ones |
| 153 // like doubleclick -> dblclick and stripping the webkit prefix. | 156 // like doubleclick -> dblclick and stripping the webkit prefix. |
| 154 String _eventNameFromType(String eventType) { | 157 String _eventNameFromType(String eventType) { |
| 155 final result = _reverseEventTranslations[eventType]; | 158 final result = _reverseEventTranslations[eventType]; |
| 156 return result != null ? result : eventType; | 159 return result != null ? result : eventType; |
| 157 } | 160 } |
| OLD | NEW |