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