| Index: sky/framework/sky-element.sky
|
| diff --git a/sky/framework/sky-element.sky b/sky/framework/sky-element.sky
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b7e16ea6d75d7e7a8c732fa272b0a092c5b8defd
|
| --- /dev/null
|
| +++ b/sky/framework/sky-element.sky
|
| @@ -0,0 +1,85 @@
|
| +<!--
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +-->
|
| +<script>
|
| +import "dart:mirrors";
|
| +import "dart:sky";
|
| +
|
| +class _Registration {
|
| + Element template;
|
| + _Registration(this.template);
|
| +}
|
| +
|
| +final Map<String, _Registration> _registery = new Map<String, _Registration>();
|
| +
|
| +String _getTagName(Type type) {
|
| + return reflectClass(type).metadata.firstWhere(
|
| + (i) => i.reflectee is tagname).reflectee.name;
|
| +}
|
| +
|
| +abstract class SkyElement extends Element {
|
| + // Override these functions to receive lifecycle notifications.
|
| + void created() {}
|
| + void attached() {}
|
| + void detached() {}
|
| + void attributeChanged(String attrName, String oldValue, String newValue) {}
|
| + void shadowRootReady() {}
|
| +
|
| + String get tagName => _getTagName(runtimeType);
|
| +
|
| + // TODO(abarth): Rather than hard-coding "example" here, we should make the
|
| + // bindings read the |tagName| property of this object during construction.
|
| + SkyElement() : super("example") {
|
| + created();
|
| +
|
| + // Invoke attributeChanged callback when element is first created too.
|
| + for (Attr attribute in getAttributes())
|
| + attributeChangedCallback(attribute.name, null, attribute.value);
|
| + }
|
| +
|
| + attachedCallback() {
|
| + if (shadowRoot == null) {
|
| + var registration = _registery[tagName];
|
| + if (registration.template != null) {
|
| + ShadowRoot shadow = ensureShadowRoot();
|
| + var tree = registration.template.content.cloneNode(deep:true);
|
| + shadow.appendChild(tree);
|
| + shadowRootReady();
|
| + }
|
| + }
|
| + attached();
|
| + }
|
| +
|
| + detachedCallback() {
|
| + detached();
|
| + }
|
| +
|
| + attributeChangedCallback(name, oldValue, newValue) {
|
| + attributeChanged(name, oldValue, newValue);
|
| + }
|
| +}
|
| +
|
| +class tagname {
|
| + final String name;
|
| + const tagname(this.name);
|
| +}
|
| +
|
| +void register(Element script, Type type) {
|
| + Element definition = script.parentNode;
|
| +
|
| + if (definition.tagName != 'sky-element')
|
| + throw new UnsupportedError('register() calls must be inside a <sky-element>.');
|
| +
|
| + ClassMirror mirror = reflectClass(type);
|
| + if (!mirror.isSubclassOf(reflectClass(SkyElement)))
|
| + throw new UnsupportedError('@tagname can only be used on descendants of SkyElement');
|
| +
|
| + String tagName = _getTagName(type);
|
| + Element template = definition.querySelector('template');
|
| +
|
| + document.registerElement(tagName, type);
|
| + _registery[tagName] = new _Registration(template);
|
| +}
|
| +</script>
|
|
|