uniformjs-rails 1.5.0.2 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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));