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