|
1 /* |
|
2 YUI 3.10.3 (build 2fb5187) |
|
3 Copyright 2013 Yahoo! Inc. All rights reserved. |
|
4 Licensed under the BSD License. |
|
5 http://yuilibrary.com/license/ |
|
6 */ |
|
7 |
|
8 YUI.add('button', function (Y, NAME) { |
|
9 |
|
10 /** |
|
11 * A Button Widget |
|
12 * |
|
13 * @module button |
|
14 * @since 3.5.0 |
|
15 */ |
|
16 |
|
17 var CLASS_NAMES = Y.ButtonCore.CLASS_NAMES, |
|
18 ARIA_STATES = Y.ButtonCore.ARIA_STATES, |
|
19 ARIA_ROLES = Y.ButtonCore.ARIA_ROLES; |
|
20 |
|
21 /** |
|
22 * Creates a Button |
|
23 * |
|
24 * @class Button |
|
25 * @extends Widget |
|
26 * @uses ButtonCore |
|
27 * @param config {Object} Configuration object |
|
28 * @constructor |
|
29 */ |
|
30 function Button() { |
|
31 Button.superclass.constructor.apply(this, arguments); |
|
32 } |
|
33 |
|
34 /* Button extends Widget */ |
|
35 Y.extend(Button, Y.Widget, { |
|
36 |
|
37 /** |
|
38 * Bounding box template that will contain the Button's DOM subtree. |
|
39 * |
|
40 * @property BOUNDING_TEMPLATE |
|
41 * @type {String} |
|
42 * @default <button/> |
|
43 */ |
|
44 BOUNDING_TEMPLATE : Y.ButtonCore.prototype.TEMPLATE, |
|
45 |
|
46 /** |
|
47 * Content box template |
|
48 * |
|
49 * @property CONTENT_TEMPLATE |
|
50 * @type {String} |
|
51 * @default null |
|
52 */ |
|
53 CONTENT_TEMPLATE : null, |
|
54 |
|
55 /** |
|
56 * @method initializer |
|
57 * @description Internal init() handler. |
|
58 * @param config {Object} Config object. |
|
59 * @private |
|
60 */ |
|
61 initializer: function(config) { |
|
62 // ButtonCore requires this |
|
63 this._host = this.get('boundingBox'); |
|
64 |
|
65 // A workaround until there's a better way to handle setting Node attributes |
|
66 // via HTML parsing in classes that extend Widget |
|
67 if (config.disabled) { |
|
68 this.set('disabled', config.disabled); |
|
69 } |
|
70 }, |
|
71 |
|
72 /** |
|
73 * bindUI implementation |
|
74 * |
|
75 * @description Hooks up events for the widget |
|
76 * @method bindUI |
|
77 */ |
|
78 bindUI: function() { |
|
79 var button = this; |
|
80 button.after('labelChange', button._afterLabelChange); |
|
81 button.after('disabledChange', button._afterDisabledChange); |
|
82 }, |
|
83 |
|
84 /** |
|
85 * @method syncUI |
|
86 * @description Updates button attributes |
|
87 */ |
|
88 syncUI: function() { |
|
89 var button = this; |
|
90 Y.ButtonCore.prototype._uiSetLabel.call(button, button.get('label')); |
|
91 Y.ButtonCore.prototype._uiSetDisabled.call(button, button.get('disabled')); |
|
92 }, |
|
93 |
|
94 /** |
|
95 * @method _afterLabelChange |
|
96 * @private |
|
97 */ |
|
98 _afterLabelChange: function(e) { |
|
99 Y.ButtonCore.prototype._uiSetLabel.call(this, e.newVal); |
|
100 }, |
|
101 |
|
102 /** |
|
103 * @method _afterDisabledChange |
|
104 * @private |
|
105 */ |
|
106 _afterDisabledChange: function(e) { |
|
107 // Unable to use `this._uiSetDisabled` because that points |
|
108 // to `Y.Widget.prototype._uiSetDisabled`. |
|
109 // This works for now. |
|
110 // @TODO Investigate most appropriate solution. |
|
111 Y.ButtonCore.prototype._uiSetDisabled.call(this, e.newVal); |
|
112 } |
|
113 |
|
114 }, { |
|
115 // Y.Button static properties |
|
116 |
|
117 /** |
|
118 * The identity of the widget. |
|
119 * |
|
120 * @property NAME |
|
121 * @type String |
|
122 * @default 'button' |
|
123 * @readOnly |
|
124 * @protected |
|
125 * @static |
|
126 */ |
|
127 NAME: 'button', |
|
128 |
|
129 /** |
|
130 * Static property used to define the default attribute configuration of |
|
131 * the Widget. |
|
132 * |
|
133 * @property ATTRS |
|
134 * @type {Object} |
|
135 * @protected |
|
136 * @static |
|
137 */ |
|
138 ATTRS: { |
|
139 |
|
140 /** |
|
141 * The text of the button (the `value` or `text` property) |
|
142 * |
|
143 * @attribute label |
|
144 * @type String |
|
145 */ |
|
146 label: { |
|
147 value: Y.ButtonCore.ATTRS.label.value |
|
148 } |
|
149 }, |
|
150 |
|
151 /** |
|
152 * @property HTML_PARSER |
|
153 * @type {Object} |
|
154 * @protected |
|
155 * @static |
|
156 */ |
|
157 HTML_PARSER: { |
|
158 label: function(node) { |
|
159 this._host = node; // TODO: remove |
|
160 return this._getLabel(); |
|
161 }, |
|
162 |
|
163 disabled: function(node) { |
|
164 return node.getDOMNode().disabled; |
|
165 } |
|
166 }, |
|
167 |
|
168 /** |
|
169 * List of class names used in the Button's DOM |
|
170 * |
|
171 * @property CLASS_NAMES |
|
172 * @type Object |
|
173 * @static |
|
174 */ |
|
175 CLASS_NAMES: CLASS_NAMES |
|
176 }); |
|
177 |
|
178 Y.mix(Button.prototype, Y.ButtonCore.prototype); |
|
179 |
|
180 /** |
|
181 * Creates a ToggleButton |
|
182 * |
|
183 * @class ToggleButton |
|
184 * @extends Button |
|
185 * @param config {Object} Configuration object |
|
186 * @constructor |
|
187 */ |
|
188 function ToggleButton() { |
|
189 Button.superclass.constructor.apply(this, arguments); |
|
190 } |
|
191 |
|
192 // TODO: move to ButtonCore subclass to enable toggle plugin, widget, etc. |
|
193 /* ToggleButton extends Button */ |
|
194 Y.extend(ToggleButton, Button, { |
|
195 |
|
196 /** |
|
197 * |
|
198 * |
|
199 * @property trigger |
|
200 * @type {String} |
|
201 * @default |
|
202 */ |
|
203 trigger: 'click', |
|
204 |
|
205 /** |
|
206 * |
|
207 * |
|
208 * @property selectedAttrName |
|
209 * @type {String} |
|
210 * @default |
|
211 */ |
|
212 selectedAttrName: '', |
|
213 |
|
214 /** |
|
215 * |
|
216 * @method initializer |
|
217 */ |
|
218 initializer: function (config) { |
|
219 var button = this, |
|
220 type = button.get('type'), |
|
221 selectedAttrName = (type === "checkbox" ? 'checked' : 'pressed'), |
|
222 selectedState = config[selectedAttrName] || false; |
|
223 |
|
224 // Create the checked/pressed attribute |
|
225 button.addAttr(selectedAttrName, { |
|
226 value: selectedState |
|
227 }); |
|
228 |
|
229 button.selectedAttrName = selectedAttrName; |
|
230 }, |
|
231 |
|
232 /** |
|
233 * |
|
234 * @method destructor |
|
235 */ |
|
236 destructor: function () { |
|
237 delete this.selectedAttrName; |
|
238 }, |
|
239 |
|
240 /** |
|
241 * @method bindUI |
|
242 * @description Hooks up events for the widget |
|
243 */ |
|
244 bindUI: function() { |
|
245 var button = this, |
|
246 cb = button.get('contentBox'); |
|
247 |
|
248 ToggleButton.superclass.bindUI.call(button); |
|
249 |
|
250 cb.on(button.trigger, button.toggle, button); |
|
251 button.after(button.selectedAttrName + 'Change', button._afterSelectedChange); |
|
252 }, |
|
253 |
|
254 /** |
|
255 * @method syncUI |
|
256 * @description Syncs the UI for the widget |
|
257 */ |
|
258 syncUI: function() { |
|
259 var button = this, |
|
260 cb = button.get('contentBox'), |
|
261 type = button.get('type'), |
|
262 ROLES = ToggleButton.ARIA_ROLES, |
|
263 role = (type === 'checkbox' ? ROLES.CHECKBOX : ROLES.TOGGLE), |
|
264 selectedAttrName = button.selectedAttrName; |
|
265 |
|
266 ToggleButton.superclass.syncUI.call(button); |
|
267 |
|
268 cb.set('role', role); |
|
269 button._uiSetSelected(button.get(selectedAttrName)); |
|
270 }, |
|
271 |
|
272 /** |
|
273 * @method _afterSelectedChange |
|
274 * @private |
|
275 */ |
|
276 _afterSelectedChange: function(e){ |
|
277 this._uiSetSelected(e.newVal); |
|
278 }, |
|
279 |
|
280 /** |
|
281 * @method _uiSetSelected |
|
282 * @private |
|
283 */ |
|
284 _uiSetSelected: function(value) { |
|
285 var button = this, |
|
286 cb = button.get('contentBox'), |
|
287 STATES = ToggleButton.ARIA_STATES, |
|
288 type = button.get('type'), |
|
289 ariaState = (type === 'checkbox' ? STATES.CHECKED : STATES.PRESSED); |
|
290 |
|
291 cb.toggleClass(Button.CLASS_NAMES.SELECTED, value); |
|
292 cb.set(ariaState, value); |
|
293 }, |
|
294 |
|
295 /** |
|
296 * @method toggle |
|
297 * @description Toggles the selected/pressed/checked state of a ToggleButton |
|
298 * @public |
|
299 */ |
|
300 toggle: function() { |
|
301 var button = this; |
|
302 button._set(button.selectedAttrName, !button.get(button.selectedAttrName)); |
|
303 } |
|
304 |
|
305 }, { |
|
306 |
|
307 /** |
|
308 * The identity of the widget. |
|
309 * |
|
310 * @property NAME |
|
311 * @type {String} |
|
312 * @default 'buttongroup' |
|
313 * @readOnly |
|
314 * @protected |
|
315 * @static |
|
316 */ |
|
317 NAME: 'toggleButton', |
|
318 |
|
319 /** |
|
320 * Static property used to define the default attribute configuration of |
|
321 * the Widget. |
|
322 * |
|
323 * @property ATTRS |
|
324 * @type {Object} |
|
325 * @protected |
|
326 * @static |
|
327 */ |
|
328 ATTRS: { |
|
329 |
|
330 /** |
|
331 * |
|
332 * |
|
333 * @attribute type |
|
334 * @type String |
|
335 */ |
|
336 type: { |
|
337 value: 'toggle', |
|
338 writeOnce: 'initOnly' |
|
339 } |
|
340 }, |
|
341 |
|
342 /** |
|
343 * @property HTML_PARSER |
|
344 * @type {Object} |
|
345 * @protected |
|
346 * @static |
|
347 */ |
|
348 HTML_PARSER: { |
|
349 checked: function(node) { |
|
350 return node.hasClass(CLASS_NAMES.SELECTED); |
|
351 }, |
|
352 pressed: function(node) { |
|
353 return node.hasClass(CLASS_NAMES.SELECTED); |
|
354 } |
|
355 }, |
|
356 |
|
357 /** |
|
358 * @property ARIA_STATES |
|
359 * @type {Object} |
|
360 * @protected |
|
361 * @static |
|
362 */ |
|
363 ARIA_STATES: ARIA_STATES, |
|
364 |
|
365 /** |
|
366 * @property ARIA_ROLES |
|
367 * @type {Object} |
|
368 * @protected |
|
369 * @static |
|
370 */ |
|
371 ARIA_ROLES: ARIA_ROLES, |
|
372 |
|
373 /** |
|
374 * Array of static constants used to identify the classnames applied to DOM nodes |
|
375 * |
|
376 * @property CLASS_NAMES |
|
377 * @type Object |
|
378 * @static |
|
379 */ |
|
380 CLASS_NAMES: CLASS_NAMES |
|
381 |
|
382 }); |
|
383 |
|
384 // Export |
|
385 Y.Button = Button; |
|
386 Y.ToggleButton = ToggleButton; |
|
387 |
|
388 |
|
389 }, '3.10.3', {"requires": ["button-core", "cssbutton", "widget"]}); |