| 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 /** | 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 for (var attr in attrs.split(attrs.contains(',') ? ',' : ' ')) { | 260 for (var attr in attrs.split(attrs.contains(',') ? ',' : ' ')) { |
| 261 // remove excess ws | 261 // remove excess ws |
| 262 attr = attr.trim(); | 262 attr = attr.trim(); |
| 263 | 263 |
| 264 // do not override explicit entries | 264 // do not override explicit entries |
| 265 if (attr != '' && _publish != null && _publish.containsKey(attr)) { | 265 if (attr != '' && _publish != null && _publish.containsKey(attr)) { |
| 266 continue; | 266 continue; |
| 267 } | 267 } |
| 268 | 268 |
| 269 var property = new Symbol(attr); | 269 var property = new Symbol(attr); |
| 270 var mirror = cls.declarations[property]; | 270 var mirror = _getProperty(cls, property); |
| 271 if (mirror is MethodMirror) { | |
| 272 if (!mirror.isGetter || !_hasSetter(cls, mirror)) mirror = null; | |
| 273 } else if (mirror is! VariableMirror) { | |
| 274 mirror = null; | |
| 275 } | |
| 276 if (mirror == null) { | 271 if (mirror == null) { |
| 277 window.console.warn('property for attribute $attr of polymer-element ' | 272 window.console.warn('property for attribute $attr of polymer-element ' |
| 278 'name=$name not found.'); | 273 'name=$name not found.'); |
| 279 continue; | 274 continue; |
| 280 } | 275 } |
| 281 if (_publish == null) _publish = {}; | 276 if (_publish == null) _publish = {}; |
| 282 _publish[property] = mirror; | 277 _publish[property] = mirror; |
| 283 } | 278 } |
| 284 } | 279 } |
| 285 | 280 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 } | 427 } |
| 433 | 428 |
| 434 /** | 429 /** |
| 435 * fetch a list of all observable properties names in our inheritance chain | 430 * fetch a list of all observable properties names in our inheritance chain |
| 436 * above Polymer. | 431 * above Polymer. |
| 437 */ | 432 */ |
| 438 // TODO(sjmiles): perf: reflection is slow, relatively speaking | 433 // TODO(sjmiles): perf: reflection is slow, relatively speaking |
| 439 // If an element may take 6us to create, getCustomPropertyNames might | 434 // If an element may take 6us to create, getCustomPropertyNames might |
| 440 // cost 1.6us more. | 435 // cost 1.6us more. |
| 441 void inferObservers(ClassMirror cls) { | 436 void inferObservers(ClassMirror cls) { |
| 437 if (cls == _objectType) return; |
| 438 inferObservers(cls.superclass); |
| 442 for (var method in cls.declarations.values) { | 439 for (var method in cls.declarations.values) { |
| 443 if (method is! MethodMirror || method.isStatic | 440 if (method is! MethodMirror || method.isStatic |
| 444 || !method.isRegularMethod) continue; | 441 || !method.isRegularMethod) continue; |
| 445 | 442 |
| 446 String name = MirrorSystem.getName(method.simpleName); | 443 String name = MirrorSystem.getName(method.simpleName); |
| 447 if (name.endsWith(_OBSERVE_SUFFIX) && name != 'attributeChanged') { | 444 if (name.endsWith(_OBSERVE_SUFFIX) && name != 'attributeChanged') { |
| 448 if (_observe == null) _observe = new Map(); | 445 if (_observe == null) _observe = new Map(); |
| 449 name = name.substring(0, name.length - 7); | 446 name = name.substring(0, name.length - 7); |
| 450 _observe[new Symbol(name)] = method.simpleName; | 447 _observe[new Symbol(name)] = method.simpleName; |
| 451 } | 448 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 } | 489 } |
| 493 | 490 |
| 494 /// track document.register'ed tag names and their declarations | 491 /// track document.register'ed tag names and their declarations |
| 495 final Map _declarations = new Map<String, PolymerDeclaration>(); | 492 final Map _declarations = new Map<String, PolymerDeclaration>(); |
| 496 | 493 |
| 497 bool _isRegistered(String name) => _declarations.containsKey(name); | 494 bool _isRegistered(String name) => _declarations.containsKey(name); |
| 498 PolymerDeclaration _getDeclaration(String name) => _declarations[name]; | 495 PolymerDeclaration _getDeclaration(String name) => _declarations[name]; |
| 499 | 496 |
| 500 final _objectType = reflectClass(Object); | 497 final _objectType = reflectClass(Object); |
| 501 | 498 |
| 499 |
| 502 Map _getPublishedProperties(ClassMirror cls, Map props) { | 500 Map _getPublishedProperties(ClassMirror cls, Map props) { |
| 503 if (cls == _objectType) return props; | 501 if (cls == _objectType) return props; |
| 504 props = _getPublishedProperties(cls.superclass, props); | 502 props = _getPublishedProperties(cls.superclass, props); |
| 505 for (var field in cls.declarations.values) { | 503 for (var member in cls.declarations.values) { |
| 506 if (field is! VariableMirror || | 504 if (member.isStatic || member.isPrivate) continue; |
| 507 field.isFinal || field.isStatic || field.isPrivate) continue; | |
| 508 | 505 |
| 509 for (var meta in field.metadata) { | 506 if (member is VariableMirror && !member.isFinal |
| 510 if (meta.reflectee is PublishedProperty) { | 507 || member is MethodMirror && member.isGetter) { |
| 511 if (props == null) props = {}; | 508 |
| 512 props[field.simpleName] = field; | 509 for (var meta in member.metadata) { |
| 513 break; | 510 if (meta.reflectee is PublishedProperty) { |
| 511 // Note: we delay the setter check until we find @published because |
| 512 // it's a tad expensive. |
| 513 if (member is! MethodMirror || _hasSetter(cls, member)) { |
| 514 if (props == null) props = {}; |
| 515 props[member.simpleName] = member; |
| 516 } |
| 517 break; |
| 518 } |
| 514 } | 519 } |
| 515 } | 520 } |
| 516 } | 521 } |
| 517 | |
| 518 for (var getter in cls.declarations.values) { | |
| 519 if (getter is! MethodMirror || !getter.isGetter || | |
| 520 getter.isStatic || getter.isPrivate) continue; | |
| 521 | |
| 522 for (var meta in getter.metadata) { | |
| 523 if (meta.reflectee is PublishedProperty) { | |
| 524 if (_hasSetter(cls, getter)) { | |
| 525 if (props == null) props = {}; | |
| 526 props[getter.simpleName] = getter; | |
| 527 } | |
| 528 break; | |
| 529 } | |
| 530 } | |
| 531 } | |
| 532 | 522 |
| 533 return props; | 523 return props; |
| 534 } | 524 } |
| 535 | 525 |
| 526 DeclarationMirror _getProperty(ClassMirror cls, Symbol property) { |
| 527 do { |
| 528 var mirror = cls.declarations[property]; |
| 529 if (mirror is MethodMirror && mirror.isGetter && _hasSetter(cls, mirror) |
| 530 || mirror is VariableMirror) { |
| 531 return mirror; |
| 532 } |
| 533 cls = cls.superclass; |
| 534 } while (cls != null); |
| 535 return null; |
| 536 } |
| 537 |
| 536 bool _hasSetter(ClassMirror cls, MethodMirror getter) { | 538 bool _hasSetter(ClassMirror cls, MethodMirror getter) { |
| 537 var setterName = new Symbol('${MirrorSystem.getName(getter.simpleName)}='); | 539 var setterName = new Symbol('${MirrorSystem.getName(getter.simpleName)}='); |
| 538 var mirror = cls.declarations[setterName]; | 540 var mirror = cls.declarations[setterName]; |
| 539 return mirror is MethodMirror && mirror.isSetter; | 541 return mirror is MethodMirror && mirror.isSetter; |
| 540 } | 542 } |
| 541 | 543 |
| 542 | 544 |
| 543 /** Attribute prefix used for declarative event handlers. */ | 545 /** Attribute prefix used for declarative event handlers. */ |
| 544 const _EVENT_PREFIX = 'on-'; | 546 const _EVENT_PREFIX = 'on-'; |
| 545 | 547 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 return map; | 640 return map; |
| 639 }(); | 641 }(); |
| 640 | 642 |
| 641 // Dart note: we need this function because we have additional renames JS does | 643 // Dart note: we need this function because we have additional renames JS does |
| 642 // not have. The JS renames are simply case differences, whereas we have ones | 644 // not have. The JS renames are simply case differences, whereas we have ones |
| 643 // like doubleclick -> dblclick and stripping the webkit prefix. | 645 // like doubleclick -> dblclick and stripping the webkit prefix. |
| 644 String _eventNameFromType(String eventType) { | 646 String _eventNameFromType(String eventType) { |
| 645 final result = _reverseEventTranslations[eventType]; | 647 final result = _reverseEventTranslations[eventType]; |
| 646 return result != null ? result : eventType; | 648 return result != null ? result : eventType; |
| 647 } | 649 } |
| OLD | NEW |