1 |
/*! |
2 |
* jQuery UI Button 1.10.3 |
3 |
* http://jqueryui.com |
4 |
* |
5 |
* Copyright 2013 jQuery Foundation and other contributors |
6 |
* Released under the MIT license. |
7 |
* http://jquery.org/license |
8 |
* |
9 |
* http://api.jqueryui.com/button/ |
10 |
* |
11 |
* Depends: |
12 |
* jquery.ui.core.js |
13 |
* jquery.ui.widget.js |
14 |
*/ |
15 |
(function( $, undefined ) { |
16 |
|
17 |
var lastActive, startXPos, startYPos, clickDragged, |
18 |
baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", |
19 |
stateClasses = "ui-state-hover ui-state-active ", |
20 |
typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", |
21 |
formResetHandler = function() { |
22 |
var form = $( this ); |
23 |
setTimeout(function() { |
24 |
form.find( ":ui-button" ).button( "refresh" ); |
25 |
}, 1 ); |
26 |
}, |
27 |
radioGroup = function( radio ) { |
28 |
var name = radio.name, |
29 |
form = radio.form, |
30 |
radios = $( [] ); |
31 |
if ( name ) { |
32 |
name = name.replace( /'/g, "\\'" ); |
33 |
if ( form ) { |
34 |
radios = $( form ).find( "[name='" + name + "']" ); |
35 |
} else { |
36 |
radios = $( "[name='" + name + "']", radio.ownerDocument ) |
37 |
.filter(function() { |
38 |
return !this.form; |
39 |
}); |
40 |
} |
41 |
} |
42 |
return radios; |
43 |
}; |
44 |
|
45 |
$.widget( "ui.button", { |
46 |
version: "1.10.3", |
47 |
defaultElement: "<button>", |
48 |
options: { |
49 |
disabled: null, |
50 |
text: true, |
51 |
label: null, |
52 |
icons: { |
53 |
primary: null, |
54 |
secondary: null |
55 |
} |
56 |
}, |
57 |
_create: function() { |
58 |
this.element.closest( "form" ) |
59 |
.unbind( "reset" + this.eventNamespace ) |
60 |
.bind( "reset" + this.eventNamespace, formResetHandler ); |
61 |
|
62 |
if ( typeof this.options.disabled !== "boolean" ) { |
63 |
this.options.disabled = !!this.element.prop( "disabled" ); |
64 |
} else { |
65 |
this.element.prop( "disabled", this.options.disabled ); |
66 |
} |
67 |
|
68 |
this._determineButtonType(); |
69 |
this.hasTitle = !!this.buttonElement.attr( "title" ); |
70 |
|
71 |
var that = this, |
72 |
options = this.options, |
73 |
toggleButton = this.type === "checkbox" || this.type === "radio", |
74 |
activeClass = !toggleButton ? "ui-state-active" : "", |
75 |
focusClass = "ui-state-focus"; |
76 |
|
77 |
if ( options.label === null ) { |
78 |
options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); |
79 |
} |
80 |
|
81 |
this._hoverable( this.buttonElement ); |
82 |
|
83 |
this.buttonElement |
84 |
.addClass( baseClasses ) |
85 |
.attr( "role", "button" ) |
86 |
.bind( "mouseenter" + this.eventNamespace, function() { |
87 |
if ( options.disabled ) { |
88 |
return; |
89 |
} |
90 |
if ( this === lastActive ) { |
91 |
$( this ).addClass( "ui-state-active" ); |
92 |
} |
93 |
}) |
94 |
.bind( "mouseleave" + this.eventNamespace, function() { |
95 |
if ( options.disabled ) { |
96 |
return; |
97 |
} |
98 |
$( this ).removeClass( activeClass ); |
99 |
}) |
100 |
.bind( "click" + this.eventNamespace, function( event ) { |
101 |
if ( options.disabled ) { |
102 |
event.preventDefault(); |
103 |
event.stopImmediatePropagation(); |
104 |
} |
105 |
}); |
106 |
|
107 |
this.element |
108 |
.bind( "focus" + this.eventNamespace, function() { |
109 |
// no need to check disabled, focus won't be triggered anyway |
110 |
that.buttonElement.addClass( focusClass ); |
111 |
}) |
112 |
.bind( "blur" + this.eventNamespace, function() { |
113 |
that.buttonElement.removeClass( focusClass ); |
114 |
}); |
115 |
|
116 |
if ( toggleButton ) { |
117 |
this.element.bind( "change" + this.eventNamespace, function() { |
118 |
if ( clickDragged ) { |
119 |
return; |
120 |
} |
121 |
that.refresh(); |
122 |
}); |
123 |
// if mouse moves between mousedown and mouseup (drag) set clickDragged flag |
124 |
// prevents issue where button state changes but checkbox/radio checked state |
125 |
// does not in Firefox (see ticket #6970) |
126 |
this.buttonElement |
127 |
.bind( "mousedown" + this.eventNamespace, function( event ) { |
128 |
if ( options.disabled ) { |
129 |
return; |
130 |
} |
131 |
clickDragged = false; |
132 |
startXPos = event.pageX; |
133 |
startYPos = event.pageY; |
134 |
}) |
135 |
.bind( "mouseup" + this.eventNamespace, function( event ) { |
136 |
if ( options.disabled ) { |
137 |
return; |
138 |
} |
139 |
if ( startXPos !== event.pageX || startYPos !== event.pageY ) { |
140 |
clickDragged = true; |
141 |
} |
142 |
}); |
143 |
} |
144 |
|
145 |
if ( this.type === "checkbox" ) { |
146 |
this.buttonElement.bind( "click" + this.eventNamespace, function() { |
147 |
if ( options.disabled || clickDragged ) { |
148 |
return false; |
149 |
} |
150 |
}); |
151 |
} else if ( this.type === "radio" ) { |
152 |
this.buttonElement.bind( "click" + this.eventNamespace, function() { |
153 |
if ( options.disabled || clickDragged ) { |
154 |
return false; |
155 |
} |
156 |
$( this ).addClass( "ui-state-active" ); |
157 |
that.buttonElement.attr( "aria-pressed", "true" ); |
158 |
|
159 |
var radio = that.element[ 0 ]; |
160 |
radioGroup( radio ) |
161 |
.not( radio ) |
162 |
.map(function() { |
163 |
return $( this ).button( "widget" )[ 0 ]; |
164 |
}) |
165 |
.removeClass( "ui-state-active" ) |
166 |
.attr( "aria-pressed", "false" ); |
167 |
}); |
168 |
} else { |
169 |
this.buttonElement |
170 |
.bind( "mousedown" + this.eventNamespace, function() { |
171 |
if ( options.disabled ) { |
172 |
return false; |
173 |
} |
174 |
$( this ).addClass( "ui-state-active" ); |
175 |
lastActive = this; |
176 |
that.document.one( "mouseup", function() { |
177 |
lastActive = null; |
178 |
}); |
179 |
}) |
180 |
.bind( "mouseup" + this.eventNamespace, function() { |
181 |
if ( options.disabled ) { |
182 |
return false; |
183 |
} |
184 |
$( this ).removeClass( "ui-state-active" ); |
185 |
}) |
186 |
.bind( "keydown" + this.eventNamespace, function(event) { |
187 |
if ( options.disabled ) { |
188 |
return false; |
189 |
} |
190 |
if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { |
191 |
$( this ).addClass( "ui-state-active" ); |
192 |
} |
193 |
}) |
194 |
// see #8559, we bind to blur here in case the button element loses |
195 |
// focus between keydown and keyup, it would be left in an "active" state |
196 |
.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { |
197 |
$( this ).removeClass( "ui-state-active" ); |
198 |
}); |
199 |
|
200 |
if ( this.buttonElement.is("a") ) { |
201 |
this.buttonElement.keyup(function(event) { |
202 |
if ( event.keyCode === $.ui.keyCode.SPACE ) { |
203 |
// TODO pass through original event correctly (just as 2nd argument doesn't work) |
204 |
$( this ).click(); |
205 |
} |
206 |
}); |
207 |
} |
208 |
} |
209 |
|
210 |
// TODO: pull out $.Widget's handling for the disabled option into |
211 |
// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can |
212 |
// be overridden by individual plugins |
213 |
this._setOption( "disabled", options.disabled ); |
214 |
this._resetButton(); |
215 |
}, |
216 |
|
217 |
_determineButtonType: function() { |
218 |
var ancestor, labelSelector, checked; |
219 |
|
220 |
if ( this.element.is("[type=checkbox]") ) { |
221 |
this.type = "checkbox"; |
222 |
} else if ( this.element.is("[type=radio]") ) { |
223 |
this.type = "radio"; |
224 |
} else if ( this.element.is("input") ) { |
225 |
this.type = "input"; |
226 |
} else { |
227 |
this.type = "button"; |
228 |
} |
229 |
|
230 |
if ( this.type === "checkbox" || this.type === "radio" ) { |
231 |
// we don't search against the document in case the element |
232 |
// is disconnected from the DOM |
233 |
ancestor = this.element.parents().last(); |
234 |
labelSelector = "label[for='" + this.element.attr("id") + "']"; |
235 |
this.buttonElement = ancestor.find( labelSelector ); |
236 |
if ( !this.buttonElement.length ) { |
237 |
ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); |
238 |
this.buttonElement = ancestor.filter( labelSelector ); |
239 |
if ( !this.buttonElement.length ) { |
240 |
this.buttonElement = ancestor.find( labelSelector ); |
241 |
} |
242 |
} |
243 |
this.element.addClass( "ui-helper-hidden-accessible" ); |
244 |
|
245 |
checked = this.element.is( ":checked" ); |
246 |
if ( checked ) { |
247 |
this.buttonElement.addClass( "ui-state-active" ); |
248 |
} |
249 |
this.buttonElement.prop( "aria-pressed", checked ); |
250 |
} else { |
251 |
this.buttonElement = this.element; |
252 |
} |
253 |
}, |
254 |
|
255 |
widget: function() { |
256 |
return this.buttonElement; |
257 |
}, |
258 |
|
259 |
_destroy: function() { |
260 |
this.element |
261 |
.removeClass( "ui-helper-hidden-accessible" ); |
262 |
this.buttonElement |
263 |
.removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) |
264 |
.removeAttr( "role" ) |
265 |
.removeAttr( "aria-pressed" ) |
266 |
.html( this.buttonElement.find(".ui-button-text").html() ); |
267 |
|
268 |
if ( !this.hasTitle ) { |
269 |
this.buttonElement.removeAttr( "title" ); |
270 |
} |
271 |
}, |
272 |
|
273 |
_setOption: function( key, value ) { |
274 |
this._super( key, value ); |
275 |
if ( key === "disabled" ) { |
276 |
if ( value ) { |
277 |
this.element.prop( "disabled", true ); |
278 |
} else { |
279 |
this.element.prop( "disabled", false ); |
280 |
} |
281 |
return; |
282 |
} |
283 |
this._resetButton(); |
284 |
}, |
285 |
|
286 |
refresh: function() { |
287 |
//See #8237 & #8828 |
288 |
var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); |
289 |
|
290 |
if ( isDisabled !== this.options.disabled ) { |
291 |
this._setOption( "disabled", isDisabled ); |
292 |
} |
293 |
if ( this.type === "radio" ) { |
294 |
radioGroup( this.element[0] ).each(function() { |
295 |
if ( $( this ).is( ":checked" ) ) { |
296 |
$( this ).button( "widget" ) |
297 |
.addClass( "ui-state-active" ) |
298 |
.attr( "aria-pressed", "true" ); |
299 |
} else { |
300 |
$( this ).button( "widget" ) |
301 |
.removeClass( "ui-state-active" ) |
302 |
.attr( "aria-pressed", "false" ); |
303 |
} |
304 |
}); |
305 |
} else if ( this.type === "checkbox" ) { |
306 |
if ( this.element.is( ":checked" ) ) { |
307 |
this.buttonElement |
308 |
.addClass( "ui-state-active" ) |
309 |
.attr( "aria-pressed", "true" ); |
310 |
} else { |
311 |
this.buttonElement |
312 |
.removeClass( "ui-state-active" ) |
313 |
.attr( "aria-pressed", "false" ); |
314 |
} |
315 |
} |
316 |
}, |
317 |
|
318 |
_resetButton: function() { |
319 |
if ( this.type === "input" ) { |
320 |
if ( this.options.label ) { |
321 |
this.element.val( this.options.label ); |
322 |
} |
323 |
return; |
324 |
} |
325 |
var buttonElement = this.buttonElement.removeClass( typeClasses ), |
326 |
buttonText = $( "<span></span>", this.document[0] ) |
327 |
.addClass( "ui-button-text" ) |
328 |
.html( this.options.label ) |
329 |
.appendTo( buttonElement.empty() ) |
330 |
.text(), |
331 |
icons = this.options.icons, |
332 |
multipleIcons = icons.primary && icons.secondary, |
333 |
buttonClasses = []; |
334 |
|
335 |
if ( icons.primary || icons.secondary ) { |
336 |
if ( this.options.text ) { |
337 |
buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); |
338 |
} |
339 |
|
340 |
if ( icons.primary ) { |
341 |
buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); |
342 |
} |
343 |
|
344 |
if ( icons.secondary ) { |
345 |
buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); |
346 |
} |
347 |
|
348 |
if ( !this.options.text ) { |
349 |
buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); |
350 |
|
351 |
if ( !this.hasTitle ) { |
352 |
buttonElement.attr( "title", $.trim( buttonText ) ); |
353 |
} |
354 |
} |
355 |
} else { |
356 |
buttonClasses.push( "ui-button-text-only" ); |
357 |
} |
358 |
buttonElement.addClass( buttonClasses.join( " " ) ); |
359 |
} |
360 |
}); |
361 |
|
362 |
$.widget( "ui.buttonset", { |
363 |
version: "1.10.3", |
364 |
options: { |
365 |
items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" |
366 |
}, |
367 |
|
368 |
_create: function() { |
369 |
this.element.addClass( "ui-buttonset" ); |
370 |
}, |
371 |
|
372 |
_init: function() { |
373 |
this.refresh(); |
374 |
}, |
375 |
|
376 |
_setOption: function( key, value ) { |
377 |
if ( key === "disabled" ) { |
378 |
this.buttons.button( "option", key, value ); |
379 |
} |
380 |
|
381 |
this._super( key, value ); |
382 |
}, |
383 |
|
384 |
refresh: function() { |
385 |
var rtl = this.element.css( "direction" ) === "rtl"; |
386 |
|
387 |
this.buttons = this.element.find( this.options.items ) |
388 |
.filter( ":ui-button" ) |
389 |
.button( "refresh" ) |
390 |
.end() |
391 |
.not( ":ui-button" ) |
392 |
.button() |
393 |
.end() |
394 |
.map(function() { |
395 |
return $( this ).button( "widget" )[ 0 ]; |
396 |
}) |
397 |
.removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) |
398 |
.filter( ":first" ) |
399 |
.addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) |
400 |
.end() |
401 |
.filter( ":last" ) |
402 |
.addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) |
403 |
.end() |
404 |
.end(); |
405 |
}, |
406 |
|
407 |
_destroy: function() { |
408 |
this.element.removeClass( "ui-buttonset" ); |
409 |
this.buttons |
410 |
.map(function() { |
411 |
return $( this ).button( "widget" )[ 0 ]; |
412 |
}) |
413 |
.removeClass( "ui-corner-left ui-corner-right" ) |
414 |
.end() |
415 |
.button( "destroy" ); |
416 |
} |
417 |
}); |
418 |
|
419 |
}( jQuery ) ); |