uniformjs-rails 1.5.0.2 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +7 -0
  2. data/lib/uniformjs-rails/version.rb +1 -1
  3. data/vendor/assets/images/agent/bg-input-agent.png +0 -0
  4. data/vendor/assets/images/agent/bg-input-focus-agent.png +0 -0
  5. data/vendor/assets/images/agent/sprite-agent.png +0 -0
  6. data/vendor/assets/images/aristo/bg-input-aristo.png +0 -0
  7. data/vendor/assets/images/aristo/bg-input-focus-aristo.png +0 -0
  8. data/vendor/assets/images/aristo/sprite-aristo.png +0 -0
  9. data/vendor/assets/images/{bg-input-focus.png → default/bg-input-focus.png} +0 -0
  10. data/vendor/assets/images/{bg-input.png → default/bg-input.png} +0 -0
  11. data/vendor/assets/images/default/sprite.png +0 -0
  12. data/vendor/assets/images/jeans/bg-input-focus-jeans.png +0 -0
  13. data/vendor/assets/images/jeans/bg-input-focus-retina-jeans.png +0 -0
  14. data/vendor/assets/images/jeans/bg-input-jeans.png +0 -0
  15. data/vendor/assets/images/jeans/bg-input-retina-jeans.png +0 -0
  16. data/vendor/assets/images/jeans/sprite-jeans.png +0 -0
  17. data/vendor/assets/images/jeans/sprite-retina-jeans.png +0 -0
  18. data/vendor/assets/javascripts/jquery.uniform.js +992 -634
  19. data/vendor/assets/stylesheets/uniformjs/_base.scss +558 -0
  20. data/vendor/assets/stylesheets/uniformjs/agent.scss +138 -0
  21. data/vendor/assets/stylesheets/uniformjs/aristo.scss +142 -0
  22. data/vendor/assets/stylesheets/uniformjs/default.scss +142 -0
  23. data/vendor/assets/stylesheets/uniformjs/jeans.scss +156 -0
  24. metadata +34 -22
  25. data/vendor/assets/images/sprite.png +0 -0
  26. data/vendor/assets/stylesheets/uniform.default.css.scss +0 -610
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ac1d3201d2fc9c372b3997eb5e9417c150626597
4
+ data.tar.gz: 5774425401a2388c4827463bb4e11388ea5e7405
5
+ SHA512:
6
+ metadata.gz: 268f13f54c2330aa30a3e88771ca3bfd49553509af688e8dbcfe9be581baaf7dd3ea84b068e574db46a1073b396bd454cf865fdef23f1a615fe4b4bf90466ca8
7
+ data.tar.gz: 590ae294b4b89033a6d72373ea7f3b186de39d952e2d266cd919bdbab1332f800b83596a2ff6c7549741410931ecf49ae6a7b4831bdc18c09fd4607b7cdaae04
@@ -1,5 +1,5 @@
1
1
  module Uniformjs
2
2
  module Rails
3
- VERSION = '1.5.0.2'
3
+ VERSION = '3.0.1'
4
4
  end
5
5
  end
