-
Notifications
You must be signed in to change notification settings - Fork 2k
/
properties.html
181 lines (171 loc) · 6.85 KB
/
properties.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
<!--
@license
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<script>
/**
* Define property metadata.
*
* properties: {
* <property>: <Type || Object>,
* ...
* }
*
* Example:
*
* properties: {
* // `foo` property can be assigned via attribute, will be deserialized to
* // the specified data-type. All `properties` properties have this behavior.
* foo: String,
*
* // `bar` property has additional behavior specifiers.
* // type: as above, type for (de-)serialization
* // notify: true to send a signal when a value is set to this property
* // reflectToAttribute: true to serialize the property to an attribute
* // readOnly: if true, the property has no setter
* bar: {
* type: Boolean,
* notify: true
* }
* }
*
* By itself the properties feature doesn't do anything but provide property
* information. Other features use this information to control behavior.
*
* The `type` information is used by the `attributes` feature to convert
* String values in attributes to typed properties. The `bind` feature uses
* property information to control property access.
*
* Marking a property as `notify` causes a change in the property to
* fire a non-bubbling event called `<property>-changed`. Elements that
* have enabled two-way binding to the property use this event to
* observe changes.
*
* `readOnly` properties have a getter, but no setter. To set a read-only
* property, use the private setter method `_set_<property>(value)`.
*
* @class base feature: properties
*/
// null object
Polymer.nob = Object.create(null);
Polymer.Base._addFeature({
/*
* Object containing property configuration data, where keys are property
* names and values are descriptor objects that configure Polymer features
* for the property. Valid fields in the property descriptor object are
* as follows:
*
* * `type` - used to determine how to deserialize attribute value strings
* to JS properties. By convention, this field takes a JS constructor
* for the type, such as `String` or `Boolean`.
* * `value` - default value for the property. The value may either be a
* primitive value, or a function that returns a value (which should be
* used for initializing Objects and Arrays to avoid shared objects on
* instances).
* * `notify` - when `true`, configures the property to fire a non-bubbling
* event called `<property>-changed` for each change to the property.
* Elements that have enabled two-way binding to the property use this
* event to observe changes.
* * `readOnly` - when `true` configures the property to have a getter, but
* no setter. To set a read-only property, use the private setter method
* `_set_<property>(value)`.
* * `reflectToAttribute` - when `true` configures the property value to
* be serialized to a string and reflected to the attribute each time
* it changes. This can impact performance, so it should be used
* only when reflecting the attribute value is important.
* * `observer` - indicates the name of a function that should be called
* each time the property changes. `e.g.: `observer: 'valueChanged'
* * `computed` - configures the property to be computed by a computing
* function each time one or more dependent properties change.
* `e.g.: `computed: 'computeValue(prop1, prop2)'
*
* Note: a shorthand may be used for the object descriptor when only the
* type needs to be specified by using the type as the descriptor directly.
*/
properties: {
},
/**
* Returns a property descriptor object for the property specified.
*
* This method allows introspecting the configuration of a Polymer element's
* properties as configured in its `properties` object. Note, this method
* normalizes shorthand forms of the `properties` object into longhand form.
*
* @method getPropertyInfo
* @param {string} property Name of property to introspect.
* @return {Object} Property descriptor for specified property.
*/
getPropertyInfo: function(property) {
var info = this._getPropertyInfo(property, this.properties);
if (!info) {
for (var i=0; i < this.behaviors.length; i++) {
info = this._getPropertyInfo(property, this.behaviors[i].properties);
if (info) {
return info;
}
};
}
return info || Polymer.nob;
},
_getPropertyInfo: function(property, properties) {
var p = properties && properties[property];
if (typeof(p) === 'function') {
p = properties[property] = {
type: p
};
}
// Let users determine whether property was defined without null check
if (p) {
p.defined = true;
}
return p;
},
// union properties, behaviors.properties, and propertyEffects
_prepPropertyInfo: function() {
this._propertyInfo = {};
for (var i=0, p; i < this.behaviors.length; i++) {
this._addPropertyInfo(this._propertyInfo, this.behaviors[i].properties);
}
this._addPropertyInfo(this._propertyInfo, this.properties);
this._addPropertyInfo(this._propertyInfo, this._propertyEffects);
},
// list of propertyInfo with {readOnly, type, attribute}
_addPropertyInfo: function(target, source) {
if (source) {
var t, s;
for (var i in source) {
t = target[i];
s = source[i];
// optimization: avoid info'ing properties that are protected and
// not read only since they are not needed for attributes or
// configuration.
if (i[0] === '_' && !s.readOnly) {
continue;
}
if (!target[i]) {
target[i] = t = typeof(s) === 'function' ? {type: s} : s;
t.attribute = Polymer.CaseMap.camelToDashCase(i);
} else {
if (!t.type) {
t.type = s.type;
}
if (!t.readOnly) {
t.readOnly = s.readOnly;
}
if (!t.notify) {
t.notify = s.notify;
}
if (!t.readOnly) {
t.readOnly = s.readOnly;
}
}
}
}
},
});
</script>