diff options
Diffstat (limited to 'node_modules/montage/ui/native/button.reel')
-rw-r--r-- | node_modules/montage/ui/native/button.reel/button.js | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/node_modules/montage/ui/native/button.reel/button.js b/node_modules/montage/ui/native/button.reel/button.js new file mode 100644 index 00000000..d7a4ffee --- /dev/null +++ b/node_modules/montage/ui/native/button.reel/button.js | |||
@@ -0,0 +1,465 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | /*global require, exports*/ | ||
7 | |||
8 | /** | ||
9 | @module "montage/ui/button.reel" | ||
10 | @requires montage/core/core | ||
11 | @requires montage/ui/component | ||
12 | @requires montage/ui/native-control | ||
13 | @requires montage/ui/composer/press-composer | ||
14 | */ | ||
15 | var Montage = require("montage").Montage, | ||
16 | Component = require("ui/component").Component, | ||
17 | NativeControl = require("ui/native-control").NativeControl, | ||
18 | PressComposer = require("ui/composer/press-composer").PressComposer; | ||
19 | |||
20 | /** | ||
21 | Wraps a native <code><button></code> or <code><input[type="button"]></code> HTML element. The element's standard attributes are exposed as bindable properties. | ||
22 | @class module:"montage/ui/button.reel".Button | ||
23 | @extends module:montage/ui/native-control.NativeControl | ||
24 | @example | ||
25 | <caption>JavaScript example</caption> | ||
26 | var b1 = Button.create(); | ||
27 | b1.element = document.querySelector("btnElement"); | ||
28 | b1.addEventListener("action", function(event) { | ||
29 | console.log("Got event 'action' event"); | ||
30 | }); | ||
31 | @example | ||
32 | <caption>Serialized example</caption> | ||
33 | { | ||
34 | "aButton": { | ||
35 | "prototype": "montage/ui/button.reel", | ||
36 | "properties": { | ||
37 | "element": {"#": "btnElement"} | ||
38 | }, | ||
39 | "listeners": [ | ||
40 | { | ||
41 | "type": "action", | ||
42 | "listener": {"@": "appListener"} | ||
43 | } | ||
44 | ] | ||
45 | }, | ||
46 | "listener": { | ||
47 | "prototype": "appListener" | ||
48 | } | ||
49 | } | ||
50 | <button data-montage-id="btnElement"></button> | ||
51 | */ | ||
52 | var Button = exports.Button = Montage.create(NativeControl, /** @lends module:"montage/ui/button.reel".Button# */ { | ||
53 | |||
54 | _preventFocus: { | ||
55 | enumerable: false, | ||
56 | value: false | ||
57 | }, | ||
58 | |||
59 | /** | ||
60 | Specifies whether the button should receive focus or not. | ||
61 | @type {boolean} | ||
62 | @default false | ||
63 | @event longpress | ||
64 | */ | ||
65 | preventFocus: { | ||
66 | get: function () { | ||
67 | return this._preventFocus; | ||
68 | }, | ||
69 | set: function (value) { | ||
70 | if (value === true) { | ||
71 | this._preventFocus = true; | ||
72 | } else { | ||
73 | this._preventFocus = false; | ||
74 | } | ||
75 | } | ||
76 | }, | ||
77 | |||
78 | |||
79 | /** | ||
80 | Enables or disables the Button from user input. When this property is set to <code>false</code>, the "disabled" CSS style is applied to the button's DOM element during the next draw cycle. When set to <code>true</code> the "disabled" CSS class is removed from the element's class list. | ||
81 | */ | ||
82 | //TODO we should prefer positive properties like enabled vs disabled, get rid of disabled | ||
83 | enabled: { | ||
84 | dependencies: ["disabled"], | ||
85 | get: function () { | ||
86 | return !this._disabled; | ||
87 | }, | ||
88 | set: function (value) { | ||
89 | this.disabled = !value; | ||
90 | } | ||
91 | }, | ||
92 | |||
93 | /** | ||
94 | A Montage converter object used to convert or format the label displayed by the Button instance. When a new value is assigned to <code>label</code>, the converter object's <code>convert()</code> method is invoked, passing it the newly assigned label value. | ||
95 | @type {Property} | ||
96 | @default null | ||
97 | */ | ||
98 | converter: { | ||
99 | value: null | ||
100 | }, | ||
101 | |||
102 | /** | ||
103 | Stores the node that contains this button's value. Only used for | ||
104 | non-`<input>` elements. | ||
105 | @private | ||
106 | */ | ||
107 | _labelNode: {value:undefined, enumerable: false}, | ||
108 | |||
109 | _label: { value: undefined, enumerable: false }, | ||
110 | |||
111 | /** | ||
112 | The label for the button. In an <input> element this is taken from the element's <code>value</code> attribute. On any other element (including <button>) this is the first child node which is a text node. If one isn't found then it will be created. | ||
113 | |||
114 | If the button has a non-null <code>converter</code> property, the converter object's <code>convert()</code> method is called on the value before being assigned to the button instance. | ||
115 | |||
116 | @type {string} | ||
117 | @default undefined | ||
118 | */ | ||
119 | label: { | ||
120 | get: function() { | ||
121 | return this._label; | ||
122 | }, | ||
123 | set: function(value) { | ||
124 | if (value && value.length > 0 && this.converter) { | ||
125 | try { | ||
126 | value = this.converter.convert(value); | ||
127 | if (this.error) { | ||
128 | this.error = null; | ||
129 | } | ||
130 | } catch(e) { | ||
131 | // unable to convert - maybe error | ||
132 | this.error = e; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | this._label = value; | ||
137 | if (this._isInputElement) { | ||
138 | this._value = value; | ||
139 | } | ||
140 | |||
141 | this.needsDraw = true; | ||
142 | } | ||
143 | }, | ||
144 | |||
145 | /** | ||
146 | The amount of time in milliseconds the user must press and hold the button a <code>hold</code> event is dispatched. The default is 1 second. | ||
147 | @type {number} | ||
148 | @default 1000 | ||
149 | */ | ||
150 | holdThreshold: { | ||
151 | get: function() { | ||
152 | return this._pressComposer.longPressThreshold; | ||
153 | }, | ||
154 | set: function(value) { | ||
155 | this._pressComposer.longPressThreshold = value; | ||
156 | } | ||
157 | }, | ||
158 | |||
159 | _pressComposer: { | ||
160 | enumberable: false, | ||
161 | value: null | ||
162 | }, | ||
163 | |||
164 | _active: { | ||
165 | enumerable: false, | ||
166 | value: false | ||
167 | }, | ||
168 | |||
169 | /** | ||
170 | This property is true when the button is being interacted with, either through mouse click or touch event, otherwise false. | ||
171 | @type {boolean} | ||
172 | @default false | ||
173 | */ | ||
174 | active: { | ||
175 | get: function() { | ||
176 | return this._active; | ||
177 | }, | ||
178 | set: function(value) { | ||
179 | this._active = value; | ||
180 | this.needsDraw = true; | ||
181 | } | ||
182 | }, | ||
183 | |||
184 | // HTMLInputElement/HTMLButtonElement methods | ||
185 | |||
186 | blur: { value: function() { this._element.blur(); } }, | ||
187 | focus: { value: function() { this._element.focus(); } }, | ||
188 | // click() deliberately omitted (it isn't available on <button> anyways) | ||
189 | |||
190 | didCreate: { | ||
191 | value: function() { | ||
192 | this._pressComposer = PressComposer.create(); | ||
193 | this.addComposer(this._pressComposer); | ||
194 | } | ||
195 | }, | ||
196 | |||
197 | prepareForActivationEvents: { | ||
198 | value: function() { | ||
199 | this._pressComposer.addEventListener("pressStart", this, false); | ||
200 | this._pressComposer.addEventListener("press", this, false); | ||
201 | this._pressComposer.addEventListener("pressCancel", this, false); | ||
202 | } | ||
203 | }, | ||
204 | |||
205 | // Optimisation | ||
206 | addEventListener: { | ||
207 | value: function(type, listener, useCapture) { | ||
208 | NativeControl.addEventListener.call(this, type, listener, useCapture); | ||
209 | if (type === "hold") { | ||
210 | this._pressComposer.addEventListener("longPress", this, false); | ||
211 | } | ||
212 | } | ||
213 | }, | ||
214 | |||
215 | // Handlers | ||
216 | |||
217 | /** | ||
218 | Called when the user starts interacting with the component. | ||
219 | */ | ||
220 | handlePressStart: { | ||
221 | value: function(event) { | ||
222 | this.active = true; | ||