OLD | NEW |
(Empty) | |
| 1 <!-- |
| 2 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. |
| 5 --> |
| 6 <script> |
| 7 import "dart:mirrors"; |
| 8 import "dart:sky"; |
| 9 |
| 10 class _Registration { |
| 11 Element template; |
| 12 _Registration(this.template); |
| 13 } |
| 14 |
| 15 final Map<String, _Registration> _registery = new Map<String, _Registration>(); |
| 16 |
| 17 String _getTagName(Type type) { |
| 18 return reflectClass(type).metadata.firstWhere( |
| 19 (i) => i.reflectee is tagname).reflectee.name; |
| 20 } |
| 21 |
| 22 abstract class SkyElement extends Element { |
| 23 // Override these functions to receive lifecycle notifications. |
| 24 void created() {} |
| 25 void attached() {} |
| 26 void detached() {} |
| 27 void attributeChanged(String attrName, String oldValue, String newValue) {} |
| 28 void shadowRootReady() {} |
| 29 |
| 30 String get tagName => _getTagName(runtimeType); |
| 31 |
| 32 // TODO(abarth): Rather than hard-coding "example" here, we should make the |
| 33 // bindings read the |tagName| property of this object during construction. |
| 34 SkyElement() : super("example") { |
| 35 created(); |
| 36 |
| 37 // Invoke attributeChanged callback when element is first created too. |
| 38 for (Attr attribute in getAttributes()) |
| 39 attributeChangedCallback(attribute.name, null, attribute.value); |
| 40 } |
| 41 |
| 42 attachedCallback() { |
| 43 if (shadowRoot == null) { |
| 44 var registration = _registery[tagName]; |
| 45 if (registration.template != null) { |
| 46 ShadowRoot shadow = ensureShadowRoot(); |
| 47 var tree = registration.template.content.cloneNode(deep:true); |
| 48 shadow.appendChild(tree); |
| 49 shadowRootReady(); |
| 50 } |
| 51 } |
| 52 attached(); |
| 53 } |
| 54 |
| 55 detachedCallback() { |
| 56 detached(); |
| 57 } |
| 58 |
| 59 attributeChangedCallback(name, oldValue, newValue) { |
| 60 attributeChanged(name, oldValue, newValue); |
| 61 } |
| 62 } |
| 63 |
| 64 class tagname { |
| 65 final String name; |
| 66 const tagname(this.name); |
| 67 } |
| 68 |
| 69 void register(Element script, Type type) { |
| 70 Element definition = script.parentNode; |
| 71 |
| 72 if (definition.tagName != 'sky-element') |
| 73 throw new UnsupportedError('register() calls must be inside a <sky-element>.
'); |
| 74 |
| 75 ClassMirror mirror = reflectClass(type); |
| 76 if (!mirror.isSubclassOf(reflectClass(SkyElement))) |
| 77 throw new UnsupportedError('@tagname can only be used on descendants of SkyE
lement'); |
| 78 |
| 79 String tagName = _getTagName(type); |
| 80 Element template = definition.querySelector('template'); |
| 81 |
| 82 document.registerElement(tagName, type); |
| 83 _registery[tagName] = new _Registration(template); |
| 84 } |
| 85 </script> |
OLD | NEW |