-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynamic-attributes.html
107 lines (83 loc) · 2.49 KB
/
dynamic-attributes.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<polymer-element name="dynamic-attributes">
<template>
<!-- FIXME: template doesn't update... -->
<p>foo: {{foo}}</p>
<p>baz: {{baz}}</p>
<p>arr: {{arr}}</p>
</template>
<script>
(function(){
var proto = {
ready: function(){
console.dir(this);
this.publishAttributes({
baz: 'baz',
foo: true,
arr: [1, 2, 3],
});
},
publishAttributes: function(attrs){
var keys = Object.keys(attrs),
watchKeys = [],
_this = this;
for (var i = keys.length - 1; i >= 0; i--) {
(function(){
var key = keys[i];
// if(key !== 'source'){ // blacklist. source assignment is automated by seriously-graph
watchKeys.push(key.toLowerCase()); // attribute names are always lowercase
// define prop accessors
Object.defineProperty(this, key, {
get: function() {
// console.log('getting', key, this[key+'_']);
return this[key+'_'];
},
set: function(value) {
// console.log('setting', key, 'to', value);
this[key+'_'] = value;
// _this.node[key] = value;
// this.templateInstance.model[key] = value;
},
});
var attr = this.getAttribute(key);
if(attr == null){
attr = attrs[key];
}else{
attr = this._deserialize(attr);
}
this[key] = attr;
}.bind(this))();
// }
}
// listen for attribute changes
if(this.attrObserver) this.attrObserver.close();
this.attrObserver = new MutationObserver(this._attrMutationHandler.bind(this));
this.attrObserver.observe(this, {
attributes: true,
// attributeOldValue: true,
attributeFilter: watchKeys,
});
},
_attrMutationHandler: function(mutations){
// console.log('_attrMutationHandler', mutations, this);
for (var i = mutations.length - 1; i >= 0; i--) {
var m = mutations[i];
var value = this.getAttribute(m.attributeName);
this[m.attributeName] = this._deserialize(value);
};
},
// convert string to array, number, or boolean
_deserialize: function(value){
// console.log('_deserialize', value);
//TODO: infer type
if(value === 'true') return true;
else if(value === 'false') return false;
else if(typeof value === 'string') return value;
else if(!isNaN(Number(value))) return Number(value);
else if(value.split(',').length > 0) return value.split(','); // array
else return null;
},
};
Polymer('dynamic-attributes', proto);
})();
</script>
</polymer-element>