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 library polymer.polymer_element; | 5 library polymer.polymer_element; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:html'; | 8 import 'dart:html'; |
| 9 import 'dart:mirrors'; | 9 import 'dart:mirrors'; |
| 10 | 10 |
| 11 import 'package:mdv/mdv.dart' as mdv; | |
| 11 import 'package:observe/observe.dart'; | 12 import 'package:observe/observe.dart'; |
| 12 | 13 |
| 13 import 'custom_element.dart'; | 14 import 'custom_element.dart'; |
| 14 import 'observe.dart'; | 15 import 'observe.dart'; |
| 15 import 'src/utils_observe.dart' show toCamelCase, toHyphenedName; | 16 import 'src/utils_observe.dart' show toCamelCase, toHyphenedName; |
| 16 | 17 |
| 17 /** | 18 /** |
| 18 * Registers a [PolymerElement]. This is similar to [registerCustomElement] | 19 * Registers a [PolymerElement]. This is similar to [registerCustomElement] |
| 19 * but it is designed to work with the `<element>` element and adds additional | 20 * but it is designed to work with the `<element>` element and adds additional |
| 20 * features. | 21 * features. |
| 21 */ | 22 */ |
| 22 // TODO(sigmund): change this to take the 'localName' (recent polymer change) | 23 void registerPolymerElement(String localName, PolymerElement create()) { |
| 23 void registerPolymerElement(Element elementElement, CustomElement create()) { | 24 registerCustomElement(localName, () => create().._initialize(localName)); |
| 24 // Creates the CustomElement and then publish attributes. | |
| 25 createElement() { | |
| 26 final CustomElement element = create(); | |
| 27 // TODO(jmesserly): to simplify the DWC compiler, we always emit calls to | |
| 28 // registerPolymerElement, regardless of the base class type. | |
| 29 if (element is PolymerElement) { | |
| 30 PolymerElement pElement = element; | |
| 31 pElement._parseHostEvents(elementElement); | |
| 32 pElement._parseLocalEvents(elementElement); | |
| 33 pElement._publishAttributes(elementElement); | |
| 34 } | |
| 35 return element; | |
| 36 } | |
| 37 | |
| 38 registerCustomElement(elementElement.attributes['name'], createElement); | |
| 39 } | 25 } |
| 40 | 26 |
| 41 /** | 27 /** |
| 42 * *Warning*: many features of this class are not fully implemented. | 28 * *Warning*: many features of this class are not fully implemented. |
| 43 * | 29 * |
| 44 * The base class for Polymer elements. It provides convience features on top | 30 * The base class for Polymer elements. It provides convience features on top |
| 45 * of the custom elements web standard. | 31 * of the custom elements web standard. |
| 46 * | 32 * |
| 47 * Currently it supports publishing attributes via: | 33 * Currently it supports publishing attributes via: |
| 48 * | 34 * |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 60 // This is a partial port of: | 46 // This is a partial port of: |
| 61 // https://github.com/Polymer/polymer/blob/stable/src/attrs.js | 47 // https://github.com/Polymer/polymer/blob/stable/src/attrs.js |
| 62 // https://github.com/Polymer/polymer/blob/stable/src/bindProperties.js | 48 // https://github.com/Polymer/polymer/blob/stable/src/bindProperties.js |
| 63 // https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js | 49 // https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js |
| 64 // https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js | 50 // https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js |
| 65 // TODO(jmesserly): we still need to port more of the functionality | 51 // TODO(jmesserly): we still need to port more of the functionality |
| 66 | 52 |
| 67 // TODO(sigmund): delete. The next line is only added to avoid warnings from | 53 // TODO(sigmund): delete. The next line is only added to avoid warnings from |
| 68 // the analyzer (see http://dartbug.com/11672) | 54 // the analyzer (see http://dartbug.com/11672) |
| 69 Element get host => super.host; | 55 Element get host => super.host; |
| 56 | |
| 57 /** | |
| 58 * The declaration of this polymer-element, used to extract template contents | |
| 59 * and other information. | |
| 60 */ | |
| 61 static Map<String, Element> _declarations = {}; | |
| 62 static Element getDeclaration(String localName) { | |
| 63 if (localName == null) return null; | |
| 64 var element = _declarations[localName]; | |
| 65 if (element == null) { | |
| 66 element = document.query('polymer-element[name="$localName"]'); | |
| 67 _declarations[localName] = element; | |
| 68 } | |
| 69 return element; | |
| 70 } | |
| 71 | |
| 70 Map<String, PathObserver> _publishedAttrs; | 72 Map<String, PathObserver> _publishedAttrs; |
| 71 Map<String, StreamSubscription> _bindings; | 73 Map<String, StreamSubscription> _bindings; |
| 74 List<String> _localNames = []; | |
|
Jennifer Messerly
2013/07/18 23:56:04
final?
Siggi Cherem (dart-lang)
2013/07/19 22:52:52
Done.
| |
| 72 | 75 |
| 73 void _publishAttributes(Element elementElement) { | 76 void _initialize(String localName) { |
| 77 if (localName == null) return; | |
| 78 | |
| 79 var declaration = getDeclaration(localName); | |
| 80 if (declaration == null) return; | |
| 81 | |
| 82 if (declaration.attributes['extends'] != null) { | |
| 83 var base = declaration.attributes['extends']; | |
| 84 // Skip normal tags, only initialize parent custom elements. | |
| 85 if (base.contains('-')) _initialize(base); | |
| 86 } | |
| 87 | |
| 88 _parseHostEvents(declaration); | |
| 89 _parseLocalEvents(declaration); | |
| 90 _publishAttributes(declaration); | |
| 91 _localNames.add(localName); | |
| 92 } | |
| 93 | |
| 94 void _publishAttributes(elementElement) { | |
| 74 _bindings = {}; | 95 _bindings = {}; |
| 75 _publishedAttrs = {}; | 96 _publishedAttrs = {}; |
| 76 | 97 |
| 77 var attrs = elementElement.attributes['attributes']; | 98 var attrs = elementElement.attributes['attributes']; |
| 78 if (attrs != null) { | 99 if (attrs != null) { |
| 79 // attributes='a b c' or attributes='a,b,c' | 100 // attributes='a b c' or attributes='a,b,c' |
| 80 for (var name in attrs.split(attrs.contains(',') ? ',' : ' ')) { | 101 for (var name in attrs.split(attrs.contains(',') ? ',' : ' ')) { |
| 81 name = name.trim(); | 102 name = name.trim(); |
| 82 | 103 |
| 83 // TODO(jmesserly): PathObserver is overkill here; it helps avoid | 104 // TODO(jmesserly): PathObserver is overkill here; it helps avoid |
| 84 // "new Symbol" and other mirrors-related warnings. | 105 // "new Symbol" and other mirrors-related warnings. |
| 85 _publishedAttrs[name] = new PathObserver(this, toCamelCase(name)); | 106 _publishedAttrs[name] = new PathObserver(this, toCamelCase(name)); |
| 86 } | 107 } |
| 87 } | 108 } |
| 88 } | 109 } |
| 89 | 110 |
| 90 void created() { | 111 void created() { |
| 91 // TODO(jmesserly): this breaks until we get some kind of type conversion. | 112 // TODO(jmesserly): this breaks until we get some kind of type conversion. |
| 92 // _publishedAttrs.forEach((name, propObserver) { | 113 // _publishedAttrs.forEach((name, propObserver) { |
| 93 // var value = attributes[name]; | 114 // var value = attributes[name]; |
| 94 // if (value != null) propObserver.value = value; | 115 // if (value != null) propObserver.value = value; |
| 95 // }); | 116 // }); |
| 96 | 117 _initShadowRoot(); |
| 97 _addHostListeners(); | 118 _addHostListeners(); |
| 98 } | 119 } |
| 99 | 120 |
| 100 // TODO(sigmund): make this private once we create the shadow root directly | 121 void _initShadowRoot() { |
| 101 // here in polymer element. | 122 for (var localName in _localNames) { |
| 102 void shadowRootReady(ShadowRoot root, String elementName) { | 123 var declaration = getDeclaration(localName); |
| 103 _addInstanceListeners(root, elementName); | 124 var root = createShadowRoot(localName); |
| 125 _addInstanceListeners(root, localName); | |
| 126 | |
| 127 // TODO(jmesserly): warn if apply-author-styles was not set and we don't | |
| 128 // have Shadow DOM support? In that case, styles won't have proper | |
|
Jennifer Messerly
2013/07/18 23:56:04
I think this TODO is obsolete :)
Siggi Cherem (dart-lang)
2013/07/19 22:52:52
Done.
| |
| 129 // encapsulation. | |
| 130 if (root is ShadowRoot && | |
|
Jennifer Messerly
2013/07/18 23:56:04
root is always ShadowRoot now, right?
Siggi Cherem (dart-lang)
2013/07/19 22:52:52
I think so. removed.
| |
| 131 declaration.attributes['apply-author-styles'] != null) { | |
|
Jennifer Messerly
2013/07/18 23:56:04
does polymer have apply-author-styles?
Siggi Cherem (dart-lang)
2013/07/19 22:52:52
turns out they have it as a property in the protot
| |
| 132 root.applyAuthorStyles = true; | |
| 133 } | |
| 134 | |
| 135 var templateNode = declaration.children.firstWhere( | |
| 136 (n) => n.localName == 'template', orElse: () => null); | |
| 137 if (templateNode == null) return; | |
| 138 | |
| 139 root.nodes.add(cloneTemplate(templateNode.content)); | |
| 140 var syntax = templateNode.attributes['syntax']; | |
|
Jennifer Messerly
2013/07/18 23:56:04
mind adding a TODO? we should treat syntax like Po
Siggi Cherem (dart-lang)
2013/07/19 22:52:52
Done.
| |
| 141 mdv.bindModel(root, this, | |
| 142 syntax != null ? TemplateElement.syntax[syntax] : null); | |
| 143 } | |
| 104 } | 144 } |
| 105 | 145 |
| 106 void bind(String name, model, String path) { | 146 void bind(String name, model, String path) { |
| 107 var propObserver = _publishedAttrs[name]; | 147 var propObserver = _publishedAttrs[name]; |
| 108 if (propObserver != null) { | 148 if (propObserver != null) { |
| 109 unbind(name); | 149 unbind(name); |
| 110 | 150 |
| 111 _bindings[name] = new PathObserver(model, path).bindSync((value) { | 151 _bindings[name] = new PathObserver(model, path).bindSync((value) { |
| 112 propObserver.value = value; | 152 propObserver.value = value; |
| 113 }); | 153 }); |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 'onKeyMessage': MediaElement.keyMessageEvent, | 510 'onKeyMessage': MediaElement.keyMessageEvent, |
| 471 'onNeedKey': MediaElement.needKeyEvent, | 511 'onNeedKey': MediaElement.needKeyEvent, |
| 472 'onWebGlContextLost': CanvasElement.webGlContextLostEvent, | 512 'onWebGlContextLost': CanvasElement.webGlContextLostEvent, |
| 473 'onWebGlContextRestored': CanvasElement.webGlContextRestoredEvent, | 513 'onWebGlContextRestored': CanvasElement.webGlContextRestoredEvent, |
| 474 'onPointerLockChange': Document.pointerLockChangeEvent, | 514 'onPointerLockChange': Document.pointerLockChangeEvent, |
| 475 'onPointerLockError': Document.pointerLockErrorEvent, | 515 'onPointerLockError': Document.pointerLockErrorEvent, |
| 476 'onReadyStateChange': Document.readyStateChangeEvent, | 516 'onReadyStateChange': Document.readyStateChangeEvent, |
| 477 'onSelectionChange': Document.selectionChangeEvent, | 517 'onSelectionChange': Document.selectionChangeEvent, |
| 478 'onSecurityPolicyViolation': Document.securityPolicyViolationEvent, | 518 'onSecurityPolicyViolation': Document.securityPolicyViolationEvent, |
| 479 }; | 519 }; |
| OLD | NEW |