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

Side by Side Diff: sky/framework/sky-element/sky-element.sky

Issue 836923002: Automate reflected properties in SkyElement. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: moar single quotes Created 5 years, 11 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 unified diff | Download patch
« no previous file with comments | « sky/framework/sky-checkbox/sky-checkbox.sky ('k') | sky/framework/sky-radio/sky-radio.sky » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 <!-- 1 <!--
2 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Copyright 2014 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be 3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file. 4 // found in the LICENSE file.
5 --> 5 -->
6 <import src="sky-binder.sky" as="binder" /> 6 <import src="sky-binder.sky" as="binder" />
7 <script> 7 <script>
8 var templates = new Map(); 8 var templates = new Map();
9 9
10 var attributeConverters = {
11 boolean: function(value) {
12 if (typeof value == 'string')
13 return value == 'true';
14 return !!value;
15 },
16 number: function(value) {
17 return Number(value);
18 },
19 string: function(value) {
20 if (value === null)
21 return '';
22 return String(value);
23 },
24 };
25
26 function defineReflectedAttribute(prototype, converter, name) {
27 Object.defineProperty(prototype, name, {
28 get: function() {
29 return converter(this.getAttribute(name));
30 },
31 set: function(newValue) {
32 this.setAttribute(name, converter(newValue));
33 },
34 enumerable: true,
35 configurable: true,
36 });
37
38 prototype[name + 'AttributeChanged'] = function(oldValue, newValue) {
39 this.notifyPropertyChanged(name, converter(oldValue), converter(newValue));
40 };
41 }
42
43 function defineReflectedAttributes(elementClass, list) {
44 var attributeNames = (list || '').split(',');
45 var prototype = elementClass.prototype;
46
47 for (var i = 0; i < attributeNames.length; ++i) {
48 var parts = attributeNames[i].split(':');
49 var name = parts[0].trim();
50 var type = (parts[1] || '').trim();
51 var converter = attributeConverters[type] || attributeConverters.string;
52
53 defineReflectedAttribute(prototype, converter, name);
54 }
55 }
56
10 class SkyElement extends HTMLElement { 57 class SkyElement extends HTMLElement {
11 58
12 static register() { 59 static register() {
13 var wrapper = document.currentScript.parentNode; 60 var wrapper = document.currentScript.parentNode;
14 61
15 if (wrapper.localName !== 'sky-element') 62 if (wrapper.localName !== 'sky-element')
16 throw new Error('No <sky-element>.'); 63 throw new Error('No <sky-element>.');
17 64
18 var tagName = wrapper.getAttribute("name"); 65 var tagName = wrapper.getAttribute('name');
19 if (!tagName) 66 if (!tagName)
20 throw new Error('<sky-element> must have a name.'); 67 throw new Error('<sky-element> must have a name.');
21 68
22 var template = wrapper.querySelector('template'); 69 var template = wrapper.querySelector('template');
23 if (template) 70 if (template)
24 templates.set(tagName, template); 71 templates.set(tagName, template);
25 72
73 defineReflectedAttributes(this, wrapper.getAttribute('attributes'));
74
26 return document.registerElement(tagName, { 75 return document.registerElement(tagName, {
27 prototype: this.prototype, 76 prototype: this.prototype,
28 }); 77 });
29 } 78 }
30 79
31 created() { 80 created() {
32 // override 81 // override
33 } 82 }
34 83
35 attached() { 84 attached() {
36 // override 85 // override
37 } 86 }
38 87
39 detached() { 88 detached() {
40 // override 89 // override
41 } 90 }
42 91
43 attributeChanged(attrName, oldValue, newValue) { 92 attributeChanged(attrName, oldValue, newValue) {
44 // override 93 // override
45 } 94 }
46 95
47 shadowRootReady() { 96 shadowRootReady() {
48 // override 97 // override
49 } 98 }
50 99
51 createdCallback() { 100 createdCallback() {
52 this.isAttached = false; 101 this.isAttached = false;
53 this.created(); 102 this.created();
103
104 // Invoke attributeChanged callback when element is first created too.
105 var attributes = this.getAttributes();
106 for (var i = 0; i < attributes.length; ++i) {
107 var attribute = attributes[i];
108 this.attributeChangedCallback(attribute.name, null, attribute.value);
109 }
54 } 110 }
55 111
56 attachedCallback() { 112 attachedCallback() {
57 if (!this.shadowRoot) { 113 if (!this.shadowRoot) {
58 var template = templates.get(this.localName); 114 var template = templates.get(this.localName);
59 if (template) { 115 if (template) {
60 var shadow = this.ensureShadowRoot(); 116 var shadow = this.ensureShadowRoot();
61 var instance = binder.createInstance(template, this); 117 var instance = binder.createInstance(template, this);
62 shadow.appendChild(instance.fragment); 118 shadow.appendChild(instance.fragment);
63 this.shadowRootReady(); 119 this.shadowRootReady();
64 } 120 }
65 } 121 }
66 this.attached(); 122 this.attached();
67 this.isAttached = true; 123 this.isAttached = true;
68 } 124 }
69 125
70 detachedCallback() { 126 detachedCallback() {
71 this.detached(); 127 this.detached();
72 this.isAttached = false; 128 this.isAttached = false;
73 } 129 }
74 130
75 attributeChangedCallback(attrName, oldValue, newValue) { 131 attributeChangedCallback(name, oldValue, newValue) {
76 // reserved for canonical behavior 132 this.attributeChanged(name, oldValue, newValue);
77 this.attributeChanged(attrName, oldValue, newValue); 133 var handler = this[name + 'AttributeChanged'];
134 if (typeof handler == 'function')
135 handler.call(this, oldValue, newValue);
136 }
137
138 notifyPropertyChanged(name, oldValue, newValue) {
139 var notifier = Object.getNotifier(this);
140 notifier.notify({
141 type: 'update',
142 name: name,
143 oldValue: oldValue,
144 });
145 var handler = this[name + 'Changed'];
146 if (typeof handler == 'function')
147 handler.call(this, oldValue, newValue);
78 } 148 }
79 }; 149 };
80 150
81 module.exports = SkyElement; 151 module.exports = SkyElement;
82 </script> 152 </script>
OLDNEW
« no previous file with comments | « sky/framework/sky-checkbox/sky-checkbox.sky ('k') | sky/framework/sky-radio/sky-radio.sky » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698