@@ -1,672 +1,1030 @@
1
- /*
2
-
3
- Uniform v1.7.5
4
- Copyright © 2009 Josh Pyles / Pixelmatrix Design LLC
5
- http://pixelmatrixdesign.com
6
-
7
- Requires jQuery 1.4 or newer
8
-
9
- Much thanks to Thomas Reynolds and Buck Wilson for their help and advice on this
10
-
11
- Disabling text selection is made possible by Mathias Bynens <http://mathiasbynens.be/>
12
- and his noSelect plugin. <http://github.com/mathiasbynens/noSelect-jQuery-Plugin>
13
-
14
- Also, thanks to David Kaneda and Eugene Bond for their contributions to the plugin
15
-
16
- License:
17
- MIT License - http://www.opensource.org/licenses/mit-license.php
18
-
19
- Enjoy!
20
-
21
- */
22
-
23
- (function($) {
24
- $.uniform = {
25
- options: {
26
- selectClass: 'selector',
27
- radioClass: 'radio',
28
- checkboxClass: 'checker',
29
- fileClass: 'uploader',
30
- filenameClass: 'filename',
31
- fileBtnClass: 'action',
32
- fileDefaultText: 'No file selected',
33
- fileBtnText: 'Choose File',
34
- checkedClass: 'checked',
35
- focusClass: 'focus',
36
- disabledClass: 'disabled',
37
- buttonClass: 'button',
38
- activeClass: 'active',
39
- hoverClass: 'hover',
40
- useID: true,
41
- idPrefix: 'uniform',
42
- resetSelector: false,
43
- autoHide: true
44
- },
45
- elements: []
46
- };
47
-
48
- if($.browser.msie && $.browser.version < 7){
49
- $.support.selectOpacity = false;
50
- }else{
51
- $.support.selectOpacity = true;
52
- }
53
-
54
- $.fn.uniform = function(options) {
55
-
56
- options = $.extend($.uniform.options, options);
57
-
58
- var el = this;
59
- //code for specifying a reset button
60
- if(options.resetSelector != false){
61
- $(options.resetSelector).mouseup(function(){
62
- function resetThis(){
63
- $.uniform.update(el);
1
+ /**
2
+ * Uniform
3
+ * A jQuery plugin to make your form controls look how you want them to.
4
+ *
5
+ * @author Josh Pyles <joshpyles@gmail.com>
6
+ * @author Tyler Akins <fidian@rumkin.com>
7
+ * @author Shahriyar Imanov <shehi@imanov.me>
8
+ *
9
+ * @license MIT
10
+ *
11
+ * @see http://opensource.audith.org/uniform
12
+ */
13
+
14
+ (function (wind, $, undef) {
15
+ "use strict";
16
+
17
+ /**
18
+ * Use .prop() if jQuery supports it, otherwise fall back to .attr()
19
+ * @usage All other parameters are passed to jQuery's function
20
+ *
21
+ * @param {jQuery} $el jQuery'd element on which we're calling attr/prop
22
+ * @return {*} The result from jQuery
23
+ */
24
+ function attrOrProp($el /* , args */) {
25
+ var args = Array.prototype.slice.call(arguments, 1);
26
+
27
+ if ($el.prop) {
28
+ // jQuery 1.6+
29
+ return $el.prop.apply($el, args);
64
30
  }
65
- setTimeout(resetThis, 10);
66
- });
67
- }
68
-
69
- function doInput(elem){
70
- $el = $(elem);
71
- $el.addClass($el.attr("type"));
72
- storeElement(elem);
73
- }
74
-
75
- function doTextarea(elem){
76
- $(elem).addClass("uniform");
77
- storeElement(elem);
31
+
32
+ // jQuery 1.5 and below
33
+ return $el.attr.apply($el, args);
78
34
  }
79
-
80
- function doButton(elem){
81
- var $el = $(elem);
82
-
83
- var divTag = $("<div>"),
84
- spanTag = $("<span>");
85
-
86
- divTag.addClass(options.buttonClass);
87
-
88
- if(options.useID && $el.attr("id") != "") divTag.attr("id", options.idPrefix+"-"+$el.attr("id"));
89
-
90
- var btnText;
91
-
92
- if($el.is("a") || $el.is("button")){
93
- btnText = $el.text();
94
- }else if($el.is(":submit") || $el.is(":reset") || $el.is("input[type=button]")){
95
- btnText = $el.attr("value");
96
- }
97
-
98
- btnText = btnText == "" ? $el.is(":reset") ? "Reset" : "Submit" : btnText;
99
-
100
- spanTag.html(btnText);
101
-
102
- $el.css("opacity", 0);
103
- $el.wrap(divTag);
104
- $el.wrap(spanTag);
105
-
106
- //redefine variables
107
- divTag = $el.closest("div");
108
- spanTag = $el.closest("span");
109
-
110
- if($el.is(":disabled")) divTag.addClass(options.disabledClass);
111
-
112
- divTag.bind({
113
- "mouseenter.uniform": function(){
114
- divTag.addClass(options.hoverClass);
115
- },
116
- "mouseleave.uniform": function(){
117
- divTag.removeClass(options.hoverClass);
118
- divTag.removeClass(options.activeClass);
119
- },
120
- "mousedown.uniform touchbegin.uniform": function(){
121
- divTag.addClass(options.activeClass);
122
- },
123
- "mouseup.uniform touchend.uniform": function(){
124
- divTag.removeClass(options.activeClass);
125
- },
126
- "click.uniform touchend.uniform": function(e){
127
- if($(e.target).is("span") || $(e.target).is("div")){
128
- if(elem[0].dispatchEvent){
129
- var ev = document.createEvent('MouseEvents');
130
- ev.initEvent( 'click', true, true );
131
- elem[0].dispatchEvent(ev);
132
- }else{
133
- elem[0].click();
35
+
36
+ /**
37
+ * For backwards compatibility with older jQuery libraries, only bind
38
+ * one thing at a time. Also, this function adds our namespace to
39
+ * events in one consistent location, shrinking the minified code.
40
+ *
41
+ * The properties on the events object are the names of the events
42
+ * that we are supposed to add to. It can be a space separated list.
43
+ * The namespace will be added automatically.
44
+ *
45
+ * @param {jQuery} $el
46
+ * @param {Object} options Uniform options for this element
47
+ * @param {Object} events Events to bind, properties are event names
48
+ */
49
+ function bindMany($el, options, events) {
50
+ var name, namespaced;
51
+
52
+ for (name in events) {
53
+ if (events.hasOwnProperty(name)) {
54
+ namespaced = name.replace(/ |$/g, options.eventNamespace);
55
+ $el.bind(namespaced, events[name]);
134
56
  }
135
- }
136
57
  }
137
- });
138
-
139
- elem.bind({
140
- "focus.uniform": function(){
141
- divTag.addClass(options.focusClass);
142
- },
143
- "blur.uniform": function(){
144
- divTag.removeClass(options.focusClass);
58
+ }
59
+
60
+ /**
61
+ * Bind the hover, active, focus, and blur UI updates
62
+ *
63
+ * @param {jQuery} $el Original element
64
+ * @param {jQuery} $target Target for the events (our div/span)
65
+ * @param {Object} options Uniform options for the element $target
66
+ */
67
+ function bindUi($el, $target, options) {
68
+ bindMany($el, options, {
69
+ focus: function () {
70
+ $target.addClass(options.focusClass);
71
+ },
72
+ blur: function () {
73
+ $target.removeClass(options.focusClass);
74
+ $target.removeClass(options.activeClass);
75
+ },
76
+ mouseenter: function () {
77
+ $target.addClass(options.hoverClass);
78
+ },
79
+ mouseleave: function () {
80
+ $target.removeClass(options.hoverClass);
81
+ $target.removeClass(options.activeClass);
82
+ },
83
+ "mousedown touchbegin": function () {
84
+ if (!$el.is(":disabled")) {
85
+ $target.addClass(options.activeClass);
86
+ }
87
+ },
88
+ "mouseup touchend": function () {
89
+ $target.removeClass(options.activeClass);
90
+ }
91
+ });
92
+ }
93
+
94
+ /**
95
+ * Remove the hover, focus, active classes.
96
+ *
97
+ * @param {jQuery} $el Element with classes
98
+ * @param {Object} options Uniform options for the element
99
+ */
100
+ function classClearStandard($el, options) {
101
+ $el.removeClass(options.hoverClass + " " + options.focusClass + " " + options.activeClass);
102
+ }
103
+
104
+ /**
105
+ * Add or remove a class, depending on if it's "enabled"
106
+ *
107
+ * @param {jQuery} $el Element that has the class added/removed
108
+ * @param {String} className Class or classes to add/remove
109
+ * @param {Boolean} enabled True to add the class, false to remove
110
+ */
111
+ function classUpdate($el, className, enabled) {
112
+ if (enabled) {
113
+ $el.addClass(className);
114
+ } else {
115
+ $el.removeClass(className);
145
116
  }
146
- });
147
-
148
- $.uniform.noSelect(divTag);
149
- storeElement(elem);
150
-
151
117
  }
152
118
 
153
- function doSelect(elem){
154
- var $el = $(elem);
155
-
156
- var divTag = $('<div />'),
157
- spanTag = $('<span />');
158
-
159
- if(!$el.css("display") == "none" && options.autoHide){
160
- divTag.hide();
161
- }
162
-
163
- divTag.addClass(options.selectClass);
164
-
165
- if(options.useID && elem.attr("id") != ""){
166
- divTag.attr("id", options.idPrefix+"-"+elem.attr("id"));
167
- }
168
-
169
- var selected = elem.find(":selected:first");
170
- if(selected.length == 0){
171
- selected = elem.find("option:first");
172
- }
173
- spanTag.html(selected.html());
174
-
175
- elem.css('opacity', 0);
176
- elem.wrap(divTag);
177
- elem.before(spanTag);
178
-
179
- //redefine variables
180
- divTag = elem.parent("div");
181
- spanTag = elem.siblings("span");
182
-
183
- elem.bind({
184
- "change.uniform": function() {
185
- spanTag.text(elem.find(":selected").html());
186
- divTag.removeClass(options.activeClass);
187
- },
188
- "focus.uniform": function() {
189
- divTag.addClass(options.focusClass);
190
- },
191
- "blur.uniform": function() {
192
- divTag.removeClass(options.focusClass);
193
- divTag.removeClass(options.activeClass);
194
- },
195
- "mousedown.uniform touchbegin.uniform": function() {
196
- divTag.addClass(options.activeClass);
197
- },
198
- "mouseup.uniform touchend.uniform": function() {
199
- divTag.removeClass(options.activeClass);
200
- },
201
- "click.uniform touchend.uniform": function(){
202
- divTag.removeClass(options.activeClass);
203
- },
204
- "mouseenter.uniform": function() {
205
- divTag.addClass(options.hoverClass);
206
- },
207
- "mouseleave.uniform": function() {
208
- divTag.removeClass(options.hoverClass);
209
- divTag.removeClass(options.activeClass);
210
- },
211
- "keyup.uniform": function(){
212
- spanTag.text(elem.find(":selected").html());
119
+ /**
120
+ * Updating the "checked" property can be a little tricky. This
121
+ * changed in jQuery 1.6 and now we can pass booleans to .prop().
122
+ * Prior to that, one either adds an attribute ("checked=checked") or
123
+ * removes the attribute.
124
+ *
125
+ * @param {jQuery} $tag Our Uniform span/div
126
+ * @param {jQuery} $el Original form element
127
+ * @param {Object} options Uniform options for this element
128
+ */
129
+ function classUpdateChecked($tag, $el, options) {
130
+ var c = "checked",
131
+ isChecked = $el.is(":" + c);
132
+
133
+ if ($el.prop) {
134
+ // jQuery 1.6+
135
+ $el.prop(c, isChecked);
136
+ } else {
137
+ // jQuery 1.5 and below
138
+ if (isChecked) {
139
+ $el.attr(c, c);
140
+ } else {
141
+ $el.removeAttr(c);
142
+ }
213
143
  }
214
- });
215
-
216
- //handle disabled state
217
- if($(elem).attr("disabled")){
218
- //box is checked by default, check our box
219
- divTag.addClass(options.disabledClass);
220
- }
221
- $.uniform.noSelect(spanTag);
222
-
223
- storeElement(elem);
224
144
 
145
+ classUpdate($tag, options.checkedClass, isChecked);
225
146
  }
226
147
 
227
- function doCheckbox(elem){
228
- var $el = $(elem);
229
-
230
- var divTag = $('<div />'),
231
- spanTag = $('<span />');
232
-
233
- if(!$el.css("display") == "none" && options.autoHide){
234
- divTag.hide();
235
- }
236
-
237
- divTag.addClass(options.checkboxClass);
238
-
239
- //assign the id of the element
240
- if(options.useID && elem.attr("id") != ""){
241
- divTag.attr("id", options.idPrefix+"-"+elem.attr("id"));
242
- }
243
-
244
- //wrap with the proper elements
245
- $(elem).wrap(divTag);
246
- $(elem).wrap(spanTag);
247
-
248
- //redefine variables
249
- spanTag = elem.parent();
250
- divTag = spanTag.parent();
251
-
252
- //hide normal input and add focus classes
253
- $(elem)
254
- .css("opacity", 0)
255
- .bind({
256
- "focus.uniform": function(){
257
- divTag.addClass(options.focusClass);
258
- },
259
- "blur.uniform": function(){
260
- divTag.removeClass(options.focusClass);
261
- },
262
- "click.uniform touchend.uniform": function(){
263
- if(!$(elem).attr("checked")){
264
- //box was just unchecked, uncheck span
265
- spanTag.removeClass(options.checkedClass);
266
- }else{
267
- //box was just checked, check span.
268
- spanTag.addClass(options.checkedClass);
269
- }
270
- },
271
- "mousedown.uniform touchbegin.uniform": function() {
272
- divTag.addClass(options.activeClass);
273
- },
274
- "mouseup.uniform touchend.uniform": function() {
275
- divTag.removeClass(options.activeClass);
276
- },
277
- "mouseenter.uniform": function() {
278
- divTag.addClass(options.hoverClass);
279
- },
280
- "mouseleave.uniform": function() {
281
- divTag.removeClass(options.hoverClass);
282
- divTag.removeClass(options.activeClass);
148
+ /**
149
+ * Set or remove the "disabled" class for disabled elements, based on
150
+ * if the element is detected to be disabled.
151
+ *
152
+ * @param {jQuery} $tag Our Uniform span/div
153
+ * @param {jQuery} $el Original form element
154
+ * @param {Object} options Uniform options for this element
155
+ */
156
+ function classUpdateDisabled($tag, $el, options) {
157
+ classUpdate($tag, options.disabledClass, $el.is(":disabled"));
158
+ }
159
+
160
+ /**
161
+ * Wrap an element inside of a container or put the container next
162
+ * to the element. See the code for examples of the different methods.
163
+ *
164
+ * Returns the container that was added to the HTML.
165
+ *
166
+ * @param {jQuery} $el Element to wrap
167
+ * @param {jQuery} $container Add this new container around/near $el
168
+ * @param {String} method One of "after", "before" or "wrap"
169
+ * @return {jQuery} $container after it has been cloned for adding to $el
170
+ */
171
+ function divSpanWrap($el, $container, method) {
172
+ switch (method) {
173
+ case "after":
174
+ // Result: <element /> <container />
175
+ $el.after($container);
176
+ return $el.next();
177
+ case "before":
178
+ // Result: <container /> <element />
179
+ $el.before($container);
180
+ return $el.prev();
181
+ case "wrap":
182
+ // Result: <container> <element /> </container>
183
+ $el.wrap($container);
184
+ return $el.parent();
283
185
  }
284
- });
285
-
286
- //handle defaults
287
- if($(elem).attr("checked")){
288
- //box is checked by default, check our box
289
- spanTag.addClass(options.checkedClass);
290
- }
291
-
292
- //handle disabled state
293
- if($(elem).attr("disabled")){
294
- //box is checked by default, check our box
295
- divTag.addClass(options.disabledClass);
296
- }
297
-
298
- storeElement(elem);
186
+
187
+ return null;
299
188
  }
300
189
 
301
- function doRadio(elem){
302
- var $el = $(elem);
303
-
304
- var divTag = $('<div />'),
305
- spanTag = $('<span />');
306
-
307
- if(!$el.css("display") == "none" && options.autoHide){
308
- divTag.hide();
309
- }
310
-
311
- divTag.addClass(options.radioClass);
312
-
313
- if(options.useID && elem.attr("id") != ""){
314
- divTag.attr("id", options.idPrefix+"-"+elem.attr("id"));
315
- }
316
-
317
- //wrap with the proper elements
318
- $(elem).wrap(divTag);
319
- $(elem).wrap(spanTag);
320
-
321
- //redefine variables
322
- spanTag = elem.parent();
323
- divTag = spanTag.parent();
324
-
325
- //hide normal input and add focus classes
326
- $(elem)
327
- .css("opacity", 0)
328
- .bind({
329
- "focus.uniform": function(){
330
- divTag.addClass(options.focusClass);
331
- },
332
- "blur.uniform": function(){
333
- divTag.removeClass(options.focusClass);
334
- },
335
- "click.uniform touchend.uniform": function(){
336
- if(!$(elem).attr("checked")){
337
- //box was just unchecked, uncheck span
338
- spanTag.removeClass(options.checkedClass);
339
- }else{
340
- //box was just checked, check span
341
- var classes = options.radioClass.split(" ")[0];
342
- $("." + classes + " span." + options.checkedClass + ":has([name='" + $(elem).attr('name') + "'])").removeClass(options.checkedClass);
343
- spanTag.addClass(options.checkedClass);
344
- }
345
- },
346
- "mousedown.uniform touchend.uniform": function() {
347
- if(!$(elem).is(":disabled")){
348
- divTag.addClass(options.activeClass);
349
- }
350
- },
351
- "mouseup.uniform touchbegin.uniform": function() {
352
- divTag.removeClass(options.activeClass);
353
- },
354
- "mouseenter.uniform touchend.uniform": function() {
355
- divTag.addClass(options.hoverClass);
356
- },
357
- "mouseleave.uniform": function() {
358
- divTag.removeClass(options.hoverClass);
359
- divTag.removeClass(options.activeClass);
190
+ /**
191
+ * Create a div/span combo for uniforming an element
192
+ *
193
+ * @param {jQuery} $el Element to wrap
194
+ * @param {Object} options Options for the element, set by the user
195
+ * @param {Object} divSpanConfig Options for how we wrap the div/span
196
+ * @return {Object} Contains the div and span as properties
197
+ */
198
+ function divSpan($el, options, divSpanConfig) {
199
+ var $div, $span, id;
200
+
201
+ if (!divSpanConfig) {
202
+ divSpanConfig = {};
360
203
  }
361
- });
362
204
 
363
- //handle defaults
364
- if($(elem).attr("checked")){
365
- //box is checked by default, check span
366
- spanTag.addClass(options.checkedClass);
367
- }
368
- //handle disabled state
369
- if($(elem).attr("disabled")){
370
- //box is checked by default, check our box
371
- divTag.addClass(options.disabledClass);
372
- }
205
+ divSpanConfig = $.extend({
206
+ bind: {},
207
+ divClass: null,
208
+ divWrap: "wrap",
209
+ spanClass: null,
210
+ spanHtml: null,
211
+ spanWrap: "wrap"
212
+ }, divSpanConfig);
213
+
214
+ $div = $('<div />');
215
+ $span = $('<span />');
216
+
217
+ // Automatically hide this div/span if the element is hidden.
218
+ // Do not hide if the element is hidden because a parent is hidden.
219
+ if (options.autoHide && $el.is(':hidden') && $el.css('display') === 'none') {
220
+ $div.hide();
221
+ }
373
222
 
374
- storeElement(elem);
223
+ if (divSpanConfig.divClass) {
224
+ $div.addClass(divSpanConfig.divClass);
225
+ }
226
+
227
+ if (options.wrapperClass) {
228
+ $div.addClass(options.wrapperClass);
229
+ }
230
+
231
+ if (divSpanConfig.spanClass) {
232
+ $span.addClass(divSpanConfig.spanClass);
233
+ }
234
+
235
+ id = attrOrProp($el, 'id');
236
+
237
+ if (options.useID && id) {
238
+ attrOrProp($div, 'id', options.idPrefix + '-' + id);
239
+ }
375
240
 
241
+ if (divSpanConfig.spanHtml) {
242
+ $span.html(divSpanConfig.spanHtml);
243
+ }
244
+
245
+ $div = divSpanWrap($el, $div, divSpanConfig.divWrap);
246
+ $span = divSpanWrap($el, $span, divSpanConfig.spanWrap);
247
+ classUpdateDisabled($div, $el, options);
248
+ return {
249
+ div: $div,
250
+ span: $span
251
+ };
376
252
  }
377
253
 
378
- function doFile(elem){
379
- //sanitize input
380
- var $el = $(elem);
381
-
382
- var divTag = $('<div />'),
383
- filenameTag = $('<span>'+options.fileDefaultText+'</span>'),
384
- btnTag = $('<span>'+options.fileBtnText+'</span>');
385
-
386
- if(!$el.css("display") == "none" && options.autoHide){
387
- divTag.hide();
388
- }
389
-
390
- divTag.addClass(options.fileClass);
391
- filenameTag.addClass(options.filenameClass);
392
- btnTag.addClass(options.fileBtnClass);
393
-
394
- if(options.useID && $el.attr("id") != ""){
395
- divTag.attr("id", options.idPrefix+"-"+$el.attr("id"));
396
- }
397
-
398
- //wrap with the proper elements
399
- $el.wrap(divTag);
400
- $el.after(btnTag);
401
- $el.after(filenameTag);
402
-
403
- //redefine variables
404
- divTag = $el.closest("div");
405
- filenameTag = $el.siblings("."+options.filenameClass);
406
- btnTag = $el.siblings("."+options.fileBtnClass);
407
-
408
- //set the size
409
- if(!$el.attr("size")){
410
- var divWidth = divTag.width();
411
- //$el.css("width", divWidth);
412
- $el.attr("size", divWidth/10);
413
- }
414
-
415
- //actions
416
- var setFilename = function()
417
- {
418
- var filename = $el.val();
419
- if (filename === '')
420
- {
421
- filename = options.fileDefaultText;
254
+ /**
255
+ * Wrap an element with a span to apply a global wrapper class
256
+ *
257
+ * @param {jQuery} $el Element to wrap
258
+ * @param {Object} options
259
+ * @return {jQuery} jQuery Wrapper element
260
+ */
261
+ function wrapWithWrapperClass($el, options) {
262
+ var $span;
263
+
264
+ if (!options.wrapperClass) {
265
+ return null;
422
266
  }
423
- else
424
- {
425
- filename = filename.split(/[\/\\]+/);
426
- filename = filename[(filename.length-1)];
267
+
268
+ $span = $('<span />').addClass(options.wrapperClass);
269
+ $span = divSpanWrap($el, $span, "wrap");
270
+ return $span;
271
+ }
272
+
273
+ /**
274
+ * Test if high contrast mode is enabled.
275
+ *
276
+ * In high contrast mode, background images can not be set and
277
+ * they are always returned as 'none'.
278
+ *
279
+ * @return {Boolean} True if in high contrast mode
280
+ */
281
+ function highContrast() {
282
+ var c, $div, el, rgb;
283
+
284
+ // High contrast mode deals with white and black
285
+ rgb = 'rgb(120,2,153)';
286
+ $div = $('<div style="width:0;height:0;color:' + rgb + '">');
287
+ $('body').append($div);
288
+ el = $div.get(0);
289
+
290
+ // $div.css() will get the style definition, not
291
+ // the actually displaying style
292
+ if (wind.getComputedStyle) {
293
+ c = wind.getComputedStyle(el, '').color;
294
+ } else {
295
+ c = (el.currentStyle || el.style || {}).color;
427
296
  }
428
- filenameTag.text(filename);
429
- };
430
297
 
431
- // Account for input saved across refreshes
432
- setFilename();
298
+ $div.remove();
299
+ return c.replace(/ /g, '') !== rgb;
300
+ }
433
301
 
434
- $el
435
- .css("opacity", 0)
436
- .bind({
437
- "focus.uniform": function(){
438
- divTag.addClass(options.focusClass);
439
- },
440
- "blur.uniform": function(){
441
- divTag.removeClass(options.focusClass);
442
- },
443
- "mousedown.uniform": function() {
444
- if(!$(elem).is(":disabled")){
445
- divTag.addClass(options.activeClass);
446
- }
447
- },
448
- "mouseup.uniform": function() {
449
- divTag.removeClass(options.activeClass);
450
- },
451
- "mouseenter.uniform": function() {
452
- divTag.addClass(options.hoverClass);
453
- },
454
- "mouseleave.uniform": function() {
455
- divTag.removeClass(options.hoverClass);
456
- divTag.removeClass(options.activeClass);
302
+ /**
303
+ * Change text into safe HTML
304
+ *
305
+ * @param {String} text
306
+ * @return {String} HTML version
307
+ */
308
+ function htmlify(text) {
309
+ if (!text) {
310
+ return "";
311
+ }
312
+
313
+ return $('<span />').text(text).html();
314
+ }
315
+
316
+ /**
317
+ * If not MSIE, return false.
318
+ * If it is, return the version number.
319
+ *
320
+ * @return {Boolean}|{Number}
321
+ */
322
+ function isMsie() {
323
+ return navigator.cpuClass && !navigator.product;
324
+ }
325
+
326
+ /**
327
+ * Return true if this version of IE allows styling
328
+ *
329
+ * @return {Boolean}
330
+ */
331
+ function isMsieSevenOrNewer() {
332
+ return wind.XMLHttpRequest !== undefined;
333
+ }
334
+
335
+ /**
336
+ * Test if the element is a multiselect
337
+ *
338
+ * @param {jQuery} $el Element
339
+ * @return {Boolean} true/false
340
+ */
341
+ function isMultiselect($el) {
342
+ var elSize;
343
+
344
+ if ($el[0].multiple) {
345
+ return true;
457
346
  }
458
- });
459
-
460
- // IE7 doesn't fire onChange until blur or second fire.
461
- if ($.browser.msie){
462
- // IE considers browser chrome blocking I/O, so it
463
- // suspends tiemouts until after the file has been selected.
464
- $el.bind('click.uniform.ie7', function() {
465
- setTimeout(setFilename, 0);
347
+
348
+ elSize = attrOrProp($el, "size");
349
+
350
+ return !(!elSize || elSize <= 1);
351
+ }
352
+
353
+ /**
354
+ * Meaningless utility function. Used mostly for improving minification.
355
+ *
356
+ * @return {Boolean}
357
+ */
358
+ function returnFalse() {
359
+ return false;
360
+ }
361
+
362
+ /**
363
+ * noSelect plugin, very slightly modified
364
+ * http://mths.be/noselect v1.0.3
365
+ *
366
+ * @param {jQuery} $elem Element that we don't want to select
367
+ * @param {Object} options Uniform options for the element
368
+ */
369
+ function noSelect($elem, options) {
370
+ var none = 'none';
371
+ bindMany($elem, options, {
372
+ 'selectstart dragstart mousedown': returnFalse
466
373
  });
467
- }else{
468
- // All other browsers behave properly
469
- $el.bind('change.uniform', setFilename);
470
- }
471
-
472
- //handle defaults
473
- if($el.attr("disabled")){
474
- //box is checked by default, check our box
475
- divTag.addClass(options.disabledClass);
476
- }
477
-
478
- $.uniform.noSelect(filenameTag);
479
- $.uniform.noSelect(btnTag);
480
-
481
- storeElement(elem);
482
374
 
375
+ $elem.css({
376
+ MozUserSelect: none,
377
+ msUserSelect: none,
378
+ webkitUserSelect: none,
379
+ userSelect: none
380
+ });
483
381
  }
484
-
485
- $.uniform.restore = function(elem){
486
- if(elem == undefined){
487
- elem = $($.uniform.elements);
488
- }
489
-
490
- $(elem).each(function(){
491
- if($(this).is(":checkbox")){
492
- //unwrap from span and div
493
- $(this).unwrap().unwrap();
494
- }else if($(this).is("select")){
495
- //remove sibling span
496
- $(this).siblings("span").remove();
497
- //unwrap parent div
498
- $(this).unwrap();
499
- }else if($(this).is(":radio")){
500
- //unwrap from span and div
501
- $(this).unwrap().unwrap();
502
- }else if($(this).is(":file")){
503
- //remove sibling spans
504
- $(this).siblings("span").remove();
505
- //unwrap parent div
506
- $(this).unwrap();
507
- }else if($(this).is("button, :submit, :reset, a, input[type='button']")){
508
- //unwrap from span and div
509
- $(this).unwrap().unwrap();
382
+
383
+ /**
384
+ * Updates the filename tag based on the value of the real input
385
+ * element.
386
+ *
387
+ * @param {jQuery} $el Actual form element
388
+ * @param {jQuery} $filenameTag Span/div to update
389
+ * @param {Object} options Uniform options for this element
390
+ */
391
+ function setFilename($el, $filenameTag, options) {
392
+ var filename = $el.val();
393
+
394
+ if (filename === "") {
395
+ filename = options.fileDefaultHtml;
396
+ } else {
397
+ filename = filename.split(/[\/\\]+/);
398
+ filename = filename[(filename.length - 1)];
510
399
  }
511
-
512
- //unbind events
513
- $(this).unbind(".uniform");
514
-
515
- //reset inline style
516
- $(this).css("opacity", "1");
517
-
518
- //remove item from list of uniformed elements
519
- var index = $.inArray($(elem), $.uniform.elements);
520
- $.uniform.elements.splice(index, 1);
521
- });
522
- };
523
400
 
524
- function storeElement(elem){
525
- //store this element in our global array
526
- elem = $(elem).get();
527
- if(elem.length > 1){
528
- $.each(elem, function(i, val){
529
- $.uniform.elements.push(val);
401
+ $filenameTag.text(filename);
402
+ }
403
+
404
+ /**
405
+ * Function from jQuery to swap some CSS values, run a callback,
406
+ * then restore the CSS. Modified to pass JSLint and handle undefined
407
+ * values with 'use strict'.
408
+ *
409
+ * @param {jQuery} $elements Element
410
+ * @param {Object} newCss CSS values to swap out
411
+ * @param {Function} callback Function to run
412
+ */
413
+ function swap($elements, newCss, callback) {
414
+ var restore, item;
415
+
416
+ restore = [];
417
+
418
+ $elements.each(function () {
419
+ var name;
420
+
421
+ for (name in newCss) {
422
+ if (Object.prototype.hasOwnProperty.call(newCss, name)) {
423
+ restore.push({
424
+ el: this,
425
+ name: name,
426
+ old: this.style[name]
427
+ });
428
+
429
+ this.style[name] = newCss[name];
430
+ }
431
+ }
530
432
  });
531
- }else{
532
- $.uniform.elements.push(elem);
533
- }
433
+
434
+ callback();
435
+
436
+ while (restore.length) {
437
+ item = restore.pop();
438
+ item.el.style[item.name] = item.old;
439
+ }
440
+ }
441
+
442
+ /**
443
+ * The browser doesn't provide sizes of elements that are not visible.
444
+ * This will clone an element and add it to the DOM for calculations.
445
+ *
446
+ * @param {jQuery} $el
447
+ * @param {Function} callback
448
+ */
449
+ function sizingInvisible($el, callback) {
450
+ var targets;
451
+
452
+ // We wish to target ourselves and any parents as long as
453
+ // they are not visible
454
+ targets = $el.parents();
455
+ targets.push($el[0]);
456
+ targets = targets.not(':visible');
457
+ swap(targets, {
458
+ visibility: "hidden",
459
+ display: "block",
460
+ position: "absolute"
461
+ }, callback);
462
+ }
463
+
464
+ /**
465
+ * Standard way to unwrap the div/span combination from an element
466
+ *
467
+ * @param {jQuery} $el Element that we wish to preserve
468
+ * @param {Object} options Uniform options for the element
469
+ * @return {Function} This generated function will perform the given work
470
+ */
471
+ function unwrapUnwrapUnbindFunction($el, options) {
472
+ return function () {
473
+ $el.unwrap().unwrap().unbind(options.eventNamespace);
474
+ };
534
475
  }
535
-
536
- //noSelect v1.0
537
- $.uniform.noSelect = function(elem) {
538
- function f() {
539
- return false;
540
- };
541
- $(elem).each(function() {
542
- this.onselectstart = this.ondragstart = f; // Webkit & IE
543
- $(this)
544
- .mousedown(f) // Webkit & Opera
545
- .css({ MozUserSelect: 'none' }); // Firefox
546
- });
547
- };
548
-
549
- $.uniform.update = function(elem){
550
- if(elem == undefined){
551
- elem = $($.uniform.elements);
552
- }
553
- //sanitize input
554
- elem = $(elem);
555
-
556
- elem.each(function(){
557
- //do to each item in the selector
558
- //function to reset all classes
559
- var $e = $(this);
560
-
561
- if($e.is("select")){
562
- //element is a select
563
- var spanTag = $e.siblings("span");
564
- var divTag = $e.parent("div");
565
-
566
- divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);
567
-
568
- //reset current selected text
569
- spanTag.html($e.find(":selected").html());
570
-
571
- if($e.is(":disabled")){
572
- divTag.addClass(options.disabledClass);
573
- }else{
574
- divTag.removeClass(options.disabledClass);
575
- }
576
-
577
- }else if($e.is(":checkbox")){
578
- //element is a checkbox
579
- var spanTag = $e.closest("span");
580
- var divTag = $e.closest("div");
581
-
582
- divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);
583
- spanTag.removeClass(options.checkedClass);
584
-
585
- if($e.is(":checked")){
586
- spanTag.addClass(options.checkedClass);
587
- }
588
- if($e.is(":disabled")){
589
- divTag.addClass(options.disabledClass);
590
- }else{
591
- divTag.removeClass(options.disabledClass);
592
- }
593
-
594
- }else if($e.is(":radio")){
595
- //element is a radio
596
- var spanTag = $e.closest("span");
597
- var divTag = $e.closest("div");
598
-
599
- divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);
600
- spanTag.removeClass(options.checkedClass);
601
-
602
- if($e.is(":checked")){
603
- spanTag.addClass(options.checkedClass);
604
- }
605
-
606
- if($e.is(":disabled")){
607
- divTag.addClass(options.disabledClass);
608
- }else{
609
- divTag.removeClass(options.disabledClass);
610
- }
611
- }else if($e.is(":file")){
612
- var divTag = $e.parent("div");
613
- var filenameTag = $e.siblings(options.filenameClass);
614
- btnTag = $e.siblings(options.fileBtnClass);
615
-
616
- divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);
617
-
618
- filenameTag.text($e.val());
619
-
620
- if($e.is(":disabled")){
621
- divTag.addClass(options.disabledClass);
622
- }else{
623
- divTag.removeClass(options.disabledClass);
624
- }
625
- }else if($e.is(":submit") || $e.is(":reset") || $e.is("button") || $e.is("a") || elem.is("input[type=button]")){
626
- var divTag = $e.closest("div");
627
- divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);
628
-
629
- if($e.is(":disabled")){
630
- divTag.addClass(options.disabledClass);
631
- }else{
632
- divTag.removeClass(options.disabledClass);
633
- }
634
-
476
+
477
+ var allowStyling = true, // False if IE6 or other unsupported browsers
478
+ highContrastTest = false, // Was the high contrast test ran?
479
+ uniformHandlers = [ // Objects that take care of "unification"
480
+ {
481
+ // Buttons
482
+ match: function ($el) {
483
+ return $el.is("a, button, :submit, :reset, input[type='button']");
484
+ },
485
+ apply: function ($el, options) {
486
+ var $div, defaultSpanHtml, ds, getHtml, doingClickEvent;
487
+ defaultSpanHtml = options.submitDefaultHtml;
488
+
489
+ if ($el.is(":reset")) {
490
+ defaultSpanHtml = options.resetDefaultHtml;
491
+ }
492
+
493
+ if ($el.is("a, button")) {
494
+ // Use the HTML inside the tag
495
+ getHtml = function () {
496
+ return $el.html() || defaultSpanHtml;
497
+ };
498
+ } else {
499
+ // Use the value property of the element
500
+ getHtml = function () {
501
+ return htmlify(attrOrProp($el, "value")) || defaultSpanHtml;
502
+ };
503
+ }
504
+
505
+ ds = divSpan($el, options, {
506
+ divClass: options.buttonClass,
507
+ spanHtml: getHtml()
508
+ });
509
+ $div = ds.div;
510
+ bindUi($el, $div, options);
511
+ doingClickEvent = false;
512
+ bindMany($div, options, {
513
+ "click touchend": function () {
514
+ var ev, res, target, href;
515
+
516
+ if (doingClickEvent) {
517
+ return;
518
+ }
519
+
520
+ if ($el.is(':disabled')) {
521
+ return;
522
+ }
523
+
524
+ doingClickEvent = true;
525
+
526
+ if ($el[0].dispatchEvent) {
527
+ ev = document.createEvent("MouseEvents");
528
+ ev.initEvent("click", true, true);
529
+ res = $el[0].dispatchEvent(ev);
530
+
531
+ if ($el.is('a') && res) {
532
+ target = attrOrProp($el, 'target');
533
+ href = attrOrProp($el, 'href');
534
+
535
+ if (!target || target === '_self') {
536
+ document.location.href = href;
537
+ } else {
538
+ wind.open(href, target);
539
+ }
540
+ }
541
+ } else {
542
+ $el.click();
543
+ }
544
+
545
+ doingClickEvent = false;
546
+ }
547
+ });
548
+ noSelect($div, options);
549
+ return {
550
+ remove: function () {
551
+ // Move $el out
552
+ $div.after($el);
553
+
554
+ // Remove div and span
555
+ $div.remove();
556
+
557
+ // Unbind events
558
+ $el.unbind(options.eventNamespace);
559
+ return $el;
560
+ },
561
+ update: function () {
562
+ classClearStandard($div, options);
563
+ classUpdateDisabled($div, $el, options);
564
+ $el.detach();
565
+ ds.span.html(getHtml()).append($el);
566
+ }
567
+ };
568
+ }
569
+ },
570
+ {
571
+ // Checkboxes
572
+ match: function ($el) {
573
+ return $el.is(":checkbox");
574
+ },
575
+ apply: function ($el, options) {
576
+ var ds, $div, $span;
577
+ ds = divSpan($el, options, {
578
+ divClass: options.checkboxClass
579
+ });
580
+ $div = ds.div;
581
+ $span = ds.span;
582
+
583
+ // Add focus classes, toggling, active, etc.
584
+ bindUi($el, $div, options);
585
+ bindMany($el, options, {
586
+ "click touchend": function () {
587
+ classUpdateChecked($span, $el, options);
588
+ }
589
+ });
590
+ classUpdateChecked($span, $el, options);
591
+ return {
592
+ remove: unwrapUnwrapUnbindFunction($el, options),
593
+ update: function () {
594
+ classClearStandard($div, options);
595
+ $span.removeClass(options.checkedClass);
596
+ classUpdateChecked($span, $el, options);
597
+ classUpdateDisabled($div, $el, options);
598
+ }
599
+ };
600
+ }
601
+ },
602
+ {
603
+ // File selection / uploads
604
+ match: function ($el) {
605
+ return $el.is(":file");
606
+ },
607
+ apply: function ($el, options) {
608
+ var ds, $div, $filename, $button;
609
+
610
+ // The "span" is the button
611
+ ds = divSpan($el, options, {
612
+ divClass: options.fileClass,
613
+ spanClass: options.fileButtonClass,
614
+ spanHtml: options.fileButtonHtml,
615
+ spanWrap: "after"
616
+ });
617
+ $div = ds.div;
618
+ $button = ds.span;
619
+ $filename = $("<span />").html(options.fileDefaultHtml);
620
+ $filename.addClass(options.filenameClass);
621
+ $filename = divSpanWrap($el, $filename, "after");
622
+
623
+ // Set the size
624
+ if (!attrOrProp($el, "size")) {
625
+ attrOrProp($el, "size", $div.width() / 10);
626
+ }
627
+
628
+ // Actions
629
+ function filenameUpdate() {
630
+ setFilename($el, $filename, options);
631
+ }
632
+
633
+ bindUi($el, $div, options);
634
+
635
+ // Account for input saved across refreshes
636
+ filenameUpdate();
637
+
638
+ // IE7 doesn't fire onChange until blur or second fire.
639
+ if (isMsie()) {
640
+ // IE considers browser chrome blocking I/O, so it
641
+ // suspends tiemouts until after the file has
642
+ // been selected.
643
+ bindMany($el, options, {
644
+ click: function () {
645
+ $el.trigger("change");
646
+ setTimeout(filenameUpdate, 0);
647
+ }
648
+ });
649
+ } else {
650
+ // All other browsers behave properly
651
+ bindMany($el, options, {
652
+ change: filenameUpdate
653
+ });
654
+ }
655
+
656
+ noSelect($filename, options);
657
+ noSelect($button, options);
658
+ return {
659
+ remove: function () {
660
+ // Remove filename and button
661
+ $filename.remove();
662
+ $button.remove();
663
+
664
+ // Unwrap parent div, remove events
665
+ return $el.unwrap().unbind(options.eventNamespace);
666
+ },
667
+ update: function () {
668
+ classClearStandard($div, options);
669
+ setFilename($el, $filename, options);
670
+ classUpdateDisabled($div, $el, options);
671
+ }
672
+ };
673
+ }
674
+ },
675
+ {
676
+ // Input fields (text)
677
+ match: function ($el) {
678
+ if ($el.is("input")) {
679
+ var t = (" " + attrOrProp($el, "type") + " ").toLowerCase(),
680
+ allowed = " color date datetime datetime-local email month number password search tel text time url week ";
681
+ return allowed.indexOf(t) >= 0;
682
+ }
683
+
684
+ return false;
685
+ },
686
+ apply: function ($el, options) {
687
+ var elType, $wrapper;
688
+
689
+ elType = attrOrProp($el, "type");
690
+ $el.addClass(options.inputClass);
691
+ $wrapper = wrapWithWrapperClass($el, options);
692
+ bindUi($el, $el, options);
693
+
694
+ if (options.inputAddTypeAsClass) {
695
+ $el.addClass(elType);
696
+ }
697
+
698
+ return {
699
+ remove: function () {
700
+ $el.removeClass(options.inputClass);
701
+
702
+ if (options.inputAddTypeAsClass) {
703
+ $el.removeClass(elType);
704
+ }
705
+
706
+ if ($wrapper) {
707
+ $el.unwrap();
708
+ }
709
+ },
710
+ update: returnFalse
711
+ };
712
+ }
713
+ },
714
+ {
715
+ // Radio buttons
716
+ match: function ($el) {
717
+ return $el.is(":radio");
718
+ },
719
+ apply: function ($el, options) {
720
+ var ds, $div, $span;
721
+ ds = divSpan($el, options, {
722
+ divClass: options.radioClass
723
+ });
724
+ $div = ds.div;
725
+ $span = ds.span;
726
+
727
+ // Add classes for focus, handle active, checked
728
+ bindUi($el, $div, options);
729
+ bindMany($el, options, {
730
+ "click touchend": function () {
731
+ // Find all radios with the same name, then update
732
+ // them with $.uniform.update() so the right
733
+ // per-element options are used
734
+ $.uniform.update($(':radio[name="' + attrOrProp($el, "name") + '"]'));
735
+ }
736
+ });
737
+ classUpdateChecked($span, $el, options);
738
+ return {
739
+ remove: unwrapUnwrapUnbindFunction($el, options),
740
+ update: function () {
741
+ classClearStandard($div, options);
742
+ classUpdateChecked($span, $el, options);
743
+ classUpdateDisabled($div, $el, options);
744
+ }
745
+ };
746
+ }
747
+ },
748
+ {
749
+ // Select lists, but do not style multiselects here
750
+ match: function ($el) {
751
+ return !!($el.is("select") && !isMultiselect($el));
752
+ },
753
+ apply: function ($el, options) {
754
+ var ds, $div, $span, origElemWidth;
755
+
756
+ if (options.selectAutoWidth) {
757
+ sizingInvisible($el, function () {
758
+ origElemWidth = $el.width();
759
+ });
760
+ }
761
+
762
+ ds = divSpan($el, options, {
763
+ divClass: options.selectClass,
764
+ spanHtml: ($el.find(":selected:first") || $el.find("option:first")).html(),
765
+ spanWrap: "before"
766
+ });
767
+ $div = ds.div;
768
+ $span = ds.span;
769
+
770
+ if (options.selectAutoWidth) {
771
+ // Use the width of the select and adjust the
772
+ // span and div accordingly
773
+ sizingInvisible($el, function () {
774
+ // Force "display: block" - related to bug #287
775
+ swap($([$span[0], $div[0]]), {
776
+ display: "block"
777
+ }, function () {
778
+ var spanPad;
779
+ spanPad = $span.outerWidth() - $span.width();
780
+ $div.width(origElemWidth + spanPad);
781
+ $span.width(origElemWidth);
782
+ });
783
+ });
784
+ } else {
785
+ // Force the select to fill the size of the div
786
+ $div.addClass('fixedWidth');
787
+ }
788
+
789
+ // Take care of events
790
+ bindUi($el, $div, options);
791
+ bindMany($el, options, {
792
+ change: function () {
793
+ $span.html($el.find(":selected").html());
794
+ $div.removeClass(options.activeClass);
795
+ },
796
+ "click touchend": function () {
797
+ // IE7 and IE8 may not update the value right
798
+ // until after click event - issue #238
799
+ var selHtml = $el.find(":selected").html();
800
+
801
+ if ($span.html() !== selHtml) {
802
+ // Change was detected
803
+ // Fire the change event on the select tag
804
+ $el.trigger('change');
805
+ }
806
+ },
807
+ keyup: function () {
808
+ $span.html($el.find(":selected").html());
809
+ }
810
+ });
811
+ noSelect($span, options);
812
+ return {
813
+ remove: function () {
814
+ // Remove sibling span
815
+ $span.remove();
816
+
817
+ // Unwrap parent div
818
+ $el.unwrap().unbind(options.eventNamespace);
819
+ return $el;
820
+ },
821
+ update: function () {
822
+ if (options.selectAutoWidth) {
823
+ // Easier to remove and reapply formatting
824
+ $.uniform.restore($el);
825
+ $el.uniform(options);
826
+ } else {
827
+ classClearStandard($div, options);
828
+
829
+ // Reset current selected text
830
+ $el[0].selectedIndex = $el[0].selectedIndex; // Force IE to have a ":selected" option (if the field was reset for example)
831
+ $span.html($el.find(":selected").html());
832
+ classUpdateDisabled($div, $el, options);
833
+ }
834
+ }
835
+ };
836
+ }
837
+ },
838
+ {
839
+ // Select lists - multiselect lists only
840
+ match: function ($el) {
841
+ return !!($el.is("select") && isMultiselect($el));
842
+ },
843
+ apply: function ($el, options) {
844
+ var $wrapper;
845
+
846
+ $el.addClass(options.selectMultiClass);
847
+ $wrapper = wrapWithWrapperClass($el, options);
848
+ bindUi($el, $el, options);
849
+
850
+ return {
851
+ remove: function () {
852
+ $el.removeClass(options.selectMultiClass);
853
+
854
+ if ($wrapper) {
855
+ $el.unwrap();
856
+ }
857
+ },
858
+ update: returnFalse
859
+ };
860
+ }
861
+ },
862
+ {
863
+ // Textareas
864
+ match: function ($el) {
865
+ return $el.is("textarea");
866
+ },
867
+ apply: function ($el, options) {
868
+ var $wrapper;
869
+
870
+ $el.addClass(options.textareaClass);
871
+ $wrapper = wrapWithWrapperClass($el, options);
872
+ bindUi($el, $el, options);
873
+
874
+ return {
875
+ remove: function () {
876
+ $el.removeClass(options.textareaClass);
877
+
878
+ if ($wrapper) {
879
+ $el.unwrap();
880
+ }
881
+ },
882
+ update: returnFalse
883
+ };
884
+ }
885
+ }
886
+ ];
887
+
888
+ // IE6 can't be styled - can't set opacity on select
889
+ if (isMsie() && !isMsieSevenOrNewer()) {
890
+ allowStyling = false;
891
+ }
892
+
893
+ $.uniform = {
894
+ // Default options that can be overridden globally or when uniformed
895
+ // globally: $.uniform.defaults.fileButtonHtml = "Pick A File";
896
+ // on uniform: $('input').uniform({fileButtonHtml: "Pick a File"});
897
+ defaults: {
898
+ activeClass: "active",
899
+ autoHide: true,
900
+ buttonClass: "button",
901
+ checkboxClass: "checker",
902
+ checkedClass: "checked",
903
+ disabledClass: "disabled",
904
+ eventNamespace: ".uniform",
905
+ fileButtonClass: "action",
906
+ fileButtonHtml: "Choose File",
907
+ fileClass: "uploader",
908
+ fileDefaultHtml: "No file selected",
909
+ filenameClass: "filename",
910
+ focusClass: "focus",
911
+ hoverClass: "hover",
912
+ idPrefix: "uniform",
913
+ inputAddTypeAsClass: true,
914
+ inputClass: "uniform-input",
915
+ radioClass: "radio",
916
+ resetDefaultHtml: "Reset",
917
+ resetSelector: false, // We'll use our own function when you don't specify one
918
+ selectAutoWidth: true,
919
+ selectClass: "selector",
920
+ selectMultiClass: "uniform-multiselect",
921
+ submitDefaultHtml: "Submit", // Only text allowed
922
+ textareaClass: "uniform",
923
+ useID: true,
924
+ wrapperClass: null
925
+ },
926
+
927
+ // All uniformed elements - DOM objects
928
+ elements: []
929
+ };
930
+
931
+ $.fn.uniform = function (options) {
932
+ var el = this;
933
+ options = $.extend({}, $.uniform.defaults, options);
934
+
935
+ // If we are in high contrast mode, do not allow styling
936
+ if (!highContrastTest) {
937
+ highContrastTest = true;
938
+
939
+ if (highContrast()) {
940
+ allowStyling = false;
941
+ }
635
942
  }
636
-
637
- });
943
+
944
+ // Only uniform on browsers that work
945
+ if (!allowStyling) {
946
+ return this;
947
+ }
948
+
949
+ // Code for specifying a reset button
950
+ if (options.resetSelector) {
951
+ $(options.resetSelector).mouseup(function () {
952
+ wind.setTimeout(function () {
953
+ $.uniform.update(el);
954
+ }, 10);
955
+ });
956
+ }
957
+
958
+ return this.each(function () {
959
+ var $el = $(this), i, handler, callbacks;
960
+
961
+ // Avoid uniforming elements already uniformed - just update
962
+ if ($el.data("uniformed")) {
963
+ $.uniform.update($el);
964
+ return;
965
+ }
966
+
967
+ // See if we have any handler for this type of element
968
+ for (i = 0; i < uniformHandlers.length; i = i + 1) {
969
+ handler = uniformHandlers[i];
970
+
971
+ if (handler.match($el, options)) {
972
+ callbacks = handler.apply($el, options);
973
+ $el.data("uniformed", callbacks);
974
+
975
+ // Store element in our global array
976
+ $.uniform.elements.push($el.get(0));
977
+ return;
978
+ }
979
+ }
980
+
981
+ // Could not style this element
982
+ });
638
983
  };
639
984
 
640
- return this.each(function() {
641
- if($.support.selectOpacity){
642
- var elem = $(this);
985
+ $.uniform.restore = $.fn.uniform.restore = function (elem) {
986
+ if (elem === undef) {
987
+ elem = $.uniform.elements;
988
+ }
989
+
990
+ $(elem).each(function () {
991
+ var $el = $(this), index, elementData;
992
+ elementData = $el.data("uniformed");
993
+
994
+ // Skip elements that are not uniformed
995
+ if (!elementData) {
996
+ return;
997
+ }
643
998
 
644
- if(elem.is("select")){
645
- //element is a select
646
- if(elem.attr("multiple") != true){
647
- //element is not a multi-select
648
- if(elem.attr("size") == undefined || elem.attr("size") <= 1){
649
- doSelect(elem);
999
+ // Unbind events, remove additional markup that was added
1000
+ elementData.remove();
1001
+
1002
+ // Remove item from list of uniformed elements
1003
+ index = $.inArray(this, $.uniform.elements);
1004
+
1005
+ if (index >= 0) {
1006
+ $.uniform.elements.splice(index, 1);
650
1007
  }
651
- }
652
- }else if(elem.is(":checkbox")){
653
- //element is a checkbox
654
- doCheckbox(elem);
655
- }else if(elem.is(":radio")){
656
- //element is a radio
657
- doRadio(elem);
658
- }else if(elem.is(":file")){
659
- //element is a file upload
660
- doFile(elem);
661
- }else if(elem.is(":text, :password, input[type='email']")){
662
- doInput(elem);
663
- }else if(elem.is("textarea")){
664
- doTextarea(elem);
665
- }else if(elem.is("a") || elem.is(":submit") || elem.is(":reset") || elem.is("button") || elem.is("input[type=button]")){
666
- doButton(elem);
1008
+
1009
+ $el.removeData("uniformed");
1010
+ });
1011
+ };
1012
+
1013
+ $.uniform.update = $.fn.uniform.update = function (elem) {
1014
+ if (elem === undef) {
1015
+ elem = $.uniform.elements;
667
1016
  }
668
-
669
- }
670
- });
671
- };
672
- })(jQuery);
1017
+
1018
+ $(elem).each(function () {
1019
+ var $el = $(this), elementData;
1020
+ elementData = $el.data("uniformed");
1021
+
1022
+ // Skip elements that are not uniformed
1023
+ if (!elementData) {
1024
+ return;
1025
+ }
1026
+
1027
+ elementData.update($el, elementData.options);
1028
+ });
1029
+ };
1030
+ }(this, jQuery));