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