Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Unified Diff: sky/framework/sky-element.sky

Issue 950493003: Add a basic sky-element custom element (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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>

Powered by Google App Engine
This is Rietveld 408576698