/packages/jQuery.1.5.1/Content/Scripts/jquery-1.5.1.js
JavaScript | 2485 lines | 1593 code | 476 blank | 416 comment | 491 complexity | 0a18474998577c7513955b91410979fc MD5 | raw file
1/*! 2* Note: While Microsoft is not the author of this file, Microsoft is 3* offering you a license subject to the terms of the Microsoft Software 4* License Terms for Microsoft ASP.NET Model View Controller 3. 5* Microsoft reserves all other rights. The notices below are provided 6* for informational purposes only and are not the license terms under 7* which Microsoft distributed this file. 8* 9* jQuery JavaScript Library v1.5.1 10* http://jquery.com/ 11* Copyright 2011, John Resig 12* 13* Includes Sizzle.js 14* http://sizzlejs.com/ 15* Copyright 2011, The Dojo Foundation 16* 17* Date: Thu Nov 11 19:04:53 2010 -0500 18*/ 19(function( window, undefined ) { 20 21// Use the correct document accordingly with window argument (sandbox) 22var document = window.document; 23var jQuery = (function() { 24 25// Define a local copy of jQuery 26var jQuery = function( selector, context ) { 27 // The jQuery object is actually just the init constructor 'enhanced' 28 return new jQuery.fn.init( selector, context, rootjQuery ); 29 }, 30 31 // Map over jQuery in case of overwrite 32 _jQuery = window.jQuery, 33 34 // Map over the $ in case of overwrite 35 _$ = window.$, 36 37 // A central reference to the root jQuery(document) 38 rootjQuery, 39 40 // A simple way to check for HTML strings or ID strings 41 // (both of which we optimize for) 42 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, 43 44 // Check if a string has a non-whitespace character in it 45 rnotwhite = /\S/, 46 47 // Used for trimming whitespace 48 trimLeft = /^\s+/, 49 trimRight = /\s+$/, 50 51 // Check for digits 52 rdigit = /\d/, 53 54 // Match a standalone tag 55 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, 56 57 // JSON RegExp 58 rvalidchars = /^[\],:{}\s]*$/, 59 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, 60 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, 61 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, 62 63 // Useragent RegExp 64 rwebkit = /(webkit)[ \/]([\w.]+)/, 65 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, 66 rmsie = /(msie) ([\w.]+)/, 67 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, 68 69 // Keep a UserAgent string for use with jQuery.browser 70 userAgent = navigator.userAgent, 71 72 // For matching the engine and version of the browser 73 browserMatch, 74 75 // Has the ready events already been bound? 76 readyBound = false, 77 78 // The deferred used on DOM ready 79 readyList, 80 81 // Promise methods 82 promiseMethods = "then done fail isResolved isRejected promise".split( " " ), 83 84 // The ready event handler 85 DOMContentLoaded, 86 87 // Save a reference to some core methods 88 toString = Object.prototype.toString, 89 hasOwn = Object.prototype.hasOwnProperty, 90 push = Array.prototype.push, 91 slice = Array.prototype.slice, 92 trim = String.prototype.trim, 93 indexOf = Array.prototype.indexOf, 94 95 // [[Class]] -> type pairs 96 class2type = {}; 97 98jQuery.fn = jQuery.prototype = { 99 constructor: jQuery, 100 init: function( selector, context, rootjQuery ) { 101 var match, elem, ret, doc; 102 103 // Handle $(""), $(null), or $(undefined) 104 if ( !selector ) { 105 return this; 106 } 107 108 // Handle $(DOMElement) 109 if ( selector.nodeType ) { 110 this.context = this[0] = selector; 111 this.length = 1; 112 return this; 113 } 114 115 // The body element only exists once, optimize finding it 116 if ( selector === "body" && !context && document.body ) { 117 this.context = document; 118 this[0] = document.body; 119 this.selector = "body"; 120 this.length = 1; 121 return this; 122 } 123 124 // Handle HTML strings 125 if ( typeof selector === "string" ) { 126 // Are we dealing with HTML string or an ID? 127 match = quickExpr.exec( selector ); 128 129 // Verify a match, and that no context was specified for #id 130 if ( match && (match[1] || !context) ) { 131 132 // HANDLE: $(html) -> $(array) 133 if ( match[1] ) { 134 context = context instanceof jQuery ? context[0] : context; 135 doc = (context ? context.ownerDocument || context : document); 136 137 // If a single string is passed in and it's a single tag 138 // just do a createElement and skip the rest 139 ret = rsingleTag.exec( selector ); 140 141 if ( ret ) { 142 if ( jQuery.isPlainObject( context ) ) { 143 selector = [ document.createElement( ret[1] ) ]; 144 jQuery.fn.attr.call( selector, context, true ); 145 146 } else { 147 selector = [ doc.createElement( ret[1] ) ]; 148 } 149 150 } else { 151 ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); 152 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; 153 } 154 155 return jQuery.merge( this, selector ); 156 157 // HANDLE: $("#id") 158 } else { 159 elem = document.getElementById( match[2] ); 160 161 // Check parentNode to catch when Blackberry 4.6 returns 162 // nodes that are no longer in the document #6963 163 if ( elem && elem.parentNode ) { 164 // Handle the case where IE and Opera return items 165 // by name instead of ID 166 if ( elem.id !== match[2] ) { 167 return rootjQuery.find( selector ); 168 } 169 170 // Otherwise, we inject the element directly into the jQuery object 171 this.length = 1; 172 this[0] = elem; 173 } 174 175 this.context = document; 176 this.selector = selector; 177 return this; 178 } 179 180 // HANDLE: $(expr, $(...)) 181 } else if ( !context || context.jquery ) { 182 return (context || rootjQuery).find( selector ); 183 184 // HANDLE: $(expr, context) 185 // (which is just equivalent to: $(context).find(expr) 186 } else { 187 return this.constructor( context ).find( selector ); 188 } 189 190 // HANDLE: $(function) 191 // Shortcut for document ready 192 } else if ( jQuery.isFunction( selector ) ) { 193 return rootjQuery.ready( selector ); 194 } 195 196 if (selector.selector !== undefined) { 197 this.selector = selector.selector; 198 this.context = selector.context; 199 } 200 201 return jQuery.makeArray( selector, this ); 202 }, 203 204 // Start with an empty selector 205 selector: "", 206 207 // The current version of jQuery being used 208 jquery: "1.5.1", 209 210 // The default length of a jQuery object is 0 211 length: 0, 212 213 // The number of elements contained in the matched element set 214 size: function() { 215 return this.length; 216 }, 217 218 toArray: function() { 219 return slice.call( this, 0 ); 220 }, 221 222 // Get the Nth element in the matched element set OR 223 // Get the whole matched element set as a clean array 224 get: function( num ) { 225 return num == null ? 226 227 // Return a 'clean' array 228 this.toArray() : 229 230 // Return just the object 231 ( num < 0 ? this[ this.length + num ] : this[ num ] ); 232 }, 233 234 // Take an array of elements and push it onto the stack 235 // (returning the new matched element set) 236 pushStack: function( elems, name, selector ) { 237 // Build a new jQuery matched element set 238 var ret = this.constructor(); 239 240 if ( jQuery.isArray( elems ) ) { 241 push.apply( ret, elems ); 242 243 } else { 244 jQuery.merge( ret, elems ); 245 } 246 247 // Add the old object onto the stack (as a reference) 248 ret.prevObject = this; 249 250 ret.context = this.context; 251 252 if ( name === "find" ) { 253 ret.selector = this.selector + (this.selector ? " " : "") + selector; 254 } else if ( name ) { 255 ret.selector = this.selector + "." + name + "(" + selector + ")"; 256 } 257 258 // Return the newly-formed element set 259 return ret; 260 }, 261 262 // Execute a callback for every element in the matched set. 263 // (You can seed the arguments with an array of args, but this is 264 // only used internally.) 265 each: function( callback, args ) { 266 return jQuery.each( this, callback, args ); 267 }, 268 269 ready: function( fn ) { 270 // Attach the listeners 271 jQuery.bindReady(); 272 273 // Add the callback 274 readyList.done( fn ); 275 276 return this; 277 }, 278 279 eq: function( i ) { 280 return i === -1 ? 281 this.slice( i ) : 282 this.slice( i, +i + 1 ); 283 }, 284 285 first: function() { 286 return this.eq( 0 ); 287 }, 288 289 last: function() { 290 return this.eq( -1 ); 291 }, 292 293 slice: function() { 294 return this.pushStack( slice.apply( this, arguments ), 295 "slice", slice.call(arguments).join(",") ); 296 }, 297 298 map: function( callback ) { 299 return this.pushStack( jQuery.map(this, function( elem, i ) { 300 return callback.call( elem, i, elem ); 301 })); 302 }, 303 304 end: function() { 305 return this.prevObject || this.constructor(null); 306 }, 307 308 // For internal use only. 309 // Behaves like an Array's method, not like a jQuery method. 310 push: push, 311 sort: [].sort, 312 splice: [].splice 313}; 314 315// Give the init function the jQuery prototype for later instantiation 316jQuery.fn.init.prototype = jQuery.fn; 317 318jQuery.extend = jQuery.fn.extend = function() { 319 var options, name, src, copy, copyIsArray, clone, 320 target = arguments[0] || {}, 321 i = 1, 322 length = arguments.length, 323 deep = false; 324 325 // Handle a deep copy situation 326 if ( typeof target === "boolean" ) { 327 deep = target; 328 target = arguments[1] || {}; 329 // skip the boolean and the target 330 i = 2; 331 } 332 333 // Handle case when target is a string or something (possible in deep copy) 334 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 335 target = {}; 336 } 337 338 // extend jQuery itself if only one argument is passed 339 if ( length === i ) { 340 target = this; 341 --i; 342 } 343 344 for ( ; i < length; i++ ) { 345 // Only deal with non-null/undefined values 346 if ( (options = arguments[ i ]) != null ) { 347 // Extend the base object 348 for ( name in options ) { 349 src = target[ name ]; 350 copy = options[ name ]; 351 352 // Prevent never-ending loop 353 if ( target === copy ) { 354 continue; 355 } 356 357 // Recurse if we're merging plain objects or arrays 358 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 359 if ( copyIsArray ) { 360 copyIsArray = false; 361 clone = src && jQuery.isArray(src) ? src : []; 362 363 } else { 364 clone = src && jQuery.isPlainObject(src) ? src : {}; 365 } 366 367 // Never move original objects, clone them 368 target[ name ] = jQuery.extend( deep, clone, copy ); 369 370 // Don't bring in undefined values 371 } else if ( copy !== undefined ) { 372 target[ name ] = copy; 373 } 374 } 375 } 376 } 377 378 // Return the modified object 379 return target; 380}; 381 382jQuery.extend({ 383 noConflict: function( deep ) { 384 window.$ = _$; 385 386 if ( deep ) { 387 window.jQuery = _jQuery; 388 } 389 390 return jQuery; 391 }, 392 393 // Is the DOM ready to be used? Set to true once it occurs. 394 isReady: false, 395 396 // A counter to track how many items to wait for before 397 // the ready event fires. See #6781 398 readyWait: 1, 399 400 // Handle when the DOM is ready 401 ready: function( wait ) { 402 // A third-party is pushing the ready event forwards 403 if ( wait === true ) { 404 jQuery.readyWait--; 405 } 406 407 // Make sure that the DOM is not already loaded 408 if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { 409 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 410 if ( !document.body ) { 411 return setTimeout( jQuery.ready, 1 ); 412 } 413 414 // Remember that the DOM is ready 415 jQuery.isReady = true; 416 417 // If a normal DOM Ready event fired, decrement, and wait if need be 418 if ( wait !== true && --jQuery.readyWait > 0 ) { 419 return; 420 } 421 422 // If there are functions bound, to execute 423 readyList.resolveWith( document, [ jQuery ] ); 424 425 // Trigger any bound ready events 426 if ( jQuery.fn.trigger ) { 427 jQuery( document ).trigger( "ready" ).unbind( "ready" ); 428 } 429 } 430 }, 431 432 bindReady: function() { 433 if ( readyBound ) { 434 return; 435 } 436 437 readyBound = true; 438 439 // Catch cases where $(document).ready() is called after the 440 // browser event has already occurred. 441 if ( document.readyState === "complete" ) { 442 // Handle it asynchronously to allow scripts the opportunity to delay ready 443 return setTimeout( jQuery.ready, 1 ); 444 } 445 446 // Mozilla, Opera and webkit nightlies currently support this event 447 if ( document.addEventListener ) { 448 // Use the handy event callback 449 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 450 451 // A fallback to window.onload, that will always work 452 window.addEventListener( "load", jQuery.ready, false ); 453 454 // If IE event model is used 455 } else if ( document.attachEvent ) { 456 // ensure firing before onload, 457 // maybe late but safe also for iframes 458 document.attachEvent("onreadystatechange", DOMContentLoaded); 459 460 // A fallback to window.onload, that will always work 461 window.attachEvent( "onload", jQuery.ready ); 462 463 // If IE and not a frame 464 // continually check to see if the document is ready 465 var toplevel = false; 466 467 try { 468 toplevel = window.frameElement == null; 469 } catch(e) {} 470 471 if ( document.documentElement.doScroll && toplevel ) { 472 doScrollCheck(); 473 } 474 } 475 }, 476 477 // See test/unit/core.js for details concerning isFunction. 478 // Since version 1.3, DOM methods and functions like alert 479 // aren't supported. They return false on IE (#2968). 480 isFunction: function( obj ) { 481 return jQuery.type(obj) === "function"; 482 }, 483 484 isArray: Array.isArray || function( obj ) { 485 return jQuery.type(obj) === "array"; 486 }, 487 488 // A crude way of determining if an object is a window 489 isWindow: function( obj ) { 490 return obj && typeof obj === "object" && "setInterval" in obj; 491 }, 492 493 isNaN: function( obj ) { 494 return obj == null || !rdigit.test( obj ) || isNaN( obj ); 495 }, 496 497 type: function( obj ) { 498 return obj == null ? 499 String( obj ) : 500 class2type[ toString.call(obj) ] || "object"; 501 }, 502 503 isPlainObject: function( obj ) { 504 // Must be an Object. 505 // Because of IE, we also have to check the presence of the constructor property. 506 // Make sure that DOM nodes and window objects don't pass through, as well 507 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 508 return false; 509 } 510 511 // Not own constructor property must be Object 512 if ( obj.constructor && 513 !hasOwn.call(obj, "constructor") && 514 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { 515 return false; 516 } 517 518 // Own properties are enumerated firstly, so to speed up, 519 // if last one is own, then all properties are own. 520 521 var key; 522 for ( key in obj ) {} 523 524 return key === undefined || hasOwn.call( obj, key ); 525 }, 526 527 isEmptyObject: function( obj ) { 528 for ( var name in obj ) { 529 return false; 530 } 531 return true; 532 }, 533 534 error: function( msg ) { 535 throw msg; 536 }, 537 538 parseJSON: function( data ) { 539 if ( typeof data !== "string" || !data ) { 540 return null; 541 } 542 543 // Make sure leading/trailing whitespace is removed (IE can't handle it) 544 data = jQuery.trim( data ); 545 546 // Make sure the incoming data is actual JSON 547 // Logic borrowed from http://json.org/json2.js 548 if ( rvalidchars.test(data.replace(rvalidescape, "@") 549 .replace(rvalidtokens, "]") 550 .replace(rvalidbraces, "")) ) { 551 552 // Try to use the native JSON parser first 553 return window.JSON && window.JSON.parse ? 554 window.JSON.parse( data ) : 555 (new Function("return " + data))(); 556 557 } else { 558 jQuery.error( "Invalid JSON: " + data ); 559 } 560 }, 561 562 // Cross-browser xml parsing 563 // (xml & tmp used internally) 564 parseXML: function( data , xml , tmp ) { 565 566 if ( window.DOMParser ) { // Standard 567 tmp = new DOMParser(); 568 xml = tmp.parseFromString( data , "text/xml" ); 569 } else { // IE 570 xml = new ActiveXObject( "Microsoft.XMLDOM" ); 571 xml.async = "false"; 572 xml.loadXML( data ); 573 } 574 575 tmp = xml.documentElement; 576 577 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { 578 jQuery.error( "Invalid XML: " + data ); 579 } 580 581 return xml; 582 }, 583 584 noop: function() {}, 585 586 // Evalulates a script in a global context 587 globalEval: function( data ) { 588 if ( data && rnotwhite.test(data) ) { 589 // Inspired by code by Andrea Giammarchi 590 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 591 var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement, 592 script = document.createElement( "script" ); 593 594 if ( jQuery.support.scriptEval() ) { 595 script.appendChild( document.createTextNode( data ) ); 596 } else { 597 script.text = data; 598 } 599 600 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 601 // This arises when a base node is used (#2709). 602 head.insertBefore( script, head.firstChild ); 603 head.removeChild( script ); 604 } 605 }, 606 607 nodeName: function( elem, name ) { 608 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 609 }, 610 611 // args is for internal usage only 612 each: function( object, callback, args ) { 613 var name, i = 0, 614 length = object.length, 615 isObj = length === undefined || jQuery.isFunction(object); 616 617 if ( args ) { 618 if ( isObj ) { 619 for ( name in object ) { 620 if ( callback.apply( object[ name ], args ) === false ) { 621 break; 622 } 623 } 624 } else { 625 for ( ; i < length; ) { 626 if ( callback.apply( object[ i++ ], args ) === false ) { 627 break; 628 } 629 } 630 } 631 632 // A special, fast, case for the most common use of each 633 } else { 634 if ( isObj ) { 635 for ( name in object ) { 636 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 637 break; 638 } 639 } 640 } else { 641 for ( var value = object[0]; 642 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} 643 } 644 } 645 646 return object; 647 }, 648 649 // Use native String.trim function wherever possible 650 trim: trim ? 651 function( text ) { 652 return text == null ? 653 "" : 654 trim.call( text ); 655 } : 656 657 // Otherwise use our own trimming functionality 658 function( text ) { 659 return text == null ? 660 "" : 661 text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); 662 }, 663 664 // results is for internal usage only 665 makeArray: function( array, results ) { 666 var ret = results || []; 667 668 if ( array != null ) { 669 // The window, strings (and functions) also have 'length' 670 // The extra typeof function check is to prevent crashes 671 // in Safari 2 (See: #3039) 672 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 673 var type = jQuery.type(array); 674 675 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { 676 push.call( ret, array ); 677 } else { 678 jQuery.merge( ret, array ); 679 } 680 } 681 682 return ret; 683 }, 684 685 inArray: function( elem, array ) { 686 if ( array.indexOf ) { 687 return array.indexOf( elem ); 688 } 689 690 for ( var i = 0, length = array.length; i < length; i++ ) { 691 if ( array[ i ] === elem ) { 692 return i; 693 } 694 } 695 696 return -1; 697 }, 698 699 merge: function( first, second ) { 700 var i = first.length, 701 j = 0; 702 703 if ( typeof second.length === "number" ) { 704 for ( var l = second.length; j < l; j++ ) { 705 first[ i++ ] = second[ j ]; 706 } 707 708 } else { 709 while ( second[j] !== undefined ) { 710 first[ i++ ] = second[ j++ ]; 711 } 712 } 713 714 first.length = i; 715 716 return first; 717 }, 718 719 grep: function( elems, callback, inv ) { 720 var ret = [], retVal; 721 inv = !!inv; 722 723 // Go through the array, only saving the items 724 // that pass the validator function 725 for ( var i = 0, length = elems.length; i < length; i++ ) { 726 retVal = !!callback( elems[ i ], i ); 727 if ( inv !== retVal ) { 728 ret.push( elems[ i ] ); 729 } 730 } 731 732 return ret; 733 }, 734 735 // arg is for internal usage only 736 map: function( elems, callback, arg ) { 737 var ret = [], value; 738 739 // Go through the array, translating each of the items to their 740 // new value (or values). 741 for ( var i = 0, length = elems.length; i < length; i++ ) { 742 value = callback( elems[ i ], i, arg ); 743 744 if ( value != null ) { 745 ret[ ret.length ] = value; 746 } 747 } 748 749 // Flatten any nested arrays 750 return ret.concat.apply( [], ret ); 751 }, 752 753 // A global GUID counter for objects 754 guid: 1, 755 756 proxy: function( fn, proxy, thisObject ) { 757 if ( arguments.length === 2 ) { 758 if ( typeof proxy === "string" ) { 759 thisObject = fn; 760 fn = thisObject[ proxy ]; 761 proxy = undefined; 762 763 } else if ( proxy && !jQuery.isFunction( proxy ) ) { 764 thisObject = proxy; 765 proxy = undefined; 766 } 767 } 768 769 if ( !proxy && fn ) { 770 proxy = function() { 771 return fn.apply( thisObject || this, arguments ); 772 }; 773 } 774 775 // Set the guid of unique handler to the same of original handler, so it can be removed 776 if ( fn ) { 777 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 778 } 779 780 // So proxy can be declared as an argument 781 return proxy; 782 }, 783 784 // Mutifunctional method to get and set values to a collection 785 // The value/s can be optionally by executed if its a function 786 access: function( elems, key, value, exec, fn, pass ) { 787 var length = elems.length; 788 789 // Setting many attributes 790 if ( typeof key === "object" ) { 791 for ( var k in key ) { 792 jQuery.access( elems, k, key[k], exec, fn, value ); 793 } 794 return elems; 795 } 796 797 // Setting one attribute 798 if ( value !== undefined ) { 799 // Optionally, function values get executed if exec is true 800 exec = !pass && exec && jQuery.isFunction(value); 801 802 for ( var i = 0; i < length; i++ ) { 803 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 804 } 805 806 return elems; 807 } 808 809 // Getting an attribute 810 return length ? fn( elems[0], key ) : undefined; 811 }, 812 813 now: function() { 814 return (new Date()).getTime(); 815 }, 816 817 // Create a simple deferred (one callbacks list) 818 _Deferred: function() { 819 var // callbacks list 820 callbacks = [], 821 // stored [ context , args ] 822 fired, 823 // to avoid firing when already doing so 824 firing, 825 // flag to know if the deferred has been cancelled 826 cancelled, 827 // the deferred itself 828 deferred = { 829 830 // done( f1, f2, ...) 831 done: function() { 832 if ( !cancelled ) { 833 var args = arguments, 834 i, 835 length, 836 elem, 837 type, 838 _fired; 839 if ( fired ) { 840 _fired = fired; 841 fired = 0; 842 } 843 for ( i = 0, length = args.length; i < length; i++ ) { 844 elem = args[ i ]; 845 type = jQuery.type( elem ); 846 if ( type === "array" ) { 847 deferred.done.apply( deferred, elem ); 848 } else if ( type === "function" ) { 849 callbacks.push( elem ); 850 } 851 } 852 if ( _fired ) { 853 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); 854 } 855 } 856 return this; 857 }, 858 859 // resolve with given context and args 860 resolveWith: function( context, args ) { 861 if ( !cancelled && !fired && !firing ) { 862 firing = 1; 863 try { 864 while( callbacks[ 0 ] ) { 865 callbacks.shift().apply( context, args ); 866 } 867 } 868 // We have to add a catch block for 869 // IE prior to 8 or else the finally 870 // block will never get executed 871 catch (e) { 872 throw e; 873 } 874 finally { 875 fired = [ context, args ]; 876 firing = 0; 877 } 878 } 879 return this; 880 }, 881 882 // resolve with this as context and given arguments 883 resolve: function() { 884 deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments ); 885 return this; 886 }, 887 888 // Has this deferred been resolved? 889 isResolved: function() { 890 return !!( firing || fired ); 891 }, 892 893 // Cancel 894 cancel: function() { 895 cancelled = 1; 896 callbacks = []; 897 return this; 898 } 899 }; 900 901 return deferred; 902 }, 903 904 // Full fledged deferred (two callbacks list) 905 Deferred: function( func ) { 906 var deferred = jQuery._Deferred(), 907 failDeferred = jQuery._Deferred(), 908 promise; 909 // Add errorDeferred methods, then and promise 910 jQuery.extend( deferred, { 911 then: function( doneCallbacks, failCallbacks ) { 912 deferred.done( doneCallbacks ).fail( failCallbacks ); 913 return this; 914 }, 915 fail: failDeferred.done, 916 rejectWith: failDeferred.resolveWith, 917 reject: failDeferred.resolve, 918 isRejected: failDeferred.isResolved, 919 // Get a promise for this deferred 920 // If obj is provided, the promise aspect is added to the object 921 promise: function( obj ) { 922 if ( obj == null ) { 923 if ( promise ) { 924 return promise; 925 } 926 promise = obj = {}; 927 } 928 var i = promiseMethods.length; 929 while( i-- ) { 930 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; 931 } 932 return obj; 933 } 934 } ); 935 // Make sure only one callback list will be used 936 deferred.done( failDeferred.cancel ).fail( deferred.cancel ); 937 // Unexpose cancel 938 delete deferred.cancel; 939 // Call given func if any 940 if ( func ) { 941 func.call( deferred, deferred ); 942 } 943 return deferred; 944 }, 945 946 // Deferred helper 947 when: function( object ) { 948 var lastIndex = arguments.length, 949 deferred = lastIndex <= 1 && object && jQuery.isFunction( object.promise ) ? 950 object : 951 jQuery.Deferred(), 952 promise = deferred.promise(); 953 954 if ( lastIndex > 1 ) { 955 var array = slice.call( arguments, 0 ), 956 count = lastIndex, 957 iCallback = function( index ) { 958 return function( value ) { 959 array[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; 960 if ( !( --count ) ) { 961 deferred.resolveWith( promise, array ); 962 } 963 }; 964 }; 965 while( ( lastIndex-- ) ) { 966 object = array[ lastIndex ]; 967 if ( object && jQuery.isFunction( object.promise ) ) { 968 object.promise().then( iCallback(lastIndex), deferred.reject ); 969 } else { 970 --count; 971 } 972 } 973 if ( !count ) { 974 deferred.resolveWith( promise, array ); 975 } 976 } else if ( deferred !== object ) { 977 deferred.resolve( object ); 978 } 979 return promise; 980 }, 981 982 // Use of jQuery.browser is frowned upon. 983 // More details: http://docs.jquery.com/Utilities/jQuery.browser 984 uaMatch: function( ua ) { 985 ua = ua.toLowerCase(); 986 987 var match = rwebkit.exec( ua ) || 988 ropera.exec( ua ) || 989 rmsie.exec( ua ) || 990 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || 991 []; 992 993 return { browser: match[1] || "", version: match[2] || "0" }; 994 }, 995 996 sub: function() { 997 function jQuerySubclass( selector, context ) { 998 return new jQuerySubclass.fn.init( selector, context ); 999 } 1000 jQuery.extend( true, jQuerySubclass, this ); 1001 jQuerySubclass.superclass = this; 1002 jQuerySubclass.fn = jQuerySubclass.prototype = this(); 1003 jQuerySubclass.fn.constructor = jQuerySubclass; 1004 jQuerySubclass.subclass = this.subclass; 1005 jQuerySubclass.fn.init = function init( selector, context ) { 1006 if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) { 1007 context = jQuerySubclass(context); 1008 } 1009 1010 return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass ); 1011 }; 1012 jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; 1013 var rootjQuerySubclass = jQuerySubclass(document); 1014 return jQuerySubclass; 1015 }, 1016 1017 browser: {} 1018}); 1019 1020// Create readyList deferred 1021readyList = jQuery._Deferred(); 1022 1023// Populate the class2type map 1024jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { 1025 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 1026}); 1027 1028browserMatch = jQuery.uaMatch( userAgent ); 1029if ( browserMatch.browser ) { 1030 jQuery.browser[ browserMatch.browser ] = true; 1031 jQuery.browser.version = browserMatch.version; 1032} 1033 1034// Deprecated, use jQuery.browser.webkit instead 1035if ( jQuery.browser.webkit ) { 1036 jQuery.browser.safari = true; 1037} 1038 1039if ( indexOf ) { 1040 jQuery.inArray = function( elem, array ) { 1041 return indexOf.call( array, elem ); 1042 }; 1043} 1044 1045// IE doesn't match non-breaking spaces with \s 1046if ( rnotwhite.test( "\xA0" ) ) { 1047 trimLeft = /^[\s\xA0]+/; 1048 trimRight = /[\s\xA0]+$/; 1049} 1050 1051// All jQuery objects should point back to these 1052rootjQuery = jQuery(document); 1053 1054// Cleanup functions for the document ready method 1055if ( document.addEventListener ) { 1056 DOMContentLoaded = function() { 1057 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 1058 jQuery.ready(); 1059 }; 1060 1061} else if ( document.attachEvent ) { 1062 DOMContentLoaded = function() { 1063 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 1064 if ( document.readyState === "complete" ) { 1065 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 1066 jQuery.ready(); 1067 } 1068 }; 1069} 1070 1071// The DOM ready check for Internet Explorer 1072function doScrollCheck() { 1073 if ( jQuery.isReady ) { 1074 return; 1075 } 1076 1077 try { 1078 // If IE is used, use the trick by Diego Perini 1079 // http://javascript.nwbox.com/IEContentLoaded/ 1080 document.documentElement.doScroll("left"); 1081 } catch(e) { 1082 setTimeout( doScrollCheck, 1 ); 1083 return; 1084 } 1085 1086 // and execute any waiting functions 1087 jQuery.ready(); 1088} 1089 1090// Expose jQuery to the global object 1091return jQuery; 1092 1093})(); 1094 1095 1096(function() { 1097 1098 jQuery.support = {}; 1099 1100 var div = document.createElement("div"); 1101 1102 div.style.display = "none"; 1103 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; 1104 1105 var all = div.getElementsByTagName("*"), 1106 a = div.getElementsByTagName("a")[0], 1107 select = document.createElement("select"), 1108 opt = select.appendChild( document.createElement("option") ), 1109 input = div.getElementsByTagName("input")[0]; 1110 1111 // Can't get basic test support 1112 if ( !all || !all.length || !a ) { 1113 return; 1114 } 1115 1116 jQuery.support = { 1117 // IE strips leading whitespace when .innerHTML is used 1118 leadingWhitespace: div.firstChild.nodeType === 3, 1119 1120 // Make sure that tbody elements aren't automatically inserted 1121 // IE will insert them into empty tables 1122 tbody: !div.getElementsByTagName("tbody").length, 1123 1124 // Make sure that link elements get serialized correctly by innerHTML 1125 // This requires a wrapper element in IE 1126 htmlSerialize: !!div.getElementsByTagName("link").length, 1127 1128 // Get the style information from getAttribute 1129 // (IE uses .cssText insted) 1130 style: /red/.test( a.getAttribute("style") ), 1131 1132 // Make sure that URLs aren't manipulated 1133 // (IE normalizes it by default) 1134 hrefNormalized: a.getAttribute("href") === "/a", 1135 1136 // Make sure that element opacity exists 1137 // (IE uses filter instead) 1138 // Use a regex to work around a WebKit issue. See #5145 1139 opacity: /^0.55$/.test( a.style.opacity ), 1140 1141 // Verify style float existence 1142 // (IE uses styleFloat instead of cssFloat) 1143 cssFloat: !!a.style.cssFloat, 1144 1145 // Make sure that if no value is specified for a checkbox 1146 // that it defaults to "on". 1147 // (WebKit defaults to "" instead) 1148 checkOn: input.value === "on", 1149 1150 // Make sure that a selected-by-default option has a working selected property. 1151 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 1152 optSelected: opt.selected, 1153 1154 // Will be defined later 1155 deleteExpando: true, 1156 optDisabled: false, 1157 checkClone: false, 1158 noCloneEvent: true, 1159 noCloneChecked: true, 1160 boxModel: null, 1161 inlineBlockNeedsLayout: false, 1162 shrinkWrapBlocks: false, 1163 reliableHiddenOffsets: true 1164 }; 1165 1166 input.checked = true; 1167 jQuery.support.noCloneChecked = input.cloneNode( true ).checked; 1168 1169 // Make sure that the options inside disabled selects aren't marked as disabled 1170 // (WebKit marks them as diabled) 1171 select.disabled = true; 1172 jQuery.support.optDisabled = !opt.disabled; 1173 1174 var _scriptEval = null; 1175 jQuery.support.scriptEval = function() { 1176 if ( _scriptEval === null ) { 1177 var root = document.documentElement, 1178 script = document.createElement("script"), 1179 id = "script" + jQuery.now(); 1180 1181 try { 1182 script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); 1183 } catch(e) {} 1184 1185 root.insertBefore( script, root.firstChild ); 1186 1187 // Make sure that the execution of code works by injecting a script 1188 // tag with appendChild/createTextNode 1189 // (IE doesn't support this, fails, and uses .text instead) 1190 if ( window[ id ] ) { 1191 _scriptEval = true; 1192 delete window[ id ]; 1193 } else { 1194 _scriptEval = false; 1195 } 1196 1197 root.removeChild( script ); 1198 // release memory in IE 1199 root = script = id = null; 1200 } 1201 1202 return _scriptEval; 1203 }; 1204 1205 // Test to see if it's possible to delete an expando from an element 1206 // Fails in Internet Explorer 1207 try { 1208 delete div.test; 1209 1210 } catch(e) { 1211 jQuery.support.deleteExpando = false; 1212 } 1213 1214 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { 1215 div.attachEvent("onclick", function click() { 1216 // Cloning a node shouldn't copy over any 1217 // bound event handlers (IE does this) 1218 jQuery.support.noCloneEvent = false; 1219 div.detachEvent("onclick", click); 1220 }); 1221 div.cloneNode(true).fireEvent("onclick"); 1222 } 1223 1224 div = document.createElement("div"); 1225 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>"; 1226 1227 var fragment = document.createDocumentFragment(); 1228 fragment.appendChild( div.firstChild ); 1229 1230 // WebKit doesn't clone checked state correctly in fragments 1231 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; 1232 1233 // Figure out if the W3C box model works as expected 1234 // document.body must exist before we can do this 1235 jQuery(function() { 1236 var div = document.createElement("div"), 1237 body = document.getElementsByTagName("body")[0]; 1238 1239 // Frameset documents with no body should not run this code 1240 if ( !body ) { 1241 return; 1242 } 1243 1244 div.style.width = div.style.paddingLeft = "1px"; 1245 body.appendChild( div ); 1246 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; 1247 1248 if ( "zoom" in div.style ) { 1249 // Check if natively block-level elements act like inline-block 1250 // elements when setting their display to 'inline' and giving 1251 // them layout 1252 // (IE < 8 does this) 1253 div.style.display = "inline"; 1254 div.style.zoom = 1; 1255 jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; 1256 1257 // Check if elements with layout shrink-wrap their children 1258 // (IE 6 does this) 1259 div.style.display = ""; 1260 div.innerHTML = "<div style='width:4px;'></div>"; 1261 jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; 1262 } 1263 1264 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>"; 1265 var tds = div.getElementsByTagName("td"); 1266 1267 // Check if table cells still have offsetWidth/Height when they are set 1268 // to display:none and there are still other visible table cells in a 1269 // table row; if so, offsetWidth/Height are not reliable for use when 1270 // determining if an element has been hidden directly using 1271 // display:none (it is still safe to use offsets if a parent element is 1272 // hidden; don safety goggles and see bug #4512 for more information). 1273 // (only IE 8 fails this test) 1274 jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; 1275 1276 tds[0].style.display = ""; 1277 tds[1].style.display = "none"; 1278 1279 // Check if empty table cells still have offsetWidth/Height 1280 // (IE < 8 fail this test) 1281 jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; 1282 div.innerHTML = ""; 1283 1284 body.removeChild( div ).style.display = "none"; 1285 div = tds = null; 1286 }); 1287 1288 // Technique from Juriy Zaytsev 1289 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ 1290 var eventSupported = function( eventName ) { 1291 var el = document.createElement("div"); 1292 eventName = "on" + eventName; 1293 1294 // We only care about the case where non-standard event systems 1295 // are used, namely in IE. Short-circuiting here helps us to 1296 // avoid an eval call (in setAttribute) which can cause CSP 1297 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP 1298 if ( !el.attachEvent ) { 1299 return true; 1300 } 1301 1302 var isSupported = (eventName in el); 1303 if ( !isSupported ) { 1304 el.setAttribute(eventName, "return;"); 1305 isSupported = typeof el[eventName] === "function"; 1306 } 1307 el = null; 1308 1309 return isSupported; 1310 }; 1311 1312 jQuery.support.submitBubbles = eventSupported("submit"); 1313 jQuery.support.changeBubbles = eventSupported("change"); 1314 1315 // release memory in IE 1316 div = all = a = null; 1317})(); 1318 1319 1320 1321var rbrace = /^(?:\{.*\}|\[.*\])$/; 1322 1323jQuery.extend({ 1324 cache: {}, 1325 1326 // Please use with caution 1327 uuid: 0, 1328 1329 // Unique for each copy of jQuery on the page 1330 // Non-digits removed to match rinlinejQuery 1331 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), 1332 1333 // The following elements throw uncatchable exceptions if you 1334 // attempt to add expando properties to them. 1335 noData: { 1336 "embed": true, 1337 // Ban all objects except for Flash (which handle expandos) 1338 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", 1339 "applet": true 1340 }, 1341 1342 hasData: function( elem ) { 1343 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; 1344 1345 return !!elem && !isEmptyDataObject( elem ); 1346 }, 1347 1348 data: function( elem, name, data, pvt /* Internal Use Only */ ) { 1349 if ( !jQuery.acceptData( elem ) ) { 1350 return; 1351 } 1352 1353 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, 1354 1355 // We have to handle DOM nodes and JS objects differently because IE6-7 1356 // can't GC object references properly across the DOM-JS boundary 1357 isNode = elem.nodeType, 1358 1359 // Only DOM nodes need the global jQuery cache; JS object data is 1360 // attached directly to the object so GC can occur automatically 1361 cache = isNode ? jQuery.cache : elem, 1362 1363 // Only defining an ID for JS objects if its cache already exists allows 1364 // the code to shortcut on the same path as a DOM node with no cache 1365 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; 1366 1367 // Avoid doing any more work than we need to when trying to get data on an 1368 // object that has no data at all 1369 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { 1370 return; 1371 } 1372 1373 if ( !id ) { 1374 // Only DOM nodes need a new unique ID for each element since their data 1375 // ends up in the global cache 1376 if ( isNode ) { 1377 elem[ jQuery.expando ] = id = ++jQuery.uuid; 1378 } else { 1379 id = jQuery.expando; 1380 } 1381 } 1382 1383 if ( !cache[ id ] ) { 1384 cache[ id ] = {}; 1385 1386 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery 1387 // metadata on plain JS objects when the object is serialized using 1388 // JSON.stringify 1389 if ( !isNode ) { 1390 cache[ id ].toJSON = jQuery.noop; 1391 } 1392 } 1393 1394 // An object can be passed to jQuery.data instead of a key/value pair; this gets 1395 // shallow copied over onto the existing cache 1396 if ( typeof name === "object" || typeof name === "function" ) { 1397 if ( pvt ) { 1398 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); 1399 } else { 1400 cache[ id ] = jQuery.extend(cache[ id ], name); 1401 } 1402 } 1403 1404 thisCache = cache[ id ]; 1405 1406 // Internal jQuery data is stored in a separate object inside the object's data 1407 // cache in order to avoid key collisions between internal data and user-defined 1408 // data 1409 if ( pvt ) { 1410 if ( !thisCache[ internalKey ] ) { 1411 thisCache[ internalKey ] = {}; 1412 } 1413 1414 thisCache = thisCache[ internalKey ]; 1415 } 1416 1417 if ( data !== undefined ) { 1418 thisCache[ name ] = data; 1419 } 1420 1421 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should 1422 // not attempt to inspect the internal events object using jQuery.data, as this 1423 // internal data object is undocumented and subject to change. 1424 if ( name === "events" && !thisCache[name] ) { 1425 return thisCache[ internalKey ] && thisCache[ internalKey ].events; 1426 } 1427 1428 return getByName ? thisCache[ name ] : thisCache; 1429 }, 1430 1431 removeData: function( elem, name, pvt /* Internal Use Only */ ) { 1432 if ( !jQuery.acceptData( elem ) ) { 1433 return; 1434 } 1435 1436 var internalKey = jQuery.expando, isNode = elem.nodeType, 1437 1438 // See jQuery.data for more information 1439 cache = isNode ? jQuery.cache : elem, 1440 1441 // See jQuery.data for more information 1442 id = isNode ? elem[ jQuery.expando ] : jQuery.expando; 1443 1444 // If there is already no cache entry for this object, there is no 1445 // purpose in continuing 1446 if ( !cache[ id ] ) { 1447 return; 1448 } 1449 1450 if ( name ) { 1451 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; 1452 1453 if ( thisCache ) { 1454 delete thisCache[ name ]; 1455 1456 // If there is no data left in the cache, we want to continue 1457 // and let the cache object itself get destroyed 1458 if ( !isEmptyDataObject(thisCache) ) { 1459 return; 1460 } 1461 } 1462 } 1463 1464 // See jQuery.data for more information 1465 if ( pvt ) { 1466 delete cache[ id ][ internalKey ]; 1467 1468 // Don't destroy the parent cache unless the internal data object 1469 // had been the only thing left in it 1470 if ( !isEmptyDataObject(cache[ id ]) ) { 1471 return; 1472 } 1473 } 1474 1475 var internalCache = cache[ id ][ internalKey ]; 1476 1477 // Browsers that fail expando deletion also refuse to delete expandos on 1478 // the window, but it will allow it on all other JS objects; other browsers 1479 // don't care 1480 if ( jQuery.support.deleteExpando || cache != window ) { 1481 delete cache[ id ]; 1482 } else { 1483 cache[ id ] = null; 1484 } 1485 1486 // We destroyed the entire user cache at once because it's faster than 1487 // iterating through each key, but we need to continue to persist internal 1488 // data if it existed 1489 if ( internalCache ) { 1490 cache[ id ] = {}; 1491 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery 1492 // metadata on plain JS objects when the object is serialized using 1493 // JSON.stringify 1494 if ( !isNode ) { 1495 cache[ id ].toJSON = jQuery.noop; 1496 } 1497 1498 cache[ id ][ internalKey ] = internalCache; 1499 1500 // Otherwise, we need to eliminate the expando on the node to avoid 1501 // false lookups in the cache for entries that no longer exist 1502 } else if ( isNode ) { 1503 // IE does not allow us to delete expando properties from nodes, 1504 // nor does it have a removeAttribute function on Document nodes; 1505 // we must handle all of these cases 1506 if ( jQuery.support.deleteExpando ) { 1507 delete elem[ jQuery.expando ]; 1508 } else if ( elem.removeAttribute ) { 1509 elem.removeAttribute( jQuery.expando ); 1510 } else { 1511 elem[ jQuery.expando ] = null; 1512 } 1513 } 1514 }, 1515 1516 // For internal use only. 1517 _data: function( elem, name, data ) { 1518 return jQuery.data( elem, name, data, true ); 1519 }, 1520 1521 // A method for determining if a DOM node can handle the data expando 1522 acceptData: function( elem ) { 1523 if ( elem.nodeName ) { 1524 var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; 1525 1526 if ( match ) { 1527 return !(match === true || elem.getAttribute("classid") !== match); 1528 } 1529 } 1530 1531 return true; 1532 } 1533}); 1534 1535jQuery.fn.extend({ 1536 data: function( key, value ) { 1537 var data = null; 1538 1539 if ( typeof key === "undefined" ) { 1540 if ( this.length ) { 1541 data = jQuery.data( this[0] ); 1542 1543 if ( this[0].nodeType === 1 ) { 1544 var attr = this[0].attributes, name; 1545 for ( var i = 0, l = attr.length; i < l; i++ ) { 1546 name = attr[i].name; 1547 1548 if ( name.indexOf( "data-" ) === 0 ) { 1549 name = name.substr( 5 ); 1550 dataAttr( this[0], name, data[ name ] ); 1551 } 1552 } 1553 } 1554 } 1555 1556 return data; 1557 1558 } else if ( typeof key === "object" ) { 1559 return this.each(function() { 1560 jQuery.data( this, key ); 1561 }); 1562 } 1563 1564 var parts = key.split("."); 1565 parts[1] = parts[1] ? "." + parts[1] : ""; 1566 1567 if ( value === undefined ) { 1568 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 1569 1570 // Try to fetch any internally stored data first 1571 if ( data === undefined && this.length ) { 1572 data = jQuery.data( this[0], key ); 1573 data = dataAttr( this[0], key, data ); 1574 } 1575 1576 return data === undefined && parts[1] ? 1577 this.data( parts[0] ) : 1578 data; 1579 1580 } else { 1581 return this.each(function() { 1582 var $this = jQuery( this ), 1583 args = [ parts[0], value ]; 1584 1585 $this.triggerHandler( "setData" + parts[1] + "!", args ); 1586 jQuery.data( this, key, value ); 1587 $this.triggerHandler( "changeData" + parts[1] + "!", args ); 1588 }); 1589 } 1590 }, 1591 1592 removeData: function( key ) { 1593 return this.each(function() { 1594 jQuery.removeData( this, key ); 1595 }); 1596 } 1597}); 1598 1599function dataAttr( elem, key, data ) { 1600 // If nothing was found internally, try to fetch any 1601 // data from the HTML5 data-* attribute 1602 if ( data === undefined && elem.nodeType === 1 ) { 1603 data = elem.getAttribute( "data-" + key ); 1604 1605 if ( typeof data === "string" ) { 1606 try { 1607 data = data === "true" ? true : 1608 data === "false" ? false : 1609 data === "null" ? null : 1610 !jQuery.isNaN( data ) ? parseFloat( data ) : 1611 rbrace.test( data ) ? jQuery.parseJSON( data ) : 1612 data; 1613 } catch( e ) {} 1614 1615 // Make sure we set the data so it isn't changed later 1616 jQuery.data( elem, key, data ); 1617 1618 } else { 1619 data = undefined; 1620 } 1621 } 1622 1623 return data; 1624} 1625 1626// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON 1627// property to be considered empty objects; this property always exists in 1628// order to make sure JSON.stringify does not expose internal metadata 1629function isEmptyDataObject( obj ) { 1630 for ( var name in obj ) { 1631 if ( name !== "toJSON" ) { 1632 return false; 1633 } 1634 } 1635 1636 return true; 1637} 1638 1639 1640 1641 1642jQuery.extend({ 1643 queue: function( elem, type, data ) { 1644 if ( !elem ) { 1645 return; 1646 } 1647 1648 type = (type || "fx") + "queue"; 1649 var q = jQuery._data( elem, type ); 1650 1651 // Speed up dequeue by getting out quickly if this is just a lookup 1652 if ( !data ) { 1653 return q || []; 1654 } 1655 1656 if ( !q || jQuery.isArray(data) ) { 1657 q = jQuery._data( elem, type, jQuery.makeArray(data) ); 1658 1659 } else { 1660 q.push( data ); 1661 } 1662 1663 return q; 1664 }, 1665 1666 dequeue: function( elem, type ) { 1667 type = type || "fx"; 1668 1669 var queue = jQuery.queue( elem, type ), 1670 fn = queue.shift(); 1671 1672 // If the fx queue is dequeued, always remove the progress sentinel 1673 if ( fn === "inprogress" ) { 1674 fn = queue.shift(); 1675 } 1676 1677 if ( fn ) { 1678 // Add a progress sentinel to prevent the fx queue from being 1679 // automatically dequeued 1680 if ( type === "fx" ) { 1681 queue.unshift("inprogress"); 1682 } 1683 1684 fn.call(elem, function() { 1685 jQuery.dequeue(elem, type); 1686 }); 1687 } 1688 1689 if ( !queue.length ) { 1690 jQuery.removeData( elem, type + "queue", true ); 1691 } 1692 } 1693}); 1694 1695jQuery.fn.extend({ 1696 queue: function( type, data ) { 1697 if ( typeof type !== "string" ) { 1698 data = type; 1699 type = "fx"; 1700 } 1701 1702 if ( data === undefined ) { 1703 return jQuery.queue( this[0], type ); 1704 } 1705 return this.each(function( i ) { 1706 var queue = jQuery.queue( this, type, data ); 1707 1708 if ( type === "fx" && queue[0] !== "inprogress" ) { 1709 jQuery.dequeue( this, type ); 1710 } 1711 }); 1712 }, 1713 dequeue: function( type ) { 1714 return this.each(function() { 1715 jQuery.dequeue( this, type ); 1716 }); 1717 }, 1718 1719 // Based off of the plugin by Clint Helfers, with permission. 1720 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 1721 delay: function( time, type ) { 1722 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; 1723 type = type || "fx"; 1724 1725 return this.queue( type, function() { 1726 var elem = this; 1727 setTimeout(function() { 1728 jQuery.dequeue( elem, type ); 1729 }, time ); 1730 }); 1731 }, 1732 1733 clearQueue: function( type ) { 1734 return this.queue( type || "fx", [] ); 1735 } 1736}); 1737 1738 1739 1740 1741var rclass = /[\n\t\r]/g, 1742 rspaces = /\s+/, 1743 rreturn = /\r/g, 1744 rspecialurl = /^(?:href|src|style)$/, 1745 rtype = /^(?:button|input)$/i, 1746 rfocusable = /^(?:button|input|object|select|textarea)$/i, 1747 rclickable = /^a(?:rea)?$/i, 1748 rradiocheck = /^(?:radio|checkbox)$/i; 1749 1750jQuery.props = { 1751 "for": "htmlFor", 1752 "class": "className", 1753 readonly: "readOnly", 1754 maxlength: "maxLength", 1755 cellspacing: "cellSpacing", 1756 rowspan: "rowSpan", 1757 colspan: "colSpan", 1758 tabindex: "tabIndex", 1759 usemap: "useMap", 1760 frameborder: "frameBorder" 1761}; 1762 1763jQuery.fn.extend({ 1764 attr: function( name, value ) { 1765 return jQuery.access( this, name, value, true, jQuery.attr ); 1766 }, 1767 1768 removeAttr: function( name, fn ) { 1769 return this.each(function(){ 1770 jQuery.attr( this, name, "" ); 1771 if ( this.nodeType === 1 ) { 1772 this.removeAttribute( name ); 1773 } 1774 }); 1775 }, 1776 1777 addClass: function( value ) { 1778 if ( jQuery.isFunction(value) ) { 1779 return this.each(function(i) { 1780 var self = jQuery(this); 1781 self.addClass( value.call(this, i, self.attr("class")) ); 1782 }); 1783 } 1784 1785 if ( value && typeof value === "string" ) { 1786 var classNames = (value || "").split( rspaces ); 1787 1788 for ( var i = 0, l = this.length; i < l; i++ ) { 1789 var elem = this[i]; 1790 1791 if ( elem.nodeType === 1 ) { 1792 if ( !elem.className ) { 1793 elem.className = value; 1794 1795 } else { 1796 var className = " " + elem.className + " ", 1797 setClass = elem.className; 1798 1799 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1800 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { 1801 setClass += " " + classNames[c]; 1802 } 1803 } 1804 elem.className = jQuery.trim( setClass ); 1805 } 1806 } 1807 } 1808 } 1809 1810 return this; 1811 }, 1812 1813 removeClass: function( value ) { 1814 if ( jQuery.isFunction(value) ) { 1815 return this.each(function(i) { 1816 var self = jQuery(this); 1817 self.removeClass( value.call(this, i, self.attr("class")) ); 1818 }); 1819 } 1820 1821 if ( (value && typeof value === "string") || value === undefined ) { 1822 var classNames = (value || "").split( rspaces ); 1823 1824 for ( var i = 0, l = this.length; i < l; i++ ) { 1825 var elem = this[i]; 1826 1827 if ( elem.nodeType === 1 && elem.className ) { 1828 if ( value ) { 1829 var className = (" " + elem.className + " ").replace(rclass, " "); 1830 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1831 className = className.replace(" " + classNames[c] + " ", " "); 1832 } 1833 elem.className = jQuery.trim( className ); 1834 1835 } else { 1836 elem.className = ""; 1837 } 1838 } 1839 } 1840 } 1841 1842 return this; 1843 }, 1844 1845 toggleClass: function( value, stateVal ) { 1846 var type = typeof value, 1847 isBool = typeof stateVal === "boolean"; 1848 1849 if ( jQuery.isFunction( value ) ) { 1850 return this.each(function(i) { 1851 var self = jQuery(this); 1852 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); 1853 }); 1854 } 1855 1856 return this.each(function() { 1857 if ( type === "string" ) { 1858 // toggle individual class names 1859 var className, 1860 i = 0, 1861 self = jQuery( this ), 1862 state = stateVal, 1863 classNames = value.split( rspaces ); 1864 1865 while ( (className = classNames[ i++ ]) ) { 1866 // check each className given, space seperated list 1867 state = isBool ? state : !self.hasClass( className ); 1868 self[ state ? "addClass" : "removeClass" ]( className ); 1869 } 1870 1871 } else if ( type === "undefined" || type === "boolean" ) { 1872 if ( this.className ) { 1873 // store className if set 1874 jQuery._data( this, "__className__", this.className ); 1875 } 1876 1877 // toggle whole className 1878 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; 1879 } 1880 }); 1881 }, 1882 1883 hasClass: function( selector ) { 1884 var className = " " + selector + " "; 1885 for ( var i = 0, l = this.length; i < l; i++ ) { 1886 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { 1887 return true; 1888 } 1889 } 1890 1891 return false; 1892 }, 1893 1894 val: function( value ) { 1895 if ( !arguments.length ) { 1896 var elem = this[0]; 1897 1898 if ( elem ) { 1899 if ( jQuery.nodeName( elem, "option" ) ) { 1900 // attributes.value is undefined in Blackberry 4.7 but 1901 // uses .value. See #6932 1902 var val = elem.attributes.value; 1903 return !val || val.specified ? elem.value : elem.text; 1904 } 1905 1906 // We need to handle select boxes special 1907 if ( jQuery.nodeName( elem, "select" ) ) { 1908 var index = elem.selectedIndex, 1909 values = [], 1910 options = elem.options, 1911 one = elem.type === "select-one"; 1912 1913 // Nothing was selected 1914 if ( index < 0 ) { 1915 return null; 1916 } 1917 1918 // Loop through all the selected options 1919 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 1920 var option = options[ i ]; 1921 1922 // Don't return options that are disabled or in a disabled optgroup 1923 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 1924 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { 1925 1926 // Get the specific value for the option 1927 value = jQuery(option).val(); 1928 1929 // We don't need an array for one selects 1930 if ( one ) { 1931 return value; 1932 } 1933 1934 // Multi-Selects return an array 1935 values.push( value ); 1936 } 1937 } 1938 1939 // Fixes Bug #2551 -- select.val() broken in IE after form.reset() 1940 if ( one && !values.length && options.length ) { 1941 return jQuery( options[ index ] ).val(); 1942 } 1943 1944 return values; 1945 } 1946 1947 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 1948 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { 1949 return elem.getAttribute("value") === null ? "on" : elem.value; 1950 } 1951 1952 // Everything else, we just grab the value 1953 return (elem.value || "").replace(rreturn, ""); 1954 1955 } 1956 1957 return undefined; 1958 } 1959 1960 var isFunction = jQuery.isFunction(value); 1961 1962 return this.each(function(i) { 1963 var self = jQuery(this), val = value; 1964 1965 if ( this.nodeType !== 1 ) { 1966 return; 1967 } 1968 1969 if ( isFunction ) { 1970 val = value.call(this, i, self.val()); 1971 } 1972 1973 // Treat null/undefined as ""; convert numbers to string 1974 if ( val == null ) { 1975 val = ""; 1976 } else if ( typeof val === "number" ) { 1977 val += ""; 1978 } else if ( jQuery.isArray(val) ) { 1979 val = jQuery.map(val, function (value) { 1980 return value == null ? "" : value + ""; 1981 }); 1982 } 1983 1984 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { 1985 this.checked = jQuery.inArray( self.val(), val ) >= 0; 1986 1987 } else if ( jQuery.nodeName( this, "select" ) ) { 1988 var values = jQuery.makeArray(val); 1989 1990 jQuery( "option", this ).each(function() { 1991 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 1992 }); 1993 1994 if ( !values.length ) { 1995 this.selectedIndex = -1; 1996 } 1997 1998 } else { 1999 this.value = val; 2000 } 2001 }); 2002 } 2003}); 2004 2005jQuery.extend({ 2006 attrFn: { 2007 val: true, 2008 css: true, 2009 html: true, 2010 text: true, 2011 data: true, 2012 width: true, 2013 height: true, 2014 offset: true 2015 }, 2016 2017 attr: function( elem, name, value, pass ) { 2018 // don't get/set attributes on text, comment and attribute nodes 2019 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { 2020 return undefined; 2021 } 2022 2023 if ( pass && name in jQuery.attrFn ) { 2024 return jQuery(elem)[name](value); 2025 } 2026 2027 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), 2028 // Whether we are setting (or getting) 2029 set = value !== undefined; 2030 2031 // Try to normalize/fix the name 2032 name = notxml && jQuery.props[ name ] || name; 2033 2034 // Only do all the following if this is a node (faster for style) 2035 if ( elem.nodeType === 1 ) { 2036 // These attributes require special treatment 2037 var special = rspecialurl.test( name ); 2038 2039 // Safari mis-reports the default selected property of an option 2040 // Accessing the parent's selectedIndex property fixes it 2041 if ( name === "selected" && !jQuery.support.optSelected ) { 2042 var parent = elem.parentNode; 2043 if ( parent ) { 2044 parent.selectedIndex; 2045 2046 // Make sure that it also works with optgroups, see #5701 2047 if ( parent.parentNode ) { 2048 parent.parentNode.selectedIndex; 2049 } 2050 } 2051 } 2052 2053 // If applicable, access the attribute via the DOM 0 way 2054 // 'in' checks fail in Blackberry 4.7 #6931 2055 if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { 2056 if ( set ) { 2057 // We can't allow the type property to be changed (since it causes problems in IE) 2058 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { 2059 jQuery.error( "type property can't be changed" ); 2060 } 2061 2062 if ( value === null ) { 2063 if ( elem.nodeType === 1 ) { 2064 elem.removeAttribute( name ); 2065 } 2066 2067 } else { 2068 elem[ name ] = value; 2069 } 2070 } 2071 2072 // browsers index elements by id/name on forms, give priority to attributes. 2073 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { 2074 return elem.getAttributeNode( name ).nodeValue; 2075 } 2076 2077 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 2078 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 2079 if ( name === "tabIndex" ) { 2080 var attributeNode = elem.getAttributeNode( "tabIndex" ); 2081 2082 return attributeNode && attributeNode.specified ? 2083 attributeNode.value : 2084 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 2085 0 : 2086 undefined; 2087 } 2088 2089 return elem[ name ]; 2090 } 2091 2092 if ( !jQuery.support.style && notxml && name === "style" ) { 2093 if ( set ) { 2094 elem.style.cssText = "" + value; 2095 } 2096 2097 return elem.style.cssText; 2098 } 2099 2100 if ( set ) { 2101 // convert the value to a string (all browsers do this but IE) see #1070 2102 elem.setAttribute( name, "" + value ); 2103 } 2104 2105 // Ensure that missing attributes return undefined 2106 // Blackberry 4.7 returns "" from getAttribute #6938 2107 if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { 2108 return undefined; 2109 } 2110 2111 var attr = !jQuery.support.hrefNormalized && notxml && special ? 2112 // Some attributes require a special call on IE 2113 elem.getAttribute( name, 2 ) : 2114 elem.getAttribute( name ); 2115 2116 // Non-existent attributes return null, we normalize to undefined 2117 return attr === null ? undefined : attr; 2118 } 2119 // Handle everything which isn't a DOM element node 2120 if ( set ) { 2121 elem[ name ] = value; 2122 } 2123 return elem[ name ]; 2124 } 2125}); 2126 2127 2128 2129 2130var rnamespaces = /\.(.*)$/, 2131 rformElems = /^(?:textarea|input|select)$/i, 2132 rperiod = /\./g, 2133 rspace = / /g, 2134 rescape = /[^\w\s.|`]/g, 2135 fcleanup = function( nm ) { 2136 return nm.replace(rescape, "\\$&"); 2137 }; 2138 2139/* 2140 * A number of helper functions used for managing events. 2141 * Many of the ideas behind this code originated from 2142 * Dean Edwards' addEvent library. 2143 */ 2144jQuery.event = { 2145 2146 // Bind an event to an element 2147 // Original by Dean Edwards 2148 add: function( elem, types, handler, data ) { 2149 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 2150 return; 2151 } 2152 2153 // TODO :: Use a try/catch until it's safe to pull this out (likely 1.6) 2154 // Minor release fix for bug #8018 2155 try { 2156 // For whatever reason, IE has trouble passing the window object 2157 // around, causing it to be cloned in the process 2158 if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { 2159 elem = window; 2160 } 2161 } 2162 catch ( e ) {} 2163 2164 if ( handler === false ) { 2165 handler = returnFalse; 2166 } else if ( !handler ) { 2167 // Fixes bug #7229. Fix recommended by jdalton 2168 return; 2169 } 2170 2171 var handleObjIn, handleObj; 2172 2173 if ( handler.handler ) { 2174 handleObjIn = handler; 2175 handler = handleObjIn.handler; 2176 } 2177 2178 // Make sure that the function being executed has a unique ID 2179 if ( !handler.guid ) { 2180 handler.guid = jQuery.guid++; 2181 } 2182 2183 // Init the element's event structure 2184 var elemData = jQuery._data( elem ); 2185 2186 // If no elemData is found then we must be trying to bind to one of the 2187 // banned noData elements 2188 if ( !elemData ) { 2189 return; 2190 } 2191 2192 var events = elemData.events, 2193 eventHandle = elemData.handle; 2194 2195 if ( !events ) { 2196 elemData.events = events = {}; 2197 } 2198 2199 if ( !eventHandle ) { 2200 elemData.handle = eventHandle = function() { 2201 // Handle the second event of a trigger and when 2202 // an event is called after a page has unloaded 2203 return typeof jQuery !== "undefined" && !jQuery.event.triggered ? 2204 jQuery.event.handle.apply( eventHandle.elem, arguments ) : 2205 undefined; 2206 }; 2207 } 2208 2209 // Add elem as a property of the handle function 2210 // This is to prevent a memory leak with non-native events in IE. 2211 eventHandle.elem = elem; 2212 2213 // Handle multiple events separated by a space 2214 // jQuery(...).bind("mouseover mouseout", fn); 2215 types = types.split(" "); 2216 2217 var type, i = 0, namespaces; 2218 2219 while ( (type = types[ i++ ]) ) { 2220 handleObj = handleObjIn ? 2221 jQuery.extend({}, handleObjIn) : 2222 { handler: handler, data: data }; 2223 2224 // Namespaced event handlers 2225 if ( type.indexOf(".") > -1 ) { 2226 namespaces = type.split("."); 2227 type = namespaces.shift(); 2228 handleObj.namespace = namespaces.slice(0).sort().join("."); 2229 2230 } else { 2231 namespaces = []; 2232 handleObj.namespace = ""; 2233 } 2234 2235 handleObj.type = type; 2236 if ( !handleObj.guid ) { 2237 handleObj.guid = handler.guid; 2238 } 2239 2240 // Get the current list of functions bound to this event 2241 var handlers = events[ type ], 2242 special = jQuery.event.special[ type ] || {}; 2243 2244 // Init the event handler queue 2245 if ( !handlers ) { 2246 handlers = events[ type ] = []; 2247 2248 // Check for a special event handler 2249 // Only use addEventListener/attachEvent if the special 2250 // events handler returns false 2251 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 2252 // Bind the global event handler to the element 2253 if ( elem.addEventListener ) { 2254 elem.addEventListener( type, eventHandle, false ); 2255 2256 } else if ( elem.attachEvent ) { 2257 elem.attachEvent( "on" + type, eventHandle ); 2258 } 2259 } 2260 } 2261 2262 if ( special.add ) { 2263 special.add.call( elem, handleObj ); 2264 2265 if ( !handleObj.handler.guid ) { 2266 handleObj.handler.guid = handler.guid; 2267 } 2268 } 2269 2270 // Add the function to the element's handler list 2271 handlers.push( handleObj ); 2272 2273 // Keep track of which events have been used, for global triggering 2274 jQuery.event.global[ type ] = true; 2275 } 2276 2277 // Nullify elem to prevent memory leaks in IE 2278 elem = null; 2279 }, 2280 2281 global: {}, 2282 2283 // Detach an event or set of events from an element 2284 remove: function( elem, types, handler, pos ) { 2285 // don't do events on text and comment nodes 2286 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 2287 return; 2288 } 2289 2290 if ( handler === false ) { 2291 handler = returnFalse; 2292 } 2293 2294 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, 2295 elemData = jQuery.hasData( elem ) && jQuery._data( elem ), 2296 events = elemData && elemData.events; 2297 2298 if ( !elemData || !events ) { 2299 return; 2300 } 2301 2302 // types is actually an event object here 2303 if ( types && types.type ) { 2304 handler = types.handler; 2305 types = types.type; 2306 } 2307 2308 // Unbind all events for the element 2309 if ( !types || typeof types === "string" && types.charAt(0) === "." ) { 2310 types = types || ""; 2311 2312 for ( type in events ) { 2313 jQuery.event.remove( elem, type + types ); 2314 } 2315 2316 return; 2317 } 2318 2319 // Handle multiple events separated by a space 2320 // jQuery(...).unbind("mouseover mouseout", fn); 2321 types = types.split(" "); 2322 2323 while ( (type = types[ i++ ]) ) { 2324 origType = type; 2325 handleObj = null; 2326 all = type.indexOf(".") < 0; 2327 namespaces = []; 2328 2329 if ( !all ) { 2330 // Namespaced event handlers 2331 namespaces = type.split("."); 2332 type = namespaces.shift(); 2333 2334 namespace = new RegExp("(^|\\.)" + 2335 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); 2336 } 2337 2338 eventType = events[ type ]; 2339 2340 if ( !eventType ) { 2341 continue; 2342 } 2343 2344 if ( !handler ) { 2345 for ( j = 0; j < eventType.length; j++ ) { 2346 handleObj = eventType[ j ]; 2347 2348 if ( all || namespace.test( handleObj.namespace ) ) { 2349 jQuery.event.remove( elem, origType, handleObj.handler, j ); 2350 eventType.splice( j--, 1 ); 2351 } 2352 } 2353 2354 continue; 2355 } 2356 2357 special = jQuery.event.special[ type ] || {}; 2358 2359 for ( j = pos || 0; j < eventType.length; j++ ) { 2360 handleObj = eventType[ j ]; 2361 2362 if ( handler.guid === handleObj.guid ) { 2363 // remove the given handler for the given type 2364 if ( all || namespace.test( handleObj.namespace ) ) { 2365 if ( pos == null ) { 2366 eventType.splice( j--, 1 ); 2367 } 2368 2369 if ( special.remove ) { 2370 special.remove.call( elem, handleObj ); 2371 } 2372 } 2373 2374 if ( pos != null ) { 2375 break; 2376 } 2377 } 2378 } 2379 2380 // remove generic event handler if no more handlers exist 2381 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { 2382 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { 2383 jQuery.removeEvent( elem, type, elemData.handle ); 2384 } 2385 2386 ret = null; 2387 delete events[ type ]; 2388 } 2389 } 2390 2391 // Remove the expando if it's no longer used 2392 if ( jQuery.isEmptyObject( events ) ) { 2393 var handle = elemData.handle; 2394 if ( handle ) { 2395 handle.elem = null; 2396 } 2397 2398 delete elemData.events; 2399 delete elemData.handle; 2400 2401 if ( jQuery.isEmptyObject( elemData ) ) { 2402 jQuery.removeData( elem, undefined, true ); 2403 } 2404 } 2405 }, 2406 2407 // bubbling is internal 2408 trigger: function( event, data, elem /*, bubbling */ ) { 2409 // Event object or event type 2410 var type = event.type || event, 2411 bubbling = arguments[3]; 2412 2413 if ( !bubbling ) { 2414 event = typeof event === "object" ? 2415 // jQuery.Event object 2416 event[ jQuery.expando ] ? event : 2417 // Object literal 2418 jQuery.extend( jQuery.Event(type), event ) : 2419 // Just the event type (string) 2420 jQuery.Event(type); 2421 2422 if ( type.indexOf("!") >= 0 ) { 2423 event.type = type = type.slice(0, -1); 2424 event.exclusive = true; 2425 } 2426 2427 // Handle a global trigger 2428 if ( !elem ) { 2429 // Don't bubble custom events when global (to avoid too much overhead) 2430 event.stopPropagation(); 2431 2432 // Only trigger if we've ever bound an event for it 2433 if ( jQuery.event.global[ type ] ) { 2434 // XXX This code smells terrible. event.js should not be directly 2435 // inspecting the data cache 2436 jQuery.each( jQuery.cache, function() { 2437 // internalKey variable is just used to make it easier to find 2438 // and potentially change this stuff later; currently it just 2439 // points to jQuery.expando 2440 var internalKey = jQuery.expando, 2441 internalCache = this[ internalKey ]; 2442 if ( internalCache && internalCache.events && internalCache.events[ type ] ) { 2443 jQuery.event.trigger( event, data, internalCache.handle.elem ); 2444 } 2445 }); 2446 } 2447 } 2448 2449 // Handle triggering a single element 2450 2451 // don't do events on text and comment nodes 2452 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 2453 return undefined; 2454 } 2455 2456 // Clean up in case it is reused 2457 event.result = undefined; 2458 event.target = elem; 2459 2460 // Clone the incoming data, if any 2461 data = jQuery.makeArray( data ); 2462 data.unshift( event ); 2463 } 2464 2465 event.currentTarget = elem; 2466 2467 // Trigger the event, it is assumed that "handle" is a function 2468 var handle = jQuery._data( elem, "handle" ); 2469 2470 if ( handle ) { 2471 handle.apply( elem, data ); 2472 } 2473 2474 var parent = elem.parentNode || elem.ownerDocument; 2475 2476 // Trigger an inline bound script 2477 try { 2478 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { 2479 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { 2480 event.result = false; 2481 event.preventDefault(); 2482 } 2483 } 2484 2485 // prevent IE from throwing an erro