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 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. |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 /// The names of published properties for this polymer-element. | 35 /// The names of published properties for this polymer-element. |
36 Iterable<String> get publishedProperties => | 36 Iterable<String> get publishedProperties => |
37 _publish != null ? _publish.keys.map((p) => '$p') : const []; | 37 _publish != null ? _publish.keys.map((p) => '$p') : const []; |
38 | 38 |
39 /// Same as [_publish] but with lower case names. | 39 /// Same as [_publish] but with lower case names. |
40 Map<String, smoke.Declaration> _publishLC; | 40 Map<String, smoke.Declaration> _publishLC; |
41 | 41 |
42 Map<PropertyPath, List<Symbol>> _observe; | 42 Map<PropertyPath, List<Symbol>> _observe; |
43 | 43 |
| 44 /// Name and expression for each computed property. |
| 45 Map<Symbol, String> _computed = {}; |
| 46 |
44 Map<String, Object> _instanceAttributes; | 47 Map<String, Object> _instanceAttributes; |
45 | 48 |
46 /// A set of properties that should be automatically reflected to attributes. | 49 /// 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 | 50 /// Typically this is used for CSS styling. If none, this variable will be |
48 /// left as null. | 51 /// left as null. |
49 Set<String> _reflect; | 52 Set<String> _reflect; |
50 | 53 |
51 List<Element> _sheets; | 54 List<Element> _sheets; |
52 List<Element> get sheets => _sheets; | 55 List<Element> get sheets => _sheets; |
53 | 56 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 // transcribe `attributes` declarations onto own prototype's `publish` | 106 // transcribe `attributes` declarations onto own prototype's `publish` |
104 publishAttributes(superDeclaration); | 107 publishAttributes(superDeclaration); |
105 | 108 |
106 publishProperties(); | 109 publishProperties(); |
107 | 110 |
108 inferObservers(); | 111 inferObservers(); |
109 | 112 |
110 // desugar compound observer syntax, e.g. @ObserveProperty('a b c') | 113 // desugar compound observer syntax, e.g. @ObserveProperty('a b c') |
111 explodeObservers(); | 114 explodeObservers(); |
112 | 115 |
| 116 createPropertyAccessors(); |
113 // install mdv delegate on template | 117 // install mdv delegate on template |
114 installBindingDelegate(fetchTemplate()); | 118 installBindingDelegate(fetchTemplate()); |
115 // install external stylesheets as if they are inline | 119 // install external stylesheets as if they are inline |
116 installSheets(); | 120 installSheets(); |
117 // adjust any paths in dom from imports | 121 // adjust any paths in dom from imports |
118 resolveElementPaths(element); | 122 resolveElementPaths(element); |
119 // compile list of attributes to copy to instances | 123 // compile list of attributes to copy to instances |
120 accumulateInstanceAttributes(); | 124 accumulateInstanceAttributes(); |
121 // parse on-* delegates declared on `this` element | 125 // parse on-* delegates declared on `this` element |
122 parseHostEvents(); | 126 parseHostEvents(); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 | 207 |
204 // merge names from 'attributes' attribute | 208 // merge names from 'attributes' attribute |
205 var attrs = element.attributes['attributes']; | 209 var attrs = element.attributes['attributes']; |
206 if (attrs != null) { | 210 if (attrs != null) { |
207 // names='a b c' or names='a,b,c' | 211 // names='a b c' or names='a,b,c' |
208 // record each name for publishing | 212 // record each name for publishing |
209 for (var attr in attrs.split(_ATTRIBUTES_REGEX)) { | 213 for (var attr in attrs.split(_ATTRIBUTES_REGEX)) { |
210 // remove excess ws | 214 // remove excess ws |
211 attr = attr.trim(); | 215 attr = attr.trim(); |
212 | 216 |
213 // do not override explicit entries | 217 // if the user hasn't specified a value, we want to use the |
| 218 // default, unless a superclass has already chosen one |
214 if (attr == '') continue; | 219 if (attr == '') continue; |
215 | 220 |
216 var property = smoke.nameToSymbol(attr); | 221 var property = smoke.nameToSymbol(attr); |
217 var path = new PropertyPath([property]); | 222 var path = new PropertyPath([property]); |
218 if (_publish != null && _publish.containsKey(path)) { | 223 if (_publish != null && _publish.containsKey(path)) { |
219 continue; | 224 continue; |
220 } | 225 } |
221 | 226 |
222 var decl = smoke.getDeclaration(type, property); | 227 var decl = smoke.getDeclaration(type, property); |
223 if (decl == null || decl.isMethod || decl.isFinal) { | 228 if (decl == null || decl.isMethod || decl.isFinal) { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 if (_publish != null) _publishLC = _lowerCaseMap(_publish); | 446 if (_publish != null) _publishLC = _lowerCaseMap(_publish); |
442 } | 447 } |
443 | 448 |
444 Map<String, dynamic> _lowerCaseMap(Map<PropertyPath, dynamic> properties) { | 449 Map<String, dynamic> _lowerCaseMap(Map<PropertyPath, dynamic> properties) { |
445 final map = new Map<String, dynamic>(); | 450 final map = new Map<String, dynamic>(); |
446 properties.forEach((PropertyPath path, value) { | 451 properties.forEach((PropertyPath path, value) { |
447 map['$path'.toLowerCase()] = value; | 452 map['$path'.toLowerCase()] = value; |
448 }); | 453 }); |
449 return map; | 454 return map; |
450 } | 455 } |
| 456 |
| 457 void createPropertyAccessors() { |
| 458 // Dart note: since we don't have a prototype in Dart, most of the work of |
| 459 // createPolymerAccessors is done lazily on the first access of properties. |
| 460 // Here we just extract the information from annotations and store it as |
| 461 // properties on the declaration. |
| 462 var options = const smoke.QueryOptions(includeInherited: true, |
| 463 includeUpTo: HtmlElement, withAnnotations: const [ComputedProperty]); |
| 464 var existing = {}; |
| 465 for (var decl in smoke.query(type, options)) { |
| 466 var meta = decl.annotations.firstWhere((e) => e is ComputedProperty); |
| 467 var name = decl.name; |
| 468 var prev = existing[name]; |
| 469 // The definition of a child class takes priority. |
| 470 if (prev == null || smoke.isSubclassOf(decl.type, prev.type)) { |
| 471 _computed[name] = meta.expression; |
| 472 existing[name] = decl; |
| 473 } |
| 474 } |
| 475 } |
451 } | 476 } |
452 | 477 |
453 /// maps tag names to prototypes | 478 /// maps tag names to prototypes |
454 final Map _typesByName = new Map<String, Type>(); | 479 final Map _typesByName = new Map<String, Type>(); |
455 | 480 |
456 Type _getRegisteredType(String name) => _typesByName[name]; | 481 Type _getRegisteredType(String name) => _typesByName[name]; |
457 | 482 |
458 /// track document.register'ed tag names and their declarations | 483 /// track document.register'ed tag names and their declarations |
459 final Map _declarations = new Map<String, PolymerDeclaration>(); | 484 final Map _declarations = new Map<String, PolymerDeclaration>(); |
460 | 485 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 bool _isObserverMethod(Symbol symbol) { | 543 bool _isObserverMethod(Symbol symbol) { |
519 String name = smoke.symbolToName(symbol); | 544 String name = smoke.symbolToName(symbol); |
520 if (name == null) return false; | 545 if (name == null) return false; |
521 return name.endsWith('Changed') && name != 'attributeChanged'; | 546 return name.endsWith('Changed') && name != 'attributeChanged'; |
522 } | 547 } |
523 | 548 |
524 | 549 |
525 final _ATTRIBUTES_REGEX = new RegExp(r'\s|,'); | 550 final _ATTRIBUTES_REGEX = new RegExp(r'\s|,'); |
526 | 551 |
527 final JsObject _Platform = js.context['Platform']; | 552 final JsObject _Platform = js.context['Platform']; |
OLD | NEW |