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

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

Issue 946813005: Port Sky widgets demo to Dart (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
« no previous file with comments | « sky/framework/sky-checkbox.sky ('k') | sky/framework/sky-input.sky » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/framework/sky-element.sky
diff --git a/sky/framework/sky-element.sky b/sky/framework/sky-element.sky
index 2fdc62ad65dcf10e6f0301995ed6ca375e637f41..e1d0a0ea715da04f9ea53e51ecceeb5be2b74d6f 100644
--- a/sky/framework/sky-element.sky
+++ b/sky/framework/sky-element.sky
@@ -7,9 +7,61 @@
import "dart:mirrors";
import "dart:sky";
+typedef dynamic _Converter(String value);
+
+final Map<String, _Converter> _kAttributeConverters = {
+ 'boolean': (String value) {
+ return value == 'true';
+ },
+ 'number': (String value) {
+ return double.parse(value);
+ },
+ 'string': (String value) {
+ return value == null ? '' : value;
+ },
+};
+
class _Registration {
- Element template;
+ final Element template;
+ final Map<String, _Converter> attributes = new Map();
+
_Registration(this.template);
+
+ void parseAttributeSpec(definition) {
+ String spec = definition.getAttribute('attributes');
+ if (spec == null)
+ return;
+
+ for (String token in spec.split(',')) {
+ List<String> parts = token.split(':');
+
+ if (parts.length != 2) {
+ window.console.error(
+ 'Invalid attribute spec "${spec}", attributes must'
+ ' be {name}:{type}, where type is one of boolean, number or'
+ ' string.');
+ continue;
+ }
+
+ var name = parts[0].trim();
+ var type = parts[1].trim();
+
+ defineAttribute(name, type);
+ }
+ }
+
+ void defineAttribute(String name, String type) {
+ _Converter converter = _kAttributeConverters[type];
+
+ if (converter == null) {
+ window.console.error(
+ 'Invalid attribute type "${type}", type must be one of boolean,'
+ ' number or string.');
+ return;
+ }
+
+ attributes[name] = converter;
+ }
}
final Map<String, _Registration> _registery = new Map<String, _Registration>();
@@ -33,21 +85,21 @@ abstract class SkyElement extends Element {
void shadowRootReady() {}
String get tagName => _getTagName(runtimeType);
+ _Registration _registration;
SkyElement() {
- created();
-
+ _registration = _registery[tagName];
// Invoke attributeChanged callback when element is first created too.
+ // TODO(abarth): Is this necessary? We shouldn't have any attribute yet...
for (Attr attribute in getAttributes())
attributeChangedCallback(attribute.name, null, attribute.value);
}
attachedCallback() {
if (shadowRoot == null) {
- var registration = _registery[tagName];
- if (registration.template != null) {
+ if (_registration.template != null) {
ShadowRoot shadow = ensureShadowRoot();
- Node content = registration.template.content;
+ Node content = _registration.template.content;
shadow.appendChild(document.importNode(content, deep: true));
shadowRootReady();
}
@@ -61,6 +113,30 @@ abstract class SkyElement extends Element {
attributeChangedCallback(name, oldValue, newValue) {
attributeChanged(name, oldValue, newValue);
+
+ _Converter converter = _registration.attributes[name];
+ if (converter == null)
+ return;
+ Symbol callback = new Symbol('${name}Changed');
+ InstanceMirror mirror = reflect(this);
+ if (mirror.type.instanceMembers.containsKey(callback))
+ mirror.invoke(callback, [converter(oldValue), converter(newValue)]);
+ }
+
+ noSuchMethod(Invocation invocation) {
+ String name = MirrorSystem.getName(invocation.memberName);
+ if (name.endsWith('='))
+ name = name.substring(0, name.length - 1);
+ _Converter converter = _registration.attributes[name];
+ if (converter != null) {
+ if (invocation.isGetter) {
+ return converter(getAttribute(name));
+ } else if (invocation.isSetter) {
+ setAttribute(name, invocation.positionalArguments[0].toString());
+ return;
+ }
+ }
+ return super.noSuchMethod(invocation);
}
}
@@ -78,6 +154,7 @@ void register(Element script, Type type) {
Element template = definition.querySelector('template');
document.registerElement(tagName, type);
- _registery[tagName] = new _Registration(template);
+ _registery[tagName] = new _Registration(template)
+ ..parseAttributeSpec(definition);
}
</script>
« no previous file with comments | « sky/framework/sky-checkbox.sky ('k') | sky/framework/sky-input.sky » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698