Chromium Code Reviews| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 // TODO(sigmund): investigate whether we need more than 1 set of local events | 72 // TODO(sigmund): investigate whether we need more than 1 set of local events |
| 73 // per element (why does the js implementation stores 1 per template node?) | 73 // per element (why does the js implementation stores 1 per template node?) |
| 74 Expando<Set<String>> _templateDelegates; | 74 Expando<Set<String>> _templateDelegates; |
| 75 | 75 |
| 76 String get extendee => superDeclaration != null ? | 76 String get extendee => superDeclaration != null ? |
| 77 superDeclaration.name : null; | 77 superDeclaration.name : null; |
| 78 | 78 |
| 79 /// The root URI for assets. | 79 /// The root URI for assets. |
| 80 Uri _rootUri; | 80 Uri _rootUri; |
| 81 | 81 |
| 82 /// List of properties to ignore for observation. | |
| 83 static Set<Symbol> _OBSERVATION_BLACKLIST = | |
| 84 new HashSet.from(const [#attribute]); | |
| 85 | |
| 86 static bool _canObserveProperty(Symbol property) => | |
| 87 !_OBSERVATION_BLACKLIST.contains(property); | |
| 88 | |
| 89 /// This list contains some property names that people commonly want to use, | |
| 90 /// but won't work because of Chrome/Safari bugs. It isn't an exhaustive | |
| 91 /// list. In particular it doesn't contain any property names found on | |
| 92 /// subtypes of HTMLElement (e.g. name, value). Rather it attempts to catch | |
| 93 /// some common cases. | |
| 94 /// | |
| 95 /// Dart Note: `class` is left out since its an invalid symbol in dart. This | |
|
Siggi Cherem (dart-lang)
2014/11/25 17:53:41
maybe add the property we use in dart:html (`class
jakemac
2014/12/01 18:42:50
Done.
| |
| 96 /// means that nobody could make a property by this name anyways though. | |
| 97 static Set<Symbol> _PROPERTY_NAME_BLACKLIST = new HashSet.from([ | |
| 98 const Symbol('children'), const Symbol('id'), const Symbol('hidden'), | |
| 99 const Symbol('style'), const Symbol('title')]); | |
| 100 | |
| 101 bool _checkPropertyBlacklist(Symbol name) { | |
| 102 if (_PROPERTY_NAME_BLACKLIST.contains(name)) { | |
| 103 print('Cannot define property "$name" for element "${this.name}" ' | |
| 104 'because it has the same name as an HTMLElement property, and not ' | |
| 105 'all browsers support overriding that. Consider giving it a ' | |
| 106 'different name. '); | |
| 107 return true; | |
| 108 } | |
| 109 return false; | |
| 110 } | |
| 111 | |
| 82 // Dart note: since polymer-element is handled in JS now, we have a simplified | 112 // Dart note: since polymer-element is handled in JS now, we have a simplified |
| 83 // flow for registering. We don't need to wait for the supertype or the code | 113 // flow for registering. We don't need to wait for the supertype or the code |
| 84 // to be noticed. | 114 // to be noticed. |
| 85 PolymerDeclaration(this.element, this.name, this.type, this.superDeclaration); | 115 PolymerDeclaration(this.element, this.name, this.type, this.superDeclaration); |
| 86 | 116 |
| 87 void register() { | 117 void register() { |
| 88 // more declarative features | 118 // more declarative features |
| 89 desugar(); | 119 desugar(); |
| 90 // register our custom element | 120 // register our custom element |
| 91 registerType(name); | 121 registerType(name); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 // NOTE: the following is not possible in Dart; fields must be declared. | 271 // NOTE: the following is not possible in Dart; fields must be declared. |
| 242 // install 'attributes' as properties on the prototype, | 272 // install 'attributes' as properties on the prototype, |
| 243 // but don't override | 273 // but don't override |
| 244 } | 274 } |
| 245 | 275 |
| 246 void _getPublishedProperties(Type type) { | 276 void _getPublishedProperties(Type type) { |
| 247 var options = const smoke.QueryOptions(includeInherited: true, | 277 var options = const smoke.QueryOptions(includeInherited: true, |
| 248 includeUpTo: HtmlElement, withAnnotations: const [PublishedProperty]); | 278 includeUpTo: HtmlElement, withAnnotations: const [PublishedProperty]); |
| 249 for (var decl in smoke.query(type, options)) { | 279 for (var decl in smoke.query(type, options)) { |
| 250 if (decl.isFinal) continue; | 280 if (decl.isFinal) continue; |
| 281 if (_checkPropertyBlacklist(decl.name)) continue; | |
| 251 if (_publish == null) _publish = {}; | 282 if (_publish == null) _publish = {}; |
| 252 _publish[new PropertyPath([decl.name])] = decl; | 283 _publish[new PropertyPath([decl.name])] = decl; |
| 253 | 284 |
| 254 // Should we reflect the property value to the attribute automatically? | 285 // Should we reflect the property value to the attribute automatically? |
| 255 if (decl.annotations | 286 if (decl.annotations |
| 256 .where((a) => a is PublishedProperty) | 287 .where((a) => a is PublishedProperty) |
| 257 .any((a) => a.reflect)) { | 288 .any((a) => a.reflect)) { |
| 258 | 289 |
| 259 if (_reflect == null) _reflect = new Set(); | 290 if (_reflect == null) _reflect = new Set(); |
| 260 _reflect.add(smoke.symbolToName(decl.name)); | 291 _reflect.add(smoke.symbolToName(decl.name)); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 | 447 |
| 417 /// Fetch a list of all *Changed methods so we can observe the associated | 448 /// Fetch a list of all *Changed methods so we can observe the associated |
| 418 /// properties. | 449 /// properties. |
| 419 void inferObservers() { | 450 void inferObservers() { |
| 420 for (var decl in smoke.query(type, _changedMethodQueryOptions)) { | 451 for (var decl in smoke.query(type, _changedMethodQueryOptions)) { |
| 421 // TODO(jmesserly): now that we have a better system, should we | 452 // TODO(jmesserly): now that we have a better system, should we |
| 422 // deprecate *Changed methods? | 453 // deprecate *Changed methods? |
| 423 if (_observe == null) _observe = new HashMap(); | 454 if (_observe == null) _observe = new HashMap(); |
| 424 var name = smoke.symbolToName(decl.name); | 455 var name = smoke.symbolToName(decl.name); |
| 425 name = name.substring(0, name.length - 7); | 456 name = name.substring(0, name.length - 7); |
| 457 if (!_canObserveProperty(decl.name)) continue; | |
| 426 _observe[new PropertyPath(name)] = [decl.name]; | 458 _observe[new PropertyPath(name)] = [decl.name]; |
| 427 } | 459 } |
| 428 } | 460 } |
| 429 | 461 |
| 430 /// Fetch a list of all methods annotated with [ObserveProperty] so we can | 462 /// Fetch a list of all methods annotated with [ObserveProperty] so we can |
| 431 /// observe the associated properties. | 463 /// observe the associated properties. |
| 432 void explodeObservers() { | 464 void explodeObservers() { |
| 433 var options = const smoke.QueryOptions(includeFields: false, | 465 var options = const smoke.QueryOptions(includeFields: false, |
| 434 includeProperties: false, includeMethods: true, includeInherited: true, | 466 includeProperties: false, includeMethods: true, includeInherited: true, |
| 435 includeUpTo: HtmlElement, withAnnotations: const [ObserveProperty]); | 467 includeUpTo: HtmlElement, withAnnotations: const [ObserveProperty]); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 463 // Here we just extract the information from annotations and store it as | 495 // Here we just extract the information from annotations and store it as |
| 464 // properties on the declaration. | 496 // properties on the declaration. |
| 465 | 497 |
| 466 // Dart Note: The js side makes computed properties read only, and does | 498 // Dart Note: The js side makes computed properties read only, and does |
| 467 // special logic right here for them. For us they are automatically read | 499 // special logic right here for them. For us they are automatically read |
| 468 // only unless you define a setter for them, so we left that out. | 500 // only unless you define a setter for them, so we left that out. |
| 469 var options = const smoke.QueryOptions(includeInherited: true, | 501 var options = const smoke.QueryOptions(includeInherited: true, |
| 470 includeUpTo: HtmlElement, withAnnotations: const [ComputedProperty]); | 502 includeUpTo: HtmlElement, withAnnotations: const [ComputedProperty]); |
| 471 var existing = {}; | 503 var existing = {}; |
| 472 for (var decl in smoke.query(type, options)) { | 504 for (var decl in smoke.query(type, options)) { |
| 505 var name = decl.name; | |
| 506 if (_checkPropertyBlacklist(name)) continue; | |
| 473 var meta = decl.annotations.firstWhere((e) => e is ComputedProperty); | 507 var meta = decl.annotations.firstWhere((e) => e is ComputedProperty); |
| 474 var name = decl.name; | |
| 475 var prev = existing[name]; | 508 var prev = existing[name]; |
| 476 // The definition of a child class takes priority. | 509 // The definition of a child class takes priority. |
| 477 if (prev == null || smoke.isSubclassOf(decl.type, prev.type)) { | 510 if (prev == null || smoke.isSubclassOf(decl.type, prev.type)) { |
| 478 _computed[name] = meta.expression; | 511 _computed[name] = meta.expression; |
| 479 existing[name] = decl; | 512 existing[name] = decl; |
| 480 } | 513 } |
| 481 } | 514 } |
| 482 } | 515 } |
| 483 } | 516 } |
| 484 | 517 |
| 485 /// maps tag names to prototypes | 518 /// maps tag names to prototypes |
| 486 final Map _typesByName = new Map<String, Type>(); | 519 final Map _typesByName = new Map<String, Type>(); |
| 487 | 520 |
| 488 Type _getRegisteredType(String name) => _typesByName[name]; | 521 Type _getRegisteredType(String name) => _typesByName[name]; |
| 489 | 522 |
| 490 /// Dart Note: instanceOfType not implemented for dart, its not needed. | 523 /// Dart Note: instanceOfType not implemented for dart, its not needed. |
| 491 | 524 |
| 492 /// track document.register'ed tag names and their declarations | 525 /// track document.register'ed tag names and their declarations |
| 493 final Map _declarations = new Map<String, PolymerDeclaration>(); | 526 final Map _declarations = new Map<String, PolymerDeclaration>(); |
| 494 | 527 |
| 495 bool _isRegistered(String name) => _declarations.containsKey(name); | 528 bool _isRegistered(String name) => _declarations.containsKey(name); |
| 496 PolymerDeclaration _getDeclaration(String name) => _declarations[name]; | 529 PolymerDeclaration _getDeclaration(String name) => _declarations[name]; |
| 497 | 530 |
| 498 /// Using Polymer's platform/src/ShadowCSS.js passing the style tag's content. | 531 /// Using Polymer's web_components/src/ShadowCSS.js passing the style tag's |
| 532 /// content. | |
| 499 void _shimShadowDomStyling(DocumentFragment template, String name, | 533 void _shimShadowDomStyling(DocumentFragment template, String name, |
| 500 String extendee) { | 534 String extendee) { |
| 501 if (_ShadowCss == null ||!_hasShadowDomPolyfill) return; | 535 if (_ShadowCss == null ||!_hasShadowDomPolyfill) return; |
| 502 | 536 |
| 503 _ShadowCss.callMethod('shimStyling', [template, name, extendee]); | 537 _ShadowCss.callMethod('shimStyling', [template, name, extendee]); |
| 504 } | 538 } |
| 505 | 539 |
| 506 final bool _hasShadowDomPolyfill = js.context.hasProperty('ShadowDOMPolyfill'); | 540 final bool _hasShadowDomPolyfill = js.context.hasProperty('ShadowDOMPolyfill'); |
|
Siggi Cherem (dart-lang)
2014/11/25 17:53:41
80
jakemac
2014/12/01 18:42:50
Done.
| |
| 507 final JsObject _ShadowCss = _Platform != null ? _Platform['ShadowCSS'] : null; | 541 final JsObject _ShadowCss = _WebComponents != null ? _WebComponents['ShadowCSS'] : null; |
| 508 | 542 |
| 509 const _STYLE_SELECTOR = 'style'; | 543 const _STYLE_SELECTOR = 'style'; |
| 510 const _SHEET_SELECTOR = 'link[rel=stylesheet]'; | 544 const _SHEET_SELECTOR = 'link[rel=stylesheet]'; |
| 511 const _STYLE_GLOBAL_SCOPE = 'global'; | 545 const _STYLE_GLOBAL_SCOPE = 'global'; |
| 512 const _SCOPE_ATTR = 'polymer-scope'; | 546 const _SCOPE_ATTR = 'polymer-scope'; |
| 513 const _STYLE_SCOPE_ATTRIBUTE = 'element'; | 547 const _STYLE_SCOPE_ATTRIBUTE = 'element'; |
| 514 const _STYLE_CONTROLLER_SCOPE = 'controller'; | 548 const _STYLE_CONTROLLER_SCOPE = 'controller'; |
| 515 | 549 |
| 516 String _cssTextFromSheet(LinkElement sheet) { | 550 String _cssTextFromSheet(LinkElement sheet) { |
| 517 if (sheet == null) return ''; | 551 if (sheet == null) return ''; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 | 585 |
| 552 bool _isObserverMethod(Symbol symbol) { | 586 bool _isObserverMethod(Symbol symbol) { |
| 553 String name = smoke.symbolToName(symbol); | 587 String name = smoke.symbolToName(symbol); |
| 554 if (name == null) return false; | 588 if (name == null) return false; |
| 555 return name.endsWith('Changed') && name != 'attributeChanged'; | 589 return name.endsWith('Changed') && name != 'attributeChanged'; |
| 556 } | 590 } |
| 557 | 591 |
| 558 | 592 |
| 559 final _ATTRIBUTES_REGEX = new RegExp(r'\s|,'); | 593 final _ATTRIBUTES_REGEX = new RegExp(r'\s|,'); |
| 560 | 594 |
| 561 final JsObject _Platform = js.context['Platform']; | 595 final JsObject _WebComponents = js.context['WebComponents']; |
| 562 final JsObject _Polymer = js.context['Polymer']; | 596 final JsObject _Polymer = js.context['Polymer']; |
| OLD | NEW |