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

Side by Side Diff: packages/polymer/lib/src/events.dart

Issue 2312183003: Removed Polymer from Observatory deps (Closed)
Patch Set: Created 4 years, 3 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 | « packages/polymer/lib/src/declaration.dart ('k') | packages/polymer/lib/src/initializers.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Code from declaration/events.js
6 part of polymer;
7
8 /// An extension of [polymer_expressions.PolymerExpressions] that adds support
9 /// for binding events using `on-eventName` using [PolymerEventBindings].
10 // TODO(jmesserly): the JS layering is a bit odd, with polymer-dev implementing
11 // events and polymer-expressions implementing everything else. I don't think
12 // this separation is right in the long term, so we're using the same class name
13 // until we can sort it out.
14 class PolymerExpressions extends BindingDelegate with PolymerEventBindings {
15
16 /// A wrapper around polymer_expressions used to implement forwarding.
17 /// Ideally we would inherit from it, but mixins can't be applied to a type
18 /// that forwards to a superclass with a constructor that has optional or
19 /// named arguments.
20 final polymer_expressions.PolymerExpressions _delegate;
21
22 Map<String, Object> get globals => _delegate.globals;
23
24 PolymerExpressions({Map<String, Object> globals})
25 : _delegate = new polymer_expressions.PolymerExpressions(
26 globals: globals);
27
28 prepareBinding(String path, name, node) {
29 if (_hasEventPrefix(name)) {
30 return prepareEventBinding(path, name, node);
31 }
32 return _delegate.prepareBinding(path, name, node);
33 }
34
35 prepareInstanceModel(Element template) =>
36 _delegate.prepareInstanceModel(template);
37
38 prepareInstancePositionChanged(Element template) =>
39 _delegate.prepareInstancePositionChanged(template);
40
41 static final getExpression =
42 polymer_expressions.PolymerExpressions.getExpression;
43 static final getBinding = polymer_expressions.PolymerExpressions.getBinding;
44 }
45
46 /// A mixin for a [BindingDelegate] to add Polymer event support.
47 /// This is included in [PolymerExpressions].
48 abstract class PolymerEventBindings {
49 /// Finds the event controller for this node.
50 Element findController(Node node) {
51 while (node.parentNode != null) {
52 if (node is Polymer && node.eventController != null) {
53 return node.eventController;
54 } else if (node is Element) {
55 // If it is a normal element, js polymer element, or dart wrapper to a
56 // js polymer element, then we try js interop.
57 var eventController =
58 new JsObject.fromBrowserObject(node)['eventController'];
59 if (eventController != null) return eventController;
60 }
61 node = node.parentNode;
62 }
63 return node is ShadowRoot ? node.host : null;
64 }
65
66 EventListener getEventHandler(controller, target, String method) => (e) {
67 if (controller == null || controller is! Polymer) {
68 controller = findController(target);
69 }
70
71 if (controller is Polymer) {
72 var detail = null;
73 if (e is CustomEvent) {
74 detail = e.detail;
75 // TODO(sigmund): this shouldn't be necessary. See issue 19315.
76 if (detail == null) {
77 detail = new JsObject.fromBrowserObject(e)['detail'];
78 }
79 }
80 var args = [e, detail, e.currentTarget];
81 controller.dispatchMethod(controller, method, args);
82 } else {
83 throw new StateError('controller $controller is not a '
84 'Dart polymer-element.');
85 }
86 };
87
88 prepareEventBinding(String path, String name, Node node) {
89 if (!_hasEventPrefix(name)) return null;
90
91 var eventType = _removeEventPrefix(name);
92 var translated = _eventTranslations[eventType];
93 eventType = translated != null ? translated : eventType;
94
95 return (model, node, oneTime) {
96 var eventHandler =
97 Zone.current.bindUnaryCallback(getEventHandler(null, node, path));
98 // TODO(jakemac): Remove this indirection if/when JsFunction gets a
99 // simpler constructor that doesn't pass this, http://dartbug.com/20545.
100 var handler = new JsFunction.withThis((_, e) => eventHandler(e));
101 PolymerGesturesJs.addEventListener(node, eventType, handler);
102
103 if (oneTime) return null;
104 return new _EventBindable(path, node, eventType, handler);
105 };
106 }
107 }
108
109 class _EventBindable extends Bindable {
110 final String _path;
111 final Node _node;
112 final String _eventType;
113 final JsFunction _handler;
114
115 _EventBindable(this._path, this._node, this._eventType, this._handler);
116
117 // TODO(rafaelw): This is really pointless work. Aside from the cost
118 // of these allocations, NodeBind is going to setAttribute back to its
119 // current value. Fixing this would mean changing the TemplateBinding
120 // binding delegate API.
121 get value => '{{ $_path }}';
122
123 open(callback) => value;
124
125 void close() {
126 PolymerGesturesJs.removeEventListener(_node, _eventType, _handler);
127 }
128 }
129
130 /// Attribute prefix used for declarative event handlers.
131 const _EVENT_PREFIX = 'on-';
132
133 /// Whether an attribute declares an event.
134 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX);
135
136 String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length);
137
138 // Dart note: polymer.js calls this mixedCaseEventTypes. But we have additional
139 // things that need translation due to renames.
140 final _eventTranslations = const {
141 'domfocusout': 'DOMFocusOut',
142 'domfocusin': 'DOMFocusIn',
143 'dommousescroll': 'DOMMouseScroll',
144
145 // Dart note: handle Dart-specific event names.
146 'animationend': 'webkitAnimationEnd',
147 'animationiteration': 'webkitAnimationIteration',
148 'animationstart': 'webkitAnimationStart',
149 'doubleclick': 'dblclick',
150 'fullscreenchange': 'webkitfullscreenchange',
151 'fullscreenerror': 'webkitfullscreenerror',
152 'keyadded': 'webkitkeyadded',
153 'keyerror': 'webkitkeyerror',
154 'keymessage': 'webkitkeymessage',
155 'needkey': 'webkitneedkey',
156 'speechchange': 'webkitSpeechChange',
157 };
158
159 final _reverseEventTranslations = () {
160 final map = new Map<String, String>();
161 _eventTranslations.forEach((onName, eventType) {
162 map[eventType] = onName;
163 });
164 return map;
165 }();
166
167 // Dart note: we need this function because we have additional renames JS does
168 // not have. The JS renames are simply case differences, whereas we have ones
169 // like doubleclick -> dblclick and stripping the webkit prefix.
170 String _eventNameFromType(String eventType) {
171 final result = _reverseEventTranslations[eventType];
172 return result != null ? result : eventType;
173 }
OLDNEW
« no previous file with comments | « packages/polymer/lib/src/declaration.dart ('k') | packages/polymer/lib/src/initializers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698