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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 }; | 81 }; |
82 | 82 |
83 prepareEventBinding(String path, String name, Node node) { | 83 prepareEventBinding(String path, String name, Node node) { |
84 if (!_hasEventPrefix(name)) return null; | 84 if (!_hasEventPrefix(name)) return null; |
85 | 85 |
86 var eventType = _removeEventPrefix(name); | 86 var eventType = _removeEventPrefix(name); |
87 var translated = _eventTranslations[eventType]; | 87 var translated = _eventTranslations[eventType]; |
88 eventType = translated != null ? translated : eventType; | 88 eventType = translated != null ? translated : eventType; |
89 | 89 |
90 return (model, node, oneTime) { | 90 return (model, node, oneTime) { |
91 var eventHandler = | 91 var handler = getEventHandler(null, node, path); |
92 Zone.current.bindUnaryCallback(getEventHandler(null, node, path)); | 92 var sub = node.on[eventType].listen(handler); |
93 // TODO(jakemac): Remove this indirection if/when JsFunction gets a | |
94 // simpler constructor that doesn't pass this, http://dartbug.com/20545. | |
95 var handler = new JsFunction.withThis((_, e) => eventHandler(e)); | |
96 _PolymerGestures.callMethod( | |
97 'addEventListener', [node, eventType, handler]); | |
98 | 93 |
99 if (oneTime) return null; | 94 if (oneTime) return null; |
100 return new _EventBindable(path, node, eventType, handler); | 95 return new _EventBindable(sub, path); |
101 }; | 96 }; |
102 } | 97 } |
103 } | 98 } |
104 | 99 |
105 | 100 |
106 class _EventBindable extends Bindable { | 101 class _EventBindable extends Bindable { |
| 102 StreamSubscription _sub; |
107 final String _path; | 103 final String _path; |
108 final Node _node; | |
109 final String _eventType; | |
110 final JsFunction _handler; | |
111 | 104 |
112 _EventBindable(this._path, this._node, this._eventType, this._handler); | 105 _EventBindable(this._sub, this._path); |
113 | 106 |
114 // TODO(rafaelw): This is really pointless work. Aside from the cost | 107 // TODO(rafaelw): This is really pointless work. Aside from the cost |
115 // of these allocations, NodeBind is going to setAttribute back to its | 108 // of these allocations, NodeBind is going to setAttribute back to its |
116 // current value. Fixing this would mean changing the TemplateBinding | 109 // current value. Fixing this would mean changing the TemplateBinding |
117 // binding delegate API. | 110 // binding delegate API. |
118 get value => '{{ $_path }}'; | 111 get value => '{{ $_path }}'; |
119 | 112 |
120 open(callback) => value; | 113 open(callback) => value; |
121 | 114 |
122 void close() { | 115 void close() { |
123 _PolymerGestures.callMethod( | 116 if (_sub != null) { |
124 'removeEventListener', [_node, _eventType, _handler]); | 117 _sub.cancel(); |
| 118 _sub = null; |
| 119 } |
125 } | 120 } |
126 } | 121 } |
127 | 122 |
128 | 123 |
129 /// Attribute prefix used for declarative event handlers. | 124 /// Attribute prefix used for declarative event handlers. |
130 const _EVENT_PREFIX = 'on-'; | 125 const _EVENT_PREFIX = 'on-'; |
131 | 126 |
132 /// Whether an attribute declares an event. | 127 /// Whether an attribute declares an event. |
133 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX); | 128 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX); |
134 | 129 |
(...skipping 28 matching lines...) Expand all Loading... |
163 return map; | 158 return map; |
164 }(); | 159 }(); |
165 | 160 |
166 // Dart note: we need this function because we have additional renames JS does | 161 // Dart note: we need this function because we have additional renames JS does |
167 // not have. The JS renames are simply case differences, whereas we have ones | 162 // not have. The JS renames are simply case differences, whereas we have ones |
168 // like doubleclick -> dblclick and stripping the webkit prefix. | 163 // like doubleclick -> dblclick and stripping the webkit prefix. |
169 String _eventNameFromType(String eventType) { | 164 String _eventNameFromType(String eventType) { |
170 final result = _reverseEventTranslations[eventType]; | 165 final result = _reverseEventTranslations[eventType]; |
171 return result != null ? result : eventType; | 166 return result != null ? result : eventType; |
172 } | 167 } |
OLD | NEW |