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

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

Issue 132403010: big update to observe, template_binding, polymer (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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
« no previous file with comments | « pkg/polymer/lib/polymer.dart ('k') | pkg/polymer/lib/src/instance.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /** 7 /**
8 * **Warning**: this class is experiental and subject to change. 8 * **Warning**: this class is experiental and subject to change.
9 * 9 *
10 * The implementation for the `polymer-element` element. 10 * The implementation for the `polymer-element` element.
(...skipping 23 matching lines...) Expand all
34 // TODO(jmesserly): this is a cache, because it's tricky in Dart to get from 34 // TODO(jmesserly): this is a cache, because it's tricky in Dart to get from
35 // Type -> Supertype. 35 // Type -> Supertype.
36 Type _supertype; 36 Type _supertype;
37 Type get supertype => _supertype; 37 Type get supertype => _supertype;
38 38
39 // TODO(jmesserly): this is also a cache, since we can't store .element on 39 // TODO(jmesserly): this is also a cache, since we can't store .element on
40 // each level of the __proto__ like JS does. 40 // each level of the __proto__ like JS does.
41 PolymerDeclaration _super; 41 PolymerDeclaration _super;
42 PolymerDeclaration get superDeclaration => _super; 42 PolymerDeclaration get superDeclaration => _super;
43 43
44 String _extendsName;
45
44 String _name; 46 String _name;
45 String get name => _name; 47 String get name => _name;
46 48
47 /** 49 /**
48 * Map of publish properties. Can be a [VariableMirror] or a [MethodMirror] 50 * Map of publish properties. Can be a [VariableMirror] or a [MethodMirror]
49 * representing a getter. If it is a getter, there will also be a setter. 51 * representing a getter. If it is a getter, there will also be a setter.
52 *
53 * Note: technically these are always single properties, so we could use
54 * a Symbol instead of a PropertyPath. However there are lookups between
55 * this map and [_observe] so it is easier to just track paths.
50 */ 56 */
51 Map<Symbol, DeclarationMirror> _publish; 57 Map<PropertyPath, DeclarationMirror> _publish;
52 58
53 /** The names of published properties for this polymer-element. */ 59 /** The names of published properties for this polymer-element. */
54 Iterable<Symbol> get publishedProperties => 60 Iterable<String> get publishedProperties =>
55 _publish != null ? _publish.keys : const []; 61 _publish != null ? _publish.keys.map((p) => '$p') : const [];
56 62
57 /** Same as [_publish] but with lower case names. */ 63 /** Same as [_publish] but with lower case names. */
58 Map<String, DeclarationMirror> _publishLC; 64 Map<String, DeclarationMirror> _publishLC;
59 65
60 Map<Symbol, Symbol> _observe; 66 Map<PropertyPath, List<Symbol>> _observe;
61 67
62 Map<String, Object> _instanceAttributes; 68 Map<String, Object> _instanceAttributes;
63 69
64 List<Element> _sheets; 70 List<Element> _sheets;
65 List<Element> get sheets => _sheets; 71 List<Element> get sheets => _sheets;
66 72
67 List<Element> _styles; 73 List<Element> _styles;
68 List<Element> get styles => _styles; 74 List<Element> get styles => _styles;
69 75
70 DocumentFragment get templateContent { 76 DocumentFragment get templateContent {
71 final template = this.querySelector('template'); 77 final template = this.querySelector('template');
72 return template != null ? templateBind(template).content : null; 78 return template != null ? templateBind(template).content : null;
73 } 79 }
74 80
75 /** Maps event names and their associated method in the element class. */ 81 /** Maps event names and their associated method in the element class. */
76 final Map<String, String> _eventDelegates = {}; 82 final Map<String, String> _eventDelegates = {};
77 83
78 /** Expected events per element node. */ 84 /** Expected events per element node. */
79 // TODO(sigmund): investigate whether we need more than 1 set of local events 85 // TODO(sigmund): investigate whether we need more than 1 set of local events
80 // per element (why does the js implementation stores 1 per template node?) 86 // per element (why does the js implementation stores 1 per template node?)
81 Expando<Set<String>> _templateDelegates; 87 Expando<Set<String>> _templateDelegates;
82 88
83 PolymerDeclaration.created() : super.created() { 89 PolymerDeclaration.created() : super.created() {
84 // fetch the element name 90 // fetch the element name
85 _name = attributes['name']; 91 _name = attributes['name'];
92 // fetch our extendee name
93 _extendsName = attributes['extends'];
86 // install element definition, if ready 94 // install element definition, if ready
87 registerWhenReady(); 95 registerWhenReady();
88 } 96 }
89 97
90 void registerWhenReady() { 98 void registerWhenReady() {
91 // if we have no prototype, wait 99 // if we have no prototype, wait
92 if (waitingForType(name)) { 100 if (waitingForType(name)) {
93 return; 101 return;
94 } 102 }
95 // fetch our extendee name 103 if (waitingForExtendee(_extendsName)) {
96 var extendee = attributes['extends'];
97 if (waitingForExtendee(extendee)) {
98 //console.warn(name + ': waitingForExtendee:' + extendee); 104 //console.warn(name + ': waitingForExtendee:' + extendee);
99 return; 105 return;
100 } 106 }
101 // TODO(sjmiles): HTMLImports polyfill awareness: 107 // TODO(sjmiles): HTMLImports polyfill awareness:
102 // elements in the main document are likely to parse 108 // elements in the main document are likely to parse
103 // in advance of elements in imports because the 109 // in advance of elements in imports because the
104 // polyfill parser is simulated 110 // polyfill parser is simulated
105 // therefore, wait for imports loaded before 111 // therefore, wait for imports loaded before
106 // finalizing elements in the main document 112 // finalizing elements in the main document
107 // TODO(jmesserly): Polymer.dart waits for HTMLImportsLoaded, so I've 113 // TODO(jmesserly): Polymer.dart waits for HTMLImportsLoaded, so I've
108 // removed "whenImportsLoaded" for now. Restore the workaround if needed. 114 // removed "whenImportsLoaded" for now. Restore the workaround if needed.
109 _register(extendee); 115 _register(_extendsName);
110 } 116 }
111 117
112 void _register(extendee) { 118 void _register(extendee) {
113 //console.group('registering', name); 119 //console.group('registering', name);
114 register(name, extendee); 120 register(name, extendee);
115 //console.groupEnd(); 121 //console.groupEnd();
116 // subclasses may now register themselves 122 // subclasses may now register themselves
117 _notifySuper(name); 123 _notifySuper(name);
118 } 124 }
119 125
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 187
182 // get basal prototype 188 // get basal prototype
183 _supertype = _getRegisteredType(extendee); 189 _supertype = _getRegisteredType(extendee);
184 if (_supertype != null) _super = _getDeclaration(extendee); 190 if (_supertype != null) _super = _getDeclaration(extendee);
185 191
186 var cls = reflectClass(_type); 192 var cls = reflectClass(_type);
187 193
188 // transcribe `attributes` declarations onto own prototype's `publish` 194 // transcribe `attributes` declarations onto own prototype's `publish`
189 publishAttributes(cls, _super); 195 publishAttributes(cls, _super);
190 196
191 publishProperties(type); 197 publishProperties(_type);
192 198
193 inferObservers(cls); 199 inferObservers(cls);
194 200
201 // desugar compound observer syntax, e.g. @ObserveProperty('a b c')
202 explodeObservers(cls);
203
195 // Skip the rest in Dart: 204 // Skip the rest in Dart:
196 // chain various meta-data objects to inherited versions 205 // chain various meta-data objects to inherited versions
197 // chain custom api to inherited 206 // chain custom api to inherited
198 // build side-chained lists to optimize iterations 207 // build side-chained lists to optimize iterations
199 // inherit publishing meta-data 208 // inherit publishing meta-data
200 // x-platform fixup 209 // x-platform fixup
201 } 210 }
202 211
203 /** Implement various declarative features. */ 212 /** Implement various declarative features. */
204 void desugar(name, extendee) { 213 void desugar(name, extendee) {
205 // compile list of attributes to copy to instances 214 // compile list of attributes to copy to instances
206 accumulateInstanceAttributes(); 215 accumulateInstanceAttributes();
207 // parse on-* delegates declared on `this` element 216 // parse on-* delegates declared on `this` element
208 parseHostEvents(); 217 parseHostEvents();
209 // install external stylesheets as if they are inline 218 // install external stylesheets as if they are inline
210 installSheets(); 219 installSheets();
211 220
221 adjustShadowElement();
222
212 // TODO(sorvell): install a helper method this.resolvePath to aid in 223 // TODO(sorvell): install a helper method this.resolvePath to aid in
213 // setting resource paths. e.g. 224 // setting resource paths. e.g.
214 // this.$.image.src = this.resolvePath('images/foo.png') 225 // this.$.image.src = this.resolvePath('images/foo.png')
215 // Potentially remove when spec bug is addressed. 226 // Potentially remove when spec bug is addressed.
216 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407 227 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407
217 // TODO(jmesserly): resolvePath not ported, see first comment in this class. 228 // TODO(jmesserly): resolvePath not ported, see first comment in this class.
218 229
219 // under ShadowDOMPolyfill, transforms to approximate missing CSS features 230 // under ShadowDOMPolyfill, transforms to approximate missing CSS features
220 _shimShadowDomStyling(templateContent, name, extendee); 231 _shimShadowDomStyling(templateContent, name, extendee);
221 232
222 var cls = reflectClass(type); 233 var cls = reflectClass(type);
223 // TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient 234 // TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient
224 // lazy static initialization, can we get by without it? 235 // lazy static initialization, can we get by without it?
225 var registered = cls.declarations[#registerCallback]; 236 var registered = cls.declarations[#registerCallback];
226 if (registered != null && 237 if (registered != null &&
227 registered is MethodMirror && 238 registered is MethodMirror &&
228 registered.isStatic && 239 registered.isStatic &&
229 registered.isRegularMethod) { 240 registered.isRegularMethod) {
230 cls.invoke(#registerCallback, [this]); 241 cls.invoke(#registerCallback, [this]);
231 } 242 }
232 } 243 }
233 244
245 // TODO(sorvell): remove when spec addressed:
246 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22460
247 // make <shadow></shadow> be <shadow><content></content></shadow>
248 void adjustShadowElement() {
249 // TODO(sorvell): avoid under SD polyfill until this bug is addressed:
250 // https://github.com/Polymer/ShadowDOM/issues/297
251 if (!_hasShadowDomPolyfill) {
252 final content = templateContent;
253 if (content == null) return;
254
255 for (var s in content.querySelectorAll('shadow')) {
256 if (s.nodes.isEmpty) s.append(new ContentElement());
257 }
258 }
259 }
260
234 void registerType(String name) { 261 void registerType(String name) {
235 var baseTag; 262 var baseTag;
236 var decl = this; 263 var decl = this;
237 while (decl != null) { 264 while (decl != null) {
238 baseTag = decl.attributes['extends']; 265 baseTag = decl.attributes['extends'];
239 decl = decl.superDeclaration; 266 decl = decl.superDeclaration;
240 } 267 }
241 document.register(name, type, extendsTag: baseTag); 268 document.register(name, type, extendsTag: baseTag);
242 } 269 }
243 270
244 void publishAttributes(ClassMirror cls, PolymerDeclaration superDecl) { 271 void publishAttributes(ClassMirror cls, PolymerDeclaration superDecl) {
245 // get properties to publish 272 // get properties to publish
246 if (superDecl != null && superDecl._publish != null) { 273 if (superDecl != null && superDecl._publish != null) {
247 // Dart note: even though we walk the type hierarchy in 274 // Dart note: even though we walk the type hierarchy in
248 // _getPublishedProperties, this will additionally include any names 275 // _getPublishedProperties, this will additionally include any names
249 // published via the `attributes` attribute. 276 // published via the `attributes` attribute.
250 _publish = new Map.from(superDecl._publish); 277 _publish = new Map.from(superDecl._publish);
251 } 278 }
252 279
253 _publish = _getPublishedProperties(cls, _publish); 280 _publish = _getPublishedProperties(cls, _publish);
254 281
255 // merge names from 'attributes' attribute 282 // merge names from 'attributes' attribute
256 var attrs = attributes['attributes']; 283 var attrs = attributes['attributes'];
257 if (attrs != null) { 284 if (attrs != null) {
258 // names='a b c' or names='a,b,c' 285 // names='a b c' or names='a,b,c'
259 // record each name for publishing 286 // record each name for publishing
260 for (var attr in attrs.split(attrs.contains(',') ? ',' : ' ')) { 287 for (var attr in attrs.split(_ATTRIBUTES_REGEX)) {
261 // remove excess ws 288 // remove excess ws
262 attr = attr.trim(); 289 attr = attr.trim();
263 290
264 // do not override explicit entries 291 // do not override explicit entries
265 if (attr != '' && _publish != null && _publish.containsKey(attr)) { 292 if (attr == '') continue;
293
294 var property = new Symbol(attr);
295 var path = new PropertyPath([property]);
296 if (_publish != null && _publish.containsKey(path)) {
266 continue; 297 continue;
267 } 298 }
268 299
269 var property = new Symbol(attr);
270 var mirror = _getProperty(cls, property); 300 var mirror = _getProperty(cls, property);
271 if (mirror == null) { 301 if (mirror == null) {
272 window.console.warn('property for attribute $attr of polymer-element ' 302 window.console.warn('property for attribute $attr of polymer-element '
273 'name=$name not found.'); 303 'name=$name not found.');
274 continue; 304 continue;
275 } 305 }
276 if (_publish == null) _publish = {}; 306 if (_publish == null) _publish = {};
277 _publish[property] = mirror; 307 _publish[path] = mirror;
278 } 308 }
279 } 309 }
280 310
281 // NOTE: the following is not possible in Dart; fields must be declared. 311 // NOTE: the following is not possible in Dart; fields must be declared.
282 // install 'attributes' as properties on the prototype, 312 // install 'attributes' as properties on the prototype,
283 // but don't override 313 // but don't override
284 } 314 }
285 315
286 void accumulateInstanceAttributes() { 316 void accumulateInstanceAttributes() {
287 // inherit instance attributes 317 // inherit instance attributes
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 new StyleElement()..text = '$cssText', 401 new StyleElement()..text = '$cssText',
372 content.firstChild); 402 content.firstChild);
373 } 403 }
374 } 404 }
375 } 405 }
376 406
377 List<Element> findNodes(String selector, [bool matcher(Element e)]) { 407 List<Element> findNodes(String selector, [bool matcher(Element e)]) {
378 var nodes = this.querySelectorAll(selector).toList(); 408 var nodes = this.querySelectorAll(selector).toList();
379 var content = templateContent; 409 var content = templateContent;
380 if (content != null) { 410 if (content != null) {
381 nodes = nodes..addAll(content.queryAll(selector)); 411 nodes = nodes..addAll(content.querySelectorAll(selector));
382 } 412 }
383 if (matcher != null) return nodes.where(matcher).toList(); 413 if (matcher != null) return nodes.where(matcher).toList();
384 return nodes; 414 return nodes;
385 } 415 }
386 416
387 /** 417 /**
388 * Promotes external stylesheets and style elements with the attribute 418 * Promotes external stylesheets and style elements with the attribute
389 * polymer-scope='global' into global scope. 419 * polymer-scope='global' into global scope.
390 * This is particularly useful for defining @keyframe rules which 420 * This is particularly useful for defining @keyframe rules which
391 * currently do not function in scoped or shadow style elements. 421 * currently do not function in scoped or shadow style elements.
392 * (See wkb.ug/72462) 422 * (See wkb.ug/72462)
393 */ 423 */
394 // TODO(sorvell): remove when wkb.ug/72462 is addressed. 424 // TODO(sorvell): remove when wkb.ug/72462 is addressed.
395 void installGlobalStyles() { 425 void installGlobalStyles() {
396 var style = styleForScope(_STYLE_GLOBAL_SCOPE); 426 var style = styleForScope(_STYLE_GLOBAL_SCOPE);
397 Polymer.applyStyleToScope(style, document.head); 427 Polymer.applyStyleToScope(style, document.head);
398 } 428 }
399 429
400 String cssTextForScope(String scopeDescriptor) { 430 String cssTextForScope(String scopeDescriptor) {
401 var cssText = new StringBuffer(); 431 var cssText = new StringBuffer();
402 // handle stylesheets 432 // handle stylesheets
403 var selector = '[$_SCOPE_ATTR=$scopeDescriptor]'; 433 var selector = '[$_SCOPE_ATTR=$scopeDescriptor]';
404 matcher(s) => s.matches(selector); 434 matcher(s) => s.matches(selector);
405 435
406 for (var sheet in sheets.where(matcher)) { 436 for (var sheet in sheets.where(matcher)) {
407 cssText..write(_cssTextFromSheet(sheet))..write('\n\n'); 437 cssText..write(_cssTextFromSheet(sheet))..write('\n\n');
408 } 438 }
409 // handle cached style elements 439 // handle cached style elements
410 for (var style in styles.where(matcher)) { 440 for (var style in styles.where(matcher)) {
411 cssText..write(style.textContent)..write('\n\n'); 441 cssText..write(style.text)..write('\n\n');
412 } 442 }
413 return cssText.toString(); 443 return cssText.toString();
414 } 444 }
415 445
416 StyleElement styleForScope(String scopeDescriptor) { 446 StyleElement styleForScope(String scopeDescriptor) {
417 var cssText = cssTextForScope(scopeDescriptor); 447 var cssText = cssTextForScope(scopeDescriptor);
418 return cssTextToScopeStyle(cssText, scopeDescriptor); 448 return cssTextToScopeStyle(cssText, scopeDescriptor);
419 } 449 }
420 450
421 StyleElement cssTextToScopeStyle(String cssText, String scopeDescriptor) { 451 StyleElement cssTextToScopeStyle(String cssText, String scopeDescriptor) {
422 if (cssText == '') return null; 452 if (cssText == '') return null;
423 453
424 return new StyleElement() 454 return new StyleElement()
425 ..text = cssText 455 ..text = cssText
426 ..attributes[_STYLE_SCOPE_ATTRIBUTE] = '$name-$scopeDescriptor'; 456 ..attributes[_STYLE_SCOPE_ATTRIBUTE] = '$name-$scopeDescriptor';
427 } 457 }
428 458
429 /** 459 /**
430 * fetch a list of all observable properties names in our inheritance chain 460 * Fetch a list of all *Changed methods so we can observe the associated
431 * above Polymer. 461 * properties.
432 */ 462 */
433 // TODO(sjmiles): perf: reflection is slow, relatively speaking
434 // If an element may take 6us to create, getCustomPropertyNames might
435 // cost 1.6us more.
436 void inferObservers(ClassMirror cls) { 463 void inferObservers(ClassMirror cls) {
437 if (cls == _objectType) return; 464 if (cls == _htmlElementType) return;
438 inferObservers(cls.superclass); 465 inferObservers(cls.superclass);
439 for (var method in cls.declarations.values) { 466 for (var method in cls.declarations.values) {
440 if (method is! MethodMirror || method.isStatic 467 if (method is! MethodMirror || method.isStatic
441 || !method.isRegularMethod) continue; 468 || !method.isRegularMethod) continue;
442 469
443 String name = MirrorSystem.getName(method.simpleName); 470 String name = MirrorSystem.getName(method.simpleName);
444 if (name.endsWith(_OBSERVE_SUFFIX) && name != 'attributeChanged') { 471 if (name.endsWith(_OBSERVE_SUFFIX) && name != 'attributeChanged') {
445 if (_observe == null) _observe = new Map(); 472 // TODO(jmesserly): now that we have a better system, should we
473 // deprecate *Changed methods?
474 if (_observe == null) _observe = new HashMap();
446 name = name.substring(0, name.length - 7); 475 name = name.substring(0, name.length - 7);
447 _observe[new Symbol(name)] = method.simpleName; 476 _observe[new PropertyPath(name)] = [method.simpleName];
448 } 477 }
449 } 478 }
450 } 479 }
480
481 /**
482 * Fetch a list of all methods annotated with [ObserveProperty] so we can
483 * observe the associated properties.
484 */
485 void explodeObservers(ClassMirror cls) {
486 if (cls == _htmlElementType) return;
487
488 explodeObservers(cls.superclass);
489 for (var method in cls.declarations.values) {
490 if (method is! MethodMirror || method.isStatic
491 || !method.isRegularMethod) continue;
492
493 for (var meta in _safeGetMetadata(method)) {
494 if (meta.reflectee is! ObserveProperty) continue;
495
496 if (_observe == null) _observe = new HashMap();
497
498 for (String name in meta.reflectee.names) {
499 _observe.putIfAbsent(new PropertyPath(name), () => [])
500 .add(method.simpleName);
501 }
502 }
503 }
504 }
451 505
452 void publishProperties(Type type) { 506 void publishProperties(Type type) {
453 // Dart note: _publish was already populated by publishAttributes 507 // Dart note: _publish was already populated by publishAttributes
454 if (_publish != null) _publishLC = _lowerCaseMap(_publish); 508 if (_publish != null) _publishLC = _lowerCaseMap(_publish);
455 } 509 }
456 510
457 Map<String, dynamic> _lowerCaseMap(Map<Symbol, dynamic> properties) { 511 Map<String, dynamic> _lowerCaseMap(Map<PropertyPath, dynamic> properties) {
458 final map = new Map<String, dynamic>(); 512 final map = new Map<String, dynamic>();
459 properties.forEach((name, value) { 513 properties.forEach((PropertyPath path, value) {
460 map[MirrorSystem.getName(name).toLowerCase()] = value; 514 map['$path'.toLowerCase()] = value;
461 }); 515 });
462 return map; 516 return map;
463 } 517 }
464 } 518 }
465 519
466 /// maps tag names to prototypes 520 /// maps tag names to prototypes
467 final Map _typesByName = new Map<String, Type>(); 521 final Map _typesByName = new Map<String, Type>();
468 522
469 Type _getRegisteredType(String name) => _typesByName[name]; 523 Type _getRegisteredType(String name) => _typesByName[name];
470 524
(...skipping 17 matching lines...) Expand all
488 } 542 }
489 } 543 }
490 544
491 /// track document.register'ed tag names and their declarations 545 /// track document.register'ed tag names and their declarations
492 final Map _declarations = new Map<String, PolymerDeclaration>(); 546 final Map _declarations = new Map<String, PolymerDeclaration>();
493 547
494 bool _isRegistered(String name) => _declarations.containsKey(name); 548 bool _isRegistered(String name) => _declarations.containsKey(name);
495 PolymerDeclaration _getDeclaration(String name) => _declarations[name]; 549 PolymerDeclaration _getDeclaration(String name) => _declarations[name];
496 550
497 final _objectType = reflectClass(Object); 551 final _objectType = reflectClass(Object);
498 552 final _htmlElementType = reflectClass(HtmlElement);
499 553
500 Map _getPublishedProperties(ClassMirror cls, Map props) { 554 Map _getPublishedProperties(ClassMirror cls, Map props) {
501 if (cls == _objectType) return props; 555 if (cls == _htmlElementType) return props;
502 props = _getPublishedProperties(cls.superclass, props); 556 props = _getPublishedProperties(cls.superclass, props);
503 for (var member in cls.declarations.values) { 557 for (var member in cls.declarations.values) {
504 if (member.isStatic || member.isPrivate) continue; 558 if (member.isStatic || member.isPrivate) continue;
505 559
506 if (member is VariableMirror && !member.isFinal 560 if (member is VariableMirror && !member.isFinal
507 || member is MethodMirror && member.isGetter) { 561 || member is MethodMirror && member.isGetter) {
508 562
509 for (var meta in member.metadata) { 563 for (var meta in member.metadata) {
510 if (meta.reflectee is PublishedProperty) { 564 if (meta.reflectee is PublishedProperty) {
511 // Note: we delay the setter check until we find @published because 565 // Note: we delay the setter check until we find @published because
512 // it's a tad expensive. 566 // it's a tad expensive.
513 if (member is! MethodMirror || _hasSetter(cls, member)) { 567 if (member is! MethodMirror || _hasSetter(cls, member)) {
514 if (props == null) props = {}; 568 if (props == null) props = {};
515 props[member.simpleName] = member; 569 props[new PropertyPath([member.simpleName])] = member;
516 } 570 }
517 break; 571 break;
518 } 572 }
519 } 573 }
520 } 574 }
521 } 575 }
522 576
523 return props; 577 return props;
524 } 578 }
525 579
(...skipping 12 matching lines...) Expand all
538 // bug introduced between Chrome 31 and 32. After 32 592 // bug introduced between Chrome 31 and 32. After 32
539 // JsClassMirror.declarations on Object calls 593 // JsClassMirror.declarations on Object calls
540 // JsClassMirror.typeVariables, which tries to get the _jsConstructor's 594 // JsClassMirror.typeVariables, which tries to get the _jsConstructor's
541 // .prototype["<>"]. This ends up getting the "" property instead, maybe 595 // .prototype["<>"]. This ends up getting the "" property instead, maybe
542 // because "<>" doesn't exist, and gets ";" which then blows up because 596 // because "<>" doesn't exist, and gets ";" which then blows up because
543 // the code later on expects a List of ints. 597 // the code later on expects a List of ints.
544 } while (cls != _objectType); 598 } while (cls != _objectType);
545 return null; 599 return null;
546 } 600 }
547 601
602 List _safeGetMetadata(MethodMirror method) {
603 // TODO(jmesserly): dart2js blows up getting metadata from methods in some
604 // cases. Why does this happen? It seems like the culprit might be named
605 // arguments. Unfortunately even calling method.parameters also
606 // triggers the bug in computeFunctionRti. For now we guard against it
607 // with this check.
608 try {
609 return method.metadata;
610 } catch (e) {
611 return [];
612 }
613 }
614
548 bool _hasSetter(ClassMirror cls, MethodMirror getter) { 615 bool _hasSetter(ClassMirror cls, MethodMirror getter) {
549 var setterName = new Symbol('${MirrorSystem.getName(getter.simpleName)}='); 616 var setterName = new Symbol('${MirrorSystem.getName(getter.simpleName)}=');
550 var mirror = cls.declarations[setterName]; 617 var mirror = cls.declarations[setterName];
551 return mirror is MethodMirror && mirror.isSetter; 618 return mirror is MethodMirror && mirror.isSetter;
552 } 619 }
553 620
554 621
555 /** Attribute prefix used for declarative event handlers. */ 622 /** Attribute prefix used for declarative event handlers. */
556 const _EVENT_PREFIX = 'on-'; 623 const _EVENT_PREFIX = 'on-';
557 624
558 /** Whether an attribute declares an event. */ 625 /** Whether an attribute declares an event. */
559 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX); 626 bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX);
560 627
561 String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length); 628 String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length);
562 629
563 /** 630 /**
564 * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content. 631 * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
565 */ 632 */
566 void _shimShadowDomStyling(DocumentFragment template, String name, 633 void _shimShadowDomStyling(DocumentFragment template, String name,
567 String extendee) { 634 String extendee) {
568 if (js.context == null || template == null) return; 635 if (template == null || !_hasShadowDomPolyfill) return;
569 if (!js.context.hasProperty('ShadowDOMPolyfill')) return;
570 636
571 var platform = js.context['Platform']; 637 var platform = js.context['Platform'];
572 if (platform == null) return; 638 if (platform == null) return;
573 var shadowCss = platform['ShadowCSS']; 639 var shadowCss = platform['ShadowCSS'];
574 if (shadowCss == null) return; 640 if (shadowCss == null) return;
575 shadowCss.callMethod('shimStyling', [template, name, extendee]); 641 shadowCss.callMethod('shimStyling', [template, name, extendee]);
576 } 642 }
577 643
644 final bool _hasShadowDomPolyfill = js.context != null &&
645 js.context.hasProperty('ShadowDOMPolyfill');
646
578 const _STYLE_SELECTOR = 'style'; 647 const _STYLE_SELECTOR = 'style';
579 const _SHEET_SELECTOR = '[rel=stylesheet]'; 648 const _SHEET_SELECTOR = '[rel=stylesheet]';
580 const _STYLE_GLOBAL_SCOPE = 'global'; 649 const _STYLE_GLOBAL_SCOPE = 'global';
581 const _SCOPE_ATTR = 'polymer-scope'; 650 const _SCOPE_ATTR = 'polymer-scope';
582 const _STYLE_SCOPE_ATTRIBUTE = 'element'; 651 const _STYLE_SCOPE_ATTRIBUTE = 'element';
583 const _STYLE_CONTROLLER_SCOPE = 'controller'; 652 const _STYLE_CONTROLLER_SCOPE = 'controller';
584 653
585 String _cssTextFromSheet(LinkElement sheet) { 654 String _cssTextFromSheet(LinkElement sheet) {
586 if (sheet == null) return ''; 655 if (sheet == null) return '';
587 656
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 // TODO(jmesserly): is this list complete? 689 // TODO(jmesserly): is this list complete?
621 final _eventTranslations = const { 690 final _eventTranslations = const {
622 // TODO(jmesserly): these three Polymer.js translations won't work in Dart, 691 // TODO(jmesserly): these three Polymer.js translations won't work in Dart,
623 // because we strip the webkit prefix (below). Reconcile. 692 // because we strip the webkit prefix (below). Reconcile.
624 'webkitanimationstart': 'webkitAnimationStart', 693 'webkitanimationstart': 'webkitAnimationStart',
625 'webkitanimationend': 'webkitAnimationEnd', 694 'webkitanimationend': 'webkitAnimationEnd',
626 'webkittransitionend': 'webkitTransitionEnd', 695 'webkittransitionend': 'webkitTransitionEnd',
627 696
628 'domfocusout': 'DOMFocusOut', 697 'domfocusout': 'DOMFocusOut',
629 'domfocusin': 'DOMFocusIn', 698 'domfocusin': 'DOMFocusIn',
699 'dommousescroll': 'DOMMouseScroll',
630 700
631 // TODO(jmesserly): Dart specific renames. Reconcile with Polymer.js 701 // TODO(jmesserly): Dart specific renames. Reconcile with Polymer.js
632 'animationend': 'webkitAnimationEnd', 702 'animationend': 'webkitAnimationEnd',
633 'animationiteration': 'webkitAnimationIteration', 703 'animationiteration': 'webkitAnimationIteration',
634 'animationstart': 'webkitAnimationStart', 704 'animationstart': 'webkitAnimationStart',
635 'doubleclick': 'dblclick', 705 'doubleclick': 'dblclick',
636 'fullscreenchange': 'webkitfullscreenchange', 706 'fullscreenchange': 'webkitfullscreenchange',
637 'fullscreenerror': 'webkitfullscreenerror', 707 'fullscreenerror': 'webkitfullscreenerror',
638 'keyadded': 'webkitkeyadded', 708 'keyadded': 'webkitkeyadded',
639 'keyerror': 'webkitkeyerror', 709 'keyerror': 'webkitkeyerror',
(...skipping 10 matching lines...) Expand all
650 return map; 720 return map;
651 }(); 721 }();
652 722
653 // Dart note: we need this function because we have additional renames JS does 723 // Dart note: we need this function because we have additional renames JS does
654 // not have. The JS renames are simply case differences, whereas we have ones 724 // not have. The JS renames are simply case differences, whereas we have ones
655 // like doubleclick -> dblclick and stripping the webkit prefix. 725 // like doubleclick -> dblclick and stripping the webkit prefix.
656 String _eventNameFromType(String eventType) { 726 String _eventNameFromType(String eventType) {
657 final result = _reverseEventTranslations[eventType]; 727 final result = _reverseEventTranslations[eventType];
658 return result != null ? result : eventType; 728 return result != null ? result : eventType;
659 } 729 }
730
731 final _ATTRIBUTES_REGEX = new RegExp(r'\s|,');
OLDNEW
« no previous file with comments | « pkg/polymer/lib/polymer.dart ('k') | pkg/polymer/lib/src/instance.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698