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

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

Issue 336013003: Version 1.5.0-dev.4.14 (Closed) Base URL: http://dart.googlecode.com/svn/trunk/
Patch Set: 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
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 /// *Warning* this class is experimental and subject to change. 7 /// *Warning* this class is experimental and subject to change.
8 /// 8 ///
9 /// The data associated with a polymer-element declaration, if it is backed 9 /// The data associated with a polymer-element declaration, if it is backed
10 /// by a Dart class instead of a JavaScript prototype. 10 /// by a Dart class instead of a JavaScript prototype.
11 class PolymerDeclaration { 11 class PolymerDeclaration {
12 /// The one syntax to rule them all.
13 static final BindingDelegate _polymerSyntax = new PolymerExpressions();
14
12 /// The polymer-element for this declaration. 15 /// The polymer-element for this declaration.
13 final HtmlElement element; 16 final HtmlElement element;
14 17
15 /// The Dart type corresponding to this custom element declaration. 18 /// The Dart type corresponding to this custom element declaration.
16 final Type type; 19 final Type type;
17 20
18 /// If we extend another custom element, this points to the super declaration. 21 /// If we extend another custom element, this points to the super declaration.
19 final PolymerDeclaration superDeclaration; 22 final PolymerDeclaration superDeclaration;
20 23
21 /// The name of the custom element. 24 /// The name of the custom element.
(...skipping 11 matching lines...) Expand all
33 Iterable<String> get publishedProperties => 36 Iterable<String> get publishedProperties =>
34 _publish != null ? _publish.keys.map((p) => '$p') : const []; 37 _publish != null ? _publish.keys.map((p) => '$p') : const [];
35 38
36 /// Same as [_publish] but with lower case names. 39 /// Same as [_publish] but with lower case names.
37 Map<String, smoke.Declaration> _publishLC; 40 Map<String, smoke.Declaration> _publishLC;
38 41
39 Map<PropertyPath, List<Symbol>> _observe; 42 Map<PropertyPath, List<Symbol>> _observe;
40 43
41 Map<String, Object> _instanceAttributes; 44 Map<String, Object> _instanceAttributes;
42 45
46 /// A set of properties that should be automatically reflected to attributes.
47 /// Typically this is used for CSS styling. If none, this variable will be
48 /// left as null.
49 Set<String> _reflect;
50
43 List<Element> _sheets; 51 List<Element> _sheets;
44 List<Element> get sheets => _sheets; 52 List<Element> get sheets => _sheets;
45 53
46 List<Element> _styles; 54 List<Element> _styles;
47 List<Element> get styles => _styles; 55 List<Element> get styles => _styles;
48 56
57 // The default syntax for polymer-elements.
58 PolymerExpressions syntax = _polymerSyntax;
59
49 DocumentFragment get templateContent { 60 DocumentFragment get templateContent {
50 final template = element.querySelector('template'); 61 final template = fetchTemplate();
51 return template != null ? templateBind(template).content : null; 62 return template != null ? templateBind(template).content : null;
52 } 63 }
53 64
54 /// Maps event names and their associated method in the element class. 65 /// Maps event names and their associated method in the element class.
55 final Map<String, String> _eventDelegates = {}; 66 final Map<String, String> _eventDelegates = {};
56 67
57 /// Expected events per element node. 68 /// Expected events per element node.
58 // TODO(sigmund): investigate whether we need more than 1 set of local events 69 // TODO(sigmund): investigate whether we need more than 1 set of local events
59 // per element (why does the js implementation stores 1 per template node?) 70 // per element (why does the js implementation stores 1 per template node?)
60 Expando<Set<String>> _templateDelegates; 71 Expando<Set<String>> _templateDelegates;
61 72
62 String get extendee => superDeclaration != null ? 73 String get extendee => superDeclaration != null ?
63 superDeclaration.name : null; 74 superDeclaration.name : null;
64 75
76 /// The root URI for assets.
77 Uri _rootUri;
78
65 // Dart note: since polymer-element is handled in JS now, we have a simplified 79 // Dart note: since polymer-element is handled in JS now, we have a simplified
66 // flow for registering. We don't need to wait for the supertype or the code 80 // flow for registering. We don't need to wait for the supertype or the code
67 // to be noticed. 81 // to be noticed.
68 PolymerDeclaration(this.element, this.name, this.type, this.superDeclaration); 82 PolymerDeclaration(this.element, this.name, this.type, this.superDeclaration);
69 83
70 void register() { 84 void register() {
71 // build prototype combining extendee, Polymer base, and named api
72 buildType();
73
74 // back reference declaration element
75 // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
76 _declarations[name] = this;
77
78 // more declarative features 85 // more declarative features
79 desugar(); 86 desugar();
80 // register our custom element 87 // register our custom element
81 registerType(name); 88 registerType(name);
82 89
83 // NOTE: skip in Dart because we don't have mutable global scope. 90 // NOTE: skip in Dart because we don't have mutable global scope.
84 // reference constructor in a global named by 'constructor' attribute 91 // reference constructor in a global named by 'constructor' attribute
85 // publishConstructor(); 92 // publishConstructor();
86 } 93 }
87 94
88 /// Gets the Dart type registered for this name, and sets up declarative 95 /// Implement various declarative features.
89 /// features. Fills in the [type] and [supertype] fields. 96 // Dart note: this merges "buildPrototype" "desugarBeforeChaining" and
90 /// 97 // "desugarAfterChaining", because we don't have prototypes.
91 /// *Note*: unlike the JavaScript version, we do not have to metaprogram the 98 void desugar() {
92 /// prototype, which simplifies this method. 99
93 void buildType() { 100 // back reference declaration element
101 _declarations[name] = this;
102
94 // transcribe `attributes` declarations onto own prototype's `publish` 103 // transcribe `attributes` declarations onto own prototype's `publish`
95 publishAttributes(superDeclaration); 104 publishAttributes(superDeclaration);
96 105
97 publishProperties(); 106 publishProperties();
98 107
99 inferObservers(); 108 inferObservers();
100 109
101 // desugar compound observer syntax, e.g. @ObserveProperty('a b c') 110 // desugar compound observer syntax, e.g. @ObserveProperty('a b c')
102 explodeObservers(); 111 explodeObservers();
103 112
104 // Skip the rest in Dart: 113 // install mdv delegate on template
105 // chain various meta-data objects to inherited versions 114 installBindingDelegate(fetchTemplate());
106 // chain custom api to inherited 115 // install external stylesheets as if they are inline
107 // build side-chained lists to optimize iterations 116 installSheets();
108 // inherit publishing meta-data 117 // adjust any paths in dom from imports
109 // x-platform fixup 118 resolveElementPaths(element);
110 }
111
112 /// Implement various declarative features.
113 void desugar() {
114 // compile list of attributes to copy to instances 119 // compile list of attributes to copy to instances
115 accumulateInstanceAttributes(); 120 accumulateInstanceAttributes();
116 // parse on-* delegates declared on `this` element 121 // parse on-* delegates declared on `this` element
117 parseHostEvents(); 122 parseHostEvents();
118 // install external stylesheets as if they are inline 123 // install a helper method this.resolvePath to aid in
119 installSheets(); 124 // setting resource urls. e.g.
120
121 adjustShadowElement();
122
123 // TODO(sorvell): install a helper method this.resolvePath to aid in
124 // setting resource paths. e.g.
125 // this.$.image.src = this.resolvePath('images/foo.png') 125 // this.$.image.src = this.resolvePath('images/foo.png')
126 // Potentially remove when spec bug is addressed. 126 initResolvePath();
127 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407
128 // TODO(jmesserly): resolvePath not ported, see first comment in this class.
129
130 // under ShadowDOMPolyfill, transforms to approximate missing CSS features 127 // under ShadowDOMPolyfill, transforms to approximate missing CSS features
131 _shimShadowDomStyling(templateContent, name, extendee); 128 _shimShadowDomStyling(templateContent, name, extendee);
132 129
133 // TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient 130 // TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient
134 // lazy static initialization, can we get by without it? 131 // lazy static initialization, can we get by without it?
135 if (smoke.hasStaticMethod(type, #registerCallback)) { 132 if (smoke.hasStaticMethod(type, #registerCallback)) {
136 smoke.invoke(type, #registerCallback, [this]); 133 smoke.invoke(type, #registerCallback, [this]);
137 } 134 }
138 } 135 }
139 136
140 // TODO(sorvell): remove when spec addressed:
141 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22460
142 // make <shadow></shadow> be <shadow><content></content></shadow>
143 void adjustShadowElement() {
144 // TODO(sorvell): avoid under SD polyfill until this bug is addressed:
145 // https://github.com/Polymer/ShadowDOM/issues/297
146 if (!_hasShadowDomPolyfill) {
147 final content = templateContent;
148 if (content == null) return;
149
150 for (var s in content.querySelectorAll('shadow')) {
151 if (s.nodes.isEmpty) s.append(new ContentElement());
152 }
153 }
154 }
155
156 void registerType(String name) { 137 void registerType(String name) {
157 var baseTag; 138 var baseTag;
158 var decl = this; 139 var decl = this;
159 while (decl != null) { 140 while (decl != null) {
160 baseTag = decl.element.attributes['extends']; 141 baseTag = decl.element.attributes['extends'];
161 decl = decl.superDeclaration; 142 decl = decl.superDeclaration;
162 } 143 }
163 document.register(name, type, extendsTag: baseTag); 144 document.registerElement(name, type, extendsTag: baseTag);
145 }
146
147 // from declaration/mdv.js
148 Element fetchTemplate() => element.querySelector('template');
149
150 void installBindingDelegate(Element template) {
151 if (template != null) {
152 templateBind(template).bindingDelegate = this.syntax;
153 }
154 }
155
156 // from declaration/path.js
157 void resolveElementPaths(Node node) {
158 if (_Platform == null) return;
159 _Platform['urlResolver'].callMethod('resolveDom', [node]);
160 }
161
162 // Dart note: renamed from "addResolvePathApi".
163 void initResolvePath() {
164 // let assetpath attribute modify the resolve path
165 var assetPath = element.attributes['assetpath'];
166 if (assetPath == null) assetPath = '';
167 var base = Uri.parse(element.ownerDocument.baseUri);
168 _rootUri = base.resolve(assetPath);
169 }
170
171 String resolvePath(String urlPath, [baseUrlOrString]) {
172 Uri base;
173 if (baseUrlOrString == null) {
174 // Dart note: this enforces the same invariant as JS, where you need to
175 // call addResolvePathApi first.
176 if (_rootUri == null) {
177 throw new StateError('call initResolvePath before calling resolvePath');
178 }
179 base = _rootUri;
180 } else if (baseUrlOrString is Uri) {
181 base = baseUrlOrString;
182 } else {
183 base = Uri.parse(baseUrlOrString);
184 }
185 return base.resolve(urlPath).toString();
164 } 186 }
165 187
166 void publishAttributes(PolymerDeclaration superDecl) { 188 void publishAttributes(PolymerDeclaration superDecl) {
167 // get properties to publish 189 // get properties to publish
168 if (superDecl != null && superDecl._publish != null) { 190 if (superDecl != null) {
169 // Dart note: even though we walk the type hierarchy in 191 // Dart note: even though we walk the type hierarchy in
170 // _getPublishedProperties, this will additionally include any names 192 // _getPublishedProperties, this will additionally include any names
171 // published via the `attributes` attribute. 193 // published via the `attributes` attribute.
172 _publish = new Map.from(superDecl._publish); 194 if (superDecl._publish != null) {
195 _publish = new Map.from(superDecl._publish);
196 }
197 if (superDecl._reflect != null) {
198 _reflect = new Set.from(superDecl._reflect);
199 }
173 } 200 }
174 201
175 _publish = _getPublishedProperties(type, _publish); 202 _getPublishedProperties(type);
176 203
177 // merge names from 'attributes' attribute 204 // merge names from 'attributes' attribute
178 var attrs = element.attributes['attributes']; 205 var attrs = element.attributes['attributes'];
179 if (attrs != null) { 206 if (attrs != null) {
180 // names='a b c' or names='a,b,c' 207 // names='a b c' or names='a,b,c'
181 // record each name for publishing 208 // record each name for publishing
182 for (var attr in attrs.split(_ATTRIBUTES_REGEX)) { 209 for (var attr in attrs.split(_ATTRIBUTES_REGEX)) {
183 // remove excess ws 210 // remove excess ws
184 attr = attr.trim(); 211 attr = attr.trim();
185 212
(...skipping 15 matching lines...) Expand all
201 if (_publish == null) _publish = {}; 228 if (_publish == null) _publish = {};
202 _publish[path] = decl; 229 _publish[path] = decl;
203 } 230 }
204 } 231 }
205 232
206 // NOTE: the following is not possible in Dart; fields must be declared. 233 // NOTE: the following is not possible in Dart; fields must be declared.
207 // install 'attributes' as properties on the prototype, 234 // install 'attributes' as properties on the prototype,
208 // but don't override 235 // but don't override
209 } 236 }
210 237
238 void _getPublishedProperties(Type type) {
239 var options = const smoke.QueryOptions(includeInherited: true,
240 includeUpTo: HtmlElement, withAnnotations: const [PublishedProperty]);
241 for (var decl in smoke.query(type, options)) {
242 if (decl.isFinal) continue;
243 if (_publish == null) _publish = {};
244 _publish[new PropertyPath([decl.name])] = decl;
245
246 // Should we reflect the property value to the attribute automatically?
247 if (decl.annotations
248 .where((a) => a is PublishedProperty)
249 .any((a) => a.reflect)) {
250
251 if (_reflect == null) _reflect = new Set();
252 _reflect.add(smoke.symbolToName(decl.name));
253 }
254 }
255 }
256
257
211 void accumulateInstanceAttributes() { 258 void accumulateInstanceAttributes() {
212 // inherit instance attributes 259 // inherit instance attributes
213 _instanceAttributes = new Map<String, Object>(); 260 _instanceAttributes = new Map<String, Object>();
214 if (superDeclaration != null) { 261 if (superDeclaration != null) {
215 _instanceAttributes.addAll(superDeclaration._instanceAttributes); 262 _instanceAttributes.addAll(superDeclaration._instanceAttributes);
216 } 263 }
217 264
218 // merge attributes from element 265 // merge attributes from element
219 element.attributes.forEach((name, value) { 266 element.attributes.forEach((name, value) {
220 if (isInstanceAttribute(name)) { 267 if (isInstanceAttribute(name)) {
221 _instanceAttributes[name] = value; 268 _instanceAttributes[name] = value;
222 } 269 }
223 }); 270 });
224 } 271 }
225 272
226 static bool isInstanceAttribute(name) { 273 static bool isInstanceAttribute(name) {
227 // do not clone these attributes onto instances 274 // do not clone these attributes onto instances
228 final blackList = const { 275 final blackList = const {
229 'name': 1, 'extends': 1, 'constructor': 1, 'noscript': 1, 276 'name': 1,
230 'attributes': 1}; 277 'extends': 1,
278 'constructor': 1,
279 'noscript': 1,
280 'assetpath': 1,
281 'cache-csstext': 1,
282 // add ATTRIBUTES_ATTRIBUTE to the blacklist
283 'attributes': 1,
284 };
231 285
232 return !blackList.containsKey(name) && !name.startsWith('on-'); 286 return !blackList.containsKey(name) && !name.startsWith('on-');
233 } 287 }
234 288
235 /// Extracts events from the element tag attributes. 289 /// Extracts events from the element tag attributes.
236 void parseHostEvents() { 290 void parseHostEvents() {
237 addAttributeDelegates(_eventDelegates); 291 addAttributeDelegates(_eventDelegates);
238 } 292 }
239 293
240 void addAttributeDelegates(Map<String, String> delegates) { 294 void addAttributeDelegates(Map<String, String> delegates) {
241 element.attributes.forEach((name, value) { 295 element.attributes.forEach((name, value) {
242 if (_hasEventPrefix(name)) { 296 if (_hasEventPrefix(name)) {
243 var start = value.indexOf('{{'); 297 var start = value.indexOf('{{');
244 var end = value.lastIndexOf('}}'); 298 var end = value.lastIndexOf('}}');
245 if (start >= 0 && end >= 0) { 299 if (start >= 0 && end >= 0) {
246 delegates[_removeEventPrefix(name)] = 300 delegates[_removeEventPrefix(name)] =
247 value.substring(start + 2, end).trim(); 301 value.substring(start + 2, end).trim();
248 } 302 }
249 } 303 }
250 }); 304 });
251 } 305 }
252 306
253 String urlToPath(String url) { 307 String urlToPath(String url) {
254 if (url == null) return ''; 308 if (url == null) return '';
255 return (url.split('/')..removeLast()..add('')).join('/'); 309 return (url.split('/')..removeLast()..add('')).join('/');
256 } 310 }
257 311
312 // Dart note: loadStyles, convertSheetsToStyles, copySheetAttribute and
313 // findLoadableStyles are not ported because they're handled by Polymer JS
314 // before we get into [register].
315
258 /// Install external stylesheets loaded in <element> elements into the 316 /// Install external stylesheets loaded in <element> elements into the
259 /// element's template. 317 /// element's template.
260 void installSheets() { 318 void installSheets() {
261 cacheSheets(); 319 cacheSheets();
262 cacheStyles(); 320 cacheStyles();
263 installLocalSheets(); 321 installLocalSheets();
264 installGlobalStyles(); 322 installGlobalStyles();
265 } 323 }
266 324
267 void cacheSheets() { 325 void cacheSheets() {
(...skipping 15 matching lines...) Expand all
283 void installLocalSheets() { 341 void installLocalSheets() {
284 var sheets = this.sheets.where( 342 var sheets = this.sheets.where(
285 (s) => !s.attributes.containsKey(_SCOPE_ATTR)); 343 (s) => !s.attributes.containsKey(_SCOPE_ATTR));
286 var content = templateContent; 344 var content = templateContent;
287 if (content != null) { 345 if (content != null) {
288 var cssText = new StringBuffer(); 346 var cssText = new StringBuffer();
289 for (var sheet in sheets) { 347 for (var sheet in sheets) {
290 cssText..write(_cssTextFromSheet(sheet))..write('\n'); 348 cssText..write(_cssTextFromSheet(sheet))..write('\n');
291 } 349 }
292 if (cssText.length > 0) { 350 if (cssText.length > 0) {
293 content.insertBefore( 351 var style = element.ownerDocument.createElement('style')
294 new StyleElement()..text = '$cssText', 352 ..text = '$cssText';
295 content.firstChild); 353
354 content.insertBefore(style, content.firstChild);
296 } 355 }
297 } 356 }
298 } 357 }
299 358
300 List<Element> findNodes(String selector, [bool matcher(Element e)]) { 359 List<Element> findNodes(String selector, [bool matcher(Element e)]) {
301 var nodes = element.querySelectorAll(selector).toList(); 360 var nodes = element.querySelectorAll(selector).toList();
302 var content = templateContent; 361 var content = templateContent;
303 if (content != null) { 362 if (content != null) {
304 nodes = nodes..addAll(content.querySelectorAll(selector)); 363 nodes = nodes..addAll(content.querySelectorAll(selector));
305 } 364 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 final Map _typesByName = new Map<String, Type>(); 454 final Map _typesByName = new Map<String, Type>();
396 455
397 Type _getRegisteredType(String name) => _typesByName[name]; 456 Type _getRegisteredType(String name) => _typesByName[name];
398 457
399 /// track document.register'ed tag names and their declarations 458 /// track document.register'ed tag names and their declarations
400 final Map _declarations = new Map<String, PolymerDeclaration>(); 459 final Map _declarations = new Map<String, PolymerDeclaration>();
401 460
402 bool _isRegistered(String name) => _declarations.containsKey(name); 461 bool _isRegistered(String name) => _declarations.containsKey(name);
403 PolymerDeclaration _getDeclaration(String name) => _declarations[name]; 462 PolymerDeclaration _getDeclaration(String name) => _declarations[name];
404 463
405 Map<PropertyPath, smoke.Declaration> _getPublishedProperties(
406 Type type, Map<PropertyPath, smoke.Declaration> props) {
407 var options = const smoke.QueryOptions(includeInherited: true,
408 includeUpTo: HtmlElement, withAnnotations: const [PublishedProperty]);
409 for (var decl in smoke.query(type, options)) {
410 if (decl.isFinal) continue;
411 if (props == null) props = {};
412 props[new PropertyPath([decl.name])] = decl;
413 }
414 return props;
415 }
416
417 /// Attribute prefix used for declarative event handlers.
418 const _EVENT_PREFIX = 'on-';
419
420 /// Whether an attribute declares an event.
421 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX);
422
423 String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length);
424
425 /// Using Polymer's platform/src/ShadowCSS.js passing the style tag's content. 464 /// Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
426 void _shimShadowDomStyling(DocumentFragment template, String name, 465 void _shimShadowDomStyling(DocumentFragment template, String name,
427 String extendee) { 466 String extendee) {
428 if (template == null || !_hasShadowDomPolyfill) return; 467 if (template == null || _ShadowCss == null) return;
429 468
430 var platform = js.context['Platform']; 469 _ShadowCss.callMethod('shimStyling', [template, name, extendee]);
431 if (platform == null) return;
432 var shadowCss = platform['ShadowCSS'];
433 if (shadowCss == null) return;
434 shadowCss.callMethod('shimStyling', [template, name, extendee]);
435 } 470 }
436 471
437 final bool _hasShadowDomPolyfill = js.context.hasProperty('ShadowDOMPolyfill'); 472 final bool _hasShadowDomPolyfill = js.context.hasProperty('ShadowDOMPolyfill');
473 final JsObject _ShadowCss = _Platform != null ? _Platform['ShadowCSS'] : null;
438 474
439 const _STYLE_SELECTOR = 'style'; 475 const _STYLE_SELECTOR = 'style';
440 const _SHEET_SELECTOR = '[rel=stylesheet]'; 476 const _SHEET_SELECTOR = 'link[rel=stylesheet]';
441 const _STYLE_GLOBAL_SCOPE = 'global'; 477 const _STYLE_GLOBAL_SCOPE = 'global';
442 const _SCOPE_ATTR = 'polymer-scope'; 478 const _SCOPE_ATTR = 'polymer-scope';
443 const _STYLE_SCOPE_ATTRIBUTE = 'element'; 479 const _STYLE_SCOPE_ATTRIBUTE = 'element';
444 const _STYLE_CONTROLLER_SCOPE = 'controller'; 480 const _STYLE_CONTROLLER_SCOPE = 'controller';
445 481
446 String _cssTextFromSheet(LinkElement sheet) { 482 String _cssTextFromSheet(LinkElement sheet) {
447 if (sheet == null) return ''; 483 if (sheet == null) return '';
448 484
449 // In deploy mode we should never do a sync XHR; link rel=stylesheet will 485 // In deploy mode we should never do a sync XHR; link rel=stylesheet will
450 // be inlined into a <style> tag by ImportInliner. 486 // be inlined into a <style> tag by ImportInliner.
(...skipping 27 matching lines...) Expand all
478 includeFields: false, includeProperties: false, includeMethods: true, 514 includeFields: false, includeProperties: false, includeMethods: true,
479 includeInherited: true, includeUpTo: HtmlElement, 515 includeInherited: true, includeUpTo: HtmlElement,
480 matches: _isObserverMethod); 516 matches: _isObserverMethod);
481 517
482 bool _isObserverMethod(Symbol symbol) { 518 bool _isObserverMethod(Symbol symbol) {
483 String name = smoke.symbolToName(symbol); 519 String name = smoke.symbolToName(symbol);
484 if (name == null) return false; 520 if (name == null) return false;
485 return name.endsWith('Changed') && name != 'attributeChanged'; 521 return name.endsWith('Changed') && name != 'attributeChanged';
486 } 522 }
487 523
488 // TODO(jmesserly): is this list complete?
489 final _eventTranslations = const {
490 // TODO(jmesserly): these three Polymer.js translations won't work in Dart,
491 // because we strip the webkit prefix (below). Reconcile.
492 'webkitanimationstart': 'webkitAnimationStart',
493 'webkitanimationend': 'webkitAnimationEnd',
494 'webkittransitionend': 'webkitTransitionEnd',
495
496 'domfocusout': 'DOMFocusOut',
497 'domfocusin': 'DOMFocusIn',
498 'dommousescroll': 'DOMMouseScroll',
499
500 // TODO(jmesserly): Dart specific renames. Reconcile with Polymer.js
501 'animationend': 'webkitAnimationEnd',
502 'animationiteration': 'webkitAnimationIteration',
503 'animationstart': 'webkitAnimationStart',
504 'doubleclick': 'dblclick',
505 'fullscreenchange': 'webkitfullscreenchange',
506 'fullscreenerror': 'webkitfullscreenerror',
507 'keyadded': 'webkitkeyadded',
508 'keyerror': 'webkitkeyerror',
509 'keymessage': 'webkitkeymessage',
510 'needkey': 'webkitneedkey',
511 'speechchange': 'webkitSpeechChange',
512 };
513
514 final _reverseEventTranslations = () {
515 final map = new Map<String, String>();
516 _eventTranslations.forEach((onName, eventType) {
517 map[eventType] = onName;
518 });
519 return map;
520 }();
521
522 // Dart note: we need this function because we have additional renames JS does
523 // not have. The JS renames are simply case differences, whereas we have ones
524 // like doubleclick -> dblclick and stripping the webkit prefix.
525 String _eventNameFromType(String eventType) {
526 final result = _reverseEventTranslations[eventType];
527 return result != null ? result : eventType;
528 }
529 524
530 final _ATTRIBUTES_REGEX = new RegExp(r'\s|,'); 525 final _ATTRIBUTES_REGEX = new RegExp(r'\s|,');
526
527 final JsObject _Platform = js.context['Platform'];
OLDNEW
« no previous file with comments | « dart/pkg/polymer/lib/src/build/script_compactor.dart ('k') | dart/pkg/polymer/lib/src/events.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698