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

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

Issue 307793002: update polymer, nodebind, and templatebinding (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: roll Created 6 years, 6 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
(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 [poly_expr.PolymerExpressions] that adds support for binding
9 /// events using `on-eventName`.
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 poly_expr.PolymerExpressions {
15 PolymerExpressions({Map<String, Object> globals})
16 : super(globals: globals);
17
18 prepareBinding(String path, name, node) {
19 if (_hasEventPrefix(name)) {
20 return prepareEventBinding(path, name, node);
21 }
22 return super.prepareBinding(path, name, node);
23 }
24
25 /// Finds the event controller for this node.
26 Element findController(Node node) {
27 while (node.parentNode != null) {
28 if (node is Polymer && node.eventController != null) {
29 return node.eventController;
30 }
31 node = node.parentNode;
32 }
33 return node is ShadowRoot ? node.host : null;
34 }
35
36 EventListener getEventHandler(controller, target, String method) => (e) {
37 if (controller == null || controller is! Polymer) {
38 controller = findController(target);
39 }
40
41 if (controller is Polymer) {
42 var args = [e, e.detail, e.currentTarget];
43 controller.dispatchMethod(controller, method, args);
44 } else {
45 throw new StateError('controller $controller is not a '
46 'Dart polymer-element.');
47 }
48 };
49
50 prepareEventBinding(String path, String name, Node node) {
Siggi Cherem (dart-lang) 2014/06/03 02:23:44 I wonder if we can make this static or refactor a
Jennifer Messerly 2014/06/04 04:42:15 yeah, I don't think so. Instance method is closer
51 if (!_hasEventPrefix(name)) return null;
52
53 var eventType = _removeEventPrefix(name);
54 var translated = _eventTranslations[eventType];
55 eventType = translated != null ? translated : eventType;
56
57 return (model, node, oneTime) {
58 var handler = getEventHandler(null, node, path);
59 node.addEventListener(eventType, handler);
60
61 if (oneTime) return null;
62 return new _EventBindable(node, eventType, handler, path);
63 };
64 }
65 }
66
67
68 class _EventBindable extends Bindable {
69 final Node _node;
70 final String _eventType;
71 final Function _handler;
72 final String _path;
73
74 _EventBindable(this._node, this._eventType, this._handler, this._path);
75
76 // TODO(rafaelw): This is really pointless work. Aside from the cost
77 // of these allocations, NodeBind is going to setAttribute back to its
78 // current value. Fixing this would mean changing the TemplateBinding
79 // binding delegate API.
80 get value => '{{ $_path }}';
81
82 open(callback) => value;
83
84 void close() => _node.removeEventListener(_eventType, _handler);
85 }
86
87
88 /// Attribute prefix used for declarative event handlers.
89 const _EVENT_PREFIX = 'on-';
90
91 /// Whether an attribute declares an event.
92 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX);
93
94 String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length);
95
96 // Dart note: polymer.js calls this mixedCaseEventTypes. But we have additional
97 // things that need translation due to renames.
98 final _eventTranslations = const {
99 'domfocusout': 'DOMFocusOut',
100 'domfocusin': 'DOMFocusIn',
101 'dommousescroll': 'DOMMouseScroll',
102
103 // Dart note: handle Dart-specific event names.
104 'animationend': 'webkitAnimationEnd',
105 'animationiteration': 'webkitAnimationIteration',
106 'animationstart': 'webkitAnimationStart',
107 'doubleclick': 'dblclick',
108 'fullscreenchange': 'webkitfullscreenchange',
109 'fullscreenerror': 'webkitfullscreenerror',
110 'keyadded': 'webkitkeyadded',
111 'keyerror': 'webkitkeyerror',
112 'keymessage': 'webkitkeymessage',
113 'needkey': 'webkitneedkey',
114 'speechchange': 'webkitSpeechChange',
115 };
116
117 final _reverseEventTranslations = () {
118 final map = new Map<String, String>();
119 _eventTranslations.forEach((onName, eventType) {
120 map[eventType] = onName;
121 });
122 return map;
123 }();
124
125 // Dart note: we need this function because we have additional renames JS does
126 // not have. The JS renames are simply case differences, whereas we have ones
127 // like doubleclick -> dblclick and stripping the webkit prefix.
128 String _eventNameFromType(String eventType) {
129 final result = _reverseEventTranslations[eventType];
130 return result != null ? result : eventType;
131 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698