diff options
Diffstat (limited to 'node_modules/montage/ui/native-control.js')
-rw-r--r-- | node_modules/montage/ui/native-control.js | 185 |
1 files changed, 145 insertions, 40 deletions
diff --git a/node_modules/montage/ui/native-control.js b/node_modules/montage/ui/native-control.js index 7cf65bd5..8dad5408 100644 --- a/node_modules/montage/ui/native-control.js +++ b/node_modules/montage/ui/native-control.js | |||
@@ -4,23 +4,32 @@ | |||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | 4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. |
5 | </copyright> */ | 5 | </copyright> */ |
6 | 6 | ||
7 | /** | ||
8 | @module "montage/ui/native-control" | ||
9 | @requires montage/core/core | ||
10 | @requires montage/ui/component | ||
11 | */ | ||
12 | |||
7 | var Montage = require("montage").Montage, | 13 | var Montage = require("montage").Montage, |
8 | Component = require("ui/component").Component; | 14 | Component = require("ui/component").Component; |
9 | 15 | ||
10 | var isUndefined = function(obj) { | ||
11 | return (typeof obj === 'undefined'); | ||
12 | }; | ||
13 | |||
14 | 16 | ||
15 | /** | 17 | /** |
16 | * Base component for all native controls. | 18 | Base component for all native components, such as RadioButton and Checkbox. |
19 | @class module:montage/ui/native-control.NativeControl | ||
20 | @extends module:montage/ui/component.Component | ||
17 | */ | 21 | */ |
18 | var NativeControl = exports.NativeControl = Montage.create(Component, { | 22 | var NativeControl = exports.NativeControl = Montage.create(Component, /** @lends module:montage/ui/native-control.NativeControl# */ { |
19 | 23 | ||
20 | hasTemplate: { | 24 | hasTemplate: { |
21 | value: false | 25 | value: false |
22 | }, | 26 | }, |
23 | 27 | ||
28 | /** | ||
29 | The HTML element associated with the NativeControl instance. | ||
30 | @type {element} | ||
31 | @default null | ||
32 | */ | ||
24 | element: { | 33 | element: { |
25 | serializable: true, | 34 | serializable: true, |
26 | enumerable: true, | 35 | enumerable: true, |
@@ -37,18 +46,19 @@ var NativeControl = exports.NativeControl = Montage.create(Component, { | |||
37 | }, | 46 | }, |
38 | 47 | ||
39 | 48 | ||
40 | /** Stores values that need to be set on the element. Cleared each draw | 49 | /** |
41 | * cycle. | 50 | Stores values that need to be set on the element. Cleared each draw cycle. |
51 | @private | ||
42 | */ | 52 | */ |
43 | _elementAttributeValues: { | 53 | _elementAttributeValues: { |
44 | value: {}, | 54 | value: {}, |
45 | distinct: true | 55 | distinct: true |
46 | }, | 56 | }, |
47 | 57 | ||
48 | /** Stores the descriptors of the properties that can be set on this | 58 | /** |
49 | * control | 59 | Stores the descriptors of the properties that can be set on this control |
60 | @private | ||
50 | */ | 61 | */ |
51 | |||
52 | _elementAttributeDescriptors: { | 62 | _elementAttributeDescriptors: { |
53 | value: {}, | 63 | value: {}, |
54 | distinct: true | 64 | distinct: true |
@@ -59,7 +69,7 @@ var NativeControl = exports.NativeControl = Montage.create(Component, { | |||
59 | value: function(attributeName) { | 69 | value: function(attributeName) { |
60 | var attributeDescriptor, instance = this; | 70 | var attributeDescriptor, instance = this; |
61 | // walk up the prototype chain from the instance to NativeControl's prototype | 71 | // walk up the prototype chain from the instance to NativeControl's prototype |
62 | while(instance && !isUndefined(instance._elementAttributeDescriptors)) { | 72 | while(instance && (typeof instance._elementAttributeDescriptors !== 'undefined')) { |
63 | attributeDescriptor = instance._elementAttributeDescriptors[attributeName]; | 73 | attributeDescriptor = instance._elementAttributeDescriptors[attributeName]; |
64 | if(attributeDescriptor) { | 74 | if(attributeDescriptor) { |
65 | break; | 75 | break; |
@@ -67,28 +77,28 @@ var NativeControl = exports.NativeControl = Montage.create(Component, { | |||
67 | instance = Object.getPrototypeOf(instance); | 77 | instance = Object.getPrototypeOf(instance); |
68 | } | 78 | } |
69 | } | 79 | } |
70 | |||
71 | return attributeDescriptor; | 80 | return attributeDescriptor; |
72 | } | 81 | } |
73 | }, | 82 | }, |
74 | 83 | ||
75 | /** | 84 | /** |
76 | * Add a property to this Component. A default getter/setter is provided and a | 85 | * Adds a property to the component with the specified name. This method is used internally by the framework convert a DOM element's standard attributes into bindable properties. It creates an accessor property (getter/setter) with the same name as the specified property, as well as a "backing" data property whose name is prepended with an underscore (_). The backing variable is assigned the value from the property descriptor. For example, if the name "title" is passed as the first parameter, a "title" accessor property is created as well a data property named "_title". |
77 | * "_" property is created by default. Eg: if the property is "title", "_title" is | 86 | * @function |
78 | * automatically created and the value set to the value from the descriptor. | 87 | * @param {String} name The property name to add. |
88 | * @param {Object} descriptor An object that specifies the new properties default attributes such as configurable and enumerable. | ||
79 | */ | 89 | */ |
80 | defineAttribute: { | 90 | defineAttribute: { |
81 | value: function(name, descriptor) { | 91 | value: function(name, descriptor) { |
82 | descriptor = descriptor || {}; | 92 | descriptor = descriptor || {}; |
93 | var _name = '_' + name; | ||
94 | |||
83 | 95 | ||
84 | var newDescriptor = { | 96 | var newDescriptor = { |
85 | configurable: isUndefined(descriptor.configurable) ? true: descriptor.configurable, | 97 | configurable: (typeof descriptor.configurable == 'undefined') ? true: descriptor.configurable, |
86 | enumerable: isUndefined(descriptor.enumerable) ? true: descriptor.enumerable, | 98 | enumerable: (typeof descriptor.enumerable == 'undefined') ? true: descriptor.enumerable, |
87 | serializable: isUndefined(descriptor.serializable) ? true: descriptor.serializable, | 99 | serializable: (typeof descriptor.serializable == 'undefined') ? true: descriptor.serializable, |
88 | set: (function(name) { | 100 | set: (function(name, attrName) { |
89 | return function(value) { | 101 | return function(value) { |
90 | var attrName = '_' + name; | ||
91 | |||
92 | var desc = this._getElementAttributeDescriptor(name, this); | 102 | var desc = this._getElementAttributeDescriptor(name, this); |
93 | 103 | ||
94 | // if requested dataType is boolean (eg: checked, readonly etc) | 104 | // if requested dataType is boolean (eg: checked, readonly etc) |
@@ -100,29 +110,31 @@ var NativeControl = exports.NativeControl = Montage.create(Component, { | |||
100 | // If the set value is different to the current one, | 110 | // If the set value is different to the current one, |
101 | // update it here, and set it to be updated on the | 111 | // update it here, and set it to be updated on the |
102 | // element in the next draw cycle. | 112 | // element in the next draw cycle. |
103 | if(!isUndefined(value) && this[attrName] !== value) { | 113 | if((typeof value !== 'undefined') && this[attrName] !== value) { |
104 | this[attrName] = value; | 114 | this[attrName] = value; |
105 | this._elementAttributeValues[name] = value; | 115 | this._elementAttributeValues[name] = value; |
106 | this.needsDraw = true; | 116 | this.needsDraw = true; |
107 | } | 117 | } |
108 | }; | 118 | }; |
109 | }(name)), | 119 | }(name, _name)), |
110 | get: (function(name) { | 120 | get: (function(name, attrName) { |
111 | return function() { | 121 | return function() { |
112 | return this['_' + name]; | 122 | return this[attrName]; |
113 | }; | 123 | }; |
114 | }(name)) | 124 | }(name, _name)) |
115 | }; | 125 | }; |
116 | 126 | ||
117 | // Define _ property | 127 | // Define _ property |
118 | Montage.defineProperty(this, '_' + name, {value: null}); | 128 | Montage.defineProperty(this, _name, {value: null}); |
119 | // Define property getter and setter | 129 | // Define property getter and setter |
120 | Montage.defineProperty(this, name, newDescriptor); | 130 | Montage.defineProperty(this, name, newDescriptor); |
121 | } | 131 | } |
122 | }, | 132 | }, |
123 | 133 | ||
124 | /** | 134 | /** |
125 | * Add the specified properties as properties of this Component | 135 | * Add the specified properties as properties of this component. |
136 | * @function | ||
137 | * @param {object} properties An object that contains the properties you want to add. | ||
126 | */ | 138 | */ |
127 | addAttributes: { | 139 | addAttributes: { |
128 | value: function(properties) { | 140 | value: function(properties) { |
@@ -142,7 +154,7 @@ var NativeControl = exports.NativeControl = Montage.create(Component, { | |||
142 | 154 | ||
143 | // Only add the internal property, and getter and setter if | 155 | // Only add the internal property, and getter and setter if |
144 | // they don't already exist. | 156 | // they don't already exist. |
145 | if(isUndefined(this[property])) { | 157 | if(typeof this[property] == 'undefined') { |
146 | this.defineAttribute(property, descriptor); | 158 | this.defineAttribute(property, descriptor); |
147 | } | 159 | } |
148 | } | 160 | } |
@@ -150,6 +162,8 @@ var NativeControl = exports.NativeControl = Montage.create(Component, { | |||
150 | } | 162 | } |
151 | }, | 163 | }, |
152 | 164 | ||
165 | // callbacks | ||
166 | |||
153 | didSetElement: { | 167 | didSetElement: { |
154 | value: function() { | 168 | value: function() { |
155 | // The element is now ready, so we can read the attributes that | 169 | // The element is now ready, so we can read the attributes that |
@@ -161,9 +175,9 @@ var NativeControl = exports.NativeControl = Montage.create(Component, { | |||
161 | name = attributes[i].name; | 175 | name = attributes[i].name; |
162 | value = attributes[i].value; | 176 | value = attributes[i].value; |
163 | 177 | ||
164 | if(isUndefined(this._elementAttributeValues[name])) { | 178 | if(typeof this._elementAttributeValues[name] == 'undefined') { |
165 | this._elementAttributeValues[name] = value; | 179 | this._elementAttributeValues[name] = value; |
166 | if(isUndefined(this[name]) || this[name] == null) { | 180 | if( (typeof this[name] == 'undefined') || this[name] == null) { |
167 | this[name] = value; | 181 | this[name] = value; |
168 | } | 182 | } |
169 | } | 183 |