Changeset 4918 for trunk/template-common/lib/jquery.js
- Timestamp:
- Feb 20, 2010, 8:56:36 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/template-common/lib/jquery.js
r3282 r4918 1 (function(){ 2 /* 3 * jQuery 1.2.6 - New Wave Javascript1 /*! 2 * jQuery JavaScript Library v1.4.1 3 * http://jquery.com/ 4 4 * 5 * Copyright (c) 2008 John Resig (jquery.com)6 * Dual licensed under the MIT (MIT-LICENSE.txt)7 * and GPL (GPL-LICENSE.txt) licenses.5 * Copyright 2010, John Resig 6 * Dual licensed under the MIT or GPL Version 2 licenses. 7 * http://jquery.org/license 8 8 * 9 * $Date: 2008-08-28T01:26:26.034575Z $ 10 * $Rev: 6329 $ 9 * Includes Sizzle.js 10 * http://sizzlejs.com/ 11 * Copyright 2010, The Dojo Foundation 12 * Released under the MIT, BSD, and GPL Licenses. 13 * 14 * Date: Mon Jan 25 19:43:33 2010 -0500 11 15 */ 12 13 // Map over jQuery in case of overwrite 14 var _jQuery = window.jQuery, 15 // Map over the $ in case of overwrite 16 _$ = window.$; 17 18 var jQuery = window.jQuery = window.$ = function( selector, context ) { 19 // The jQuery object is actually just the init constructor 'enhanced' 20 return new jQuery.fn.init( selector, context ); 21 }; 22 23 // A simple way to check for HTML strings or ID strings 24 // (both of which we optimize for) 25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/, 26 27 // Is it a simple selector 28 isSimple = /^.[^:#\[\.]*$/, 29 30 // Will speed up references to undefined, and allows munging its name. 31 undefined; 16 (function( window, undefined ) { 17 18 // Define a local copy of jQuery 19 var jQuery = function( selector, context ) { 20 // The jQuery object is actually just the init constructor 'enhanced' 21 return new jQuery.fn.init( selector, context ); 22 }, 23 24 // Map over jQuery in case of overwrite 25 _jQuery = window.jQuery, 26 27 // Map over the $ in case of overwrite 28 _$ = window.$, 29 30 // Use the correct document accordingly with window argument (sandbox) 31 document = window.document, 32 33 // A central reference to the root jQuery(document) 34 rootjQuery, 35 36 // A simple way to check for HTML strings or ID strings 37 // (both of which we optimize for) 38 quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/, 39 40 // Is it a simple selector 41 isSimple = /^.[^:#\[\.,]*$/, 42 43 // Check if a string has a non-whitespace character in it 44 rnotwhite = /\S/, 45 46 // Used for trimming whitespace 47 rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g, 48 49 // Match a standalone tag 50 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, 51 52 // Keep a UserAgent string for use with jQuery.browser 53 userAgent = navigator.userAgent, 54 55 // For matching the engine and version of the browser 56 browserMatch, 57 58 // Has the ready events already been bound? 59 readyBound = false, 60 61 // The functions to execute on DOM ready 62 readyList = [], 63 64 // The ready event handler 65 DOMContentLoaded, 66 67 // Save a reference to some core methods 68 toString = Object.prototype.toString, 69 hasOwnProperty = Object.prototype.hasOwnProperty, 70 push = Array.prototype.push, 71 slice = Array.prototype.slice, 72 indexOf = Array.prototype.indexOf; 32 73 33 74 jQuery.fn = jQuery.prototype = { 34 75 init: function( selector, context ) { 35 // Make sure that a selection was provided 36 selector = selector || document; 76 var match, elem, ret, doc; 77 78 // Handle $(""), $(null), or $(undefined) 79 if ( !selector ) { 80 return this; 81 } 37 82 38 83 // Handle $(DOMElement) 39 84 if ( selector.nodeType ) { 40 this [0] = selector;85 this.context = this[0] = selector; 41 86 this.length = 1; 42 87 return this; 43 88 } 89 44 90 // Handle HTML strings 45 if ( typeof selector == "string" ) {91 if ( typeof selector === "string" ) { 46 92 // Are we dealing with HTML string or an ID? 47 varmatch = quickExpr.exec( selector );93 match = quickExpr.exec( selector ); 48 94 49 95 // Verify a match, and that no context was specified for #id … … 51 97 52 98 // HANDLE: $(html) -> $(array) 53 if ( match[1] ) 54 selector = jQuery.clean( [ match[1] ], context ); 99 if ( match[1] ) { 100 doc = (context ? context.ownerDocument || context : document); 101 102 // If a single string is passed in and it's a single tag 103 // just do a createElement and skip the rest 104 ret = rsingleTag.exec( selector ); 105 106 if ( ret ) { 107 if ( jQuery.isPlainObject( context ) ) { 108 selector = [ document.createElement( ret[1] ) ]; 109 jQuery.fn.attr.call( selector, context, true ); 110 111 } else { 112 selector = [ doc.createElement( ret[1] ) ]; 113 } 114 115 } else { 116 ret = buildFragment( [ match[1] ], [ doc ] ); 117 selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; 118 } 55 119 56 120 // HANDLE: $("#id") 57 else { 58 var elem = document.getElementById( match[3] ); 59 60 // Make sure an element was located 61 if ( elem ){ 121 } else { 122 elem = document.getElementById( match[2] ); 123 124 if ( elem ) { 62 125 // Handle the case where IE and Opera return items 63 126 // by name instead of ID 64 if ( elem.id != match[3] ) 65 return jQuery().find( selector ); 127 if ( elem.id !== match[2] ) { 128 return rootjQuery.find( selector ); 129 } 66 130 67 131 // Otherwise, we inject the element directly into the jQuery object 68 return jQuery( elem ); 132 this.length = 1; 133 this[0] = elem; 69 134 } 70 selector = []; 71 } 72 73 // HANDLE: $(expr, [context]) 74 // (which is just equivalent to: $(content).find(expr) 75 } else 135 136 this.context = document; 137 this.selector = selector; 138 return this; 139 } 140 141 // HANDLE: $("TAG") 142 } else if ( !context && /^\w+$/.test( selector ) ) { 143 this.selector = selector; 144 this.context = document; 145 selector = document.getElementsByTagName( selector ); 146 147 // HANDLE: $(expr, $(...)) 148 } else if ( !context || context.jquery ) { 149 return (context || rootjQuery).find( selector ); 150 151 // HANDLE: $(expr, context) 152 // (which is just equivalent to: $(context).find(expr) 153 } else { 76 154 return jQuery( context ).find( selector ); 155 } 77 156 78 157 // HANDLE: $(function) 79 158 // Shortcut for document ready 80 } else if ( jQuery.isFunction( selector ) ) 81 return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); 82 83 return this.setArray(jQuery.makeArray(selector)); 84 }, 159 } else if ( jQuery.isFunction( selector ) ) { 160 return rootjQuery.ready( selector ); 161 } 162 163 if (selector.selector !== undefined) { 164 this.selector = selector.selector; 165 this.context = selector.context; 166 } 167 168 return jQuery.isArray( selector ) ? 169 this.setArray( selector ) : 170 jQuery.makeArray( selector, this ); 171 }, 172 173 // Start with an empty selector 174 selector: "", 85 175 86 176 // The current version of jQuery being used 87 jquery: "1.2.6", 177 jquery: "1.4.1", 178 179 // The default length of a jQuery object is 0 180 length: 0, 88 181 89 182 // The number of elements contained in the matched element set … … 92 185 }, 93 186 94 // The number of elements contained in the matched element set 95 length: 0, 187 toArray: function() { 188 return slice.call( this, 0 ); 189 }, 96 190 97 191 // Get the Nth element in the matched element set OR 98 192 // Get the whole matched element set as a clean array 99 193 get: function( num ) { 100 return num == undefined?194 return num == null ? 101 195 102 196 // Return a 'clean' array 103 jQuery.makeArray( this) :197 this.toArray() : 104 198 105 199 // Return just the object 106 this[ num ];200 ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] ); 107 201 }, 108 202 109 203 // Take an array of elements and push it onto the stack 110 204 // (returning the new matched element set) 111 pushStack: function( elems ) {205 pushStack: function( elems, name, selector ) { 112 206 // Build a new jQuery matched element set 113 var ret = jQuery( elems );207 var ret = jQuery( elems || null ); 114 208 115 209 // Add the old object onto the stack (as a reference) 116 210 ret.prevObject = this; 211 212 ret.context = this.context; 213 214 if ( name === "find" ) { 215 ret.selector = this.selector + (this.selector ? " " : "") + selector; 216 } else if ( name ) { 217 ret.selector = this.selector + "." + name + "(" + selector + ")"; 218 } 117 219 118 220 // Return the newly-formed element set … … 127 229 // is a super-fast way to populate an object with array-like properties 128 230 this.length = 0; 129 Array.prototype.push.apply( this, elems );231 push.apply( this, elems ); 130 232 131 233 return this; … … 138 240 return jQuery.each( this, callback, args ); 139 241 }, 140 242 243 ready: function( fn ) { 244 // Attach the listeners 245 jQuery.bindReady(); 246 247 // If the DOM is already ready 248 if ( jQuery.isReady ) { 249 // Execute the function immediately 250 fn.call( document, jQuery ); 251 252 // Otherwise, remember the function for later 253 } else if ( readyList ) { 254 // Add the function to the wait list 255 readyList.push( fn ); 256 } 257 258 return this; 259 }, 260 261 eq: function( i ) { 262 return i === -1 ? 263 this.slice( i ) : 264 this.slice( i, +i + 1 ); 265 }, 266 267 first: function() { 268 return this.eq( 0 ); 269 }, 270 271 last: function() { 272 return this.eq( -1 ); 273 }, 274 275 slice: function() { 276 return this.pushStack( slice.apply( this, arguments ), 277 "slice", slice.call(arguments).join(",") ); 278 }, 279 280 map: function( callback ) { 281 return this.pushStack( jQuery.map(this, function( elem, i ) { 282 return callback.call( elem, i, elem ); 283 })); 284 }, 285 286 end: function() { 287 return this.prevObject || jQuery(null); 288 }, 289 290 // For internal use only. 291 // Behaves like an Array's method, not like a jQuery method. 292 push: push, 293 sort: [].sort, 294 splice: [].splice 295 }; 296 297 // Give the init function the jQuery prototype for later instantiation 298 jQuery.fn.init.prototype = jQuery.fn; 299 300 jQuery.extend = jQuery.fn.extend = function() { 301 // copy reference to target object 302 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy; 303 304 // Handle a deep copy situation 305 if ( typeof target === "boolean" ) { 306 deep = target; 307 target = arguments[1] || {}; 308 // skip the boolean and the target 309 i = 2; 310 } 311 312 // Handle case when target is a string or something (possible in deep copy) 313 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 314 target = {}; 315 } 316 317 // extend jQuery itself if only one argument is passed 318 if ( length === i ) { 319 target = this; 320 --i; 321 } 322 323 for ( ; i < length; i++ ) { 324 // Only deal with non-null/undefined values 325 if ( (options = arguments[ i ]) != null ) { 326 // Extend the base object 327 for ( name in options ) { 328 src = target[ name ]; 329 copy = options[ name ]; 330 331 // Prevent never-ending loop 332 if ( target === copy ) { 333 continue; 334 } 335 336 // Recurse if we're merging object literal values or arrays 337 if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) { 338 var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src 339 : jQuery.isArray(copy) ? [] : {}; 340 341 // Never move original objects, clone them 342 target[ name ] = jQuery.extend( deep, clone, copy ); 343 344 // Don't bring in undefined values 345 } else if ( copy !== undefined ) { 346 target[ name ] = copy; 347 } 348 } 349 } 350 } 351 352 // Return the modified object 353 return target; 354 }; 355 356 jQuery.extend({ 357 noConflict: function( deep ) { 358 window.$ = _$; 359 360 if ( deep ) { 361 window.jQuery = _jQuery; 362 } 363 364 return jQuery; 365 }, 366 367 // Is the DOM ready to be used? Set to true once it occurs. 368 isReady: false, 369 370 // Handle when the DOM is ready 371 ready: function() { 372 // Make sure that the DOM is not already loaded 373 if ( !jQuery.isReady ) { 374 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 375 if ( !document.body ) { 376 return setTimeout( jQuery.ready, 13 ); 377 } 378 379 // Remember that the DOM is ready 380 jQuery.isReady = true; 381 382 // If there are functions bound, to execute 383 if ( readyList ) { 384 // Execute all of them 385 var fn, i = 0; 386 while ( (fn = readyList[ i++ ]) ) { 387 fn.call( document, jQuery ); 388 } 389 390 // Reset the list of functions 391 readyList = null; 392 } 393 394 // Trigger any bound ready events 395 if ( jQuery.fn.triggerHandler ) { 396 jQuery( document ).triggerHandler( "ready" ); 397 } 398 } 399 }, 400 401 bindReady: function() { 402 if ( readyBound ) { 403 return; 404 } 405 406 readyBound = true; 407 408 // Catch cases where $(document).ready() is called after the 409 // browser event has already occurred. 410 if ( document.readyState === "complete" ) { 411 return jQuery.ready(); 412 } 413 414 // Mozilla, Opera and webkit nightlies currently support this event 415 if ( document.addEventListener ) { 416 // Use the handy event callback 417 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 418 419 // A fallback to window.onload, that will always work 420 window.addEventListener( "load", jQuery.ready, false ); 421 422 // If IE event model is used 423 } else if ( document.attachEvent ) { 424 // ensure firing before onload, 425 // maybe late but safe also for iframes 426 document.attachEvent("onreadystatechange", DOMContentLoaded); 427 428 // A fallback to window.onload, that will always work 429 window.attachEvent( "onload", jQuery.ready ); 430 431 // If IE and not a frame 432 // continually check to see if the document is ready 433 var toplevel = false; 434 435 try { 436 toplevel = window.frameElement == null; 437 } catch(e) {} 438 439 if ( document.documentElement.doScroll && toplevel ) { 440 doScrollCheck(); 441 } 442 } 443 }, 444 445 // See test/unit/core.js for details concerning isFunction. 446 // Since version 1.3, DOM methods and functions like alert 447 // aren't supported. They return false on IE (#2968). 448 isFunction: function( obj ) { 449 return toString.call(obj) === "[object Function]"; 450 }, 451 452 isArray: function( obj ) { 453 return toString.call(obj) === "[object Array]"; 454 }, 455 456 isPlainObject: function( obj ) { 457 // Must be an Object. 458 // Because of IE, we also have to check the presence of the constructor property. 459 // Make sure that DOM nodes and window objects don't pass through, as well 460 if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) { 461 return false; 462 } 463 464 // Not own constructor property must be Object 465 if ( obj.constructor 466 && !hasOwnProperty.call(obj, "constructor") 467 && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) { 468 return false; 469 } 470 471 // Own properties are enumerated firstly, so to speed up, 472 // if last one is own, then all properties are own. 473 474 var key; 475 for ( key in obj ) {} 476 477 return key === undefined || hasOwnProperty.call( obj, key ); 478 }, 479 480 isEmptyObject: function( obj ) { 481 for ( var name in obj ) { 482 return false; 483 } 484 return true; 485 }, 486 487 error: function( msg ) { 488 throw msg; 489 }, 490 491 parseJSON: function( data ) { 492 if ( typeof data !== "string" || !data ) { 493 return null; 494 } 495 496 // Make sure the incoming data is actual JSON 497 // Logic borrowed from http://json.org/json2.js 498 if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@") 499 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]") 500 .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) { 501 502 // Try to use the native JSON parser first 503 return window.JSON && window.JSON.parse ? 504 window.JSON.parse( data ) : 505 (new Function("return " + data))(); 506 507 } else { 508 jQuery.error( "Invalid JSON: " + data ); 509 } 510 }, 511 512 noop: function() {}, 513 514 // Evalulates a script in a global context 515 globalEval: function( data ) { 516 if ( data && rnotwhite.test(data) ) { 517 // Inspired by code by Andrea Giammarchi 518 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 519 var head = document.getElementsByTagName("head")[0] || document.documentElement, 520 script = document.createElement("script"); 521 522 script.type = "text/javascript"; 523 524 if ( jQuery.support.scriptEval ) { 525 script.appendChild( document.createTextNode( data ) ); 526 } else { 527 script.text = data; 528 } 529 530 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 531 // This arises when a base node is used (#2709). 532 head.insertBefore( script, head.firstChild ); 533 head.removeChild( script ); 534 } 535 }, 536 537 nodeName: function( elem, name ) { 538 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 539 }, 540 541 // args is for internal usage only 542 each: function( object, callback, args ) { 543 var name, i = 0, 544 length = object.length, 545 isObj = length === undefined || jQuery.isFunction(object); 546 547 if ( args ) { 548 if ( isObj ) { 549 for ( name in object ) { 550 if ( callback.apply( object[ name ], args ) === false ) { 551 break; 552 } 553 } 554 } else { 555 for ( ; i < length; ) { 556 if ( callback.apply( object[ i++ ], args ) === false ) { 557 break; 558 } 559 } 560 } 561 562 // A special, fast, case for the most common use of each 563 } else { 564 if ( isObj ) { 565 for ( name in object ) { 566 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 567 break; 568 } 569 } 570 } else { 571 for ( var value = object[0]; 572 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} 573 } 574 } 575 576 return object; 577 }, 578 579 trim: function( text ) { 580 return (text || "").replace( rtrim, "" ); 581 }, 582 583 // results is for internal usage only 584 makeArray: function( array, results ) { 585 var ret = results || []; 586 587 if ( array != null ) { 588 // The window, strings (and functions) also have 'length' 589 // The extra typeof function check is to prevent crashes 590 // in Safari 2 (See: #3039) 591 if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) { 592 push.call( ret, array ); 593 } else { 594 jQuery.merge( ret, array ); 595 } 596 } 597 598 return ret; 599 }, 600 601 inArray: function( elem, array ) { 602 if ( array.indexOf ) { 603 return array.indexOf( elem ); 604 } 605 606 for ( var i = 0, length = array.length; i < length; i++ ) { 607 if ( array[ i ] === elem ) { 608 return i; 609 } 610 } 611 612 return -1; 613 }, 614 615 merge: function( first, second ) { 616 var i = first.length, j = 0; 617 618 if ( typeof second.length === "number" ) { 619 for ( var l = second.length; j < l; j++ ) { 620 first[ i++ ] = second[ j ]; 621 } 622 } else { 623 while ( second[j] !== undefined ) { 624 first[ i++ ] = second[ j++ ]; 625 } 626 } 627 628 first.length = i; 629 630 return first; 631 }, 632 633 grep: function( elems, callback, inv ) { 634 var ret = []; 635 636 // Go through the array, only saving the items 637 // that pass the validator function 638 for ( var i = 0, length = elems.length; i < length; i++ ) { 639 if ( !inv !== !callback( elems[ i ], i ) ) { 640 ret.push( elems[ i ] ); 641 } 642 } 643 644 return ret; 645 }, 646 647 // arg is for internal usage only 648 map: function( elems, callback, arg ) { 649 var ret = [], value; 650 651 // Go through the array, translating each of the items to their 652 // new value (or values). 653 for ( var i = 0, length = elems.length; i < length; i++ ) { 654 value = callback( elems[ i ], i, arg ); 655 656 if ( value != null ) { 657 ret[ ret.length ] = value; 658 } 659 } 660 661 return ret.concat.apply( [], ret ); 662 }, 663 664 // A global GUID counter for objects 665 guid: 1, 666 667 proxy: function( fn, proxy, thisObject ) { 668 if ( arguments.length === 2 ) { 669 if ( typeof proxy === "string" ) { 670 thisObject = fn; 671 fn = thisObject[ proxy ]; 672 proxy = undefined; 673 674 } else if ( proxy && !jQuery.isFunction( proxy ) ) { 675 thisObject = proxy; 676 proxy = undefined; 677 } 678 } 679 680 if ( !proxy && fn ) { 681 proxy = function() { 682 return fn.apply( thisObject || this, arguments ); 683 }; 684 } 685 686 // Set the guid of unique handler to the same of original handler, so it can be removed 687 if ( fn ) { 688 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 689 } 690 691 // So proxy can be declared as an argument 692 return proxy; 693 }, 694 695 // Use of jQuery.browser is frowned upon. 696 // More details: http://docs.jquery.com/Utilities/jQuery.browser 697 uaMatch: function( ua ) { 698 ua = ua.toLowerCase(); 699 700 var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) || 701 /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) || 702 /(msie) ([\w.]+)/.exec( ua ) || 703 !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) || 704 []; 705 706 return { browser: match[1] || "", version: match[2] || "0" }; 707 }, 708 709 browser: {} 710 }); 711 712 browserMatch = jQuery.uaMatch( userAgent ); 713 if ( browserMatch.browser ) { 714 jQuery.browser[ browserMatch.browser ] = true; 715 jQuery.browser.version = browserMatch.version; 716 } 717 718 // Deprecated, use jQuery.browser.webkit instead 719 if ( jQuery.browser.webkit ) { 720 jQuery.browser.safari = true; 721 } 722 723 if ( indexOf ) { 724 jQuery.inArray = function( elem, array ) { 725 return indexOf.call( array, elem ); 726 }; 727 } 728 729 // All jQuery objects should point back to these 730 rootjQuery = jQuery(document); 731 732 // Cleanup functions for the document ready method 733 if ( document.addEventListener ) { 734 DOMContentLoaded = function() { 735 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 736 jQuery.ready(); 737 }; 738 739 } else if ( document.attachEvent ) { 740 DOMContentLoaded = function() { 741 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 742 if ( document.readyState === "complete" ) { 743 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 744 jQuery.ready(); 745 } 746 }; 747 } 748 749 // The DOM ready check for Internet Explorer 750 function doScrollCheck() { 751 if ( jQuery.isReady ) { 752 return; 753 } 754 755 try { 756 // If IE is used, use the trick by Diego Perini 757 // http://javascript.nwbox.com/IEContentLoaded/ 758 document.documentElement.doScroll("left"); 759 } catch( error ) { 760 setTimeout( doScrollCheck, 1 ); 761 return; 762 } 763 764 // and execute any waiting functions 765 jQuery.ready(); 766 } 767 768 function evalScript( i, elem ) { 769 if ( elem.src ) { 770 jQuery.ajax({ 771 url: elem.src, 772 async: false, 773 dataType: "script" 774 }); 775 } else { 776 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 777 } 778 779 if ( elem.parentNode ) { 780 elem.parentNode.removeChild( elem ); 781 } 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 function access( 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 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 ) : null; 811 } 812 813 function now() { 814 return (new Date).getTime(); 815 } 816 (function() { 817 818 jQuery.support = {}; 819 820 var root = document.documentElement, 821 script = document.createElement("script"), 822 div = document.createElement("div"), 823 id = "script" + now(); 824 825 div.style.display = "none"; 826 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; 827 828 var all = div.getElementsByTagName("*"), 829 a = div.getElementsByTagName("a")[0]; 830 831 // Can't get basic test support 832 if ( !all || !all.length || !a ) { 833 return; 834 } 835 836 jQuery.support = { 837 // IE strips leading whitespace when .innerHTML is used 838 leadingWhitespace: div.firstChild.nodeType === 3, 839 840 // Make sure that tbody elements aren't automatically inserted 841 // IE will insert them into empty tables 842 tbody: !div.getElementsByTagName("tbody").length, 843 844 // Make sure that link elements get serialized correctly by innerHTML 845 // This requires a wrapper element in IE 846 htmlSerialize: !!div.getElementsByTagName("link").length, 847 848 // Get the style information from getAttribute 849 // (IE uses .cssText insted) 850 style: /red/.test( a.getAttribute("style") ), 851 852 // Make sure that URLs aren't manipulated 853 // (IE normalizes it by default) 854 hrefNormalized: a.getAttribute("href") === "/a", 855 856 // Make sure that element opacity exists 857 // (IE uses filter instead) 858 // Use a regex to work around a WebKit issue. See #5145 859 opacity: /^0.55$/.test( a.style.opacity ), 860 861 // Verify style float existence 862 // (IE uses styleFloat instead of cssFloat) 863 cssFloat: !!a.style.cssFloat, 864 865 // Make sure that if no value is specified for a checkbox 866 // that it defaults to "on". 867 // (WebKit defaults to "" instead) 868 checkOn: div.getElementsByTagName("input")[0].value === "on", 869 870 // Make sure that a selected-by-default option has a working selected property. 871 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 872 optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected, 873 874 // Will be defined later 875 checkClone: false, 876 scriptEval: false, 877 noCloneEvent: true, 878 boxModel: null 879 }; 880 881 script.type = "text/javascript"; 882 try { 883 script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); 884 } catch(e) {} 885 886 root.insertBefore( script, root.firstChild ); 887 888 // Make sure that the execution of code works by injecting a script 889 // tag with appendChild/createTextNode 890 // (IE doesn't support this, fails, and uses .text instead) 891 if ( window[ id ] ) { 892 jQuery.support.scriptEval = true; 893 delete window[ id ]; 894 } 895 896 root.removeChild( script ); 897 898 if ( div.attachEvent && div.fireEvent ) { 899 div.attachEvent("onclick", function click() { 900 // Cloning a node shouldn't copy over any 901 // bound event handlers (IE does this) 902 jQuery.support.noCloneEvent = false; 903 div.detachEvent("onclick", click); 904 }); 905 div.cloneNode(true).fireEvent("onclick"); 906 } 907 908 div = document.createElement("div"); 909 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>"; 910 911 var fragment = document.createDocumentFragment(); 912 fragment.appendChild( div.firstChild ); 913 914 // WebKit doesn't clone checked state correctly in fragments 915 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; 916 917 // Figure out if the W3C box model works as expected 918 // document.body must exist before we can do this 919 jQuery(function() { 920 var div = document.createElement("div"); 921 div.style.width = div.style.paddingLeft = "1px"; 922 923 document.body.appendChild( div ); 924 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; 925 document.body.removeChild( div ).style.display = 'none'; 926 div = null; 927 }); 928 929 // Technique from Juriy Zaytsev 930 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ 931 var eventSupported = function( eventName ) { 932 var el = document.createElement("div"); 933 eventName = "on" + eventName; 934 935 var isSupported = (eventName in el); 936 if ( !isSupported ) { 937 el.setAttribute(eventName, "return;"); 938 isSupported = typeof el[eventName] === "function"; 939 } 940 el = null; 941 942 return isSupported; 943 }; 944 945 jQuery.support.submitBubbles = eventSupported("submit"); 946 jQuery.support.changeBubbles = eventSupported("change"); 947 948 // release memory in IE 949 root = script = div = all = a = null; 950 })(); 951 952 jQuery.props = { 953 "for": "htmlFor", 954 "class": "className", 955 readonly: "readOnly", 956 maxlength: "maxLength", 957 cellspacing: "cellSpacing", 958 rowspan: "rowSpan", 959 colspan: "colSpan", 960 tabindex: "tabIndex", 961 usemap: "useMap", 962 frameborder: "frameBorder" 963 }; 964 var expando = "jQuery" + now(), uuid = 0, windowData = {}; 965 var emptyObject = {}; 966 967 jQuery.extend({ 968 cache: {}, 969 970 expando:expando, 971 972 // The following elements throw uncatchable exceptions if you 973 // attempt to add expando properties to them. 974 noData: { 975 "embed": true, 976 "object": true, 977 "applet": true 978 }, 979 980 data: function( elem, name, data ) { 981 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { 982 return; 983 } 984 985 elem = elem == window ? 986 windowData : 987 elem; 988 989 var id = elem[ expando ], cache = jQuery.cache, thisCache; 990 991 // Handle the case where there's no name immediately 992 if ( !name && !id ) { 993 return null; 994 } 995 996 // Compute a unique ID for the element 997 if ( !id ) { 998 id = ++uuid; 999 } 1000 1001 // Avoid generating a new cache unless none exists and we 1002 // want to manipulate it. 1003 if ( typeof name === "object" ) { 1004 elem[ expando ] = id; 1005 thisCache = cache[ id ] = jQuery.extend(true, {}, name); 1006 } else if ( cache[ id ] ) { 1007 thisCache = cache[ id ]; 1008 } else if ( typeof data === "undefined" ) { 1009 thisCache = emptyObject; 1010 } else { 1011 thisCache = cache[ id ] = {}; 1012 } 1013 1014 // Prevent overriding the named cache with undefined values 1015 if ( data !== undefined ) { 1016 elem[ expando ] = id; 1017 thisCache[ name ] = data; 1018 } 1019 1020 return typeof name === "string" ? thisCache[ name ] : thisCache; 1021 }, 1022 1023 removeData: function( elem, name ) { 1024 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { 1025 return; 1026 } 1027 1028 elem = elem == window ? 1029 windowData : 1030 elem; 1031 1032 var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ]; 1033 1034 // If we want to remove a specific section of the element's data 1035 if ( name ) { 1036 if ( thisCache ) { 1037 // Remove the section of cache data 1038 delete thisCache[ name ]; 1039 1040 // If we've removed all the data, remove the element's cache 1041 if ( jQuery.isEmptyObject(thisCache) ) { 1042 jQuery.removeData( elem ); 1043 } 1044 } 1045 1046 // Otherwise, we want to remove all of the element's data 1047 } else { 1048 // Clean up the element expando 1049 try { 1050 delete elem[ expando ]; 1051 } catch( e ) { 1052 // IE has trouble directly removing the expando 1053 // but it's ok with using removeAttribute 1054 if ( elem.removeAttribute ) { 1055 elem.removeAttribute( expando ); 1056 } 1057 } 1058 1059 // Completely remove the data cache 1060 delete cache[ id ]; 1061 } 1062 } 1063 }); 1064 1065 jQuery.fn.extend({ 1066 data: function( key, value ) { 1067 if ( typeof key === "undefined" && this.length ) { 1068 return jQuery.data( this[0] ); 1069 1070 } else if ( typeof key === "object" ) { 1071 return this.each(function() { 1072 jQuery.data( this, key ); 1073 }); 1074 } 1075 1076 var parts = key.split("."); 1077 parts[1] = parts[1] ? "." + parts[1] : ""; 1078 1079 if ( value === undefined ) { 1080 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 1081 1082 if ( data === undefined && this.length ) { 1083 data = jQuery.data( this[0], key ); 1084 } 1085 return data === undefined && parts[1] ? 1086 this.data( parts[0] ) : 1087 data; 1088 } else { 1089 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() { 1090 jQuery.data( this, key, value ); 1091 }); 1092 } 1093 }, 1094 1095 removeData: function( key ) { 1096 return this.each(function() { 1097 jQuery.removeData( this, key ); 1098 }); 1099 } 1100 }); 1101 jQuery.extend({ 1102 queue: function( elem, type, data ) { 1103 if ( !elem ) { 1104 return; 1105 } 1106 1107 type = (type || "fx") + "queue"; 1108 var q = jQuery.data( elem, type ); 1109 1110 // Speed up dequeue by getting out quickly if this is just a lookup 1111 if ( !data ) { 1112 return q || []; 1113 } 1114 1115 if ( !q || jQuery.isArray(data) ) { 1116 q = jQuery.data( elem, type, jQuery.makeArray(data) ); 1117 1118 } else { 1119 q.push( data ); 1120 } 1121 1122 return q; 1123 }, 1124 1125 dequeue: function( elem, type ) { 1126 type = type || "fx"; 1127 1128 var queue = jQuery.queue( elem, type ), fn = queue.shift(); 1129 1130 // If the fx queue is dequeued, always remove the progress sentinel 1131 if ( fn === "inprogress" ) { 1132 fn = queue.shift(); 1133 } 1134 1135 if ( fn ) { 1136 // Add a progress sentinel to prevent the fx queue from being 1137 // automatically dequeued 1138 if ( type === "fx" ) { 1139 queue.unshift("inprogress"); 1140 } 1141 1142 fn.call(elem, function() { 1143 jQuery.dequeue(elem, type); 1144 }); 1145 } 1146 } 1147 }); 1148 1149 jQuery.fn.extend({ 1150 queue: function( type, data ) { 1151 if ( typeof type !== "string" ) { 1152 data = type; 1153 type = "fx"; 1154 } 1155 1156 if ( data === undefined ) { 1157 return jQuery.queue( this[0], type ); 1158 } 1159 return this.each(function( i, elem ) { 1160 var queue = jQuery.queue( this, type, data ); 1161 1162 if ( type === "fx" && queue[0] !== "inprogress" ) { 1163 jQuery.dequeue( this, type ); 1164 } 1165 }); 1166 }, 1167 dequeue: function( type ) { 1168 return this.each(function() { 1169 jQuery.dequeue( this, type ); 1170 }); 1171 }, 1172 1173 // Based off of the plugin by Clint Helfers, with permission. 1174 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 1175 delay: function( time, type ) { 1176 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; 1177 type = type || "fx"; 1178 1179 return this.queue( type, function() { 1180 var elem = this; 1181 setTimeout(function() { 1182 jQuery.dequeue( elem, type ); 1183 }, time ); 1184 }); 1185 }, 1186 1187 clearQueue: function( type ) { 1188 return this.queue( type || "fx", [] ); 1189 } 1190 }); 1191 var rclass = /[\n\t]/g, 1192 rspace = /\s+/, 1193 rreturn = /\r/g, 1194 rspecialurl = /href|src|style/, 1195 rtype = /(button|input)/i, 1196 rfocusable = /(button|input|object|select|textarea)/i, 1197 rclickable = /^(a|area)$/i, 1198 rradiocheck = /radio|checkbox/; 1199 1200 jQuery.fn.extend({ 1201 attr: function( name, value ) { 1202 return access( this, name, value, true, jQuery.attr ); 1203 }, 1204 1205 removeAttr: function( name, fn ) { 1206 return this.each(function(){ 1207 jQuery.attr( this, name, "" ); 1208 if ( this.nodeType === 1 ) { 1209 this.removeAttribute( name ); 1210 } 1211 }); 1212 }, 1213 1214 addClass: function( value ) { 1215 if ( jQuery.isFunction(value) ) { 1216 return this.each(function(i) { 1217 var self = jQuery(this); 1218 self.addClass( value.call(this, i, self.attr("class")) ); 1219 }); 1220 } 1221 1222 if ( value && typeof value === "string" ) { 1223 var classNames = (value || "").split( rspace ); 1224 1225 for ( var i = 0, l = this.length; i < l; i++ ) { 1226 var elem = this[i]; 1227 1228 if ( elem.nodeType === 1 ) { 1229 if ( !elem.className ) { 1230 elem.className = value; 1231 1232 } else { 1233 var className = " " + elem.className + " "; 1234 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1235 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { 1236 elem.className += " " + classNames[c]; 1237 } 1238 } 1239 } 1240 } 1241 } 1242 } 1243 1244 return this; 1245 }, 1246 1247 removeClass: function( value ) { 1248 if ( jQuery.isFunction(value) ) { 1249 return this.each(function(i) { 1250 var self = jQuery(this); 1251 self.removeClass( value.call(this, i, self.attr("class")) ); 1252 }); 1253 } 1254 1255 if ( (value && typeof value === "string") || value === undefined ) { 1256 var classNames = (value || "").split(rspace); 1257 1258 for ( var i = 0, l = this.length; i < l; i++ ) { 1259 var elem = this[i]; 1260 1261 if ( elem.nodeType === 1 && elem.className ) { 1262 if ( value ) { 1263 var className = (" " + elem.className + " ").replace(rclass, " "); 1264 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { 1265 className = className.replace(" " + classNames[c] + " ", " "); 1266 } 1267 elem.className = className.substring(1, className.length - 1); 1268 1269 } else { 1270 elem.className = ""; 1271 } 1272 } 1273 } 1274 } 1275 1276 return this; 1277 }, 1278 1279 toggleClass: function( value, stateVal ) { 1280 var type = typeof value, isBool = typeof stateVal === "boolean"; 1281 1282 if ( jQuery.isFunction( value ) ) { 1283 return this.each(function(i) { 1284 var self = jQuery(this); 1285 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); 1286 }); 1287 } 1288 1289 return this.each(function() { 1290 if ( type === "string" ) { 1291 // toggle individual class names 1292 var className, i = 0, self = jQuery(this), 1293 state = stateVal, 1294 classNames = value.split( rspace ); 1295 1296 while ( (className = classNames[ i++ ]) ) { 1297 // check each className given, space seperated list 1298 state = isBool ? state : !self.hasClass( className ); 1299 self[ state ? "addClass" : "removeClass" ]( className ); 1300 } 1301 1302 } else if ( type === "undefined" || type === "boolean" ) { 1303 if ( this.className ) { 1304 // store className if set 1305 jQuery.data( this, "__className__", this.className ); 1306 } 1307 1308 // toggle whole className 1309 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || ""; 1310 } 1311 }); 1312 }, 1313 1314 hasClass: function( selector ) { 1315 var className = " " + selector + " "; 1316 for ( var i = 0, l = this.length; i < l; i++ ) { 1317 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { 1318 return true; 1319 } 1320 } 1321 1322 return false; 1323 }, 1324 1325 val: function( value ) { 1326 if ( value === undefined ) { 1327 var elem = this[0]; 1328 1329 if ( elem ) { 1330 if ( jQuery.nodeName( elem, "option" ) ) { 1331 return (elem.attributes.value || {}).specified ? elem.value : elem.text; 1332 } 1333 1334 // We need to handle select boxes special 1335 if ( jQuery.nodeName( elem, "select" ) ) { 1336 var index = elem.selectedIndex, 1337 values = [], 1338 options = elem.options, 1339 one = elem.type === "select-one"; 1340 1341 // Nothing was selected 1342 if ( index < 0 ) { 1343 return null; 1344 } 1345 1346 // Loop through all the selected options 1347 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 1348 var option = options[ i ]; 1349 1350 if ( option.selected ) { 1351 // Get the specifc value for the option 1352 value = jQuery(option).val(); 1353 1354 // We don't need an array for one selects 1355 if ( one ) { 1356 return value; 1357 } 1358 1359 // Multi-Selects return an array 1360 values.push( value ); 1361 } 1362 } 1363 1364 return values; 1365 } 1366 1367 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 1368 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { 1369 return elem.getAttribute("value") === null ? "on" : elem.value; 1370 } 1371 1372 1373 // Everything else, we just grab the value 1374 return (elem.value || "").replace(rreturn, ""); 1375 1376 } 1377 1378 return undefined; 1379 } 1380 1381 var isFunction = jQuery.isFunction(value); 1382 1383 return this.each(function(i) { 1384 var self = jQuery(this), val = value; 1385 1386 if ( this.nodeType !== 1 ) { 1387 return; 1388 } 1389 1390 if ( isFunction ) { 1391 val = value.call(this, i, self.val()); 1392 } 1393 1394 // Typecast each time if the value is a Function and the appended 1395 // value is therefore different each time. 1396 if ( typeof val === "number" ) { 1397 val += ""; 1398 } 1399 1400 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { 1401 this.checked = jQuery.inArray( self.val(), val ) >= 0; 1402 1403 } else if ( jQuery.nodeName( this, "select" ) ) { 1404 var values = jQuery.makeArray(val); 1405 1406 jQuery( "option", this ).each(function() { 1407 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 1408 }); 1409 1410 if ( !values.length ) { 1411 this.selectedIndex = -1; 1412 } 1413 1414 } else { 1415 this.value = val; 1416 } 1417 }); 1418 } 1419 }); 1420 1421 jQuery.extend({ 1422 attrFn: { 1423 val: true, 1424 css: true, 1425 html: true, 1426 text: true, 1427 data: true, 1428 width: true, 1429 height: true, 1430 offset: true 1431 }, 1432 1433 attr: function( elem, name, value, pass ) { 1434 // don't set attributes on text and comment nodes 1435 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 1436 return undefined; 1437 } 1438 1439 if ( pass && name in jQuery.attrFn ) { 1440 return jQuery(elem)[name](value); 1441 } 1442 1443 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), 1444 // Whether we are setting (or getting) 1445 set = value !== undefined; 1446 1447 // Try to normalize/fix the name 1448 name = notxml && jQuery.props[ name ] || name; 1449 1450 // Only do all the following if this is a node (faster for style) 1451 if ( elem.nodeType === 1 ) { 1452 // These attributes require special treatment 1453 var special = rspecialurl.test( name ); 1454 1455 // Safari mis-reports the default selected property of an option 1456 // Accessing the parent's selectedIndex property fixes it 1457 if ( name === "selected" && !jQuery.support.optSelected ) { 1458 var parent = elem.parentNode; 1459 if ( parent ) { 1460 parent.selectedIndex; 1461 1462 // Make sure that it also works with optgroups, see #5701 1463 if ( parent.parentNode ) { 1464 parent.parentNode.selectedIndex; 1465 } 1466 } 1467 } 1468 1469 // If applicable, access the attribute via the DOM 0 way 1470 if ( name in elem && notxml && !special ) { 1471 if ( set ) { 1472 // We can't allow the type property to be changed (since it causes problems in IE) 1473 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { 1474 jQuery.error( "type property can't be changed" ); 1475 } 1476 1477 elem[ name ] = value; 1478 } 1479 1480 // browsers index elements by id/name on forms, give priority to attributes. 1481 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { 1482 return elem.getAttributeNode( name ).nodeValue; 1483 } 1484 1485 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 1486 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 1487 if ( name === "tabIndex" ) { 1488 var attributeNode = elem.getAttributeNode( "tabIndex" ); 1489 1490 return attributeNode && attributeNode.specified ? 1491 attributeNode.value : 1492 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 1493 0 : 1494 undefined; 1495 } 1496 1497 return elem[ name ]; 1498 } 1499 1500 if ( !jQuery.support.style && notxml && name === "style" ) { 1501 if ( set ) { 1502 elem.style.cssText = "" + value; 1503 } 1504 1505 return elem.style.cssText; 1506 } 1507 1508 if ( set ) { 1509 // convert the value to a string (all browsers do this but IE) see #1070 1510 elem.setAttribute( name, "" + value ); 1511 } 1512 1513 var attr = !jQuery.support.hrefNormalized && notxml && special ? 1514 // Some attributes require a special call on IE 1515 elem.getAttribute( name, 2 ) : 1516 elem.getAttribute( name ); 1517 1518 // Non-existent attributes return null, we normalize to undefined 1519 return attr === null ? undefined : attr; 1520 } 1521 1522 // elem is actually elem.style ... set the style 1523 // Using attr for specific style information is now deprecated. Use style insead. 1524 return jQuery.style( elem, name, value ); 1525 } 1526 }); 1527 var fcleanup = function( nm ) { 1528 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) { 1529 return "\\" + ch; 1530 }); 1531 }; 1532 1533 /* 1534 * A number of helper functions used for managing events. 1535 * Many of the ideas behind this code originated from 1536 * Dean Edwards' addEvent library. 1537 */ 1538 jQuery.event = { 1539 1540 // Bind an event to an element 1541 // Original by Dean Edwards 1542 add: function( elem, types, handler, data ) { 1543 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 1544 return; 1545 } 1546 1547 // For whatever reason, IE has trouble passing the window object 1548 // around, causing it to be cloned in the process 1549 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) { 1550 elem = window; 1551 } 1552 1553 // Make sure that the function being executed has a unique ID 1554 if ( !handler.guid ) { 1555 handler.guid = jQuery.guid++; 1556 } 1557 1558 // if data is passed, bind to handler 1559 if ( data !== undefined ) { 1560 // Create temporary function pointer to original handler 1561 var fn = handler; 1562 1563 // Create unique handler function, wrapped around original handler 1564 handler = jQuery.proxy( fn ); 1565 1566 // Store data in unique handler 1567 handler.data = data; 1568 } 1569 1570 // Init the element's event structure 1571 var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ), 1572 handle = jQuery.data( elem, "handle" ), eventHandle; 1573 1574 if ( !handle ) { 1575 eventHandle = function() { 1576 // Handle the second event of a trigger and when 1577 // an event is called after a page has unloaded 1578 return typeof jQuery !== "undefined" && !jQuery.event.triggered ? 1579 jQuery.event.handle.apply( eventHandle.elem, arguments ) : 1580 undefined; 1581 }; 1582 1583 handle = jQuery.data( elem, "handle", eventHandle ); 1584 } 1585 1586 // If no handle is found then we must be trying to bind to one of the 1587 // banned noData elements 1588 if ( !handle ) { 1589 return; 1590 } 1591 1592 // Add elem as a property of the handle function 1593 // This is to prevent a memory leak with non-native 1594 // event in IE. 1595 handle.elem = elem; 1596 1597 // Handle multiple events separated by a space 1598 // jQuery(...).bind("mouseover mouseout", fn); 1599 types = types.split( /\s+/ ); 1600 1601 var type, i = 0; 1602 1603 while ( (type = types[ i++ ]) ) { 1604 // Namespaced event handlers 1605 var namespaces = type.split("."); 1606 type = namespaces.shift(); 1607 1608 if ( i > 1 ) { 1609 handler = jQuery.proxy( handler ); 1610 1611 if ( data !== undefined ) { 1612 handler.data = data; 1613 } 1614 } 1615 1616 handler.type = namespaces.slice(0).sort().join("."); 1617 1618 // Get the current list of functions bound to this event 1619 var handlers = events[ type ], 1620 special = this.special[ type ] || {}; 1621 1622 // Init the event handler queue 1623 if ( !handlers ) { 1624 handlers = events[ type ] = {}; 1625 1626 // Check for a special event handler 1627 // Only use addEventListener/attachEvent if the special 1628 // events handler returns false 1629 if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) { 1630 // Bind the global event handler to the element 1631 if ( elem.addEventListener ) { 1632 elem.addEventListener( type, handle, false ); 1633 } else if ( elem.attachEvent ) { 1634 elem.attachEvent( "on" + type, handle ); 1635 } 1636 } 1637 } 1638 1639 if ( special.add ) { 1640 var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers ); 1641 if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) { 1642 modifiedHandler.guid = modifiedHandler.guid || handler.guid; 1643 modifiedHandler.data = modifiedHandler.data || handler.data; 1644 modifiedHandler.type = modifiedHandler.type || handler.type; 1645 handler = modifiedHandler; 1646 } 1647 } 1648 1649 // Add the function to the element's handler list 1650 handlers[ handler.guid ] = handler; 1651 1652 // Keep track of which events have been used, for global triggering 1653 this.global[ type ] = true; 1654 } 1655 1656 // Nullify elem to prevent memory leaks in IE 1657 elem = null; 1658 }, 1659 1660 global: {}, 1661 1662 // Detach an event or set of events from an element 1663 remove: function( elem, types, handler ) { 1664 // don't do events on text and comment nodes 1665 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 1666 return; 1667 } 1668 1669 var events = jQuery.data( elem, "events" ), ret, type, fn; 1670 1671 if ( events ) { 1672 // Unbind all events for the element 1673 if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) { 1674 for ( type in events ) { 1675 this.remove( elem, type + (types || "") ); 1676 } 1677 } else { 1678 // types is actually an event object here 1679 if ( types.type ) { 1680 handler = types.handler; 1681 types = types.type; 1682 } 1683 1684 // Handle multiple events separated by a space 1685 // jQuery(...).unbind("mouseover mouseout", fn); 1686 types = types.split(/\s+/); 1687 var i = 0; 1688 while ( (type = types[ i++ ]) ) { 1689 // Namespaced event handlers 1690 var namespaces = type.split("."); 1691 type = namespaces.shift(); 1692 var all = !namespaces.length, 1693 cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ), 1694 namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"), 1695 special = this.special[ type ] || {}; 1696 1697 if ( events[ type ] ) { 1698 // remove the given handler for the given type 1699 if ( handler ) { 1700 fn = events[ type ][ handler.guid ]; 1701 delete events[ type ][ handler.guid ]; 1702 1703 // remove all handlers for the given type 1704 } else { 1705 for ( var handle in events[ type ] ) { 1706 // Handle the removal of namespaced events 1707 if ( all || namespace.test( events[ type ][ handle ].type ) ) { 1708 delete events[ type ][ handle ]; 1709 } 1710 } 1711 } 1712 1713 if ( special.remove ) { 1714 special.remove.call( elem, namespaces, fn); 1715 } 1716 1717 // remove generic event handler if no more handlers exist 1718 for ( ret in events[ type ] ) { 1719 break; 1720 } 1721 if ( !ret ) { 1722 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { 1723 if ( elem.removeEventListener ) { 1724 elem.removeEventListener( type, jQuery.data( elem, "handle" ), false ); 1725 } else if ( elem.detachEvent ) { 1726 elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) ); 1727 } 1728 } 1729 ret = null; 1730 delete events[ type ]; 1731 } 1732 } 1733 } 1734 } 1735 1736 // Remove the expando if it's no longer used 1737 for ( ret in events ) { 1738 break; 1739 } 1740 if ( !ret ) { 1741 var handle = jQuery.data( elem, "handle" ); 1742 if ( handle ) { 1743 handle.elem = null; 1744 } 1745 jQuery.removeData( elem, "events" ); 1746 jQuery.removeData( elem, "handle" ); 1747 } 1748 } 1749 }, 1750 1751 // bubbling is internal 1752 trigger: function( event, data, elem /*, bubbling */ ) { 1753 // Event object or event type 1754 var type = event.type || event, 1755 bubbling = arguments[3]; 1756 1757 if ( !bubbling ) { 1758 event = typeof event === "object" ? 1759 // jQuery.Event object 1760 event[expando] ? event : 1761 // Object literal 1762 jQuery.extend( jQuery.Event(type), event ) : 1763 // Just the event type (string) 1764 jQuery.Event(type); 1765 1766 if ( type.indexOf("!") >= 0 ) { 1767 event.type = type = type.slice(0, -1); 1768 event.exclusive = true; 1769 } 1770 1771 // Handle a global trigger 1772 if ( !elem ) { 1773 // Don't bubble custom events when global (to avoid too much overhead) 1774 event.stopPropagation(); 1775 1776 // Only trigger if we've ever bound an event for it 1777 if ( this.global[ type ] ) { 1778 jQuery.each( jQuery.cache, function() { 1779 if ( this.events && this.events[type] ) { 1780 jQuery.event.trigger( event, data, this.handle.elem ); 1781 } 1782 }); 1783 } 1784 } 1785 1786 // Handle triggering a single element 1787 1788 // don't do events on text and comment nodes 1789 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 1790 return undefined; 1791 } 1792 1793 // Clean up in case it is reused 1794 event.result = undefined; 1795 event.target = elem; 1796 1797 // Clone the incoming data, if any 1798 data = jQuery.makeArray( data ); 1799 data.unshift( event ); 1800 } 1801 1802 event.currentTarget = elem; 1803 1804 // Trigger the event, it is assumed that "handle" is a function 1805 var handle = jQuery.data( elem, "handle" ); 1806 if ( handle ) { 1807 handle.apply( elem, data ); 1808 } 1809 1810 var parent = elem.parentNode || elem.ownerDocument; 1811 1812 // Trigger an inline bound script 1813 try { 1814 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { 1815 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { 1816 event.result = false; 1817 } 1818 } 1819 1820 // prevent IE from throwing an error for some elements with some event types, see #3533 1821 } catch (e) {} 1822 1823 if ( !event.isPropagationStopped() && parent ) { 1824 jQuery.event.trigger( event, data, parent, true ); 1825 1826 } else if ( !event.isDefaultPrevented() ) { 1827 var target = event.target, old, 1828 isClick = jQuery.nodeName(target, "a") && type === "click"; 1829 1830 if ( !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { 1831 try { 1832 if ( target[ type ] ) { 1833 // Make sure that we don't accidentally re-trigger the onFOO events 1834 old = target[ "on" + type ]; 1835 1836 if ( old ) { 1837 target[ "on" + type ] = null; 1838 } 1839 1840 this.triggered = true; 1841 target[ type ](); 1842 } 1843 1844 // prevent IE from throwing an error for some elements with some event types, see #3533 1845 } catch (e) {} 1846 1847 if ( old ) { 1848 target[ "on" + type ] = old; 1849 } 1850 1851 this.triggered = false; 1852 } 1853 } 1854 }, 1855 1856 handle: function( event ) { 1857 // returned undefined or false 1858 var all, handlers; 1859 1860 event = arguments[0] = jQuery.event.fix( event || window.event ); 1861 event.currentTarget = this; 1862 1863 // Namespaced event handlers 1864 var namespaces = event.type.split("."); 1865 event.type = namespaces.shift(); 1866 1867 // Cache this now, all = true means, any handler 1868 all = !namespaces.length && !event.exclusive; 1869 1870 var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)"); 1871 1872 handlers = ( jQuery.data(this, "events") || {} )[ event.type ]; 1873 1874 for ( var j in handlers ) { 1875 var handler = handlers[ j ]; 1876 1877 // Filter the functions by class 1878 if ( all || namespace.test(handler.type) ) { 1879 // Pass in a reference to the handler function itself 1880 // So that we can later remove it 1881 event.handler = handler; 1882 event.data = handler.data; 1883 1884 var ret = handler.apply( this, arguments ); 1885 1886 if ( ret !== undefined ) { 1887 event.result = ret; 1888 if ( ret === false ) { 1889 event.preventDefault(); 1890 event.stopPropagation(); 1891 } 1892 } 1893 1894 if ( event.isImmediatePropagationStopped() ) { 1895 break; 1896 } 1897 1898 } 1899 } 1900 1901 return event.result; 1902 }, 1903 1904 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), 1905 1906 fix: function( event ) { 1907 if ( event[ expando ] ) { 1908 return event; 1909 } 1910 1911 // store a copy of the original event object 1912 // and "clone" to set read-only properties 1913 var originalEvent = event; 1914 event = jQuery.Event( originalEvent ); 1915 1916 for ( var i = this.props.length, prop; i; ) { 1917 prop = this.props[ --i ]; 1918 event[ prop ] = originalEvent[ prop ]; 1919 } 1920 1921 // Fix target property, if necessary 1922 if ( !event.target ) { 1923 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 1924 } 1925 1926 // check if target is a textnode (safari) 1927 if ( event.target.nodeType === 3 ) { 1928 event.target = event.target.parentNode; 1929 } 1930 1931 // Add relatedTarget, if necessary 1932 if ( !event.relatedTarget && event.fromElement ) { 1933 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 1934 } 1935 1936 // Calculate pageX/Y if missing and clientX/Y available 1937 if ( event.pageX == null && event.clientX != null ) { 1938 var doc = document.documentElement, body = document.body; 1939 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 1940 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 1941 } 1942 1943 // Add which for key events 1944 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) { 1945 event.which = event.charCode || event.keyCode; 1946 } 1947 1948 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 1949 if ( !event.metaKey && event.ctrlKey ) { 1950 event.metaKey = event.ctrlKey; 1951 } 1952 1953 // Add which for click: 1 === left; 2 === middle; 3 === right 1954 // Note: button is not normalized, so don't use it 1955 if ( !event.which && event.button !== undefined ) { 1956 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 1957 } 1958 1959 return event; 1960 }, 1961 1962 // Deprecated, use jQuery.guid instead 1963 guid: 1E8, 1964 1965 // Deprecated, use jQuery.proxy instead 1966 proxy: jQuery.proxy, 1967 1968 special: { 1969 ready: { 1970 // Make sure the ready event is setup 1971 setup: jQuery.bindReady, 1972 teardown: jQuery.noop 1973 }, 1974 1975 live: { 1976 add: function( proxy, data, namespaces, live ) { 1977 jQuery.extend( proxy, data || {} ); 1978 1979 proxy.guid += data.selector + data.live; 1980 data.liveProxy = proxy; 1981 1982 jQuery.event.add( this, data.live, liveHandler, data ); 1983 1984 }, 1985 1986 remove: function( namespaces ) { 1987 if ( namespaces.length ) { 1988 var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)"); 1989 1990 jQuery.each( (jQuery.data(this, "events").live || {}), function() { 1991 if ( name.test(this.type) ) { 1992 remove++; 1993 } 1994 }); 1995 1996 if ( remove < 1 ) { 1997 jQuery.event.remove( this, namespaces[0], liveHandler ); 1998 } 1999 } 2000 }, 2001 special: {} 2002 }, 2003 beforeunload: { 2004 setup: function( data, namespaces, fn ) { 2005 // We only want to do this special case on windows 2006 if ( this.setInterval ) { 2007 this.onbeforeunload = fn; 2008 } 2009 2010 return false; 2011 }, 2012 teardown: function( namespaces, fn ) { 2013 if ( this.onbeforeunload === fn ) { 2014 this.onbeforeunload = null; 2015 } 2016 } 2017 } 2018 } 2019 }; 2020 2021 jQuery.Event = function( src ) { 2022 // Allow instantiation without the 'new' keyword 2023 if ( !this.preventDefault ) { 2024 return new jQuery.Event( src ); 2025 } 2026 2027 // Event object 2028 if ( src && src.type ) { 2029 this.originalEvent = src; 2030 this.type = src.type; 2031 // Event type 2032 } else { 2033 this.type = src; 2034 } 2035 2036 // timeStamp is buggy for some events on Firefox(#3843) 2037 // So we won't rely on the native value 2038 this.timeStamp = now(); 2039 2040 // Mark it as fixed 2041 this[ expando ] = true; 2042 }; 2043 2044 function returnFalse() { 2045 return false; 2046 } 2047 function returnTrue() { 2048 return true; 2049 } 2050 2051 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 2052 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 2053 jQuery.Event.prototype = { 2054 preventDefault: function() { 2055 this.isDefaultPrevented = returnTrue; 2056 2057 var e = this.originalEvent; 2058 if ( !e ) { 2059 return; 2060 } 2061 2062 // if preventDefault exists run it on the original event 2063 if ( e.preventDefault ) { 2064 e.preventDefault(); 2065 } 2066 // otherwise set the returnValue property of the original event to false (IE) 2067 e.returnValue = false; 2068 }, 2069 stopPropagation: function() { 2070 this.isPropagationStopped = returnTrue; 2071 2072 var e = this.originalEvent; 2073 if ( !e ) { 2074 return; 2075 } 2076 // if stopPropagation exists run it on the original event 2077 if ( e.stopPropagation ) { 2078 e.stopPropagation(); 2079 } 2080 // otherwise set the cancelBubble property of the original event to true (IE) 2081 e.cancelBubble = true; 2082 }, 2083 stopImmediatePropagation: function() { 2084 this.isImmediatePropagationStopped = returnTrue; 2085 this.stopPropagation(); 2086 }, 2087 isDefaultPrevented: returnFalse, 2088 isPropagationStopped: returnFalse, 2089 isImmediatePropagationStopped: returnFalse 2090 }; 2091 2092 // Checks if an event happened on an element within another element 2093 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2094 var withinElement = function( event ) { 2095 // Check if mouse(over|out) are still within the same parent element 2096 var parent = event.relatedTarget; 2097 2098 // Traverse up the tree 2099 while ( parent && parent !== this ) { 2100 // Firefox sometimes assigns relatedTarget a XUL element 2101 // which we cannot access the parentNode property of 2102 try { 2103 parent = parent.parentNode; 2104 2105 // assuming we've left the element since we most likely mousedover a xul element 2106 } catch(e) { 2107 break; 2108 } 2109 } 2110 2111 if ( parent !== this ) { 2112 // set the correct event type 2113 event.type = event.data; 2114 2115 // handle event if we actually just moused on to a non sub-element 2116 jQuery.event.handle.apply( this, arguments ); 2117 } 2118 2119 }, 2120 2121 // In case of event delegation, we only need to rename the event.type, 2122 // liveHandler will take care of the rest. 2123 delegate = function( event ) { 2124 event.type = event.data; 2125 jQuery.event.handle.apply( this, arguments ); 2126 }; 2127 2128 // Create mouseenter and mouseleave events 2129 jQuery.each({ 2130 mouseenter: "mouseover", 2131 mouseleave: "mouseout" 2132 }, function( orig, fix ) { 2133 jQuery.event.special[ orig ] = { 2134 setup: function( data ) { 2135 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); 2136 }, 2137 teardown: function( data ) { 2138 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); 2139 } 2140 }; 2141 }); 2142 2143 // submit delegation 2144 if ( !jQuery.support.submitBubbles ) { 2145 2146 jQuery.event.special.submit = { 2147 setup: function( data, namespaces, fn ) { 2148 if ( this.nodeName.toLowerCase() !== "form" ) { 2149 jQuery.event.add(this, "click.specialSubmit." + fn.guid, function( e ) { 2150 var elem = e.target, type = elem.type; 2151 2152 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { 2153 return trigger( "submit", this, arguments ); 2154 } 2155 }); 2156 2157 jQuery.event.add(this, "keypress.specialSubmit." + fn.guid, function( e ) { 2158 var elem = e.target, type = elem.type; 2159 2160 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { 2161 return trigger( "submit", this, arguments ); 2162 } 2163 }); 2164 2165 } else { 2166 return false; 2167 } 2168 }, 2169 2170 remove: function( namespaces, fn ) { 2171 jQuery.event.remove( this, "click.specialSubmit" + (fn ? "."+fn.guid : "") ); 2172 jQuery.event.remove( this, "keypress.specialSubmit" + (fn ? "."+fn.guid : "") ); 2173 } 2174 }; 2175 2176 } 2177 2178 // change delegation, happens here so we have bind. 2179 if ( !jQuery.support.changeBubbles ) { 2180 2181 var formElems = /textarea|input|select/i; 2182 2183 function getVal( elem ) { 2184 var type = elem.type, val = elem.value; 2185 2186 if ( type === "radio" || type === "checkbox" ) { 2187 val = elem.checked; 2188 2189 } else if ( type === "select-multiple" ) { 2190 val = elem.selectedIndex > -1 ? 2191 jQuery.map( elem.options, function( elem ) { 2192 return elem.selected; 2193 }).join("-") : 2194 ""; 2195 2196 } else if ( elem.nodeName.toLowerCase() === "select" ) { 2197 val = elem.selectedIndex; 2198 } 2199 2200 return val; 2201 } 2202 2203 function testChange( e ) { 2204 var elem = e.target, data, val; 2205 2206 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) { 2207 return; 2208 } 2209 2210 data = jQuery.data( elem, "_change_data" ); 2211 val = getVal(elem); 2212 2213 // the current data will be also retrieved by beforeactivate 2214 if ( e.type !== "focusout" || elem.type !== "radio" ) { 2215 jQuery.data( elem, "_change_data", val ); 2216 } 2217 2218 if ( data === undefined || val === data ) { 2219 return; 2220 } 2221 2222 if ( data != null || val ) { 2223 e.type = "change"; 2224 return jQuery.event.trigger( e, arguments[1], elem ); 2225 } 2226 } 2227 2228 jQuery.event.special.change = { 2229 filters: { 2230 focusout: testChange, 2231 2232 click: function( e ) { 2233 var elem = e.target, type = elem.type; 2234 2235 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { 2236 return testChange.call( this, e ); 2237 } 2238 }, 2239 2240 // Change has to be called before submit 2241 // Keydown will be called before keypress, which is used in submit-event delegation 2242 keydown: function( e ) { 2243 var elem = e.target, type = elem.type; 2244 2245 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || 2246 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || 2247 type === "select-multiple" ) { 2248 return testChange.call( this, e ); 2249 } 2250 }, 2251 2252 // Beforeactivate happens also before the previous element is blurred 2253 // with this event you can't trigger a change event, but you can store 2254 // information/focus[in] is not needed anymore 2255 beforeactivate: function( e ) { 2256 var elem = e.target; 2257 2258 if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) { 2259 jQuery.data( elem, "_change_data", getVal(elem) ); 2260 } 2261 } 2262 }, 2263 setup: function( data, namespaces, fn ) { 2264 for ( var type in changeFilters ) { 2265 jQuery.event.add( this, type + ".specialChange." + fn.guid, changeFilters[type] ); 2266 } 2267 2268 return formElems.test( this.nodeName ); 2269 }, 2270 remove: function( namespaces, fn ) { 2271 for ( var type in changeFilters ) { 2272 jQuery.event.remove( this, type + ".specialChange" + (fn ? "."+fn.guid : ""), changeFilters[type] ); 2273 } 2274 2275 return formElems.test( this.nodeName ); 2276 } 2277 }; 2278 2279 var changeFilters = jQuery.event.special.change.filters; 2280 2281 } 2282 2283 function trigger( type, elem, args ) { 2284 args[0].type = type; 2285 return jQuery.event.handle.apply( elem, args ); 2286 } 2287 2288 // Create "bubbling" focus and blur events 2289 if ( document.addEventListener ) { 2290 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 2291 jQuery.event.special[ fix ] = { 2292 setup: function() { 2293 this.addEventListener( orig, handler, true ); 2294 }, 2295 teardown: function() { 2296 this.removeEventListener( orig, handler, true ); 2297 } 2298 }; 2299 2300 function handler( e ) { 2301 e = jQuery.event.fix( e ); 2302 e.type = fix; 2303 return jQuery.event.handle.call( this, e ); 2304 } 2305 }); 2306 } 2307 2308 jQuery.each(["bind", "one"], function( i, name ) { 2309 jQuery.fn[ name ] = function( type, data, fn ) { 2310 // Handle object literals 2311 if ( typeof type === "object" ) { 2312 for ( var key in type ) { 2313 this[ name ](key, data, type[key], fn); 2314 } 2315 return this; 2316 } 2317 2318 if ( jQuery.isFunction( data ) ) { 2319 fn = data; 2320 data = undefined; 2321 } 2322 2323 var handler = name === "one" ? jQuery.proxy( fn, function( event ) { 2324 jQuery( this ).unbind( event, handler ); 2325 return fn.apply( this, arguments ); 2326 }) : fn; 2327 2328 return type === "unload" && name !== "one" ? 2329 this.one( type, data, fn ) : 2330 this.each(function() { 2331 jQuery.event.add( this, type, handler, data ); 2332 }); 2333 }; 2334 }); 2335 2336 jQuery.fn.extend({ 2337 unbind: function( type, fn ) { 2338 // Handle object literals 2339 if ( typeof type === "object" && !type.preventDefault ) { 2340 for ( var key in type ) { 2341 this.unbind(key, type[key]); 2342 } 2343 return this; 2344 } 2345 2346 return this.each(function() { 2347 jQuery.event.remove( this, type, fn ); 2348 }); 2349 }, 2350 trigger: function( type, data ) { 2351 return this.each(function() { 2352 jQuery.event.trigger( type, data, this ); 2353 }); 2354 }, 2355 2356 triggerHandler: function( type, data ) { 2357 if ( this[0] ) { 2358 var event = jQuery.Event( type ); 2359 event.preventDefault(); 2360 event.stopPropagation(); 2361 jQuery.event.trigger( event, data, this[0] ); 2362 return event.result; 2363 } 2364 }, 2365 2366 toggle: function( fn ) { 2367 // Save reference to arguments for access in closure 2368 var args = arguments, i = 1; 2369 2370 // link all the functions, so any of them can unbind this click handler 2371 while ( i < args.length ) { 2372 jQuery.proxy( fn, args[ i++ ] ); 2373 } 2374 2375 return this.click( jQuery.proxy( fn, function( event ) { 2376 // Figure out which function to execute 2377 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; 2378 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 2379 2380 // Make sure that clicks stop 2381 event.preventDefault(); 2382 2383 // and execute the function 2384 return args[ lastToggle ].apply( this, arguments ) || false; 2385 })); 2386 }, 2387 2388 hover: function( fnOver, fnOut ) { 2389 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 2390 } 2391 }); 2392 2393 jQuery.each(["live", "die"], function( i, name ) { 2394 jQuery.fn[ name ] = function( types, data, fn ) { 2395 var type, i = 0; 2396 2397 if ( jQuery.isFunction( data ) ) { 2398 fn = data; 2399 data = undefined; 2400 } 2401 2402 types = (types || "").split( /\s+/ ); 2403 2404 while ( (type = types[ i++ ]) != null ) { 2405 type = type === "focus" ? "focusin" : // focus --> focusin 2406 type === "blur" ? "focusout" : // blur --> focusout 2407 type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support 2408 type; 2409 2410 if ( name === "live" ) { 2411 // bind live handler 2412 jQuery( this.context ).bind( liveConvert( type, this.selector ), { 2413 data: data, selector: this.selector, live: type 2414 }, fn ); 2415 2416 } else { 2417 // unbind live handler 2418 jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null ); 2419 } 2420 } 2421 2422 return this; 2423 } 2424 }); 2425 2426 function liveHandler( event ) { 2427 var stop, elems = [], selectors = [], args = arguments, 2428 related, match, fn, elem, j, i, l, data, 2429 live = jQuery.extend({}, jQuery.data( this, "events" ).live); 2430 2431 // Make sure we avoid non-left-click bubbling in Firefox (#3861) 2432 if ( event.button && event.type === "click" ) { 2433 return; 2434 } 2435 2436 for ( j in live ) { 2437 fn = live[j]; 2438 if ( fn.live === event.type || 2439 fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) { 2440 2441 data = fn.data; 2442 if ( !(data.beforeFilter && data.beforeFilter[event.type] && 2443 !data.beforeFilter[event.type](event)) ) { 2444 selectors.push( fn.selector ); 2445 } 2446 } else { 2447 delete live[j]; 2448 } 2449 } 2450 2451 match = jQuery( event.target ).closest( selectors, event.currentTarget ); 2452 2453 for ( i = 0, l = match.length; i < l; i++ ) { 2454 for ( j in live ) { 2455 fn = live[j]; 2456 elem = match[i].elem; 2457 related = null; 2458 2459 if ( match[i].selector === fn.selector ) { 2460 // Those two events require additional checking 2461 if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) { 2462 related = jQuery( event.relatedTarget ).closest( fn.selector )[0]; 2463 } 2464 2465 if ( !related || related !== elem ) { 2466 elems.push({ elem: elem, fn: fn }); 2467 } 2468 } 2469 } 2470 } 2471 2472 for ( i = 0, l = elems.length; i < l; i++ ) { 2473 match = elems[i]; 2474 event.currentTarget = match.elem; 2475 event.data = match.fn.data; 2476 if ( match.fn.apply( match.elem, args ) === false ) { 2477 stop = false; 2478 break; 2479 } 2480 } 2481 2482 return stop; 2483 } 2484 2485 function liveConvert( type, selector ) { 2486 return "live." + (type ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&"); 2487 } 2488 2489 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 2490 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 2491 "change select submit keydown keypress keyup error").split(" "), function( i, name ) { 2492 2493 // Handle event binding 2494 jQuery.fn[ name ] = function( fn ) { 2495 return fn ? this.bind( name, fn ) : this.trigger( name ); 2496 }; 2497 2498 if ( jQuery.attrFn ) { 2499 jQuery.attrFn[ name ] = true; 2500 } 2501 }); 2502 2503 // Prevent memory leaks in IE 2504 // Window isn't included so as not to unbind existing unload events 2505 // More info: 2506 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/ 2507 if ( window.attachEvent && !window.addEventListener ) { 2508 window.attachEvent("onunload", function() { 2509 for ( var id in jQuery.cache ) { 2510 if ( jQuery.cache[ id ].handle ) { 2511 // Try/Catch is to handle iframes being unloaded, see #4280 2512 try { 2513 jQuery.event.remove( jQuery.cache[ id ].handle.elem ); 2514 } catch(e) {} 2515 } 2516 } 2517 }); 2518 } 2519 /*! 2520 * Sizzle CSS Selector Engine - v1.0 2521 * Copyright 2009, The Dojo Foundation 2522 * Released under the MIT, BSD, and GPL Licenses. 2523 * More information: http://sizzlejs.com/ 2524 */ 2525 (function(){ 2526 2527 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, 2528 done = 0, 2529 toString = Object.prototype.toString, 2530 hasDuplicate = false, 2531 baseHasDuplicate = true; 2532 2533 // Here we check if the JavaScript engine is using some sort of 2534 // optimization where it does not always call our comparision 2535 // function. If that is the case, discard the hasDuplicate value. 2536 // Thus far that includes Google Chrome. 2537 [0, 0].sort(function(){ 2538 baseHasDuplicate = false; 2539 return 0; 2540 }); 2541 2542 var Sizzle = function(selector, context, results, seed) { 2543 results = results || []; 2544 var origContext = context = context || document; 2545 2546 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { 2547 return []; 2548 } 2549 2550 if ( !selector || typeof selector !== "string" ) { 2551 return results; 2552 } 2553 2554 var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context), 2555 soFar = selector; 2556 2557 // Reset the position of the chunker regexp (start from head) 2558 while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { 2559 soFar = m[3]; 2560 2561 parts.push( m[1] ); 2562 2563 if ( m[2] ) { 2564 extra = m[3]; 2565 break; 2566 } 2567 } 2568 2569 if ( parts.length > 1 && origPOS.exec( selector ) ) { 2570 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 2571 set = posProcess( parts[0] + parts[1], context ); 2572 } else { 2573 set = Expr.relative[ parts[0] ] ? 2574 [ context ] : 2575 Sizzle( parts.shift(), context ); 2576 2577 while ( parts.length ) { 2578 selector = parts.shift(); 2579 2580 if ( Expr.relative[ selector ] ) { 2581 selector += parts.shift(); 2582 } 2583 2584 set = posProcess( selector, set ); 2585 } 2586 } 2587 } else { 2588 // Take a shortcut and set the context if the root selector is an ID 2589 // (but not if it'll be faster if the inner selector is an ID) 2590 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && 2591 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { 2592 var ret = Sizzle.find( parts.shift(), context, contextXML ); 2593 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; 2594 } 2595 2596 if ( context ) { 2597 var ret = seed ? 2598 { expr: parts.pop(), set: makeArray(seed) } : 2599 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); 2600 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; 2601 2602 if ( parts.length > 0 ) { 2603 checkSet = makeArray(set); 2604 } else { 2605 prune = false; 2606 } 2607 2608 while ( parts.length ) { 2609 var cur = parts.pop(), pop = cur; 2610 2611 if ( !Expr.relative[ cur ] ) { 2612 cur = ""; 2613 } else { 2614 pop = parts.pop(); 2615 } 2616 2617 if ( pop == null ) { 2618 pop = context; 2619 } 2620 2621 Expr.relative[ cur ]( checkSet, pop, contextXML ); 2622 } 2623 } else { 2624 checkSet = parts = []; 2625 } 2626 } 2627 2628 if ( !checkSet ) { 2629 checkSet = set; 2630 } 2631 2632 if ( !checkSet ) { 2633 Sizzle.error( cur || selector ); 2634 } 2635 2636 if ( toString.call(checkSet) === "[object Array]" ) { 2637 if ( !prune ) { 2638 results.push.apply( results, checkSet ); 2639 } else if ( context && context.nodeType === 1 ) { 2640 for ( var i = 0; checkSet[i] != null; i++ ) { 2641 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { 2642 results.push( set[i] ); 2643 } 2644 } 2645 } else { 2646 for ( var i = 0; checkSet[i] != null; i++ ) { 2647 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 2648 results.push( set[i] ); 2649 } 2650 } 2651 } 2652 } else { 2653 makeArray( checkSet, results ); 2654 } 2655 2656 if ( extra ) { 2657 Sizzle( extra, origContext, results, seed ); 2658 Sizzle.uniqueSort( results ); 2659 } 2660 2661 return results; 2662 }; 2663 2664 Sizzle.uniqueSort = function(results){ 2665 if ( sortOrder ) { 2666 hasDuplicate = baseHasDuplicate; 2667 results.sort(sortOrder); 2668 2669 if ( hasDuplicate ) { 2670 for ( var i = 1; i < results.length; i++ ) { 2671 if ( results[i] === results[i-1] ) { 2672 results.splice(i--, 1); 2673 } 2674 } 2675 } 2676 } 2677 2678 return results; 2679 }; 2680 2681 Sizzle.matches = function(expr, set){ 2682 return Sizzle(expr, null, null, set); 2683 }; 2684 2685 Sizzle.find = function(expr, context, isXML){ 2686 var set, match; 2687 2688 if ( !expr ) { 2689 return []; 2690 } 2691 2692 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { 2693 var type = Expr.order[i], match; 2694 2695 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 2696 var left = match[1]; 2697 match.splice(1,1); 2698 2699 if ( left.substr( left.length - 1 ) !== "\\" ) { 2700 match[1] = (match[1] || "").replace(/\\/g, ""); 2701 set = Expr.find[ type ]( match, context, isXML ); 2702 if ( set != null ) { 2703 expr = expr.replace( Expr.match[ type ], "" ); 2704 break; 2705 } 2706 } 2707 } 2708 } 2709 2710 if ( !set ) { 2711 set = context.getElementsByTagName("*"); 2712 } 2713 2714 return {set: set, expr: expr}; 2715 }; 2716 2717 Sizzle.filter = function(expr, set, inplace, not){ 2718 var old = expr, result = [], curLoop = set, match, anyFound, 2719 isXMLFilter = set && set[0] && isXML(set[0]); 2720 2721 while ( expr && set.length ) { 2722 for ( var type in Expr.filter ) { 2723 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { 2724 var filter = Expr.filter[ type ], found, item, left = match[1]; 2725 anyFound = false; 2726 2727 match.splice(1,1); 2728 2729 if ( left.substr( left.length - 1 ) === "\\" ) { 2730 continue; 2731 } 2732 2733 if ( curLoop === result ) { 2734 result = []; 2735 } 2736 2737 if ( Expr.preFilter[ type ] ) { 2738 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 2739 2740 if ( !match ) { 2741 anyFound = found = true; 2742 } else if ( match === true ) { 2743 continue; 2744 } 2745 } 2746 2747 if ( match ) { 2748 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { 2749 if ( item ) { 2750 found = filter( item, match, i, curLoop ); 2751 var pass = not ^ !!found; 2752 2753 if ( inplace && found != null ) { 2754 if ( pass ) { 2755 anyFound = true; 2756 } else { 2757 curLoop[i] = false; 2758 } 2759 } else if ( pass ) { 2760 result.push( item ); 2761 anyFound = true; 2762 } 2763 } 2764 } 2765 } 2766 2767 if ( found !== undefined ) { 2768 if ( !inplace ) { 2769 curLoop = result; 2770 } 2771 2772 expr = expr.replace( Expr.match[ type ], "" ); 2773 2774 if ( !anyFound ) { 2775 return []; 2776 } 2777 2778 break; 2779 } 2780 } 2781 } 2782 2783 // Improper expression 2784 if ( expr === old ) { 2785 if ( anyFound == null ) { 2786 Sizzle.error( expr ); 2787 } else { 2788 break; 2789 } 2790 } 2791 2792 old = expr; 2793 } 2794 2795 return curLoop; 2796 }; 2797 2798 Sizzle.error = function( msg ) { 2799 throw "Syntax error, unrecognized expression: " + msg; 2800 }; 2801 2802 var Expr = Sizzle.selectors = { 2803 order: [ "ID", "NAME", "TAG" ], 2804 match: { 2805 ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, 2806 CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, 2807 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, 2808 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, 2809 TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, 2810 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, 2811 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, 2812 PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ 2813 }, 2814 leftMatch: {}, 2815 attrMap: { 2816 "class": "className", 2817 "for": "htmlFor" 2818 }, 2819 attrHandle: { 2820 href: function(elem){ 2821 return elem.getAttribute("href"); 2822 } 2823 }, 2824 relative: { 2825 "+": function(checkSet, part){ 2826 var isPartStr = typeof part === "string", 2827 isTag = isPartStr && !/\W/.test(part), 2828 isPartStrNotTag = isPartStr && !isTag; 2829 2830 if ( isTag ) { 2831 part = part.toLowerCase(); 2832 } 2833 2834 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 2835 if ( (elem = checkSet[i]) ) { 2836 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 2837 2838 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? 2839 elem || false : 2840 elem === part; 2841 } 2842 } 2843 2844 if ( isPartStrNotTag ) { 2845 Sizzle.filter( part, checkSet, true ); 2846 } 2847 }, 2848 ">": function(checkSet, part){ 2849 var isPartStr = typeof part === "string"; 2850 2851 if ( isPartStr && !/\W/.test(part) ) { 2852 part = part.toLowerCase(); 2853 2854 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 2855 var elem = checkSet[i]; 2856 if ( elem ) { 2857 var parent = elem.parentNode; 2858 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; 2859 } 2860 } 2861 } else { 2862 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 2863 var elem = checkSet[i]; 2864 if ( elem ) { 2865 checkSet[i] = isPartStr ? 2866 elem.parentNode : 2867 elem.parentNode === part; 2868 } 2869 } 2870 2871 if ( isPartStr ) { 2872 Sizzle.filter( part, checkSet, true ); 2873 } 2874 } 2875 }, 2876 "": function(checkSet, part, isXML){ 2877 var doneName = done++, checkFn = dirCheck; 2878 2879 if ( typeof part === "string" && !/\W/.test(part) ) { 2880 var nodeCheck = part = part.toLowerCase(); 2881 checkFn = dirNodeCheck; 2882 } 2883 2884 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); 2885 }, 2886 "~": function(checkSet, part, isXML){ 2887 var doneName = done++, checkFn = dirCheck; 2888 2889 if ( typeof part === "string" && !/\W/.test(part) ) { 2890 var nodeCheck = part = part.toLowerCase(); 2891 checkFn = dirNodeCheck; 2892 } 2893 2894 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); 2895 } 2896 }, 2897 find: { 2898 ID: function(match, context, isXML){ 2899 if ( typeof context.getElementById !== "undefined" && !isXML ) { 2900 var m = context.getElementById(match[1]); 2901 return m ? [m] : []; 2902 } 2903 }, 2904 NAME: function(match, context){ 2905 if ( typeof context.getElementsByName !== "undefined" ) { 2906 var ret = [], results = context.getElementsByName(match[1]); 2907 2908 for ( var i = 0, l = results.length; i < l; i++ ) { 2909 if ( results[i].getAttribute("name") === match[1] ) { 2910 ret.push( results[i] ); 2911 } 2912 } 2913 2914 return ret.length === 0 ? null : ret; 2915 } 2916 }, 2917 TAG: function(match, context){ 2918 return context.getElementsByTagName(match[1]); 2919 } 2920 }, 2921 preFilter: { 2922 CLASS: function(match, curLoop, inplace, result, not, isXML){ 2923 match = " " + match[1].replace(/\\/g, "") + " "; 2924 2925 if ( isXML ) { 2926 return match; 2927 } 2928 2929 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { 2930 if ( elem ) { 2931 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { 2932 if ( !inplace ) { 2933 result.push( elem ); 2934 } 2935 } else if ( inplace ) { 2936 curLoop[i] = false; 2937 } 2938 } 2939 } 2940 2941 return false; 2942 }, 2943 ID: function(match){ 2944 return match[1].replace(/\\/g, ""); 2945 }, 2946 TAG: function(match, curLoop){ 2947 return match[1].toLowerCase(); 2948 }, 2949 CHILD: function(match){ 2950 if ( match[1] === "nth" ) { 2951 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 2952 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 2953 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || 2954 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); 2955 2956 // calculate the numbers (first)n+(last) including if they are negative 2957 match[2] = (test[1] + (test[2] || 1)) - 0; 2958 match[3] = test[3] - 0; 2959 } 2960 2961 // TODO: Move to normal caching system 2962 match[0] = done++; 2963 2964 return match; 2965 }, 2966 ATTR: function(match, curLoop, inplace, result, not, isXML){ 2967 var name = match[1].replace(/\\/g, ""); 2968 2969 if ( !isXML && Expr.attrMap[name] ) { 2970 match[1] = Expr.attrMap[name]; 2971 } 2972 2973 if ( match[2] === "~=" ) { 2974 match[4] = " " + match[4] + " "; 2975 } 2976 2977 return match; 2978 }, 2979 PSEUDO: function(match, curLoop, inplace, result, not){ 2980 if ( match[1] === "not" ) { 2981 // If we're dealing with a complex expression, or a simple one 2982 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { 2983 match[3] = Sizzle(match[3], null, null, curLoop); 2984 } else { 2985 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); 2986 if ( !inplace ) { 2987 result.push.apply( result, ret ); 2988 } 2989 return false; 2990 } 2991 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { 2992 return true; 2993 } 2994 2995 return match; 2996 }, 2997 POS: function(match){ 2998 match.unshift( true ); 2999 return match; 3000 } 3001 }, 3002 filters: { 3003 enabled: function(elem){ 3004 return elem.disabled === false && elem.type !== "hidden"; 3005 }, 3006 disabled: function(elem){ 3007 return elem.disabled === true; 3008 }, 3009 checked: function(elem){ 3010 return elem.checked === true; 3011 }, 3012 selected: function(elem){ 3013 // Accessing this property makes selected-by-default 3014 // options in Safari work properly 3015 elem.parentNode.selectedIndex; 3016 return elem.selected === true; 3017 }, 3018 parent: function(elem){ 3019 return !!elem.firstChild; 3020 }, 3021 empty: function(elem){ 3022 return !elem.firstChild; 3023 }, 3024 has: function(elem, i, match){ 3025 return !!Sizzle( match[3], elem ).length; 3026 }, 3027 header: function(elem){ 3028 return /h\d/i.test( elem.nodeName ); 3029 }, 3030 text: function(elem){ 3031 return "text" === elem.type; 3032 }, 3033 radio: function(elem){ 3034 return "radio" === elem.type; 3035 }, 3036 checkbox: function(elem){ 3037 return "checkbox" === elem.type; 3038 }, 3039 file: function(elem){ 3040 return "file" === elem.type; 3041 }, 3042 password: function(elem){ 3043 return "password" === elem.type; 3044 }, 3045 submit: function(elem){ 3046 return "submit" === elem.type; 3047 }, 3048 image: function(elem){ 3049 return "image" === elem.type; 3050 }, 3051 reset: function(elem){ 3052 return "reset" === elem.type; 3053 }, 3054 button: function(elem){ 3055 return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; 3056 }, 3057 input: function(elem){ 3058 return /input|select|textarea|button/i.test(elem.nodeName); 3059 } 3060 }, 3061 setFilters: { 3062 first: function(elem, i){ 3063 return i === 0; 3064 }, 3065 last: function(elem, i, match, array){ 3066 return i === array.length - 1; 3067 }, 3068 even: function(elem, i){ 3069 return i % 2 === 0; 3070 }, 3071 odd: function(elem, i){ 3072 return i % 2 === 1; 3073 }, 3074 lt: function(elem, i, match){ 3075 return i < match[3] - 0; 3076 }, 3077 gt: function(elem, i, match){ 3078 return i > match[3] - 0; 3079 }, 3080 nth: function(elem, i, match){ 3081 return match[3] - 0 === i; 3082 }, 3083 eq: function(elem, i, match){ 3084 return match[3] - 0 === i; 3085 } 3086 }, 3087 filter: { 3088 PSEUDO: function(elem, match, i, array){ 3089 var name = match[1], filter = Expr.filters[ name ]; 3090 3091 if ( filter ) { 3092 return filter( elem, i, match, array ); 3093 } else if ( name === "contains" ) { 3094 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; 3095 } else if ( name === "not" ) { 3096 var not = match[3]; 3097 3098 for ( var i = 0, l = not.length; i < l; i++ ) { 3099 if ( not[i] === elem ) { 3100 return false; 3101 } 3102 } 3103 3104 return true; 3105 } else { 3106 Sizzle.error( "Syntax error, unrecognized expression: " + name ); 3107 } 3108 }, 3109 CHILD: function(elem, match){ 3110 var type = match[1], node = elem; 3111 switch (type) { 3112 case 'only': 3113 case 'first': 3114 while ( (node = node.previousSibling) ) { 3115 if ( node.nodeType === 1 ) { 3116 return false; 3117 } 3118 } 3119 if ( type === "first" ) { 3120 return true; 3121 } 3122 node = elem; 3123 case 'last': 3124 while ( (node = node.nextSibling) ) { 3125 if ( node.nodeType === 1 ) { 3126 return false; 3127 } 3128 } 3129 return true; 3130 case 'nth': 3131 var first = match[2], last = match[3]; 3132 3133 if ( first === 1 && last === 0 ) { 3134 return true; 3135 } 3136 3137 var doneName = match[0], 3138 parent = elem.parentNode; 3139 3140 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { 3141 var count = 0; 3142 for ( node = parent.firstChild; node; node = node.nextSibling ) { 3143 if ( node.nodeType === 1 ) { 3144 node.nodeIndex = ++count; 3145 } 3146 } 3147 parent.sizcache = doneName; 3148 } 3149 3150 var diff = elem.nodeIndex - last; 3151 if ( first === 0 ) { 3152 return diff === 0; 3153 } else { 3154 return ( diff % first === 0 && diff / first >= 0 ); 3155 } 3156 } 3157 }, 3158 ID: function(elem, match){ 3159 return elem.nodeType === 1 && elem.getAttribute("id") === match; 3160 }, 3161 TAG: function(elem, match){ 3162 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; 3163 }, 3164 CLASS: function(elem, match){ 3165 return (" " + (elem.className || elem.getAttribute("class")) + " ") 3166 .indexOf( match ) > -1; 3167 }, 3168 ATTR: function(elem, match){ 3169 var name = match[1], 3170 result = Expr.attrHandle[ name ] ? 3171 Expr.attrHandle[ name ]( elem ) : 3172 elem[ name ] != null ? 3173 elem[ name ] : 3174 elem.getAttribute( name ), 3175 value = result + "", 3176 type = match[2], 3177 check = match[4]; 3178 3179 return result == null ? 3180 type === "!=" : 3181 type === "=" ? 3182 value === check : 3183 type === "*=" ? 3184 value.indexOf(check) >= 0 : 3185 type === "~=" ? 3186 (" " + value + " ").indexOf(check) >= 0 : 3187 !check ? 3188 value && result !== false : 3189 type === "!=" ? 3190 value !== check : 3191 type === "^=" ? 3192 value.indexOf(check) === 0 : 3193 type === "$=" ? 3194 value.substr(value.length - check.length) === check : 3195 type === "|=" ? 3196 value === check || value.substr(0, check.length + 1) === check + "-" : 3197 false; 3198 }, 3199 POS: function(elem, match, i, array){ 3200 var name = match[2], filter = Expr.setFilters[ name ]; 3201 3202 if ( filter ) { 3203 return filter( elem, i, match, array ); 3204 } 3205 } 3206 } 3207 }; 3208 3209 var origPOS = Expr.match.POS; 3210 3211 for ( var type in Expr.match ) { 3212 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); 3213 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){ 3214 return "\\" + (num - 0 + 1); 3215 })); 3216 } 3217 3218 var makeArray = function(array, results) { 3219 array = Array.prototype.slice.call( array, 0 ); 3220 3221 if ( results ) { 3222 results.push.apply( results, array ); 3223 return results; 3224 } 3225 3226 return array; 3227 }; 3228 3229 // Perform a simple check to determine if the browser is capable of 3230 // converting a NodeList to an array using builtin methods. 3231 try { 3232 Array.prototype.slice.call( document.documentElement.childNodes, 0 ); 3233 3234 // Provide a fallback method if it does not work 3235 } catch(e){ 3236 makeArray = function(array, results) { 3237 var ret = results || []; 3238 3239 if ( toString.call(array) === "[object Array]" ) { 3240 Array.prototype.push.apply( ret, array ); 3241 } else { 3242 if ( typeof array.length === "number" ) { 3243 for ( var i = 0, l = array.length; i < l; i++ ) { 3244 ret.push( array[i] ); 3245 } 3246 } else { 3247 for ( var i = 0; array[i]; i++ ) { 3248 ret.push( array[i] ); 3249 } 3250 } 3251 } 3252 3253 return ret; 3254 }; 3255 } 3256 3257 var sortOrder; 3258 3259 if ( document.documentElement.compareDocumentPosition ) { 3260 sortOrder = function( a, b ) { 3261 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { 3262 if ( a == b ) { 3263 hasDuplicate = true; 3264 } 3265 return a.compareDocumentPosition ? -1 : 1; 3266 } 3267 3268 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; 3269 if ( ret === 0 ) { 3270 hasDuplicate = true; 3271 } 3272 return ret; 3273 }; 3274 } else if ( "sourceIndex" in document.documentElement ) { 3275 sortOrder = function( a, b ) { 3276 if ( !a.sourceIndex || !b.sourceIndex ) { 3277 if ( a == b ) { 3278 hasDuplicate = true; 3279 } 3280 return a.sourceIndex ? -1 : 1; 3281 } 3282 3283 var ret = a.sourceIndex - b.sourceIndex; 3284 if ( ret === 0 ) { 3285 hasDuplicate = true; 3286 } 3287 return ret; 3288 }; 3289 } else if ( document.createRange ) { 3290 sortOrder = function( a, b ) { 3291 if ( !a.ownerDocument || !b.ownerDocument ) { 3292 if ( a == b ) { 3293 hasDuplicate = true; 3294 } 3295 return a.ownerDocument ? -1 : 1; 3296 } 3297 3298 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); 3299 aRange.setStart(a, 0); 3300 aRange.setEnd(a, 0); 3301 bRange.setStart(b, 0); 3302 bRange.setEnd(b, 0); 3303 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); 3304 if ( ret === 0 ) { 3305 hasDuplicate = true; 3306 } 3307 return ret; 3308 }; 3309 } 3310 3311 // Utility function for retreiving the text value of an array of DOM nodes 3312 function getText( elems ) { 3313 var ret = "", elem; 3314 3315 for ( var i = 0; elems[i]; i++ ) { 3316 elem = elems[i]; 3317 3318 // Get the text from text nodes and CDATA nodes 3319 if ( elem.nodeType === 3 || elem.nodeType === 4 ) { 3320 ret += elem.nodeValue; 3321 3322 // Traverse everything else, except comment nodes 3323 } else if ( elem.nodeType !== 8 ) { 3324 ret += getText( elem.childNodes ); 3325 } 3326 } 3327 3328 return ret; 3329 } 3330 3331 // Check to see if the browser returns elements by name when 3332 // querying by getElementById (and provide a workaround) 3333 (function(){ 3334 // We're going to inject a fake input element with a specified name 3335 var form = document.createElement("div"), 3336 id = "script" + (new Date).getTime(); 3337 form.innerHTML = "<a name='" + id + "'/>"; 3338 3339 // Inject it into the root element, check its status, and remove it quickly 3340 var root = document.documentElement; 3341 root.insertBefore( form, root.firstChild ); 3342 3343 // The workaround has to do additional checks after a getElementById 3344 // Which slows things down for other browsers (hence the branching) 3345 if ( document.getElementById( id ) ) { 3346 Expr.find.ID = function(match, context, isXML){ 3347 if ( typeof context.getElementById !== "undefined" && !isXML ) { 3348 var m = context.getElementById(match[1]); 3349 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; 3350 } 3351 }; 3352 3353 Expr.filter.ID = function(elem, match){ 3354 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 3355 return elem.nodeType === 1 && node && node.nodeValue === match; 3356 }; 3357 } 3358 3359 root.removeChild( form ); 3360 root = form = null; // release memory in IE 3361 })(); 3362 3363 (function(){ 3364 // Check to see if the browser returns only elements 3365 // when doing getElementsByTagName("*") 3366 3367 // Create a fake element 3368 var div = document.createElement("div"); 3369 div.appendChild( document.createComment("") ); 3370 3371 // Make sure no comments are found 3372 if ( div.getElementsByTagName("*").length > 0 ) { 3373 Expr.find.TAG = function(match, context){ 3374 var results = context.getElementsByTagName(match[1]); 3375 3376 // Filter out possible comments 3377 if ( match[1] === "*" ) { 3378 var tmp = []; 3379 3380 for ( var i = 0; results[i]; i++ ) { 3381 if ( results[i].nodeType === 1 ) { 3382 tmp.push( results[i] ); 3383 } 3384 } 3385 3386 results = tmp; 3387 } 3388 3389 return results; 3390 }; 3391 } 3392 3393 // Check to see if an attribute returns normalized href attributes 3394 div.innerHTML = "<a href='#'></a>"; 3395 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && 3396 div.firstChild.getAttribute("href") !== "#" ) { 3397 Expr.attrHandle.href = function(elem){ 3398 return elem.getAttribute("href", 2); 3399 }; 3400 } 3401 3402 div = null; // release memory in IE 3403 })(); 3404 3405 if ( document.querySelectorAll ) { 3406 (function(){ 3407 var oldSizzle = Sizzle, div = document.createElement("div"); 3408 div.innerHTML = "<p class='TEST'></p>"; 3409 3410 // Safari can't handle uppercase or unicode characters when 3411 // in quirks mode. 3412 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 3413 return; 3414 } 3415 3416 Sizzle = function(query, context, extra, seed){ 3417 context = context || document; 3418 3419 // Only use querySelectorAll on non-XML documents 3420 // (ID selectors don't work in non-HTML documents) 3421 if ( !seed && context.nodeType === 9 && !isXML(context) ) { 3422 try { 3423 return makeArray( context.querySelectorAll(query), extra ); 3424 } catch(e){} 3425 } 3426 3427 return oldSizzle(query, context, extra, seed); 3428 }; 3429 3430 for ( var prop in oldSizzle ) { 3431 Sizzle[ prop ] = oldSizzle[ prop ]; 3432 } 3433 3434 div = null; // release memory in IE 3435 })(); 3436 } 3437 3438 (function(){ 3439 var div = document.createElement("div"); 3440 3441 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; 3442 3443 // Opera can't find a second classname (in 9.6) 3444 // Also, make sure that getElementsByClassName actually exists 3445 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { 3446 return; 3447 } 3448 3449 // Safari caches class attributes, doesn't catch changes (in 3.2) 3450 div.lastChild.className = "e"; 3451 3452 if ( div.getElementsByClassName("e").length === 1 ) { 3453 return; 3454 } 3455 3456 Expr.order.splice(1, 0, "CLASS"); 3457 Expr.find.CLASS = function(match, context, isXML) { 3458 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { 3459 return context.getElementsByClassName(match[1]); 3460 } 3461 }; 3462 3463 div = null; // release memory in IE 3464 })(); 3465 3466 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 3467 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 3468 var elem = checkSet[i]; 3469 if ( elem ) { 3470 elem = elem[dir]; 3471 var match = false; 3472 3473 while ( elem ) { 3474 if ( elem.sizcache === doneName ) { 3475 match = checkSet[elem.sizset]; 3476 break; 3477 } 3478 3479 if ( elem.nodeType === 1 && !isXML ){ 3480 elem.sizcache = doneName; 3481 elem.sizset = i; 3482 } 3483 3484 if ( elem.nodeName.toLowerCase() === cur ) { 3485 match = elem; 3486 break; 3487 } 3488 3489 elem = elem[dir]; 3490 } 3491 3492 checkSet[i] = match; 3493 } 3494 } 3495 } 3496 3497 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 3498 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 3499 var elem = checkSet[i]; 3500 if ( elem ) { 3501 elem = elem[dir]; 3502 var match = false; 3503 3504 while ( elem ) { 3505 if ( elem.sizcache === doneName ) { 3506 match = checkSet[elem.sizset]; 3507 break; 3508 } 3509 3510 if ( elem.nodeType === 1 ) { 3511 if ( !isXML ) { 3512 elem.sizcache = doneName; 3513 elem.sizset = i; 3514 } 3515 if ( typeof cur !== "string" ) { 3516 if ( elem === cur ) { 3517 match = true; 3518 break; 3519 } 3520 3521 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { 3522 match = elem; 3523 break; 3524 } 3525 } 3526 3527 elem = elem[dir]; 3528 } 3529 3530 checkSet[i] = match; 3531 } 3532 } 3533 } 3534 3535 var contains = document.compareDocumentPosition ? function(a, b){ 3536 return a.compareDocumentPosition(b) & 16; 3537 } : function(a, b){ 3538 return a !== b && (a.contains ? a.contains(b) : true); 3539 }; 3540 3541 var isXML = function(elem){ 3542 // documentElement is verified for cases where it doesn't yet exist 3543 // (such as loading iframes in IE - #4833) 3544 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; 3545 return documentElement ? documentElement.nodeName !== "HTML" : false; 3546 }; 3547 3548 var posProcess = function(selector, context){ 3549 var tmpSet = [], later = "", match, 3550 root = context.nodeType ? [context] : context; 3551 3552 // Position selectors must be done after the filter 3553 // And so must :not(positional) so we move all PSEUDOs to the end 3554 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { 3555 later += match[0]; 3556 selector = selector.replace( Expr.match.PSEUDO, "" ); 3557 } 3558 3559 selector = Expr.relative[selector] ? selector + "*" : selector; 3560 3561 for ( var i = 0, l = root.length; i < l; i++ ) { 3562 Sizzle( selector, root[i], tmpSet ); 3563 } 3564 3565 return Sizzle.filter( later, tmpSet ); 3566 }; 3567 3568 // EXPOSE 3569 jQuery.find = Sizzle; 3570 jQuery.expr = Sizzle.selectors; 3571 jQuery.expr[":"] = jQuery.expr.filters; 3572 jQuery.unique = Sizzle.uniqueSort; 3573 jQuery.getText = getText; 3574 jQuery.isXMLDoc = isXML; 3575 jQuery.contains = contains; 3576 3577 return; 3578 3579 window.Sizzle = Sizzle; 3580 3581 })(); 3582 var runtil = /Until$/, 3583 rparentsprev = /^(?:parents|prevUntil|prevAll)/, 3584 // Note: This RegExp should be improved, or likely pulled from Sizzle 3585 rmultiselector = /,/, 3586 slice = Array.prototype.slice; 3587 3588 // Implement the identical functionality for filter and not 3589 var winnow = function( elements, qualifier, keep ) { 3590 if ( jQuery.isFunction( qualifier ) ) { 3591 return jQuery.grep(elements, function( elem, i ) { 3592 return !!qualifier.call( elem, i, elem ) === keep; 3593 }); 3594 3595 } else if ( qualifier.nodeType ) { 3596 return jQuery.grep(elements, function( elem, i ) { 3597 return (elem === qualifier) === keep; 3598 }); 3599 3600 } else if ( typeof qualifier === "string" ) { 3601 var filtered = jQuery.grep(elements, function( elem ) { 3602 return elem.nodeType === 1; 3603 }); 3604 3605 if ( isSimple.test( qualifier ) ) { 3606 return jQuery.filter(qualifier, filtered, !keep); 3607 } else { 3608 qualifier = jQuery.filter( qualifier, filtered ); 3609 } 3610 } 3611 3612 return jQuery.grep(elements, function( elem, i ) { 3613 return (jQuery.inArray( elem, qualifier ) >= 0) === keep; 3614 }); 3615 }; 3616 3617 jQuery.fn.extend({ 3618 find: function( selector ) { 3619 var ret = this.pushStack( "", "find", selector ), length = 0; 3620 3621 for ( var i = 0, l = this.length; i < l; i++ ) { 3622 length = ret.length; 3623 jQuery.find( selector, this[i], ret ); 3624 3625 if ( i > 0 ) { 3626 // Make sure that the results are unique 3627 for ( var n = length; n < ret.length; n++ ) { 3628 for ( var r = 0; r < length; r++ ) { 3629 if ( ret[r] === ret[n] ) { 3630 ret.splice(n--, 1); 3631 break; 3632 } 3633 } 3634 } 3635 } 3636 } 3637 3638 return ret; 3639 }, 3640 3641 has: function( target ) { 3642 var targets = jQuery( target ); 3643 return this.filter(function() { 3644 for ( var i = 0, l = targets.length; i < l; i++ ) { 3645 if ( jQuery.contains( this, targets[i] ) ) { 3646 return true; 3647 } 3648 } 3649 }); 3650 }, 3651 3652 not: function( selector ) { 3653 return this.pushStack( winnow(this, selector, false), "not", selector); 3654 }, 3655 3656 filter: function( selector ) { 3657 return this.pushStack( winnow(this, selector, true), "filter", selector ); 3658 }, 3659 3660 is: function( selector ) { 3661 return !!selector && jQuery.filter( selector, this ).length > 0; 3662 }, 3663 3664 closest: function( selectors, context ) { 3665 if ( jQuery.isArray( selectors ) ) { 3666 var ret = [], cur = this[0], match, matches = {}, selector; 3667 3668 if ( cur && selectors.length ) { 3669 for ( var i = 0, l = selectors.length; i < l; i++ ) { 3670 selector = selectors[i]; 3671 3672 if ( !matches[selector] ) { 3673 matches[selector] = jQuery.expr.match.POS.test( selector ) ? 3674 jQuery( selector, context || this.context ) : 3675 selector; 3676 } 3677 } 3678 3679 while ( cur && cur.ownerDocument && cur !== context ) { 3680 for ( selector in matches ) { 3681 match = matches[selector]; 3682 3683 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { 3684 ret.push({ selector: selector, elem: cur }); 3685 delete matches[selector]; 3686 } 3687 } 3688 cur = cur.parentNode; 3689 } 3690 } 3691 3692 return ret; 3693 } 3694 3695 var pos = jQuery.expr.match.POS.test( selectors ) ? 3696 jQuery( selectors, context || this.context ) : null; 3697 3698 return this.map(function( i, cur ) { 3699 while ( cur && cur.ownerDocument && cur !== context ) { 3700 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) { 3701 return cur; 3702 } 3703 cur = cur.parentNode; 3704 } 3705 return null; 3706 }); 3707 }, 3708 141 3709 // Determine the position of an element within 142 3710 // the matched set of elements 143 3711 index: function( elem ) { 144 var ret = -1; 145 3712 if ( !elem || typeof elem === "string" ) { 3713 return jQuery.inArray( this[0], 3714 // If it receives a string, the selector is used 3715 // If it receives nothing, the siblings are used 3716 elem ? jQuery( elem ) : this.parent().children() ); 3717 } 146 3718 // Locate the position of the desired element 147 3719 return jQuery.inArray( 148 3720 // If it receives a jQuery object, the first element is used 149 elem && elem.jquery ? elem[0] : elem 150 , this ); 151 }, 152 153 attr: function( name, value, type ) { 154 var options = name; 155 156 // Look for the case where we're accessing a style value 157 if ( name.constructor == String ) 158 if ( value === undefined ) 159 return this[0] && jQuery[ type || "attr" ]( this[0], name ); 160 161 else { 162 options = {}; 163 options[ name ] = value; 164 } 165 166 // Check to see if we're setting style values 167 return this.each(function(i){ 168 // Set all the styles 169 for ( name in options ) 170 jQuery.attr( 171 type ? 172 this.style : 173 this, 174 name, jQuery.prop( this, options[ name ], type, i, name ) 175 ); 3721 elem.jquery ? elem[0] : elem, this ); 3722 }, 3723 3724 add: function( selector, context ) { 3725 var set = typeof selector === "string" ? 3726 jQuery( selector, context || this.context ) : 3727 jQuery.makeArray( selector ), 3728 all = jQuery.merge( this.get(), set ); 3729 3730 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? 3731 all : 3732 jQuery.unique( all ) ); 3733 }, 3734 3735 andSelf: function() { 3736 return this.add( this.prevObject ); 3737 } 3738 }); 3739 3740 // A painfully simple check to see if an element is disconnected 3741 // from a document (should be improved, where feasible). 3742 function isDisconnected( node ) { 3743 return !node || !node.parentNode || node.parentNode.nodeType === 11; 3744 } 3745 3746 jQuery.each({ 3747 parent: function( elem ) { 3748 var parent = elem.parentNode; 3749 return parent && parent.nodeType !== 11 ? parent : null; 3750 }, 3751 parents: function( elem ) { 3752 return jQuery.dir( elem, "parentNode" ); 3753 }, 3754 parentsUntil: function( elem, i, until ) { 3755 return jQuery.dir( elem, "parentNode", until ); 3756 }, 3757 next: function( elem ) { 3758 return jQuery.nth( elem, 2, "nextSibling" ); 3759 }, 3760 prev: function( elem ) { 3761 return jQuery.nth( elem, 2, "previousSibling" ); 3762 }, 3763 nextAll: function( elem ) { 3764 return jQuery.dir( elem, "nextSibling" ); 3765 }, 3766 prevAll: function( elem ) { 3767 return jQuery.dir( elem, "previousSibling" ); 3768 }, 3769 nextUntil: function( elem, i, until ) { 3770 return jQuery.dir( elem, "nextSibling", until ); 3771 }, 3772 prevUntil: function( elem, i, until ) { 3773 return jQuery.dir( elem, "previousSibling", until ); 3774 }, 3775 siblings: function( elem ) { 3776 return jQuery.sibling( elem.parentNode.firstChild, elem ); 3777 }, 3778 children: function( elem ) { 3779 return jQuery.sibling( elem.firstChild ); 3780 }, 3781 contents: function( elem ) { 3782 return jQuery.nodeName( elem, "iframe" ) ? 3783 elem.contentDocument || elem.contentWindow.document : 3784 jQuery.makeArray( elem.childNodes ); 3785 } 3786 }, function( name, fn ) { 3787 jQuery.fn[ name ] = function( until, selector ) { 3788 var ret = jQuery.map( this, fn, until ); 3789 3790 if ( !runtil.test( name ) ) { 3791 selector = until; 3792 } 3793 3794 if ( selector && typeof selector === "string" ) { 3795 ret = jQuery.filter( selector, ret ); 3796 } 3797 3798 ret = this.length > 1 ? jQuery.unique( ret ) : ret; 3799 3800 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { 3801 ret = ret.reverse(); 3802 } 3803 3804 return this.pushStack( ret, name, slice.call(arguments).join(",") ); 3805 }; 3806 }); 3807 3808 jQuery.extend({ 3809 filter: function( expr, elems, not ) { 3810 if ( not ) { 3811 expr = ":not(" + expr + ")"; 3812 } 3813 3814 return jQuery.find.matches(expr, elems); 3815 }, 3816 3817 dir: function( elem, dir, until ) { 3818 var matched = [], cur = elem[dir]; 3819 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { 3820 if ( cur.nodeType === 1 ) { 3821 matched.push( cur ); 3822 } 3823 cur = cur[dir]; 3824 } 3825 return matched; 3826 }, 3827 3828 nth: function( cur, result, dir, elem ) { 3829 result = result || 1; 3830 var num = 0; 3831 3832 for ( ; cur; cur = cur[dir] ) { 3833 if ( cur.nodeType === 1 && ++num === result ) { 3834 break; 3835 } 3836 } 3837 3838 return cur; 3839 }, 3840 3841 sibling: function( n, elem ) { 3842 var r = []; 3843 3844 for ( ; n; n = n.nextSibling ) { 3845 if ( n.nodeType === 1 && n !== elem ) { 3846 r.push( n ); 3847 } 3848 } 3849 3850 return r; 3851 } 3852 }); 3853 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, 3854 rleadingWhitespace = /^\s+/, 3855 rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g, 3856 rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, 3857 rtagName = /<([\w:]+)/, 3858 rtbody = /<tbody/i, 3859 rhtml = /<|&\w+;/, 3860 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5) 3861 fcloseTag = function( all, front, tag ) { 3862 return rselfClosing.test( tag ) ? 3863 all : 3864 front + "></" + tag + ">"; 3865 }, 3866 wrapMap = { 3867 option: [ 1, "<select multiple='multiple'>", "</select>" ], 3868 legend: [ 1, "<fieldset>", "</fieldset>" ], 3869 thead: [ 1, "<table>", "</table>" ], 3870 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 3871 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 3872 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], 3873 area: [ 1, "<map>", "</map>" ], 3874 _default: [ 0, "", "" ] 3875 }; 3876 3877 wrapMap.optgroup = wrapMap.option; 3878 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 3879 wrapMap.th = wrapMap.td; 3880 3881 // IE can't serialize <link> and <script> tags normally 3882 if ( !jQuery.support.htmlSerialize ) { 3883 wrapMap._default = [ 1, "div<div>", "</div>" ]; 3884 } 3885 3886 jQuery.fn.extend({ 3887 text: function( text ) { 3888 if ( jQuery.isFunction(text) ) { 3889 return this.each(function(i) { 3890 var self = jQuery(this); 3891 self.text( text.call(this, i, self.text()) ); 3892 }); 3893 } 3894 3895 if ( typeof text !== "object" && text !== undefined ) { 3896 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 3897 } 3898 3899 return jQuery.getText( this ); 3900 }, 3901 3902 wrapAll: function( html ) { 3903 if ( jQuery.isFunction( html ) ) { 3904 return this.each(function(i) { 3905 jQuery(this).wrapAll( html.call(this, i) ); 3906 }); 3907 } 3908 3909 if ( this[0] ) { 3910 // The elements to wrap the target around 3911 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); 3912 3913 if ( this[0].parentNode ) { 3914 wrap.insertBefore( this[0] ); 3915 } 3916 3917 wrap.map(function() { 3918 var elem = this; 3919 3920 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { 3921 elem = elem.firstChild; 3922 } 3923 3924 return elem; 3925 }).append(this); 3926 } 3927 3928 return this; 3929 }, 3930 3931 wrapInner: function( html ) { 3932 if ( jQuery.isFunction( html ) ) { 3933 return this.each(function(i) { 3934 jQuery(this).wrapInner( html.call(this, i) ); 3935 }); 3936 } 3937 3938 return this.each(function() { 3939 var self = jQuery( this ), contents = self.contents(); 3940 3941 if ( contents.length ) { 3942 contents.wrapAll( html ); 3943 3944 } else { 3945 self.append( html ); 3946 } 176 3947 }); 177 3948 }, 178 3949 179 css: function( key, value ) {180 // ignore negative width and height values181 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )182 value = undefined;183 return this.attr( key, value, "curCSS" );184 },185 186 text: function( text ) {187 if ( typeof text != "object" && text != null )188 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );189 190 var ret = "";191 192 jQuery.each( text || this, function(){193 jQuery.each( this.childNodes, function(){194 if ( this.nodeType != 8 )195 ret += this.nodeType != 1 ?196 this.nodeValue :197 jQuery.fn.text( [ this ] );198 });199 });200 201 return ret;202 },203 204 wrapAll: function( html ) {205 if ( this[0] )206 // The elements to wrap the target around207 jQuery( html, this[0].ownerDocument )208 .clone()209 .insertBefore( this[0] )210 .map(function(){211 var elem = this;212 213 while ( elem.firstChild )214 elem = elem.firstChild;215 216 return elem;217 })218 .append(this);219 220 return this;221 },222 223 wrapInner: function( html ) {224 return this.each(function(){225 jQuery( this ).contents().wrapAll( html );226 });227 },228 229 3950 wrap: function( html ) { 230 return this.each(function() {3951 return this.each(function() { 231 3952 jQuery( this ).wrapAll( html ); 232 3953 }); 233 3954 }, 234 3955 3956 unwrap: function() { 3957 return this.parent().each(function() { 3958 if ( !jQuery.nodeName( this, "body" ) ) { 3959 jQuery( this ).replaceWith( this.childNodes ); 3960 } 3961 }).end(); 3962 }, 3963 235 3964 append: function() { 236 return this.domManip(arguments, true, f alse, function(elem){237 if ( this.nodeType == 1)3965 return this.domManip(arguments, true, function( elem ) { 3966 if ( this.nodeType === 1 ) { 238 3967 this.appendChild( elem ); 3968 } 239 3969 }); 240 3970 }, 241 3971 242 3972 prepend: function() { 243 return this.domManip(arguments, true, true, function(elem){244 if ( this.nodeType == 1)3973 return this.domManip(arguments, true, function( elem ) { 3974 if ( this.nodeType === 1 ) { 245 3975 this.insertBefore( elem, this.firstChild ); 3976 } 246 3977 }); 247 3978 }, 248 3979 249 3980 before: function() { 250 return this.domManip(arguments, false, false, function(elem){ 251 this.parentNode.insertBefore( elem, this ); 252 }); 3981 if ( this[0] && this[0].parentNode ) { 3982 return this.domManip(arguments, false, function( elem ) { 3983 this.parentNode.insertBefore( elem, this ); 3984 }); 3985 } else if ( arguments.length ) { 3986 var set = jQuery(arguments[0]); 3987 set.push.apply( set, this.toArray() ); 3988 return this.pushStack( set, "before", arguments ); 3989 } 253 3990 }, 254 3991 255 3992 after: function() { 256 return this.domManip(arguments, false, true, function(elem){ 257 this.parentNode.insertBefore( elem, this.nextSibling ); 258 }); 259 }, 260 261 end: function() { 262 return this.prevObject || jQuery( [] ); 263 }, 264 265 find: function( selector ) { 266 var elems = jQuery.map(this, function(elem){ 267 return jQuery.find( selector, elem ); 268 }); 269 270 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? 271 jQuery.unique( elems ) : 272 elems ); 3993 if ( this[0] && this[0].parentNode ) { 3994 return this.domManip(arguments, false, function( elem ) { 3995 this.parentNode.insertBefore( elem, this.nextSibling ); 3996 }); 3997 } else if ( arguments.length ) { 3998 var set = this.pushStack( this, "after", arguments ); 3999 set.push.apply( set, jQuery(arguments[0]).toArray() ); 4000 return set; 4001 } 273 4002 }, 274 4003 275 4004 clone: function( events ) { 276 4005 // Do the clone 277 var ret = this.map(function() {278 if ( jQuery.browser.msie&& !jQuery.isXMLDoc(this) ) {4006 var ret = this.map(function() { 4007 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { 279 4008 // IE copies events bound via attachEvent when 280 4009 // using cloneNode. Calling detachEvent on the … … 285 4014 // as properties will not be copied (such as the 286 4015 // the name attribute on an input). 287 var clone = this.cloneNode(true), 288 container = document.createElement("div"); 289 container.appendChild(clone); 290 return jQuery.clean([container.innerHTML])[0]; 291 } else 4016 var html = this.outerHTML, ownerDocument = this.ownerDocument; 4017 if ( !html ) { 4018 var div = ownerDocument.createElement("div"); 4019 div.appendChild( this.cloneNode(true) ); 4020 html = div.innerHTML; 4021 } 4022 4023 return jQuery.clean([html.replace(rinlinejQuery, "") 4024 .replace(rleadingWhitespace, "")], ownerDocument)[0]; 4025 } else { 292 4026 return this.cloneNode(true); 4027 } 293 4028 }); 294 4029 295 // Need to set the expando to null on the cloned set if it exists296 // removeData doesn't work here, IE removes it from the original as well297 // this is primarily for IE but the data expando shouldn't be copied over in any browser298 var clone = ret.find("*").andSelf().each(function(){299 if ( this[ expando ] != undefined )300 this[ expando ] = null;301 });302 303 4030 // Copy the events from the original to the clone 304 if ( events === true ) 305 this.find("*").andSelf().each(function(i){ 306 if (this.nodeType == 3) 307 return; 308 var events = jQuery.data( this, "events" ); 309 310 for ( var type in events ) 311 for ( var handler in events[ type ] ) 312 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); 313 }); 4031 if ( events === true ) { 4032 cloneCopyEvent( this, ret ); 4033 cloneCopyEvent( this.find("*"), ret.find("*") ); 4034 } 314 4035 315 4036 // Return the cloned set … … 317 4038 }, 318 4039 319 filter: function( selector ) { 320 return this.pushStack( 321 jQuery.isFunction( selector ) && 322 jQuery.grep(this, function(elem, i){ 323 return selector.call( elem, i ); 324 }) || 325 326 jQuery.multiFilter( selector, this ) ); 327 }, 328 329 not: function( selector ) { 330 if ( selector.constructor == String ) 331 // test special case where just one selector is passed in 332 if ( isSimple.test( selector ) ) 333 return this.pushStack( jQuery.multiFilter( selector, this, true ) ); 334 else 335 selector = jQuery.multiFilter( selector, this ); 336 337 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; 338 return this.filter(function() { 339 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; 340 }); 341 }, 342 343 add: function( selector ) { 344 return this.pushStack( jQuery.unique( jQuery.merge( 345 this.get(), 346 typeof selector == 'string' ? 347 jQuery( selector ) : 348 jQuery.makeArray( selector ) 349 ))); 350 }, 351 352 is: function( selector ) { 353 return !!selector && jQuery.multiFilter( selector, this ).length > 0; 354 }, 355 356 hasClass: function( selector ) { 357 return this.is( "." + selector ); 358 }, 359 360 val: function( value ) { 361 if ( value == undefined ) { 362 363 if ( this.length ) { 364 var elem = this[0]; 365 366 // We need to handle select boxes special 367 if ( jQuery.nodeName( elem, "select" ) ) { 368 var index = elem.selectedIndex, 369 values = [], 370 options = elem.options, 371 one = elem.type == "select-one"; 372 373 // Nothing was selected 374 if ( index < 0 ) 375 return null; 376 377 // Loop through all the selected options 378 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 379 var option = options[ i ]; 380 381 if ( option.selected ) { 382 // Get the specifc value for the option 383 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; 384 385 // We don't need an array for one selects 386 if ( one ) 387 return value; 388 389 // Multi-Selects return an array 390 values.push( value ); 391 } 4040 html: function( value ) { 4041 if ( value === undefined ) { 4042 return this[0] && this[0].nodeType === 1 ? 4043 this[0].innerHTML.replace(rinlinejQuery, "") : 4044 null; 4045 4046 // See if we can take a shortcut and just use innerHTML 4047 } else if ( typeof value === "string" && !/<script/i.test( value ) && 4048 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && 4049 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { 4050 4051 value = value.replace(rxhtmlTag, fcloseTag); 4052 4053 try { 4054 for ( var i = 0, l = this.length; i < l; i++ ) { 4055 // Remove element nodes and prevent memory leaks 4056 if ( this[i].nodeType === 1 ) { 4057 jQuery.cleanData( this[i].getElementsByTagName("*") ); 4058 this[i].innerHTML = value; 392 4059 } 393 394 return values; 395 396 // Everything else, we just grab the value 397 } else 398 return (this[0].value || "").replace(/\r/g, ""); 399 400 } 401 402 return undefined; 403 } 404 405 if( value.constructor == Number ) 406 value += ''; 407 408 return this.each(function(){ 409 if ( this.nodeType != 1 ) 410 return; 411 412 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) 413 this.checked = (jQuery.inArray(this.value, value) >= 0 || 414 jQuery.inArray(this.name, value) >= 0); 415 416 else if ( jQuery.nodeName( this, "select" ) ) { 417 var values = jQuery.makeArray(value); 418 419 jQuery( "option", this ).each(function(){ 420 this.selected = (jQuery.inArray( this.value, values ) >= 0 || 421 jQuery.inArray( this.text, values ) >= 0); 4060 } 4061 4062 // If using innerHTML throws an exception, use the fallback method 4063 } catch(e) { 4064 this.empty().append( value ); 4065 } 4066 4067 } else if ( jQuery.isFunction( value ) ) { 4068 this.each(function(i){ 4069 var self = jQuery(this), old = self.html(); 4070 self.empty().append(function(){ 4071 return value.call( this, i, old ); 422 4072 }); 423 424 if ( !values.length ) 425 this.selectedIndex = -1; 426 427 } else 428 this.value = value; 429 }); 430 }, 431 432 html: function( value ) { 433 return value == undefined ? 434 (this[0] ? 435 this[0].innerHTML : 436 null) : 4073 }); 4074 4075 } else { 437 4076 this.empty().append( value ); 4077 } 4078 4079 return this; 438 4080 }, 439 4081 440 4082 replaceWith: function( value ) { 441 return this.after( value ).remove(); 442 }, 443 444 eq: function( i ) { 445 return this.slice( i, i + 1 ); 446 }, 447 448 slice: function() { 449 return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); 450 }, 451 452 map: function( callback ) { 453 return this.pushStack( jQuery.map(this, function(elem, i){ 454 return callback.call( elem, i, elem ); 455 })); 456 }, 457 458 andSelf: function() { 459 return this.add( this.prevObject ); 460 }, 461 462 data: function( key, value ){ 463 var parts = key.split("."); 464 parts[1] = parts[1] ? "." + parts[1] : ""; 465 466 if ( value === undefined ) { 467 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 468 469 if ( data === undefined && this.length ) 470 data = jQuery.data( this[0], key ); 471 472 return data === undefined && parts[1] ? 473 this.data( parts[0] ) : 474 data; 475 } else 476 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ 477 jQuery.data( this, key, value ); 4083 if ( this[0] && this[0].parentNode ) { 4084 // Make sure that the elements are removed from the DOM before they are inserted 4085 // this can help fix replacing a parent with child elements 4086 if ( !jQuery.isFunction( value ) ) { 4087 value = jQuery( value ).detach(); 4088 4089 } else { 4090 return this.each(function(i) { 4091 var self = jQuery(this), old = self.html(); 4092 self.replaceWith( value.call( this, i, old ) ); 4093 }); 4094 } 4095 4096 return this.each(function() { 4097 var next = this.nextSibling, parent = this.parentNode; 4098 4099 jQuery(this).remove(); 4100 4101 if ( next ) { 4102 jQuery(next).before( value ); 4103 } else { 4104 jQuery(parent).append( value ); 4105 } 478 4106 }); 479 }, 480 481 removeData: function( key ){ 482 return this.each(function(){ 483 jQuery.removeData( this, key ); 484 }); 485 }, 486 487 domManip: function( args, table, reverse, callback ) { 488 var clone = this.length > 1, elems; 489 490 return this.each(function(){ 491 if ( !elems ) { 492 elems = jQuery.clean( args, this.ownerDocument ); 493 494 if ( reverse ) 495 elems.reverse(); 496 } 497 498 var obj = this; 499 500 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) 501 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); 502 503 var scripts = jQuery( [] ); 504 505 jQuery.each(elems, function(){ 506 var elem = clone ? 507 jQuery( this ).clone( true )[0] : 508 this; 509 510 // execute all scripts after the elements have been injected 511 if ( jQuery.nodeName( elem, "script" ) ) 512 scripts = scripts.add( elem ); 513 else { 514 // Remove any inner scripts for later evaluation 515 if ( elem.nodeType == 1 ) 516 scripts = scripts.add( jQuery( "script", elem ).remove() ); 517 518 // Inject the elements into the document 519 callback.call( obj, elem ); 520 } 4107 } else { 4108 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ); 4109 } 4110 }, 4111 4112 detach: function( selector ) { 4113 return this.remove( selector, true ); 4114 }, 4115 4116 domManip: function( args, table, callback ) { 4117 var results, first, value = args[0], scripts = []; 4118 4119 // We can't cloneNode fragments that contain checked, in WebKit 4120 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { 4121 return this.each(function() { 4122 jQuery(this).domManip( args, table, callback, true ); 521 4123 }); 522 523 scripts.each( evalScript ); 524 }); 525 } 526 }; 527 528 // Give the init function the jQuery prototype for later instantiation 529 jQuery.fn.init.prototype = jQuery.fn; 530 531 function evalScript( i, elem ) { 532 if ( elem.src ) 533 jQuery.ajax({ 534 url: elem.src, 535 async: false, 536 dataType: "script" 537 }); 538 539 else 540 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 541 542 if ( elem.parentNode ) 543 elem.parentNode.removeChild( elem ); 4124 } 4125 4126 if ( jQuery.isFunction(value) ) { 4127 return this.each(function(i) { 4128 var self = jQuery(this); 4129 args[0] = value.call(this, i, table ? self.html() : undefined); 4130 self.domManip( args, table, callback ); 4131 }); 4132 } 4133 4134 if ( this[0] ) { 4135 // If we're in a fragment, just use that instead of building a new one 4136 if ( args[0] && args[0].parentNode && args[0].parentNode.nodeType === 11 ) { 4137 results = { fragment: args[0].parentNode }; 4138 } else { 4139 results = buildFragment( args, this, scripts ); 4140 } 4141 4142 first = results.fragment.firstChild; 4143 4144 if ( first ) { 4145 table = table && jQuery.nodeName( first, "tr" ); 4146 4147 for ( var i = 0, l = this.length; i < l; i++ ) { 4148 callback.call( 4149 table ? 4150 root(this[i], first) : 4151 this[i], 4152 results.cacheable || this.length > 1 || i > 0 ? 4153 results.fragment.cloneNode(true) : 4154 results.fragment 4155 ); 4156 } 4157 } 4158 4159 if ( scripts ) { 4160 jQuery.each( scripts, evalScript ); 4161 } 4162 } 4163 4164 return this; 4165 4166 function root( elem, cur ) { 4167 return jQuery.nodeName(elem, "table") ? 4168 (elem.getElementsByTagName("tbody")[0] || 4169 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : 4170 elem; 4171 } 4172 } 4173 }); 4174 4175 function cloneCopyEvent(orig, ret) { 4176 var i = 0; 4177 4178 ret.each(function() { 4179 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) { 4180 return; 4181 } 4182 4183 var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events; 4184 4185 if ( events ) { 4186 delete curData.handle; 4187 curData.events = {}; 4188 4189 for ( var type in events ) { 4190 for ( var handler in events[ type ] ) { 4191 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); 4192 } 4193 } 4194 } 4195 }); 544 4196 } 545 4197 546 function now(){ 547 return +new Date; 4198 function buildFragment( args, nodes, scripts ) { 4199 var fragment, cacheable, cacheresults, doc; 4200 4201 // webkit does not clone 'checked' attribute of radio inputs on cloneNode, so don't cache if string has a checked 4202 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { 4203 cacheable = true; 4204 cacheresults = jQuery.fragments[ args[0] ]; 4205 if ( cacheresults ) { 4206 if ( cacheresults !== 1 ) { 4207 fragment = cacheresults; 4208 } 4209 } 4210 } 4211 4212 if ( !fragment ) { 4213 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document); 4214 fragment = doc.createDocumentFragment(); 4215 jQuery.clean( args, doc, fragment, scripts ); 4216 } 4217 4218 if ( cacheable ) { 4219 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1; 4220 } 4221 4222 return { fragment: fragment, cacheable: cacheable }; 548 4223 } 549 4224 550 jQuery.extend = jQuery.fn.extend = function() { 551 // copy reference to target object 552 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; 553 554 // Handle a deep copy situation 555 if ( target.constructor == Boolean ) { 556 deep = target; 557 target = arguments[1] || {}; 558 // skip the boolean and the target 559 i = 2; 560 } 561 562 // Handle case when target is a string or something (possible in deep copy) 563 if ( typeof target != "object" && typeof target != "function" ) 564 target = {}; 565 566 // extend jQuery itself if only one argument is passed 567 if ( length == i ) { 568 target = this; 569 --i; 570 } 571 572 for ( ; i < length; i++ ) 573 // Only deal with non-null/undefined values 574 if ( (options = arguments[ i ]) != null ) 575 // Extend the base object 576 for ( var name in options ) { 577 var src = target[ name ], copy = options[ name ]; 578 579 // Prevent never-ending loop 580 if ( target === copy ) 581 continue; 582 583 // Recurse if we're merging object values 584 if ( deep && copy && typeof copy == "object" && !copy.nodeType ) 585 target[ name ] = jQuery.extend( deep, 586 // Never move original objects, clone them 587 src || ( copy.length != null ? [ ] : { } ) 588 , copy ); 589 590 // Don't bring in undefined values 591 else if ( copy !== undefined ) 592 target[ name ] = copy; 593 594 } 595 596 // Return the modified object 597 return target; 598 }; 599 600 var expando = "jQuery" + now(), uuid = 0, windowData = {}, 601 // exclude the following css properties to add px 602 exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, 603 // cache defaultView 604 defaultView = document.defaultView || {}; 605 606 jQuery.extend({ 607 noConflict: function( deep ) { 608 window.$ = _$; 609 610 if ( deep ) 611 window.jQuery = _jQuery; 612 613 return jQuery; 614 }, 615 616 // See test/unit/core.js for details concerning this function. 617 isFunction: function( fn ) { 618 return !!fn && typeof fn != "string" && !fn.nodeName && 619 fn.constructor != Array && /^[\s[]?function/.test( fn + "" ); 620 }, 621 622 // check if an element is in a (or is an) XML document 623 isXMLDoc: function( elem ) { 624 return elem.documentElement && !elem.body || 625 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; 626 }, 627 628 // Evalulates a script in a global context 629 globalEval: function( data ) { 630 data = jQuery.trim( data ); 631 632 if ( data ) { 633 // Inspired by code by Andrea Giammarchi 634 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 635 var head = document.getElementsByTagName("head")[0] || document.documentElement, 636 script = document.createElement("script"); 637 638 script.type = "text/javascript"; 639 if ( jQuery.browser.msie ) 640 script.text = data; 641 else 642 script.appendChild( document.createTextNode( data ) ); 643 644 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 645 // This arises when a base node is used (#2709). 646 head.insertBefore( script, head.firstChild ); 647 head.removeChild( script ); 648 } 649 }, 650 651 nodeName: function( elem, name ) { 652 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); 653 }, 654 655 cache: {}, 656 657 data: function( elem, name, data ) { 658 elem = elem == window ? 659 windowData : 660 elem; 661 662 var id = elem[ expando ]; 663 664 // Compute a unique ID for the element 665 if ( !id ) 666 id = elem[ expando ] = ++uuid; 667 668 // Only generate the data cache if we're 669 // trying to access or manipulate it 670 if ( name && !jQuery.cache[ id ] ) 671 jQuery.cache[ id ] = {}; 672 673 // Prevent overriding the named cache with undefined values 674 if ( data !== undefined ) 675 jQuery.cache[ id ][ name ] = data; 676 677 // Return the named cache data, or the ID for the element 678 return name ? 679 jQuery.cache[ id ][ name ] : 680 id; 681 }, 682 683 removeData: function( elem, name ) { 684 elem = elem == window ? 685 windowData : 686 elem; 687 688 var id = elem[ expando ]; 689 690 // If we want to remove a specific section of the element's data 691 if ( name ) { 692 if ( jQuery.cache[ id ] ) { 693 // Remove the section of cache data 694 delete jQuery.cache[ id ][ name ]; 695 696 // If we've removed all the data, remove the element's cache 697 name = ""; 698 699 for ( name in jQuery.cache[ id ] ) 700 break; 701 702 if ( !name ) 703 jQuery.removeData( elem ); 704 } 705 706 // Otherwise, we want to remove all of the element's data 707 } else { 708 // Clean up the element expando 709 try { 710 delete elem[ expando ]; 711 } catch(e){ 712 // IE has trouble directly removing the expando 713 // but it's ok with using removeAttribute 714 if ( elem.removeAttribute ) 715 elem.removeAttribute( expando ); 716 } 717 718 // Completely remove the data cache 719 delete jQuery.cache[ id ]; 720 } 721 }, 722 723 // args is for internal usage only 724 each: function( object, callback, args ) { 725 var name, i = 0, length = object.length; 726 727 if ( args ) { 728 if ( length == undefined ) { 729 for ( name in object ) 730 if ( callback.apply( object[ name ], args ) === false ) 731 break; 732 } else 733 for ( ; i < length; ) 734 if ( callback.apply( object[ i++ ], args ) === false ) 735 break; 736 737 // A special, fast, case for the most common use of each 738 } else { 739 if ( length == undefined ) { 740 for ( name in object ) 741 if ( callback.call( object[ name ], name, object[ name ] ) === false ) 742 break; 743 } else 744 for ( var value = object[0]; 745 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} 746 } 747 748 return object; 749 }, 750 751 prop: function( elem, value, type, i, name ) { 752 // Handle executable functions 753 if ( jQuery.isFunction( value ) ) 754 value = value.call( elem, i ); 755 756 // Handle passing in a number to a CSS property 757 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? 758 value + "px" : 759 value; 760 }, 761 762 className: { 763 // internal only, use addClass("class") 764 add: function( elem, classNames ) { 765 jQuery.each((classNames || "").split(/\s+/), function(i, className){ 766 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) 767 elem.className += (elem.className ? " " : "") + className; 768 }); 769 }, 770 771 // internal only, use removeClass("class") 772 remove: function( elem, classNames ) { 773 if (elem.nodeType == 1) 774 elem.className = classNames != undefined ? 775 jQuery.grep(elem.className.split(/\s+/), function(className){ 776 return !jQuery.className.has( classNames, className ); 777 }).join(" ") : 778 ""; 779 }, 780 781 // internal only, use hasClass("class") 782 has: function( elem, className ) { 783 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; 784 } 785 }, 786 787 // A method for quickly swapping in/out CSS properties to get correct calculations 788 swap: function( elem, options, callback ) { 789 var old = {}; 790 // Remember the old values, and insert the new ones 791 for ( var name in options ) { 792 old[ name ] = elem.style[ name ]; 793 elem.style[ name ] = options[ name ]; 794 } 795 796 callback.call( elem ); 797 798 // Revert the old values 799 for ( var name in options ) 800 elem.style[ name ] = old[ name ]; 801 }, 802 803 css: function( elem, name, force ) { 804 if ( name == "width" || name == "height" ) { 805 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; 806 807 function getWH() { 808 val = name == "width" ? elem.offsetWidth : elem.offsetHeight; 809 var padding = 0, border = 0; 810 jQuery.each( which, function() { 811 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 812 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 813 }); 814 val -= Math.round(padding + border); 815 } 816 817 if ( jQuery(elem).is(":visible") ) 818 getWH(); 819 else 820 jQuery.swap( elem, props, getWH ); 821 822 return Math.max(0, val); 823 } 824 825 return jQuery.curCSS( elem, name, force ); 826 }, 827 828 curCSS: function( elem, name, force ) { 829 var ret, style = elem.style; 830 831 // A helper method for determining if an element's values are broken 832 function color( elem ) { 833 if ( !jQuery.browser.safari ) 834 return false; 835 836 // defaultView is cached 837 var ret = defaultView.getComputedStyle( elem, null ); 838 return !ret || ret.getPropertyValue("color") == ""; 839 } 840 841 // We need to handle opacity special in IE 842 if ( name == "opacity" && jQuery.browser.msie ) { 843 ret = jQuery.attr( style, "opacity" ); 844 845 return ret == "" ? 846 "1" : 847 ret; 848 } 849 // Opera sometimes will give the wrong display answer, this fixes it, see #2037 850 if ( jQuery.browser.opera && name == "display" ) { 851 var save = style.outline; 852 style.outline = "0 solid black"; 853 style.outline = save; 854 } 855 856 // Make sure we're using the right name for getting the float value 857 if ( name.match( /float/i ) ) 858 name = styleFloat; 859 860 if ( !force && style && style[ name ] ) 861 ret = style[ name ]; 862 863 else if ( defaultView.getComputedStyle ) { 864 865 // Only "float" is needed here 866 if ( name.match( /float/i ) ) 867 name = "float"; 868 869 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); 870 871 var computedStyle = defaultView.getComputedStyle( elem, null ); 872 873 if ( computedStyle && !color( elem ) ) 874 ret = computedStyle.getPropertyValue( name ); 875 876 // If the element isn't reporting its values properly in Safari 877 // then some display: none elements are involved 878 else { 879 var swap = [], stack = [], a = elem, i = 0; 880 881 // Locate all of the parent display: none elements 882 for ( ; a && color(a); a = a.parentNode ) 883 stack.unshift(a); 884 885 // Go through and make them visible, but in reverse 886 // (It would be better if we knew the exact display type that they had) 887 for ( ; i < stack.length; i++ ) 888 if ( color( stack[ i ] ) ) { 889 swap[ i ] = stack[ i ].style.display; 890 stack[ i ].style.display = "block"; 891 } 892 893 // Since we flip the display style, we have to handle that 894 // one special, otherwise get the value 895 ret = name == "display" && swap[ stack.length - 1 ] != null ? 896 "none" : 897 ( computedStyle && computedStyle.getPropertyValue( name ) ) || ""; 898 899 // Finally, revert the display styles back 900 for ( i = 0; i < swap.length; i++ ) 901 if ( swap[ i ] != null ) 902 stack[ i ].style.display = swap[ i ]; 903 } 904 905 // We should always get a number back from opacity 906 if ( name == "opacity" && ret == "" ) 907 ret = "1"; 908 909 } else if ( elem.currentStyle ) { 910 var camelCase = name.replace(/\-(\w)/g, function(all, letter){ 911 return letter.toUpperCase(); 912 }); 913 914 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 915 916 // From the awesome hack by Dean Edwards 917 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 918 919 // If we're not dealing with a regular pixel number 920 // but a number that has a weird ending, we need to convert it to pixels 921 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { 922 // Remember the original values 923 var left = style.left, rsLeft = elem.runtimeStyle.left; 924 925 // Put in the new values to get a computed value out 926 elem.runtimeStyle.left = elem.currentStyle.left; 927 style.left = ret || 0; 928 ret = style.pixelLeft + "px"; 929 930 // Revert the changed values 931 style.left = left; 932 elem.runtimeStyle.left = rsLeft; 933 } 934 } 935 936 return ret; 937 }, 938 939 clean: function( elems, context ) { 940 var ret = []; 941 context = context || document; 942 // !context.createElement fails in IE with an error but returns typeof 'object' 943 if (typeof context.createElement == 'undefined') 944 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 945 946 jQuery.each(elems, function(i, elem){ 947 if ( !elem ) 948 return; 949 950 if ( elem.constructor == Number ) 951 elem += ''; 952 953 // Convert html string into DOM nodes 954 if ( typeof elem == "string" ) { 955 // Fix "XHTML"-style tags in all browsers 956 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ 957 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? 958 all : 959 front + "></" + tag + ">"; 960 }); 961 962 // Trim whitespace, otherwise indexOf won't work as expected 963 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); 964 965 var wrap = 966 // option or optgroup 967 !tags.indexOf("<opt") && 968 [ 1, "<select multiple='multiple'>", "</select>" ] || 969 970 !tags.indexOf("<leg") && 971 [ 1, "<fieldset>", "</fieldset>" ] || 972 973 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && 974 [ 1, "<table>", "</table>" ] || 975 976 !tags.indexOf("<tr") && 977 [ 2, "<table><tbody>", "</tbody></table>" ] || 978 979 // <thead> matched above 980 (!tags.indexOf("<td") || !tags.indexOf("<th")) && 981 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || 982 983 !tags.indexOf("<col") && 984 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || 985 986 // IE can't serialize <link> and <script> tags normally 987 jQuery.browser.msie && 988 [ 1, "div<div>", "</div>" ] || 989 990 [ 0, "", "" ]; 991 992 // Go to html and back, then peel off extra wrappers 993 div.innerHTML = wrap[1] + elem + wrap[2]; 994 995 // Move to the right depth 996 while ( wrap[0]-- ) 997 div = div.lastChild; 998 999 // Remove IE's autoinserted <tbody> from table fragments 1000 if ( jQuery.browser.msie ) { 1001 1002 // String was a <table>, *may* have spurious <tbody> 1003 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ? 1004 div.firstChild && div.firstChild.childNodes : 1005 1006 // String was a bare <thead> or <tfoot> 1007 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ? 1008 div.childNodes : 1009 []; 1010 1011 for ( var j = tbody.length - 1; j >= 0 ; --j ) 1012 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) 1013 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 1014 1015 // IE completely kills leading whitespace when innerHTML is used 1016 if ( /^\s/.test( elem ) ) 1017 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); 1018 1019 } 1020 1021 elem = jQuery.makeArray( div.childNodes ); 1022 } 1023 1024 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) ) 1025 return; 1026 1027 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options ) 1028 ret.push( elem ); 1029 1030 else 1031 ret = jQuery.merge( ret, elem ); 1032 1033 }); 1034 1035 return ret; 1036 }, 1037 1038 attr: function( elem, name, value ) { 1039 // don't set attributes on text and comment nodes 1040 if (!elem || elem.nodeType == 3 || elem.nodeType == 8) 1041 return undefined; 1042 1043 var notxml = !jQuery.isXMLDoc( elem ), 1044 // Whether we are setting (or getting) 1045 set = value !== undefined, 1046 msie = jQuery.browser.msie; 1047 1048 // Try to normalize/fix the name 1049 name = notxml && jQuery.props[ name ] || name; 1050 1051 // Only do all the following if this is a node (faster for style) 1052 // IE elem.getAttribute passes even for style 1053 if ( elem.tagName ) { 1054 1055 // These attributes require special treatment 1056 var special = /href|src|style/.test( name ); 1057 1058 // Safari mis-reports the default selected property of a hidden option 1059 // Accessing the parent's selectedIndex property fixes it 1060 if ( name == "selected" && jQuery.browser.safari ) 1061 elem.parentNode.selectedIndex; 1062 1063 // If applicable, access the attribute via the DOM 0 way 1064 if ( name in elem && notxml && !special ) { 1065 if ( set ){ 1066 // We can't allow the type property to be changed (since it causes problems in IE) 1067 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode ) 1068 throw "type property can't be changed"; 1069 1070 elem[ name ] = value; 1071 } 1072 1073 // browsers index elements by id/name on forms, give priority to attributes. 1074 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) 1075 return elem.getAttributeNode( name ).nodeValue; 1076 1077 return elem[ name ]; 1078 } 1079 1080 if ( msie && notxml && name == "style" ) 1081 return jQuery.attr( elem.style, "cssText", value ); 1082 1083 if ( set ) 1084 // convert the value to a string (all browsers do this but IE) see #1070 1085 elem.setAttribute( name, "" + value ); 1086 1087 var attr = msie && notxml && special 1088 // Some attributes require a special call on IE 1089 ? elem.getAttribute( name, 2 ) 1090 : elem.getAttribute( name ); 1091 1092 // Non-existent attributes return null, we normalize to undefined 1093 return attr === null ? undefined : attr; 1094 } 1095 1096 // elem is actually elem.style ... set the style 1097 1098 // IE uses filters for opacity 1099 if ( msie && name == "opacity" ) { 1100 if ( set ) { 1101 // IE has trouble with opacity if it does not have layout 1102 // Force it by setting the zoom level 1103 elem.zoom = 1; 1104 1105 // Set the alpha filter to set the opacity 1106 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + 1107 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); 1108 } 1109 1110 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? 1111 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '': 1112 ""; 1113 } 1114 1115 name = name.replace(/-([a-z])/ig, function(all, letter){ 1116 return letter.toUpperCase(); 1117 }); 1118 1119 if ( set ) 1120 elem[ name ] = value; 1121 1122 return elem[ name ]; 1123 }, 1124 1125 trim: function( text ) { 1126 return (text || "").replace( /^\s+|\s+$/g, "" ); 1127 }, 1128 1129 makeArray: function( array ) { 1130 var ret = []; 1131 1132 if( array != null ){ 1133 var i = array.length; 1134 //the window, strings and functions also have 'length' 1135 if( i == null || array.split || array.setInterval || array.call ) 1136 ret[0] = array; 1137 else 1138 while( i ) 1139 ret[--i] = array[i]; 1140 } 1141 1142 return ret; 1143 }, 1144 1145 inArray: function( elem, array ) { 1146 for ( var i = 0, length = array.length; i < length; i++ ) 1147 // Use === because on IE, window == document 1148 if ( array[ i ] === elem ) 1149 return i; 1150 1151 return -1; 1152 }, 1153 1154 merge: function( first, second ) { 1155 // We have to loop this way because IE & Opera overwrite the length 1156 // expando of getElementsByTagName 1157 var i = 0, elem, pos = first.length; 1158 // Also, we need to make sure that the correct elements are being returned 1159 // (IE returns comment nodes in a '*' query) 1160 if ( jQuery.browser.msie ) { 1161 while ( elem = second[ i++ ] ) 1162 if ( elem.nodeType != 8 ) 1163 first[ pos++ ] = elem; 1164 1165 } else 1166 while ( elem = second[ i++ ] ) 1167 first[ pos++ ] = elem; 1168 1169 return first; 1170 }, 1171 1172 unique: function( array ) { 1173 var ret = [], done = {}; 1174 1175 try { 1176 1177 for ( var i = 0, length = array.length; i < length; i++ ) { 1178 var id = jQuery.data( array[ i ] ); 1179 1180 if ( !done[ id ] ) { 1181 done[ id ] = true; 1182 ret.push( array[ i ] ); 1183 } 1184 } 1185 1186 } catch( e ) { 1187 ret = array; 1188 } 1189 1190 return ret; 1191 }, 1192 1193 grep: function( elems, callback, inv ) { 1194 var ret = []; 1195 1196 // Go through the array, only saving the items 1197 // that pass the validator function 1198 for ( var i = 0, length = elems.length; i < length; i++ ) 1199 if ( !inv != !callback( elems[ i ], i ) ) 1200 ret.push( elems[ i ] ); 1201 1202 return ret; 1203 }, 1204 1205 map: function( elems, callback ) { 1206 var ret = []; 1207 1208 // Go through the array, translating each of the items to their 1209 // new value (or values). 1210 for ( var i = 0, length = elems.length; i < length; i++ ) { 1211 var value = callback( elems[ i ], i ); 1212 1213 if ( value != null ) 1214 ret[ ret.length ] = value; 1215 } 1216 1217 return ret.concat.apply( [], ret ); 1218 } 1219 }); 1220 1221 var userAgent = navigator.userAgent.toLowerCase(); 1222 1223 // Figure out what browser is being used 1224 jQuery.browser = { 1225 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1], 1226 safari: /webkit/.test( userAgent ), 1227 opera: /opera/.test( userAgent ), 1228 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), 1229 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) 1230 }; 1231 1232 var styleFloat = jQuery.browser.msie ? 1233 "styleFloat" : 1234 "cssFloat"; 1235 1236 jQuery.extend({ 1237 // Check to see if the W3C box model is being used 1238 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat", 1239 1240 props: { 1241 "for": "htmlFor", 1242 "class": "className", 1243 "float": styleFloat, 1244 cssFloat: styleFloat, 1245 styleFloat: styleFloat, 1246 readonly: "readOnly", 1247 maxlength: "maxLength", 1248 cellspacing: "cellSpacing" 1249 } 1250 }); 1251 1252 jQuery.each({ 1253 parent: function(elem){return elem.parentNode;}, 1254 parents: function(elem){return jQuery.dir(elem,"parentNode");}, 1255 next: function(elem){return jQuery.nth(elem,2,"nextSibling");}, 1256 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");}, 1257 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");}, 1258 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");}, 1259 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);}, 1260 children: function(elem){return jQuery.sibling(elem.firstChild);}, 1261 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);} 1262 }, function(name, fn){ 1263 jQuery.fn[ name ] = function( selector ) { 1264 var ret = jQuery.map( this, fn ); 1265 1266 if ( selector && typeof selector == "string" ) 1267 ret = jQuery.multiFilter( selector, ret ); 1268 1269 return this.pushStack( jQuery.unique( ret ) ); 1270 }; 1271 }); 4225 jQuery.fragments = {}; 1272 4226 1273 4227 jQuery.each({ … … 1277 4231 insertAfter: "after", 1278 4232 replaceAll: "replaceWith" 1279 }, function(name, original){ 1280 jQuery.fn[ name ] = function() { 1281 var args = arguments; 1282 1283 return this.each(function(){ 1284 for ( var i = 0, length = args.length; i < length; i++ ) 1285 jQuery( args[ i ] )[ original ]( this ); 1286 }); 4233 }, function( name, original ) { 4234 jQuery.fn[ name ] = function( selector ) { 4235 var ret = [], insert = jQuery( selector ); 4236 4237 for ( var i = 0, l = insert.length; i < l; i++ ) { 4238 var elems = (i > 0 ? this.clone(true) : this).get(); 4239 jQuery.fn[ original ].apply( jQuery(insert[i]), elems ); 4240 ret = ret.concat( elems ); 4241 } 4242 return this.pushStack( ret, name, insert.selector ); 1287 4243 }; 1288 4244 }); 1289 4245 1290 4246 jQuery.each({ 1291 removeAttr: function( name ) { 1292 jQuery.attr( this, name, "" ); 1293 if (this.nodeType == 1) 1294 this.removeAttribute( name ); 1295 }, 1296 1297 addClass: function( classNames ) { 1298 jQuery.className.add( this, classNames ); 1299 }, 1300 1301 removeClass: function( classNames ) { 1302 jQuery.className.remove( this, classNames ); 1303 }, 1304 1305 toggleClass: function( classNames ) { 1306 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames ); 1307 }, 1308 1309 remove: function( selector ) { 1310 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) { 1311 // Prevent memory leaks 1312 jQuery( "*", this ).add(this).each(function(){ 1313 jQuery.event.remove(this); 1314 jQuery.removeData(this); 1315 }); 1316 if (this.parentNode) 1317 this.parentNode.removeChild( this ); 4247 // keepData is for internal use only--do not document 4248 remove: function( selector, keepData ) { 4249 if ( !selector || jQuery.filter( selector, [ this ] ).length ) { 4250 if ( !keepData && this.nodeType === 1 ) { 4251 jQuery.cleanData( this.getElementsByTagName("*") ); 4252 jQuery.cleanData( [ this ] ); 4253 } 4254 4255 if ( this.parentNode ) { 4256 this.parentNode.removeChild( this ); 4257 } 1318 4258 } 1319 4259 }, … … 1321 4261 empty: function() { 1322 4262 // Remove element nodes and prevent memory leaks 1323 jQuery( ">*", this ).remove(); 4263 if ( this.nodeType === 1 ) { 4264 jQuery.cleanData( this.getElementsByTagName("*") ); 4265 } 1324 4266 1325 4267 // Remove any remaining nodes 1326 while ( this.firstChild ) 4268 while ( this.firstChild ) { 1327 4269 this.removeChild( this.firstChild ); 1328 } 1329 }, function(name, fn){ 1330 jQuery.fn[ name ] = function(){ 4270 } 4271 } 4272 }, function( name, fn ) { 4273 jQuery.fn[ name ] = function() { 1331 4274 return this.each( fn, arguments ); 1332 4275 }; 1333 4276 }); 1334 4277 1335 jQuery.each([ "Height", "Width" ], function(i, name){1336 var type = name.toLowerCase();1337 1338 jQuery.fn[ type ] = function( size ) {1339 // Get window width or height1340 return this[0] == window ?1341 // Opera reports document.body.client[Width/Height] properly in both quirks and standards1342 jQuery.browser.opera && document.body[ "client" + name ] ||1343 1344 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)1345 jQuery.browser.safari && window[ "inner" + name ] ||1346 1347 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode1348 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :1349 1350 // Get document width or height1351 this[0] == document ?1352 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater1353 Math.max(1354 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),1355 Math.max(document.body["offset" + name], document.documentElement["offset" + name])1356 ) :1357 1358 // Get or set width or height on the element1359 size == undefined ?1360 // Get width or height on the element1361 (this.length ? jQuery.css( this[0], type ) : null) :1362 1363 // Set the width or height on the element (default to pixels if value is unitless)1364 this.css( type, size.constructor == String ? size : size + "px" );1365 };1366 });1367 1368 // Helper function used by the dimensions and offset modules1369 function num(elem, prop) {1370 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?1372 "(?:[\\w*_-]|\\\\.)" :1373 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",1374 quickChild = new RegExp("^>\\s*(" + chars + "+)"),1375 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),1376 quickClass = new RegExp("^([#.]?)(" + chars + "*)");1377 1378 4278 jQuery.extend({ 1379 expr: { 1380 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);}, 1381 "#": function(a,i,m){return a.getAttribute("id")==m[2];}, 1382 ":": { 1383 // Position Checks 1384 lt: function(a,i,m){return i<m[3]-0;}, 1385 gt: function(a,i,m){return i>m[3]-0;}, 1386 nth: function(a,i,m){return m[3]-0==i;}, 1387 eq: function(a,i,m){return m[3]-0==i;}, 1388 first: function(a,i){return i==0;}, 1389 last: function(a,i,m,r){return i==r.length-1;}, 1390 even: function(a,i){return i%2==0;}, 1391 odd: function(a,i){return i%2;}, 1392 1393 // Child Checks 1394 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;}, 1395 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;}, 1396 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");}, 1397 1398 // Parent Checks 1399 parent: function(a){return a.firstChild;}, 1400 empty: function(a){return !a.firstChild;}, 1401 1402 // Text Check 1403 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;}, 1404 1405 // Visibility 1406 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";}, 1407 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";}, 1408 1409 // Form attributes 1410 enabled: function(a){return !a.disabled;}, 1411 disabled: function(a){return a.disabled;}, 1412 checked: function(a){return a.checked;}, 1413 selected: function(a){return a.selected||jQuery.attr(a,"selected");}, 1414 1415 // Form elements 1416 text: function(a){return "text"==a.type;}, 1417 radio: function(a){return "radio"==a.type;}, 1418 checkbox: function(a){return "checkbox"==a.type;}, 1419 file: function(a){return "file"==a.type;}, 1420 password: function(a){return "password"==a.type;}, 1421 submit: function(a){return "submit"==a.type;}, 1422 image: function(a){return "image"==a.type;}, 1423 reset: function(a){return "reset"==a.type;}, 1424 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");}, 1425 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);}, 1426 1427 // :has() 1428 has: function(a,i,m){return jQuery.find(m[3],a).length;}, 1429 1430 // :header 1431 header: function(a){return /h\d/i.test(a.nodeName);}, 1432 1433 // :animated 1434 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;} 1435 } 1436 }, 1437 1438 // The regular expressions that power the parsing engine 1439 parse: [ 1440 // Match: [@value='test'], [@foo] 1441 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/, 1442 1443 // Match: :contains('foo') 1444 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/, 1445 1446 // Match: :even, :last-child, #id, .class 1447 new RegExp("^([:.#]*)(" + chars + "+)") 1448 ], 1449 1450 multiFilter: function( expr, elems, not ) { 1451 var old, cur = []; 1452 1453 while ( expr && expr != old ) { 1454 old = expr; 1455 var f = jQuery.filter( expr, elems, not ); 1456 expr = f.t.replace(/^\s*,\s*/, "" ); 1457 cur = not ? elems = f.r : jQuery.merge( cur, f.r ); 1458 } 1459 1460 return cur; 1461 }, 1462 1463 find: function( t, context ) { 1464 // Quickly handle non-string expressions 1465 if ( typeof t != "string" ) 1466 return [ t ]; 1467 1468 // check to make sure context is a DOM element or a document 1469 if ( context && context.nodeType != 1 && context.nodeType != 9) 1470 return [ ]; 1471 1472 // Set the correct context (if none is provided) 4279 clean: function( elems, context, fragment, scripts ) { 1473 4280 context = context || document; 1474 4281 1475 // Initialize the search 1476 var ret = [context], done = [], last, nodeName; 1477 1478 // Continue while a selector expression exists, and while 1479 // we're no longer looping upon ourselves 1480 while ( t && last != t ) { 1481 var r = []; 1482 last = t; 1483 1484 t = jQuery.trim(t); 1485 1486 var foundToken = false, 1487 1488 // An attempt at speeding up child selectors that 1489 // point to a specific element tag 1490 re = quickChild, 1491 1492 m = re.exec(t); 1493 1494 if ( m ) { 1495 nodeName = m[1].toUpperCase(); 1496 1497 // Perform our own iteration and filter 1498 for ( var i = 0; ret[i]; i++ ) 1499 for ( var c = ret[i].firstChild; c; c = c.nextSibling ) 1500 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) ) 1501 r.push( c ); 1502 1503 ret = r; 1504 t = t.replace( re, "" ); 1505 if ( t.indexOf(" ") == 0 ) continue; 1506 foundToken = true; 1507 } else { 1508 re = /^([>+~])\s*(\w*)/i; 1509 1510 if ( (m = re.exec(t)) != null ) { 1511 r = []; 1512 1513 var merge = {}; 1514 nodeName = m[2].toUpperCase(); 1515 m = m[1]; 1516 1517 for ( var j = 0, rl = ret.length; j < rl; j++ ) { 1518 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild; 1519 for ( ; n; n = n.nextSibling ) 1520 if ( n.nodeType == 1 ) { 1521 var id = jQuery.data(n); 1522 1523 if ( m == "~" && merge[id] ) break; 1524 1525 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) { 1526 if ( m == "~" ) merge[id] = true; 1527 r.push( n ); 1528 } 1529 1530 if ( m == "+" ) break; 1531 } 1532 } 1533 1534 ret = r; 1535 1536 // And remove the token 1537 t = jQuery.trim( t.replace( re, "" ) ); 1538 foundToken = true; 1539 } 1540 } 1541 1542 // See if there's still an expression, and that we haven't already 1543 // matched a token 1544 if ( t && !foundToken ) { 1545 // Handle multiple expressions 1546 if ( !t.indexOf(",") ) { 1547 // Clean the result set 1548 if ( context == ret[0] ) ret.shift(); 1549 1550 // Merge the result sets 1551 done = jQuery.merge( done, ret ); 1552 1553 // Reset the context 1554 r = ret = [context]; 1555 1556 // Touch up the selector string 1557 t = " " + t.substr(1,t.length); 1558 1559 } else { 1560 // Optimize for the case nodeName#idName 1561 var re2 = quickID; 1562 var m = re2.exec(t); 1563 1564 // Re-organize the results, so that they're consistent 1565 if ( m ) { 1566 m = [ 0, m[2], m[3], m[1] ]; 1567 1568 } else { 1569 // Otherwise, do a traditional filter check for 1570 // ID, class, and element selectors 1571 re2 = quickClass; 1572 m = re2.exec(t); 1573 } 1574 1575 m[2] = m[2].replace(/\\/g, ""); 1576 1577 var elem = ret[ret.length-1]; 1578 1579 // Try to do a global search by ID, where we can 1580 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) { 1581 // Optimization for HTML document case 1582 var oid = elem.getElementById(m[2]); 1583 1584 // Do a quick check for the existence of the actual ID attribute 1585 // to avoid selecting by the name attribute in IE 1586 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form 1587 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] ) 1588 oid = jQuery('[@id="'+m[2]+'"]', elem)[0]; 1589 1590 // Do a quick check for node name (where applicable) so 1591 // that div#foo searches will be really fast 1592 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : []; 1593 } else { 1594 // We need to find all descendant elements 1595 for ( var i = 0; ret[i]; i++ ) { 1596 // Grab the tag name being searched for 1597 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2]; 1598 1599 // Handle IE7 being really dumb about <object>s 1600 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" ) 1601 tag = "param"; 1602 1603 r = jQuery.merge( r, ret[i].getElementsByTagName( tag )); 1604 } 1605 1606 // It's faster to filter by class and be done with it 1607 if ( m[1] == "." ) 1608 r = jQuery.classFilter( r, m[2] ); 1609 1610 // Same with ID filtering 1611 if ( m[1] == "#" ) { 1612 var tmp = []; 1613 1614 // Try to find the element with the ID 1615 for ( var i = 0; r[i]; i++ ) 1616 if ( r[i].getAttribute("id") == m[2] ) { 1617 tmp = [ r[i] ]; 1618 break; 1619 } 1620 1621 r = tmp; 1622 } 1623 1624 ret = r; 1625 } 1626 1627 t = t.replace( re2, "" ); 1628 } 1629 1630 } 1631 1632 // If a selector string still exists 1633 if ( t ) { 1634 // Attempt to filter it 1635 var val = jQuery.filter(t,r); 1636 ret = r = val.r; 1637 t = jQuery.trim(val.t); 1638 } 1639 } 1640 1641 // An error occurred with the selector; 1642 // just return an empty set instead 1643 if ( t ) 1644 ret = []; 1645 1646 // Remove the root context 1647 if ( ret && context == ret[0] ) 1648 ret.shift(); 1649 1650 // And combine the results 1651 done = jQuery.merge( done, ret ); 1652 1653 return done; 1654 }, 1655 1656 classFilter: function(r,m,not){ 1657 m = " " + m + " "; 1658 var tmp = []; 1659 for ( var i = 0; r[i]; i++ ) { 1660 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0; 1661 if ( !not && pass || not && !pass ) 1662 tmp.push( r[i] ); 1663 } 1664 return tmp; 1665 }, 1666 1667 filter: function(t,r,not) { 1668 var last; 1669 1670 // Look for common filter expressions 1671 while ( t && t != last ) { 1672 last = t; 1673 1674 var p = jQuery.parse, m; 1675 1676 for ( var i = 0; p[i]; i++ ) { 1677 m = p[i].exec( t ); 1678 1679 if ( m ) { 1680 // Remove what we just matched 1681 t = t.substring( m[0].length ); 1682 1683 m[2] = m[2].replace(/\\/g, ""); 1684 break; 1685 } 1686 } 1687 1688 if ( !m ) 1689 break; 1690 1691 // :not() is a special case that can be optimized by 1692 // keeping it out of the expression list 1693 if ( m[1] == ":" && m[2] == "not" ) 1694 // optimize if only one selector found (most common case) 1695 r = isSimple.test( m[3] ) ? 1696 jQuery.filter(m[3], r, true).r : 1697 jQuery( r ).not( m[3] ); 1698 1699 // We can get a big speed boost by filtering by class here 1700 else if ( m[1] == "." ) 1701 r = jQuery.classFilter(r, m[2], not); 1702 1703 else if ( m[1] == "[" ) { 1704 var tmp = [], type = m[3]; 1705 1706 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1707 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ]; 1708 1709 if ( z == null || /href|src|selected/.test(m[2]) ) 1710 z = jQuery.attr(a,m[2]) || ''; 1711 1712 if ( (type == "" && !!z || 1713 type == "=" && z == m[5] || 1714 type == "!=" && z != m[5] || 1715 type == "^=" && z && !z.indexOf(m[5]) || 1716 type == "$=" && z.substr(z.length - m[5].length) == m[5] || 1717 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not ) 1718 tmp.push( a ); 1719 } 1720 1721 r = tmp; 1722 1723 // We can get a speed boost by handling nth-child here 1724 } else if ( m[1] == ":" && m[2] == "nth-child" ) { 1725 var merge = {}, tmp = [], 1726 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 1727 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 1728 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" || 1729 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]), 1730 // calculate the numbers (first)n+(last) including if they are negative 1731 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0; 1732 1733 // loop through all the elements left in the jQuery object 1734 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1735 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode); 1736 1737 if ( !merge[id] ) { 1738 var c = 1; 1739 1740 for ( var n = parentNode.firstChild; n; n = n.nextSibling ) 1741 if ( n.nodeType == 1 ) 1742 n.nodeIndex = c++; 1743 1744 merge[id] = true; 1745 } 1746 1747 var add = false; 1748 1749 if ( first == 0 ) { 1750 if ( node.nodeIndex == last ) 1751 add = true; 1752 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 ) 1753 add = true; 1754 1755 if ( add ^ not ) 1756 tmp.push( node ); 1757 } 1758 1759 r = tmp; 1760 1761 // Otherwise, find the expression to execute 1762 } else { 1763 var fn = jQuery.expr[ m[1] ]; 1764 if ( typeof fn == "object" ) 1765 fn = fn[ m[2] ]; 1766 1767 if ( typeof fn == "string" ) 1768 fn = eval("false||function(a,i){return " + fn + ";}"); 1769 1770 // Execute it against the current filter 1771 r = jQuery.grep( r, function(elem, i){ 1772 return fn(elem, i, m, r); 1773 }, not ); 1774 } 1775 } 1776 1777 // Return an array of filtered elements (r) 1778 // and the modified expression string (t) 1779 return { r: r, t: t }; 1780 }, 1781 1782 dir: function( elem, dir ){ 1783 var matched = [], 1784 cur = elem[dir]; 1785 while ( cur && cur != document ) { 1786 if ( cur.nodeType == 1 ) 1787 matched.push( cur ); 1788 cur = cur[dir]; 1789 } 1790 return matched; 1791 }, 1792 1793 nth: function(cur,result,dir,elem){ 1794 result = result || 1; 1795 var num = 0; 1796 1797 for ( ; cur; cur = cur[dir] ) 1798 if ( cur.nodeType == 1 && ++num == result ) 1799 break; 1800 1801 return cur; 1802 }, 1803 1804 sibling: function( n, elem ) { 1805 var r = []; 1806 1807 for ( ; n; n = n.nextSibling ) { 1808 if ( n.nodeType == 1 && n != elem ) 1809 r.push( n ); 1810 } 1811 1812 return r; 1813 } 1814 }); 1815 /* 1816 * A number of helper functions used for managing events. 1817 * Many of the ideas behind this code orignated from 1818 * Dean Edwards' addEvent library. 1819 */ 1820 jQuery.event = { 1821 1822 // Bind an event to an element 1823 // Original by Dean Edwards 1824 add: function(elem, types, handler, data) { 1825 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1826 return; 1827 1828 // For whatever reason, IE has trouble passing the window object 1829 // around, causing it to be cloned in the process 1830 if ( jQuery.browser.msie && elem.setInterval ) 1831 elem = window; 1832 1833 // Make sure that the function being executed has a unique ID 1834 if ( !handler.guid ) 1835 handler.guid = this.guid++; 1836 1837 // if data is passed, bind to handler 1838 if( data != undefined ) { 1839 // Create temporary function pointer to original handler 1840 var fn = handler; 1841 1842 // Create unique handler function, wrapped around original handler 1843 handler = this.proxy( fn, function() { 1844 // Pass arguments and context to original handler 1845 return fn.apply(this, arguments); 1846 }); 1847 1848 // Store data in unique handler 1849 handler.data = data; 1850 } 1851 1852 // Init the element's event structure 1853 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}), 1854 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){ 1855 // Handle the second event of a trigger and when 1856 // an event is called after a page has unloaded 1857 if ( typeof jQuery != "undefined" && !jQuery.event.triggered ) 1858 return jQuery.event.handle.apply(arguments.callee.elem, arguments); 1859 }); 1860 // Add elem as a property of the handle function 1861 // This is to prevent a memory leak with non-native 1862 // event in IE. 1863 handle.elem = elem; 1864 1865 // Handle multiple events separated by a space 1866 // jQuery(...).bind("mouseover mouseout", fn); 1867 jQuery.each(types.split(/\s+/), function(index, type) { 1868 // Namespaced event handlers 1869 var parts = type.split("."); 1870 type = parts[0]; 1871 handler.type = parts[1]; 1872 1873 // Get the current list of functions bound to this event 1874 var handlers = events[type]; 1875 1876 // Init the event handler queue 1877 if (!handlers) { 1878 handlers = events[type] = {}; 1879 1880 // Check for a special event handler 1881 // Only use addEventListener/attachEvent if the special 1882 // events handler returns false 1883 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) { 1884 // Bind the global event handler to the element 1885 if (elem.addEventListener) 1886 elem.addEventListener(type, handle, false); 1887 else if (elem.attachEvent) 1888 elem.attachEvent("on" + type, handle); 1889 } 1890 } 1891 1892 // Add the function to the element's handler list 1893 handlers[handler.guid] = handler; 1894 1895 // Keep track of which events have been used, for global triggering 1896 jQuery.event.global[type] = true; 1897 }); 1898 1899 // Nullify elem to prevent memory leaks in IE 1900 elem = null; 1901 }, 1902 1903 guid: 1, 1904 global: {}, 1905 1906 // Detach an event or set of events from an element 1907 remove: function(elem, types, handler) { 1908 // don't do events on text and comment nodes 1909 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1910 return; 1911 1912 var events = jQuery.data(elem, "events"), ret, index; 1913 1914 if ( events ) { 1915 // Unbind all events for the element 1916 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") ) 1917 for ( var type in events ) 1918 this.remove( elem, type + (types || "") ); 1919 else { 1920 // types is actually an event object here 1921 if ( types.type ) { 1922 handler = types.handler; 1923 types = types.type; 1924 } 1925 1926 // Handle multiple events seperated by a space 1927 // jQuery(...).unbind("mouseover mouseout", fn); 1928 jQuery.each(types.split(/\s+/), function(index, type){ 1929 // Namespaced event handlers 1930 var parts = type.split("."); 1931 type = parts[0]; 1932 1933 if ( events[type] ) { 1934 // remove the given handler for the given type 1935 if ( handler ) 1936 delete events[type][handler.guid]; 1937 1938 // remove all handlers for the given type 1939 else 1940 for ( handler in events[type] ) 1941 // Handle the removal of namespaced events 1942 if ( !parts[1] || events[type][handler].type == parts[1] ) 1943 delete events[type][handler]; 1944 1945 // remove generic event handler if no more handlers exist 1946 for ( ret in events[type] ) break; 1947 if ( !ret ) { 1948 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) { 1949 if (elem.removeEventListener) 1950 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); 1951 else if (elem.detachEvent) 1952 elem.detachEvent("on" + type, jQuery.data(elem, "handle")); 1953 } 1954 ret = null; 1955 delete events[type]; 4282 // !context.createElement fails in IE with an error but returns typeof 'object' 4283 if ( typeof context.createElement === "undefined" ) { 4284 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 4285 } 4286 4287 var ret = []; 4288 4289 jQuery.each(elems, function( i, elem ) { 4290 if ( typeof elem === "number" ) { 4291 elem += ""; 4292 } 4293 4294 if ( !elem ) { 4295 return; 4296 } 4297 4298 // Convert html string into DOM nodes 4299 if ( typeof elem === "string" && !rhtml.test( elem ) ) { 4300 elem = context.createTextNode( elem ); 4301 4302 } else if ( typeof elem === "string" ) { 4303 // Fix "XHTML"-style tags in all browsers 4304 elem = elem.replace(rxhtmlTag, fcloseTag); 4305 4306 // Trim whitespace, otherwise indexOf won't work as expected 4307 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), 4308 wrap = wrapMap[ tag ] || wrapMap._default, 4309 depth = wrap[0], 4310 div = context.createElement("div"); 4311 4312 // Go to html and back, then peel off extra wrappers 4313 div.innerHTML = wrap[1] + elem + wrap[2]; 4314 4315 // Move to the right depth 4316 while ( depth-- ) { 4317 div = div.lastChild; 4318 } 4319 4320 // Remove IE's autoinserted <tbody> from table fragments 4321 if ( !jQuery.support.tbody ) { 4322 4323 // String was a <table>, *may* have spurious <tbody> 4324 var hasBody = rtbody.test(elem), 4325 tbody = tag === "table" && !hasBody ? 4326 div.firstChild && div.firstChild.childNodes : 4327 4328 // String was a bare <thead> or <tfoot> 4329 wrap[1] === "<table>" && !hasBody ? 4330 div.childNodes : 4331 []; 4332 4333 for ( var j = tbody.length - 1; j >= 0 ; --j ) { 4334 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { 4335 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 1956 4336 } 1957 4337 } 4338 4339 } 4340 4341 // IE completely kills leading whitespace when innerHTML is used 4342 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { 4343 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); 4344 } 4345 4346 elem = jQuery.makeArray( div.childNodes ); 4347 } 4348 4349 if ( elem.nodeType ) { 4350 ret.push( elem ); 4351 } else { 4352 ret = jQuery.merge( ret, elem ); 4353 } 4354 4355 }); 4356 4357 if ( fragment ) { 4358 for ( var i = 0; ret[i]; i++ ) { 4359 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { 4360 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); 4361 } else { 4362 if ( ret[i].nodeType === 1 ) { 4363 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); 4364 } 4365 fragment.appendChild( ret[i] ); 4366 } 4367 } 4368 } 4369 4370 return ret; 4371 }, 4372 4373 cleanData: function( elems ) { 4374 for ( var i = 0, elem, id; (elem = elems[i]) != null; i++ ) { 4375 jQuery.event.remove( elem ); 4376 jQuery.removeData( elem ); 4377 } 4378 } 4379 }); 4380 // exclude the following css properties to add px 4381 var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, 4382 ralpha = /alpha\([^)]*\)/, 4383 ropacity = /opacity=([^)]*)/, 4384 rfloat = /float/i, 4385 rdashAlpha = /-([a-z])/ig, 4386 rupper = /([A-Z])/g, 4387 rnumpx = /^-?\d+(?:px)?$/i, 4388 rnum = /^-?\d/, 4389 4390 cssShow = { position: "absolute", visibility: "hidden", display:"block" }, 4391 cssWidth = [ "Left", "Right" ], 4392 cssHeight = [ "Top", "Bottom" ], 4393 4394 // cache check for defaultView.getComputedStyle 4395 getComputedStyle = document.defaultView && document.defaultView.getComputedStyle, 4396 // normalize float css property 4397 styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat", 4398 fcamelCase = function( all, letter ) { 4399 return letter.toUpperCase(); 4400 }; 4401 4402 jQuery.fn.css = function( name, value ) { 4403 return access( this, name, value, true, function( elem, name, value ) { 4404 if ( value === undefined ) { 4405 return jQuery.curCSS( elem, name ); 4406 } 4407 4408 if ( typeof value === "number" && !rexclude.test(name) ) { 4409 value += "px"; 4410 } 4411 4412 jQuery.style( elem, name, value ); 4413 }); 4414 }; 4415 4416 jQuery.extend({ 4417 style: function( elem, name, value ) { 4418 // don't set styles on text and comment nodes 4419 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { 4420 return undefined; 4421 } 4422 4423 // ignore negative width and height values #1599 4424 if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) { 4425 value = undefined; 4426 } 4427 4428 var style = elem.style || elem, set = value !== undefined; 4429 4430 // IE uses filters for opacity 4431 if ( !jQuery.support.opacity && name === "opacity" ) { 4432 if ( set ) { 4433 // IE has trouble with opacity if it does not have layout 4434 // Force it by setting the zoom level 4435 style.zoom = 1; 4436 4437 // Set the alpha filter to set the opacity 4438 var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"; 4439 var filter = style.filter || jQuery.curCSS( elem, "filter" ) || ""; 4440 style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity; 4441 } 4442 4443 return style.filter && style.filter.indexOf("opacity=") >= 0 ? 4444 (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "": 4445 ""; 4446 } 4447 4448 // Make sure we're using the right name for getting the float value 4449 if ( rfloat.test( name ) ) { 4450 name = styleFloat; 4451 } 4452 4453 name = name.replace(rdashAlpha, fcamelCase); 4454 4455 if ( set ) { 4456 style[ name ] = value; 4457 } 4458 4459 return style[ name ]; 4460 }, 4461 4462 css: function( elem, name, force, extra ) { 4463 if ( name === "width" || name === "height" ) { 4464 var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight; 4465 4466 function getWH() { 4467 val = name === "width" ? elem.offsetWidth : elem.offsetHeight; 4468 4469 if ( extra === "border" ) { 4470 return; 4471 } 4472 4473 jQuery.each( which, function() { 4474 if ( !extra ) { 4475 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 4476 } 4477 4478 if ( extra === "margin" ) { 4479 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; 4480 } else { 4481 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 4482 } 1958 4483 }); 1959 4484 } 1960 4485 1961 // Remove the expando if it's no longer used 1962 for ( ret in events ) break; 1963 if ( !ret ) { 1964 var handle = jQuery.data( elem, "handle" ); 1965 if ( handle ) handle.elem = null; 1966 jQuery.removeData( elem, "events" ); 1967 jQuery.removeData( elem, "handle" ); 1968 } 1969 } 1970 }, 1971 1972 trigger: function(type, data, elem, donative, extra) { 1973 // Clone the incoming data, if any 1974 data = jQuery.makeArray(data); 1975 1976 if ( type.indexOf("!") >= 0 ) { 1977 type = type.slice(0, -1); 1978 var exclusive = true; 1979 } 1980 1981 // Handle a global trigger 1982 if ( !elem ) { 1983 // Only trigger if we've ever bound an event for it 1984 if ( this.global[type] ) 1985 jQuery("*").add([window, document]).trigger(type, data); 1986 1987 // Handle triggering a single element 1988 } else { 1989 // don't do events on text and comment nodes 1990 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1991 return undefined; 1992 1993 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ), 1994 // Check to see if we need to provide a fake event, or not 1995 event = !data[0] || !data[0].preventDefault; 1996 1997 // Pass along a fake event 1998 if ( event ) { 1999 data.unshift({ 2000 type: type, 2001 target: elem, 2002 preventDefault: function(){}, 2003 stopPropagation: function(){}, 2004 timeStamp: now() 2005 }); 2006 data[0][expando] = true; // no need to fix fake event 2007 } 2008 2009 // Enforce the right trigger type 2010 data[0].type = type; 2011 if ( exclusive ) 2012 data[0].exclusive = true; 2013 2014 // Trigger the event, it is assumed that "handle" is a function 2015 var handle = jQuery.data(elem, "handle"); 2016 if ( handle ) 2017 val = handle.apply( elem, data ); 2018 2019 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links) 2020 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 2021 val = false; 2022 2023 // Extra functions don't get the custom event object 2024 if ( event ) 2025 data.shift(); 2026 2027 // Handle triggering of extra function 2028 if ( extra && jQuery.isFunction( extra ) ) { 2029 // call the extra function and tack the current return value on the end for possible inspection 2030 ret = extra.apply( elem, val == null ? data : data.concat( val ) ); 2031 // if anything is returned, give it precedence and have it overwrite the previous value 2032 if (ret !== undefined) 2033 val = ret; 2034 } 2035 2036 // Trigger the native events (except for clicks on links) 2037 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) { 2038 this.triggered = true; 2039 try { 2040 elem[ type ](); 2041 // prevent IE from throwing an error for some hidden elements 2042 } catch (e) {} 2043 } 2044 2045 this.triggered = false; 2046 } 2047 2048 return val; 2049 }, 2050 2051 handle: function(event) { 2052 // returned undefined or false 2053 var val, ret, namespace, all, handlers; 2054 2055 event = arguments[0] = jQuery.event.fix( event || window.event ); 2056 2057 // Namespaced event handlers 2058 namespace = event.type.split("."); 2059 event.type = namespace[0]; 2060 namespace = namespace[1]; 2061 // Cache this now, all = true means, any handler 2062 all = !namespace && !event.exclusive; 2063 2064 handlers = ( jQuery.data(this, "events") || {} )[event.type]; 2065 2066 for ( var j in handlers ) { 2067 var handler = handlers[j]; 2068 2069 // Filter the functions by class 2070 if ( all || handler.type == namespace ) { 2071 // Pass in a reference to the handler function itself 2072 // So that we can later remove it 2073 event.handler = handler; 2074 event.data = handler.data; 2075 2076 ret = handler.apply( this, arguments ); 2077 2078 if ( val !== false ) 2079 val = ret; 2080 2081 if ( ret === false ) { 2082 event.preventDefault(); 2083 event.stopPropagation(); 2084 } 2085 } 2086 } 2087 2088 return val; 2089 }, 2090 2091 fix: function(event) { 2092 if ( event[expando] == true ) 2093 return event; 2094 2095 // store a copy of the original event object 2096 // and "clone" to set read-only properties 2097 var originalEvent = event; 2098 event = { originalEvent: originalEvent }; 2099 var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" "); 2100 for ( var i=props.length; i; i-- ) 2101 event[ props[i] ] = originalEvent[ props[i] ]; 2102 2103 // Mark it as fixed 2104 event[expando] = true; 2105 2106 // add preventDefault and stopPropagation since 2107 // they will not work on the clone 2108 event.preventDefault = function() { 2109 // if preventDefault exists run it on the original event 2110 if (originalEvent.preventDefault) 2111 originalEvent.preventDefault(); 2112 // otherwise set the returnValue property of the original event to false (IE) 2113 originalEvent.returnValue = false; 2114 }; 2115 event.stopPropagation = function() { 2116 // if stopPropagation exists run it on the original event 2117 if (originalEvent.stopPropagation) 2118 originalEvent.stopPropagation(); 2119 // otherwise set the cancelBubble property of the original event to true (IE) 2120 originalEvent.cancelBubble = true; 2121 }; 2122 2123 // Fix timeStamp 2124 event.timeStamp = event.timeStamp || now(); 2125 2126 // Fix target property, if necessary 2127 if ( !event.target ) 2128 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 2129 2130 // check if target is a textnode (safari) 2131 if ( event.target.nodeType == 3 ) 2132 event.target = event.target.parentNode; 2133 2134 // Add relatedTarget, if necessary 2135 if ( !event.relatedTarget && event.fromElement ) 2136 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; 2137 2138 // Calculate pageX/Y if missing and clientX/Y available 2139 if ( event.pageX == null && event.clientX != null ) { 2140 var doc = document.documentElement, body = document.body; 2141 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); 2142 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); 2143 } 2144 2145 // Add which for key events 2146 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) 2147 event.which = event.charCode || event.keyCode; 2148 2149 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2150 if ( !event.metaKey && event.ctrlKey ) 2151 event.metaKey = event.ctrlKey; 2152 2153 // Add which for click: 1 == left; 2 == middle; 3 == right 2154 // Note: button is not normalized, so don't use it 2155 if ( !event.which && event.button ) 2156 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2157 2158 return event; 2159 }, 2160 2161 proxy: function( fn, proxy ){ 2162 // Set the guid of unique handler to the same of original handler, so it can be removed 2163 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++; 2164 // So proxy can be declared as an argument 2165 return proxy; 2166 }, 2167 2168 special: { 2169 ready: { 2170 setup: function() { 2171 // Make sure the ready event is setup 2172 bindReady(); 2173 return; 2174 }, 2175 2176 teardown: function() { return; } 2177 }, 2178 2179 mouseenter: { 2180 setup: function() { 2181 if ( jQuery.browser.msie ) return false; 2182 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler); 2183 return true; 2184 }, 2185 2186 teardown: function() { 2187 if ( jQuery.browser.msie ) return false; 2188 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler); 2189 return true; 2190 }, 2191 2192 handler: function(event) { 2193 // If we actually just moused on to a sub-element, ignore it 2194 if ( withinElement(event, this) ) return true; 2195 // Execute the right handlers by setting the event type to mouseenter 2196 event.type = "mouseenter"; 2197 return jQuery.event.handle.apply(this, arguments); 2198 } 2199 }, 2200 2201 mouseleave: { 2202 setup: function() { 2203 if ( jQuery.browser.msie ) return false; 2204 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler); 2205 return true; 2206 }, 2207 2208 teardown: function() { 2209 if ( jQuery.browser.msie ) return false; 2210 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler); 2211 return true; 2212 }, 2213 2214 handler: function(event) { 2215 // If we actually just moused on to a sub-element, ignore it 2216 if ( withinElement(event, this) ) return true; 2217 // Execute the right handlers by setting the event type to mouseleave 2218 event.type = "mouseleave"; 2219 return jQuery.event.handle.apply(this, arguments); 2220 } 2221 } 2222 } 2223 }; 2224 2225 jQuery.fn.extend({ 2226 bind: function( type, data, fn ) { 2227 return type == "unload" ? this.one(type, data, fn) : this.each(function(){ 2228 jQuery.event.add( this, type, fn || data, fn && data ); 2229 }); 2230 }, 2231 2232 one: function( type, data, fn ) { 2233 var one = jQuery.event.proxy( fn || data, function(event) { 2234 jQuery(this).unbind(event, one); 2235 return (fn || data).apply( this, arguments ); 2236 }); 2237 return this.each(function(){ 2238 jQuery.event.add( this, type, one, fn && data); 2239 }); 2240 }, 2241 2242 unbind: function( type, fn ) { 2243 return this.each(function(){ 2244 jQuery.event.remove( this, type, fn ); 2245 }); 2246 }, 2247 2248 trigger: function( type, data, fn ) { 2249 return this.each(function(){ 2250 jQuery.event.trigger( type, data, this, true, fn ); 2251 }); 2252 }, 2253 2254 triggerHandler: function( type, data, fn ) { 2255 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn ); 2256 }, 2257 2258 toggle: function( fn ) { 2259 // Save reference to arguments for access in closure 2260 var args = arguments, i = 1; 2261 2262 // link all the functions, so any of them can unbind this click handler 2263 while( i < args.length ) 2264 jQuery.event.proxy( fn, args[i++] ); 2265 2266 return this.click( jQuery.event.proxy( fn, function(event) { 2267 // Figure out which function to execute 2268 this.lastToggle = ( this.lastToggle || 0 ) % i; 2269 2270 // Make sure that clicks stop 2271 event.preventDefault(); 2272 2273 // and execute the function 2274 return args[ this.lastToggle++ ].apply( this, arguments ) || false; 2275 })); 2276 }, 2277 2278 hover: function(fnOver, fnOut) { 2279 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut); 2280 }, 2281 2282 ready: function(fn) { 2283 // Attach the listeners 2284 bindReady(); 2285 2286 // If the DOM is already ready 2287 if ( jQuery.isReady ) 2288 // Execute the function immediately 2289 fn.call( document, jQuery ); 2290 2291 // Otherwise, remember the function for later 2292 else 2293 // Add the function to the wait list 2294 jQuery.readyList.push( function() { return fn.call(this, jQuery); } ); 2295 2296 return this; 4486 if ( elem.offsetWidth !== 0 ) { 4487 getWH(); 4488 } else { 4489 jQuery.swap( elem, props, getWH ); 4490 } 4491 4492 return Math.max(0, Math.round(val)); 4493 } 4494 4495 return jQuery.curCSS( elem, name, force ); 4496 }, 4497 4498 curCSS: function( elem, name, force ) { 4499 var ret, style = elem.style, filter; 4500 4501 // IE uses filters for opacity 4502 if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) { 4503 ret = ropacity.test(elem.currentStyle.filter || "") ? 4504 (parseFloat(RegExp.$1) / 100) + "" : 4505 ""; 4506 4507 return ret === "" ? 4508 "1" : 4509 ret; 4510 } 4511 4512 // Make sure we're using the right name for getting the float value 4513 if ( rfloat.test( name ) ) { 4514 name = styleFloat; 4515 } 4516 4517 if ( !force && style && style[ name ] ) { 4518 ret = style[ name ]; 4519 4520 } else if ( getComputedStyle ) { 4521 4522 // Only "float" is needed here 4523 if ( rfloat.test( name ) ) { 4524 name = "float"; 4525 } 4526 4527 name = name.replace( rupper, "-$1" ).toLowerCase(); 4528 4529 var defaultView = elem.ownerDocument.defaultView; 4530 4531 if ( !defaultView ) { 4532 return null; 4533 } 4534 4535 var computedStyle = defaultView.getComputedStyle( elem, null ); 4536 4537 if ( computedStyle ) { 4538 ret = computedStyle.getPropertyValue( name ); 4539 } 4540 4541 // We should always get a number back from opacity 4542 if ( name === "opacity" && ret === "" ) { 4543 ret = "1"; 4544 } 4545 4546 } else if ( elem.currentStyle ) { 4547 var camelCase = name.replace(rdashAlpha, fcamelCase); 4548 4549 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 4550 4551 // From the awesome hack by Dean Edwards 4552 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 4553 4554 // If we're not dealing with a regular pixel number 4555 // but a number that has a weird ending, we need to convert it to pixels 4556 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { 4557 // Remember the original values 4558 var left = style.left, rsLeft = elem.runtimeStyle.left; 4559 4560 // Put in the new values to get a computed value out 4561 elem.runtimeStyle.left = elem.currentStyle.left; 4562 style.left = camelCase === "fontSize" ? "1em" : (ret || 0); 4563 ret = style.pixelLeft + "px"; 4564 4565 // Revert the changed values 4566 style.left = left; 4567 elem.runtimeStyle.left = rsLeft; 4568 } 4569 } 4570 4571 return ret; 4572 }, 4573 4574 // A method for quickly swapping in/out CSS properties to get correct calculations 4575 swap: function( elem, options, callback ) { 4576 var old = {}; 4577 4578 // Remember the old values, and insert the new ones 4579 for ( var name in options ) { 4580 old[ name ] = elem.style[ name ]; 4581 elem.style[ name ] = options[ name ]; 4582 } 4583 4584 callback.call( elem ); 4585 4586 // Revert the old values 4587 for ( var name in options ) { 4588 elem.style[ name ] = old[ name ]; 4589 } 2297 4590 } 2298 4591 }); 2299 4592 2300 jQuery.extend({ 2301 isReady: false, 2302 readyList: [], 2303 // Handle when the DOM is ready 2304 ready: function() { 2305 // Make sure that the DOM is not already loaded 2306 if ( !jQuery.isReady ) { 2307 // Remember that the DOM is ready 2308 jQuery.isReady = true; 2309 2310 // If there are functions bound, to execute 2311 if ( jQuery.readyList ) { 2312 // Execute all of them 2313 jQuery.each( jQuery.readyList, function(){ 2314 this.call( document ); 2315 }); 2316 2317 // Reset the list of functions 2318 jQuery.readyList = null; 2319 } 2320 2321 // Trigger any bound ready events 2322 jQuery(document).triggerHandler("ready"); 2323 } 2324 } 2325 }); 2326 2327 var readyBound = false; 2328 2329 function bindReady(){ 2330 if ( readyBound ) return; 2331 readyBound = true; 2332 2333 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event 2334 if ( document.addEventListener && !jQuery.browser.opera) 2335 // Use the handy event callback 2336 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 2337 2338 // If IE is used and is not in a frame 2339 // Continually check to see if the document is ready 2340 if ( jQuery.browser.msie && window == top ) (function(){ 2341 if (jQuery.isReady) return; 2342 try { 2343 // If IE is used, use the trick by Diego Perini 2344 // http://javascript.nwbox.com/IEContentLoaded/ 2345 document.documentElement.doScroll("left"); 2346 } catch( error ) { 2347 setTimeout( arguments.callee, 0 ); 2348 return; 2349 } 2350 // and execute any waiting functions 2351 jQuery.ready(); 2352 })(); 2353 2354 if ( jQuery.browser.opera ) 2355 document.addEventListener( "DOMContentLoaded", function () { 2356 if (jQuery.isReady) return; 2357 for (var i = 0; i < document.styleSheets.length; i++) 2358 if (document.styleSheets[i].disabled) { 2359 setTimeout( arguments.callee, 0 ); 2360 return; 2361 } 2362 // and execute any waiting functions 2363 jQuery.ready(); 2364 }, false); 2365 2366 if ( jQuery.browser.safari ) { 2367 var numStyles; 2368 (function(){ 2369 if (jQuery.isReady) return; 2370 if ( document.readyState != "loaded" && document.readyState != "complete" ) { 2371 setTimeout( arguments.callee, 0 ); 2372 return; 2373 } 2374 if ( numStyles === undefined ) 2375 numStyles = jQuery("style, link[rel=stylesheet]").length; 2376 if ( document.styleSheets.length != numStyles ) { 2377 setTimeout( arguments.callee, 0 ); 2378 return; 2379 } 2380 // and execute any waiting functions 2381 jQuery.ready(); 2382 })(); 2383 } 2384 2385 // A fallback to window.onload, that will always work 2386 jQuery.event.add( window, "load", jQuery.ready ); 4593 if ( jQuery.expr && jQuery.expr.filters ) { 4594 jQuery.expr.filters.hidden = function( elem ) { 4595 var width = elem.offsetWidth, height = elem.offsetHeight, 4596 skip = elem.nodeName.toLowerCase() === "tr"; 4597 4598 return width === 0 && height === 0 && !skip ? 4599 true : 4600 width > 0 && height > 0 && !skip ? 4601 false : 4602 jQuery.curCSS(elem, "display") === "none"; 4603 }; 4604 4605 jQuery.expr.filters.visible = function( elem ) { 4606 return !jQuery.expr.filters.hidden( elem ); 4607 }; 2387 4608 } 2388 2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + 2390 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 2391 "submit,keydown,keypress,keyup,error").split(","), function(i, name){ 2392 2393 // Handle event binding 2394 jQuery.fn[name] = function(fn){ 2395 return fn ? this.bind(name, fn) : this.trigger(name); 2396 }; 2397 }); 2398 2399 // Checks if an event happened on an element within another element 2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2401 var withinElement = function(event, elem) { 2402 // Check if mouse(over|out) are still within the same parent element 2403 var parent = event.relatedTarget; 2404 // Traverse up the tree 2405 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; } 2406 // Return true if we actually just moused on to a sub-element 2407 return parent == elem; 2408 }; 2409 2410 // Prevent memory leaks in IE 2411 // And prevent errors on refresh with events like mouseover in other browsers 2412 // Window isn't included so as not to unbind existing unload events 2413 jQuery(window).bind("unload", function() { 2414 jQuery("*").add(document).unbind(); 2415 }); 4609 var jsc = now(), 4610 rscript = /<script(.|\s)*?\/script>/gi, 4611 rselectTextarea = /select|textarea/i, 4612 rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i, 4613 jsre = /=\?(&|$)/, 4614 rquery = /\?/, 4615 rts = /(\?|&)_=.*?(&|$)/, 4616 rurl = /^(\w+:)?\/\/([^\/?#]+)/, 4617 r20 = /%20/g; 4618 2416 4619 jQuery.fn.extend({ 2417 4620 // Keep a copy of the old load … … 2419 4622 2420 4623 load: function( url, params, callback ) { 2421 if ( typeof url != 'string' )4624 if ( typeof url !== "string" ) { 2422 4625 return this._load( url ); 4626 4627 // Don't do a request if no elements are being requested 4628 } else if ( !this.length ) { 4629 return this; 4630 } 2423 4631 2424 4632 var off = url.indexOf(" "); … … 2428 4636 } 2429 4637 2430 callback = callback || function(){};2431 2432 4638 // Default to a GET request 2433 4639 var type = "GET"; 2434 4640 2435 4641 // If the second parameter was provided 2436 if ( params ) 4642 if ( params ) { 2437 4643 // If it's a function 2438 4644 if ( jQuery.isFunction( params ) ) { … … 2442 4648 2443 4649 // Otherwise, build a param string 2444 } else {2445 params = jQuery.param( params );4650 } else if ( typeof params === "object" ) { 4651 params = jQuery.param( params, jQuery.ajaxSettings.traditional ); 2446 4652 type = "POST"; 2447 4653 } 4654 } 2448 4655 2449 4656 var self = this; … … 2455 4662 dataType: "html", 2456 4663 data: params, 2457 complete: function( res, status){4664 complete: function( res, status ) { 2458 4665 // If successful, inject the HTML into all the matched elements 2459 if ( status == "success" || status == "notmodified" )4666 if ( status === "success" || status === "notmodified" ) { 2460 4667 // See if a selector was specified 2461 4668 self.html( selector ? 2462 4669 // Create a dummy div to hold the results 2463 jQuery("<div />")4670 jQuery("<div />") 2464 4671 // inject the contents of the document in, removing the scripts 2465 4672 // to avoid any 'Permission Denied' errors in IE 2466 .append(res.responseText.replace( /<script(.|\s)*?\/script>/g, ""))4673 .append(res.responseText.replace(rscript, "")) 2467 4674 2468 4675 // Locate the specified elements … … 2471 4678 // If not, just inject the full result 2472 4679 res.responseText ); 2473 2474 self.each( callback, [res.responseText, status, res] ); 4680 } 4681 4682 if ( callback ) { 4683 self.each( callback, [res.responseText, status, res] ); 4684 } 2475 4685 } 2476 4686 }); 4687 2477 4688 return this; 2478 4689 }, … … 2482 4693 }, 2483 4694 serializeArray: function() { 2484 return this.map(function(){ 2485 return jQuery.nodeName(this, "form") ? 2486 jQuery.makeArray(this.elements) : this; 4695 return this.map(function() { 4696 return this.elements ? jQuery.makeArray(this.elements) : this; 2487 4697 }) 2488 .filter(function() {4698 .filter(function() { 2489 4699 return this.name && !this.disabled && 2490 (this.checked || /select|textarea/i.test(this.nodeName) ||2491 /text|hidden|password/i.test(this.type));4700 (this.checked || rselectTextarea.test(this.nodeName) || 4701 rinput.test(this.type)); 2492 4702 }) 2493 .map(function( i, elem){4703 .map(function( i, elem ) { 2494 4704 var val = jQuery(this).val(); 2495 return val == null ? null : 2496 val.constructor == Array ? 2497 jQuery.map( val, function(val, i){ 2498 return {name: elem.name, value: val}; 4705 4706 return val == null ? 4707 null : 4708 jQuery.isArray(val) ? 4709 jQuery.map( val, function( val, i ) { 4710 return { name: elem.name, value: val }; 2499 4711 }) : 2500 { name: elem.name, value: val};4712 { name: elem.name, value: val }; 2501 4713 }).get(); 2502 4714 } … … 2504 4716 2505 4717 // Attach a bunch of functions for handling common AJAX events 2506 jQuery.each( "ajaxStart ,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){2507 jQuery.fn[o] = function( f){4718 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) { 4719 jQuery.fn[o] = function( f ) { 2508 4720 return this.bind(o, f); 2509 4721 }; 2510 4722 }); 2511 4723 2512 var jsc = now();2513 2514 4724 jQuery.extend({ 4725 2515 4726 get: function( url, data, callback, type ) { 2516 // shift arguments if data argument was om mited4727 // shift arguments if data argument was omited 2517 4728 if ( jQuery.isFunction( data ) ) { 4729 type = type || callback; 2518 4730 callback = data; 2519 4731 data = null; … … 2538 4750 2539 4751 post: function( url, data, callback, type ) { 4752 // shift arguments if data argument was omited 2540 4753 if ( jQuery.isFunction( data ) ) { 4754 type = type || callback; 2541 4755 callback = data; 2542 4756 data = {}; … … 2560 4774 global: true, 2561 4775 type: "GET", 2562 timeout: 0,2563 4776 contentType: "application/x-www-form-urlencoded", 2564 4777 processData: true, 2565 4778 async: true, 4779 /* 4780 timeout: 0, 2566 4781 data: null, 2567 4782 username: null, 2568 4783 password: null, 4784 traditional: false, 4785 */ 4786 // Create the request object; Microsoft failed to properly 4787 // implement the XMLHttpRequest in IE7 (can't request local files), 4788 // so we use the ActiveXObject when it is available 4789 // This function can be overriden by calling jQuery.ajaxSetup 4790 xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ? 4791 function() { 4792 return new window.XMLHttpRequest(); 4793 } : 4794 function() { 4795 try { 4796 return new window.ActiveXObject("Microsoft.XMLHTTP"); 4797 } catch(e) {} 4798 }, 2569 4799 accepts: { 2570 4800 xml: "application/xml, text/xml", … … 2579 4809 // Last-Modified header cache for next request 2580 4810 lastModified: {}, 2581 2582 ajax: function( s ) { 2583 // Extend the settings, but re-extend 's' so that it can be2584 // checked again later (in the test suite, specifically)2585 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));2586 2587 var jsonp, jsre = /=\?(&|$)/g, status, data,4811 etag: {}, 4812 4813 ajax: function( origSettings ) { 4814 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings); 4815 4816 var jsonp, status, data, 4817 callbackContext = origSettings && origSettings.context || s, 2588 4818 type = s.type.toUpperCase(); 2589 4819 2590 4820 // convert data if not already a string 2591 if ( s.data && s.processData && typeof s.data != "string" ) 2592 s.data = jQuery.param(s.data); 4821 if ( s.data && s.processData && typeof s.data !== "string" ) { 4822 s.data = jQuery.param( s.data, s.traditional ); 4823 } 2593 4824 2594 4825 // Handle JSONP Parameter Callbacks 2595 if ( s.dataType == "jsonp" ) { 2596 if ( type == "GET" ) { 2597 if ( !s.url.match(jsre) ) 2598 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 2599 } else if ( !s.data || !s.data.match(jsre) ) 4826 if ( s.dataType === "jsonp" ) { 4827 if ( type === "GET" ) { 4828 if ( !jsre.test( s.url ) ) { 4829 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 4830 } 4831 } else if ( !s.data || !jsre.test(s.data) ) { 2600 4832 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 4833 } 2601 4834 s.dataType = "json"; 2602 4835 } 2603 4836 2604 4837 // Build temporary JSONP function 2605 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {2606 jsonp = "jsonp" + jsc++;4838 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) { 4839 jsonp = s.jsonpCallback || ("jsonp" + jsc++); 2607 4840 2608 4841 // Replace the =? sequence both in the query string and the data 2609 if ( s.data ) 4842 if ( s.data ) { 2610 4843 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 4844 } 4845 2611 4846 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 2612 4847 … … 2616 4851 2617 4852 // Handle JSONP-style loading 2618 window[ jsonp ] = function(tmp){4853 window[ jsonp ] = window[ jsonp ] || function( tmp ) { 2619 4854 data = tmp; 2620 4855 success(); … … 2622 4857 // Garbage collect 2623 4858 window[ jsonp ] = undefined; 2624 try{ delete window[ jsonp ]; } catch(e){} 2625 if ( head ) 4859 4860 try { 4861 delete window[ jsonp ]; 4862 } catch(e) {} 4863 4864 if ( head ) { 2626 4865 head.removeChild( script ); 4866 } 2627 4867 }; 2628 4868 } 2629 4869 2630 if ( s.dataType == "script" && s.cache == null )4870 if ( s.dataType === "script" && s.cache === null ) { 2631 4871 s.cache = false; 2632 2633 if ( s.cache === false && type == "GET" ) { 4872 } 4873 4874 if ( s.cache === false && type === "GET" ) { 2634 4875 var ts = now(); 4876 2635 4877 // try replacing _= if it is there 2636 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); 4878 var ret = s.url.replace(rts, "$1_=" + ts + "$2"); 4879 2637 4880 // if nothing was replaced, add timestamp to the end 2638 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");4881 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : ""); 2639 4882 } 2640 4883 2641 4884 // If data is available, append data to url for get requests 2642 if ( s.data && type == "GET" ) { 2643 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data; 2644 2645 // IE likes to send both get and post data, prevent this 2646 s.data = null; 4885 if ( s.data && type === "GET" ) { 4886 s.url += (rquery.test(s.url) ? "&" : "?") + s.data; 2647 4887 } 2648 4888 2649 4889 // Watch for a new set of requests 2650 if ( s.global && ! jQuery.active++ ) 4890 if ( s.global && ! jQuery.active++ ) { 2651 4891 jQuery.event.trigger( "ajaxStart" ); 4892 } 2652 4893 2653 4894 // Matches an absolute URL, and saves the domain 2654 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/; 4895 var parts = rurl.exec( s.url ), 4896 remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host); 2655 4897 2656 4898 // If we're requesting a remote document 2657 4899 // and trying to load JSON or Script with a GET 2658 if ( s.dataType == "script" && type == "GET" 2659 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){ 2660 var head = document.getElementsByTagName("head")[0]; 4900 if ( s.dataType === "script" && type === "GET" && remote ) { 4901 var head = document.getElementsByTagName("head")[0] || document.documentElement; 2661 4902 var script = document.createElement("script"); 2662 4903 script.src = s.url; 2663 if ( s.scriptCharset)4904 if ( s.scriptCharset ) { 2664 4905 script.charset = s.scriptCharset; 4906 } 2665 4907 2666 4908 // Handle Script loading … … 2669 4911 2670 4912 // Attach handlers for all browsers 2671 script.onload = script.onreadystatechange = function() {4913 script.onload = script.onreadystatechange = function() { 2672 4914 if ( !done && (!this.readyState || 2673 this.readyState == "loaded" || this.readyState== "complete") ) {4915 this.readyState === "loaded" || this.readyState === "complete") ) { 2674 4916 done = true; 2675 4917 success(); 2676 4918 complete(); 2677 head.removeChild( script ); 4919 4920 // Handle memory leak in IE 4921 script.onload = script.onreadystatechange = null; 4922 if ( head && script.parentNode ) { 4923 head.removeChild( script ); 4924 } 2678 4925 } 2679 4926 }; 2680 4927 } 2681 4928 2682 head.appendChild(script); 4929 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 4930 // This arises when a base node is used (#2709 and #4378). 4931 head.insertBefore( script, head.firstChild ); 2683 4932 2684 4933 // We handle everything using the script element injection … … 2688 4937 var requestDone = false; 2689 4938 2690 // Create the request object; Microsoft failed to properly 2691 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 2692 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 4939 // Create the request object 4940 var xhr = s.xhr(); 4941 4942 if ( !xhr ) { 4943 return; 4944 } 2693 4945 2694 4946 // Open the socket 2695 4947 // Passing null username, generates a login popup on Opera (#2865) 2696 if ( s.username )4948 if ( s.username ) { 2697 4949 xhr.open(type, s.url, s.async, s.username, s.password); 2698 else4950 } else { 2699 4951 xhr.open(type, s.url, s.async); 4952 } 2700 4953 2701 4954 // Need an extra try/catch for cross domain requests in Firefox 3 2702 4955 try { 2703 4956 // Set the correct header, if data is being sent 2704 if ( s.data )4957 if ( s.data || origSettings && origSettings.contentType ) { 2705 4958 xhr.setRequestHeader("Content-Type", s.contentType); 2706 2707 // Set the If-Modified-Since header, if ifModified mode. 2708 if ( s.ifModified ) 2709 xhr.setRequestHeader("If-Modified-Since", 2710 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 4959 } 4960 4961 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 4962 if ( s.ifModified ) { 4963 if ( jQuery.lastModified[s.url] ) { 4964 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]); 4965 } 4966 4967 if ( jQuery.etag[s.url] ) { 4968 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]); 4969 } 4970 } 2711 4971 2712 4972 // Set header so the called script knows that it's an XMLHttpRequest 2713 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 4973 // Only send the header if it's not a remote XHR 4974 if ( !remote ) { 4975 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 4976 } 2714 4977 2715 4978 // Set the Accepts header for the server, depending on the dataType … … 2717 4980 s.accepts[ s.dataType ] + ", */*" : 2718 4981 s.accepts._default ); 2719 } catch(e){} 2720 2721 // Allow custom headers/mimetypes 2722 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) { 2723 // cleanup active request counter 2724 s.global && jQuery.active--; 4982 } catch(e) {} 4983 4984 // Allow custom headers/mimetypes and early abort 4985 if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) { 4986 // Handle the global AJAX counter 4987 if ( s.global && ! --jQuery.active ) { 4988 jQuery.event.trigger( "ajaxStop" ); 4989 } 4990 2725 4991 // close opended socket 2726 4992 xhr.abort(); … … 2728 4994 } 2729 4995 2730 if ( s.global ) 2731 jQuery.event.trigger("ajaxSend", [xhr, s]); 4996 if ( s.global ) { 4997 trigger("ajaxSend", [xhr, s]); 4998 } 2732 4999 2733 5000 // Wait for a response to come back 2734 var onreadystatechange = function(isTimeout){ 5001 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) { 5002 // The request was aborted 5003 if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) { 5004 // Opera doesn't call onreadystatechange before this point 5005 // so we simulate the call 5006 if ( !requestDone ) { 5007 complete(); 5008 } 5009 5010 requestDone = true; 5011 if ( xhr ) { 5012 xhr.onreadystatechange = jQuery.noop; 5013 } 5014 2735 5015 // The transfer is complete and the data is available, or the request timed out 2736 if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout== "timeout") ) {5016 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) { 2737 5017 requestDone = true; 2738 2739 // clear poll interval 2740 if (ival) {2741 clearInterval(ival);2742 ival = null;2743 }2744 2745 status = isTimeout == "timeout" && "timeout" ||2746 !jQuery.httpSuccess( xhr ) && "error" ||2747 s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" || 2748 "success";2749 2750 if ( status == "success" ) {5018 xhr.onreadystatechange = jQuery.noop; 5019 5020 status = isTimeout === "timeout" ? 5021 "timeout" : 5022 !jQuery.httpSuccess( xhr ) ? 5023 "error" : 5024 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? 5025 "notmodified" : 5026 "success"; 5027 5028 var errMsg; 5029 5030 if ( status === "success" ) { 2751 5031 // Watch for, and catch, XML document parse errors 2752 5032 try { 2753 5033 // process the data (runs the xml through httpData regardless of callback) 2754 data = jQuery.httpData( xhr, s.dataType, s .dataFilter);2755 } catch(e ) {5034 data = jQuery.httpData( xhr, s.dataType, s ); 5035 } catch(err) { 2756 5036 status = "parsererror"; 5037 errMsg = err; 2757 5038 } 2758 5039 } 2759 5040 2760 5041 // Make sure that the request was successful or notmodified 2761 if ( status == "success" ) { 2762 // Cache Last-Modified header, if ifModified mode. 2763 var modRes; 2764 try { 2765 modRes = xhr.getResponseHeader("Last-Modified"); 2766 } catch(e) {} // swallow exception thrown by FF if header is not available 2767 2768 if ( s.ifModified && modRes ) 2769 jQuery.lastModified[s.url] = modRes; 2770 5042 if ( status === "success" || status === "notmodified" ) { 2771 5043 // JSONP handles its own success callback 2772 if ( !jsonp ) 5044 if ( !jsonp ) { 2773 5045 success(); 2774 } else 2775 jQuery.handleError(s, xhr, status); 5046 } 5047 } else { 5048 jQuery.handleError(s, xhr, status, errMsg); 5049 } 2776 5050 2777 5051 // Fire the complete handlers 2778 5052 complete(); 2779 5053 5054 if ( isTimeout === "timeout" ) { 5055 xhr.abort(); 5056 } 5057 2780 5058 // Stop memory leaks 2781 if ( s.async ) 5059 if ( s.async ) { 2782 5060 xhr = null; 5061 } 2783 5062 } 2784 5063 }; 2785 5064 2786 if ( s.async ) { 2787 // don't attach the handler to the request, just poll it instead 2788 var ival = setInterval(onreadystatechange, 13); 2789 2790 // Timeout checker 2791 if ( s.timeout > 0 ) 2792 setTimeout(function(){ 2793 // Check to see if the request is still happening 2794 if ( xhr ) { 2795 // Cancel the request 2796 xhr.abort(); 2797 2798 if( !requestDone ) 2799 onreadystatechange( "timeout" ); 2800 } 2801 }, s.timeout); 5065 // Override the abort handler, if we can (IE doesn't allow it, but that's OK) 5066 // Opera doesn't fire onreadystatechange at all on abort 5067 try { 5068 var oldAbort = xhr.abort; 5069 xhr.abort = function() { 5070 if ( xhr ) { 5071 oldAbort.call( xhr ); 5072 } 5073 5074 onreadystatechange( "abort" ); 5075 }; 5076 } catch(e) { } 5077 5078 // Timeout checker 5079 if ( s.async && s.timeout > 0 ) { 5080 setTimeout(function() { 5081 // Check to see if the request is still happening 5082 if ( xhr && !requestDone ) { 5083 onreadystatechange( "timeout" ); 5084 } 5085 }, s.timeout); 2802 5086 } 2803 5087 2804 5088 // Send the data 2805 5089 try { 2806 xhr.send( s.data);5090 xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null ); 2807 5091 } catch(e) { 2808 5092 jQuery.handleError(s, xhr, null, e); 5093 // Fire the complete handlers 5094 complete(); 2809 5095 } 2810 5096 2811 5097 // firefox 1.5 doesn't fire statechange for sync requests 2812 if ( !s.async ) 5098 if ( !s.async ) { 2813 5099 onreadystatechange(); 2814 2815 function success(){ 5100 } 5101 5102 function success() { 2816 5103 // If a local callback was specified, fire it and pass it the data 2817 if ( s.success ) 2818 s.success( data, status ); 5104 if ( s.success ) { 5105 s.success.call( callbackContext, data, status, xhr ); 5106 } 2819 5107 2820 5108 // Fire the global callback 2821 if ( s.global ) 2822 jQuery.event.trigger( "ajaxSuccess", [xhr, s] ); 2823 } 2824 2825 function complete(){ 5109 if ( s.global ) { 5110 trigger( "ajaxSuccess", [xhr, s] ); 5111 } 5112 } 5113 5114 function complete() { 2826 5115 // Process result 2827 if ( s.complete ) 2828 s.complete(xhr, status); 5116 if ( s.complete ) { 5117 s.complete.call( callbackContext, xhr, status); 5118 } 2829 5119 2830 5120 // The request was completed 2831 if ( s.global ) 2832 jQuery.event.trigger( "ajaxComplete", [xhr, s] ); 5121 if ( s.global ) { 5122 trigger( "ajaxComplete", [xhr, s] ); 5123 } 2833 5124 2834 5125 // Handle the global AJAX counter 2835 if ( s.global && ! --jQuery.active ) 5126 if ( s.global && ! --jQuery.active ) { 2836 5127 jQuery.event.trigger( "ajaxStop" ); 5128 } 5129 } 5130 5131 function trigger(type, args) { 5132 (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args); 2837 5133 } 2838 5134 … … 2843 5139 handleError: function( s, xhr, status, e ) { 2844 5140 // If a local callback was specified, fire it 2845 if ( s.error ) s.error( xhr, status, e ); 5141 if ( s.error ) { 5142 s.error.call( s.context || s, xhr, status, e ); 5143 } 2846 5144 2847 5145 // Fire the global callback 2848 if ( s.global ) 2849 jQuery.event.trigger( "ajaxError", [xhr, s, e] ); 5146 if ( s.global ) { 5147 (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] ); 5148 } 2850 5149 }, 2851 5150 … … 2857 5156 try { 2858 5157 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 2859 return !xhr.status && location.protocol == "file:" || 2860 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 || 2861 jQuery.browser.safari && xhr.status == undefined; 2862 } catch(e){} 5158 return !xhr.status && location.protocol === "file:" || 5159 // Opera returns 0 when status is 304 5160 ( xhr.status >= 200 && xhr.status < 300 ) || 5161 xhr.status === 304 || xhr.status === 1223 || xhr.status === 0; 5162 } catch(e) {} 5163 2863 5164 return false; 2864 5165 }, … … 2866 5167 // Determines if an XMLHttpRequest returns NotModified 2867 5168 httpNotModified: function( xhr, url ) { 2868 try { 2869 var xhrRes = xhr.getResponseHeader("Last-Modified"); 2870 2871 // Firefox always returns 200. check Last-Modified date 2872 return xhr.status == 304 || xhrRes == jQuery.lastModified[url] || 2873 jQuery.browser.safari && xhr.status == undefined; 2874 } catch(e){} 2875 return false; 2876 }, 2877 2878 httpData: function( xhr, type, filter ) { 2879 var ct = xhr.getResponseHeader("content-type"), 2880 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0, 5169 var lastModified = xhr.getResponseHeader("Last-Modified"), 5170 etag = xhr.getResponseHeader("Etag"); 5171 5172 if ( lastModified ) { 5173 jQuery.lastModified[url] = lastModified; 5174 } 5175 5176 if ( etag ) { 5177 jQuery.etag[url] = etag; 5178 } 5179 5180 // Opera returns 0 when status is 304 5181 return xhr.status === 304 || xhr.status === 0; 5182 }, 5183 5184 httpData: function( xhr, type, s ) { 5185 var ct = xhr.getResponseHeader("content-type") || "", 5186 xml = type === "xml" || !type && ct.indexOf("xml") >= 0, 2881 5187 data = xml ? xhr.responseXML : xhr.responseText; 2882 5188 2883 if ( xml && data.documentElement.tagName == "parsererror" ) 2884 throw "parsererror"; 2885 5189 if ( xml && data.documentElement.nodeName === "parsererror" ) { 5190 jQuery.error( "parsererror" ); 5191 } 5192 2886 5193 // Allow a pre-filtering function to sanitize the response 2887 if( filter ) 2888 data = filter( data, type ); 2889 2890 // If the type is "script", eval it in global context 2891 if ( type == "script" ) 2892 jQuery.globalEval( data ); 2893 2894 // Get the JavaScript object, if JSON is used. 2895 if ( type == "json" ) 2896 data = eval("(" + data + ")"); 5194 // s is checked to keep backwards compatibility 5195 if ( s && s.dataFilter ) { 5196 data = s.dataFilter( data, type ); 5197 } 5198 5199 // The filter can actually parse the response 5200 if ( typeof data === "string" ) { 5201 // Get the JavaScript object, if JSON is used. 5202 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) { 5203 data = jQuery.parseJSON( data ); 5204 5205 // If the type is "script", eval it in global context 5206 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) { 5207 jQuery.globalEval( data ); 5208 } 5209 } 2897 5210 2898 5211 return data; … … 2901 5214 // Serialize an array of form elements or a set of 2902 5215 // key/values into a query string 2903 param: function( a ) {5216 param: function( a, traditional ) { 2904 5217 var s = []; 2905 2906 // If an array was passed in, assume that it is an array 2907 // of form elements 2908 if ( a.constructor == Array || a.jquery ) 5218 5219 // Set traditional to true for jQuery <= 1.3.2 behavior. 5220 if ( traditional === undefined ) { 5221 traditional = jQuery.ajaxSettings.traditional; 5222 } 5223 5224 // If an array was passed in, assume that it is an array of form elements. 5225 if ( jQuery.isArray(a) || a.jquery ) { 2909 5226 // Serialize the form elements 2910 jQuery.each( a, function() {2911 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ));5227 jQuery.each( a, function() { 5228 add( this.name, this.value ); 2912 5229 }); 2913 2914 // Otherwise, assume that it's an object of key/value pairs 2915 else 2916 // Serialize the key/values 2917 for ( var j in a ) 2918 // If the value is an array then the key names need to be repeated 2919 if ( a[j] && a[j].constructor == Array ) 2920 jQuery.each( a[j], function(){ 2921 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) ); 2922 }); 2923 else 2924 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) ); 5230 5231 } else { 5232 // If traditional, encode the "old" way (the way 1.3.2 or older 5233 // did it), otherwise encode params recursively. 5234 for ( var prefix in a ) { 5235 buildParams( prefix, a[prefix] ); 5236 } 5237 } 2925 5238 2926 5239 // Return the resulting serialization 2927 return s.join("&").replace(/%20/g, "+"); 2928 } 2929 5240 return s.join("&").replace(r20, "+"); 5241 5242 function buildParams( prefix, obj ) { 5243 if ( jQuery.isArray(obj) ) { 5244 // Serialize array item. 5245 jQuery.each( obj, function( i, v ) { 5246 if ( traditional ) { 5247 // Treat each array item as a scalar. 5248 add( prefix, v ); 5249 } else { 5250 // If array item is non-scalar (array or object), encode its 5251 // numeric index to resolve deserialization ambiguity issues. 5252 // Note that rack (as of 1.0.0) can't currently deserialize 5253 // nested arrays properly, and attempting to do so may cause 5254 // a server error. Possible fixes are to modify rack's 5255 // deserialization algorithm or to provide an option or flag 5256 // to force array serialization to be shallow. 5257 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v ); 5258 } 5259 }); 5260 5261 } else if ( !traditional && obj != null && typeof obj === "object" ) { 5262 // Serialize object item. 5263 jQuery.each( obj, function( k, v ) { 5264 buildParams( prefix + "[" + k + "]", v ); 5265 }); 5266 5267 } else { 5268 // Serialize scalar item. 5269 add( prefix, obj ); 5270 } 5271 } 5272 5273 function add( key, value ) { 5274 // If value is a function, invoke it and return its value 5275 value = jQuery.isFunction(value) ? value() : value; 5276 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value); 5277 } 5278 } 2930 5279 }); 5280 var elemdisplay = {}, 5281 rfxtypes = /toggle|show|hide/, 5282 rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/, 5283 timerId, 5284 fxAttrs = [ 5285 // height animations 5286 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], 5287 // width animations 5288 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], 5289 // opacity animations 5290 [ "opacity" ] 5291 ]; 5292 2931 5293 jQuery.fn.extend({ 2932 show: function(speed,callback){ 2933 return speed ? 2934 this.animate({ 2935 height: "show", width: "show", opacity: "show" 2936 }, speed, callback) : 2937 2938 this.filter(":hidden").each(function(){ 2939 this.style.display = this.oldblock || ""; 2940 if ( jQuery.css(this,"display") == "none" ) { 2941 var elem = jQuery("<" + this.tagName + " />").appendTo("body"); 2942 this.style.display = elem.css("display"); 2943 // handle an edge condition where css is - div { display:none; } or similar 2944 if (this.style.display == "none") 2945 this.style.display = "block"; 2946 elem.remove(); 2947 } 2948 }).end(); 2949 }, 2950 2951 hide: function(speed,callback){ 2952 return speed ? 2953 this.animate({ 2954 height: "hide", width: "hide", opacity: "hide" 2955 }, speed, callback) : 2956 2957 this.filter(":visible").each(function(){ 2958 this.oldblock = this.oldblock || jQuery.css(this,"display"); 2959 this.style.display = "none"; 2960 }).end(); 5294 show: function( speed, callback ) { 5295 if ( speed || speed === 0) { 5296 return this.animate( genFx("show", 3), speed, callback); 5297 5298 } else { 5299 for ( var i = 0, l = this.length; i < l; i++ ) { 5300 var old = jQuery.data(this[i], "olddisplay"); 5301 5302 this[i].style.display = old || ""; 5303 5304 if ( jQuery.css(this[i], "display") === "none" ) { 5305 var nodeName = this[i].nodeName, display; 5306 5307 if ( elemdisplay[ nodeName ] ) { 5308 display = elemdisplay[ nodeName ]; 5309 5310 } else { 5311 var elem = jQuery("<" + nodeName + " />").appendTo("body"); 5312 5313 display = elem.css("display"); 5314 5315 if ( display === "none" ) { 5316 display = "block"; 5317 } 5318 5319 elem.remove(); 5320 5321 elemdisplay[ nodeName ] = display; 5322 } 5323 5324 jQuery.data(this[i], "olddisplay", display); 5325 } 5326 } 5327 5328 // Set the display of the elements in a second loop 5329 // to avoid the constant reflow 5330 for ( var j = 0, k = this.length; j < k; j++ ) { 5331 this[j].style.display = jQuery.data(this[j], "olddisplay") || ""; 5332 } 5333 5334 return this; 5335 } 5336 }, 5337 5338 hide: function( speed, callback ) { 5339 if ( speed || speed === 0 ) { 5340 return this.animate( genFx("hide", 3), speed, callback); 5341 5342 } else { 5343 for ( var i = 0, l = this.length; i < l; i++ ) { 5344 var old = jQuery.data(this[i], "olddisplay"); 5345 if ( !old && old !== "none" ) { 5346 jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display")); 5347 } 5348 } 5349 5350 // Set the display of the elements in a second loop 5351 // to avoid the constant reflow 5352 for ( var j = 0, k = this.length; j < k; j++ ) { 5353 this[j].style.display = "none"; 5354 } 5355 5356 return this; 5357 } 2961 5358 }, 2962 5359 … … 2964 5361 _toggle: jQuery.fn.toggle, 2965 5362 2966 toggle: function( fn, fn2 ){ 2967 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? 2968 this._toggle.apply( this, arguments ) : 2969 fn ? 2970 this.animate({ 2971 height: "toggle", width: "toggle", opacity: "toggle" 2972 }, fn, fn2) : 2973 this.each(function(){ 2974 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); 2975 }); 2976 }, 2977 2978 slideDown: function(speed,callback){ 2979 return this.animate({height: "show"}, speed, callback); 2980 }, 2981 2982 slideUp: function(speed,callback){ 2983 return this.animate({height: "hide"}, speed, callback); 2984 }, 2985 2986 slideToggle: function(speed, callback){ 2987 return this.animate({height: "toggle"}, speed, callback); 2988 }, 2989 2990 fadeIn: function(speed, callback){ 2991 return this.animate({opacity: "show"}, speed, callback); 2992 }, 2993 2994 fadeOut: function(speed, callback){ 2995 return this.animate({opacity: "hide"}, speed, callback); 2996 }, 2997 2998 fadeTo: function(speed,to,callback){ 2999 return this.animate({opacity: to}, speed, callback); 5363 toggle: function( fn, fn2 ) { 5364 var bool = typeof fn === "boolean"; 5365 5366 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { 5367 this._toggle.apply( this, arguments ); 5368 5369 } else if ( fn == null || bool ) { 5370 this.each(function() { 5371 var state = bool ? fn : jQuery(this).is(":hidden"); 5372 jQuery(this)[ state ? "show" : "hide" ](); 5373 }); 5374 5375 } else { 5376 this.animate(genFx("toggle", 3), fn, fn2); 5377 } 5378 5379 return this; 5380 }, 5381 5382 fadeTo: function( speed, to, callback ) { 5383 return this.filter(":hidden").css("opacity", 0).show().end() 5384 .animate({opacity: to}, speed, callback); 3000 5385 }, 3001 5386 … … 3003 5388 var optall = jQuery.speed(speed, easing, callback); 3004 5389 3005 return this[ optall.queue === false ? "each" : "queue" ](function(){ 3006 if ( this.nodeType != 1) 3007 return false; 3008 5390 if ( jQuery.isEmptyObject( prop ) ) { 5391 return this.each( optall.complete ); 5392 } 5393 5394 return this[ optall.queue === false ? "each" : "queue" ](function() { 3009 5395 var opt = jQuery.extend({}, optall), p, 3010 hidden = jQuery(this).is(":hidden"), self = this; 5396 hidden = this.nodeType === 1 && jQuery(this).is(":hidden"), 5397 self = this; 3011 5398 3012 5399 for ( p in prop ) { 3013 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) 5400 var name = p.replace(rdashAlpha, fcamelCase); 5401 5402 if ( p !== name ) { 5403 prop[ name ] = prop[ p ]; 5404 delete prop[ p ]; 5405 p = name; 5406 } 5407 5408 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) { 3014 5409 return opt.complete.call(this); 3015 3016 if ( p == "height" || p == "width" ) { 5410 } 5411 5412 if ( ( p === "height" || p === "width" ) && this.style ) { 3017 5413 // Store display property 3018 5414 opt.display = jQuery.css(this, "display"); … … 3021 5417 opt.overflow = this.style.overflow; 3022 5418 } 3023 } 3024 3025 if ( opt.overflow != null ) 5419 5420 if ( jQuery.isArray( prop[p] ) ) { 5421 // Create (if needed) and add to specialEasing 5422 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1]; 5423 prop[p] = prop[p][0]; 5424 } 5425 } 5426 5427 if ( opt.overflow != null ) { 3026 5428 this.style.overflow = "hidden"; 5429 } 3027 5430 3028 5431 opt.curAnim = jQuery.extend({}, prop); 3029 5432 3030 jQuery.each( prop, function( name, val){5433 jQuery.each( prop, function( name, val ) { 3031 5434 var e = new jQuery.fx( self, opt, name ); 3032 5435 3033 if ( /toggle|show|hide/.test(val) ) 3034 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 3035 else { 3036 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), 5436 if ( rfxtypes.test(val) ) { 5437 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 5438 5439 } else { 5440 var parts = rfxnum.exec(val), 3037 5441 start = e.cur(true) || 0; 3038 5442 3039 5443 if ( parts ) { 3040 var end = parseFloat( parts[2]),5444 var end = parseFloat( parts[2] ), 3041 5445 unit = parts[3] || "px"; 3042 5446 3043 5447 // We need to compute starting value 3044 if ( unit != "px" ) {5448 if ( unit !== "px" ) { 3045 5449 self.style[ name ] = (end || 1) + unit; 3046 5450 start = ((end || 1) / e.cur(true)) * start; … … 3049 5453 3050 5454 // If a +=/-= token was provided, we're doing a relative animation 3051 if ( parts[1] ) 3052 end = ((parts[1] == "-=" ? -1 : 1) * end) + start; 5455 if ( parts[1] ) { 5456 end = ((parts[1] === "-=" ? -1 : 1) * end) + start; 5457 } 3053 5458 3054 5459 e.custom( start, end, unit ); 3055 } else 5460 5461 } else { 3056 5462 e.custom( start, val, "" ); 5463 } 3057 5464 } 3058 5465 }); … … 3063 5470 }, 3064 5471 3065 queue: function(type, fn){ 3066 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) { 3067 fn = type; 3068 type = "fx"; 3069 } 3070 3071 if ( !type || (typeof type == "string" && !fn) ) 3072 return queue( this[0], type ); 3073 3074 return this.each(function(){ 3075 if ( fn.constructor == Array ) 3076 queue(this, type, fn); 3077 else { 3078 queue(this, type).push( fn ); 3079 3080 if ( queue(this, type).length == 1 ) 3081 fn.call(this); 3082 } 3083 }); 3084 }, 3085 3086 stop: function(clearQueue, gotoEnd){ 5472 stop: function( clearQueue, gotoEnd ) { 3087 5473 var timers = jQuery.timers; 3088 5474 3089 if ( clearQueue)5475 if ( clearQueue ) { 3090 5476 this.queue([]); 3091 3092 this.each(function(){ 5477 } 5478 5479 this.each(function() { 3093 5480 // go in reverse order so anything added to the queue during the loop is ignored 3094 for ( var i = timers.length - 1; i >= 0; i-- ) 3095 if ( timers[i].elem == this ) {3096 if (gotoEnd) 5481 for ( var i = timers.length - 1; i >= 0; i-- ) { 5482 if ( timers[i].elem === this ) { 5483 if (gotoEnd) { 3097 5484 // force the next step to be the last 3098 5485 timers[i](true); 5486 } 5487 3099 5488 timers.splice(i, 1); 3100 5489 } 5490 } 3101 5491 }); 3102 5492 3103 5493 // start the next in the queue if the last step wasn't forced 3104 if ( !gotoEnd)5494 if ( !gotoEnd ) { 3105 5495 this.dequeue(); 5496 } 3106 5497 3107 5498 return this; … … 3110 5501 }); 3111 5502 3112 var queue = function( elem, type, array ) { 3113 if ( elem ){ 3114 3115 type = type || "fx"; 3116 3117 var q = jQuery.data( elem, type + "queue" ); 3118 3119 if ( !q || array ) 3120 q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) ); 3121 3122 } 3123 return q; 3124 }; 3125 3126 jQuery.fn.dequeue = function(type){ 3127 type = type || "fx"; 3128 3129 return this.each(function(){ 3130 var q = queue(this, type); 3131 3132 q.shift(); 3133 3134 if ( q.length ) 3135 q[0].call( this ); 3136 }); 3137 }; 5503 // Generate shortcuts for custom animations 5504 jQuery.each({ 5505 slideDown: genFx("show", 1), 5506 slideUp: genFx("hide", 1), 5507 slideToggle: genFx("toggle", 1), 5508 fadeIn: { opacity: "show" }, 5509 fadeOut: { opacity: "hide" } 5510 }, function( name, props ) { 5511 jQuery.fn[ name ] = function( speed, callback ) { 5512 return this.animate( props, speed, callback ); 5513 }; 5514 }); 3138 5515 3139 5516 jQuery.extend({ 3140 3141 speed: function(speed, easing, fn) { 3142 var opt = speed && speed.constructor == Object ? speed : { 5517 speed: function( speed, easing, fn ) { 5518 var opt = speed && typeof speed === "object" ? speed : { 3143 5519 complete: fn || !fn && easing || 3144 5520 jQuery.isFunction( speed ) && speed, 3145 5521 duration: speed, 3146 easing: fn && easing || easing && easing.constructor != Function&& easing5522 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing 3147 5523 }; 3148 5524 3149 opt.duration = (opt.duration && opt.duration.constructor == Number ? 3150 opt.duration : 3151 jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def; 5525 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 5526 jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default; 3152 5527 3153 5528 // Queueing 3154 5529 opt.old = opt.complete; 3155 opt.complete = function() {3156 if ( opt.queue !== false ) 5530 opt.complete = function() { 5531 if ( opt.queue !== false ) { 3157 5532 jQuery(this).dequeue(); 3158 if ( jQuery.isFunction( opt.old ) ) 5533 } 5534 if ( jQuery.isFunction( opt.old ) ) { 3159 5535 opt.old.call( this ); 5536 } 3160 5537 }; 3161 5538 … … 3173 5550 3174 5551 timers: [], 3175 timerId: null, 3176 3177 fx: function( elem, options, prop ){ 5552 5553 fx: function( elem, options, prop ) { 3178 5554 this.options = options; 3179 5555 this.elem = elem; 3180 5556 this.prop = prop; 3181 5557 3182 if ( !options.orig ) 5558 if ( !options.orig ) { 3183 5559 options.orig = {}; 5560 } 3184 5561 } 3185 5562 … … 3187 5564 3188 5565 jQuery.fx.prototype = { 3189 3190 5566 // Simple function for setting a style value 3191 update: function() {3192 if ( this.options.step ) 5567 update: function() { 5568 if ( this.options.step ) { 3193 5569 this.options.step.call( this.elem, this.now, this ); 5570 } 3194 5571 3195 5572 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 3196 5573 3197 5574 // Set display property to block for height/width animations 3198 if ( this.prop == "height" || this.prop == "width" )5575 if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) { 3199 5576 this.elem.style.display = "block"; 5577 } 3200 5578 }, 3201 5579 3202 5580 // Get the current size 3203 cur: function( force){3204 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )5581 cur: function( force ) { 5582 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) { 3205 5583 return this.elem[ this.prop ]; 5584 } 3206 5585 3207 5586 var r = parseFloat(jQuery.css(this.elem, this.prop, force)); … … 3210 5589 3211 5590 // Start an animation from one number to another 3212 custom: function( from, to, unit){5591 custom: function( from, to, unit ) { 3213 5592 this.startTime = now(); 3214 5593 this.start = from; … … 3217 5596 this.now = this.start; 3218 5597 this.pos = this.state = 0; 3219 this.update();3220 5598 3221 5599 var self = this; 3222 function t( gotoEnd){5600 function t( gotoEnd ) { 3223 5601 return self.step(gotoEnd); 3224 5602 } … … 3226 5604 t.elem = this.elem; 3227 5605 3228 jQuery.timers.push(t); 3229 3230 if ( jQuery.timerId == null ) { 3231 jQuery.timerId = setInterval(function(){ 3232 var timers = jQuery.timers; 3233 3234 for ( var i = 0; i < timers.length; i++ ) 3235 if ( !timers[i]() ) 3236 timers.splice(i--, 1); 3237 3238 if ( !timers.length ) { 3239 clearInterval( jQuery.timerId ); 3240 jQuery.timerId = null; 3241 } 3242 }, 13); 5606 if ( t() && jQuery.timers.push(t) && !timerId ) { 5607 timerId = setInterval(jQuery.fx.tick, 13); 3243 5608 } 3244 5609 }, 3245 5610 3246 5611 // Simple 'show' function 3247 show: function() {5612 show: function() { 3248 5613 // Remember where we started, so that we can go back to it later 3249 this.options.orig[this.prop] = jQuery. attr( this.elem.style, this.prop );5614 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); 3250 5615 this.options.show = true; 3251 5616 3252 5617 // Begin the animation 3253 this.custom(0, this.cur());3254 3255 5618 // Make sure that we start at a small width/height to avoid any 3256 5619 // flash of content 3257 if ( this.prop == "width" || this.prop == "height" ) 3258 this.elem.style[this.prop] = "1px"; 5620 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur()); 3259 5621 3260 5622 // Start by showing the element 3261 jQuery( this.elem).show();5623 jQuery( this.elem ).show(); 3262 5624 }, 3263 5625 3264 5626 // Simple 'hide' function 3265 hide: function() {5627 hide: function() { 3266 5628 // Remember where we started, so that we can go back to it later 3267 this.options.orig[this.prop] = jQuery. attr( this.elem.style, this.prop );5629 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); 3268 5630 this.options.hide = true; 3269 5631 … … 3273 5635 3274 5636 // Each step of an animation 3275 step: function( gotoEnd){3276 var t = now() ;3277 3278 if ( gotoEnd || t > this.options.duration + this.startTime ) {5637 step: function( gotoEnd ) { 5638 var t = now(), done = true; 5639 5640 if ( gotoEnd || t >= this.options.duration + this.startTime ) { 3279 5641 this.now = this.end; 3280 5642 this.pos = this.state = 1; … … 3283 5645 this.options.curAnim[ this.prop ] = true; 3284 5646 3285 var done = true; 3286 for ( var i in this.options.curAnim ) 3287 if ( this.options.curAnim[i] !== true ) 5647 for ( var i in this.options.curAnim ) { 5648 if ( this.options.curAnim[i] !== true ) { 3288 5649 done = false; 5650 } 5651 } 3289 5652 3290 5653 if ( done ) { … … 3294 5657 3295 5658 // Reset the display 3296 this.elem.style.display = this.options.display; 3297 if ( jQuery.css(this.elem, "display") == "none" ) 5659 var old = jQuery.data(this.elem, "olddisplay"); 5660 this.elem.style.display = old ? old : this.options.display; 5661 5662 if ( jQuery.css(this.elem, "display") === "none" ) { 3298 5663 this.elem.style.display = "block"; 5664 } 3299 5665 } 3300 5666 3301 5667 // Hide the element if the "hide" operation was done 3302 if ( this.options.hide ) 3303 this.elem.style.display = "none"; 5668 if ( this.options.hide ) { 5669 jQuery(this.elem).hide(); 5670 } 3304 5671 3305 5672 // Reset the properties, if the item has been hidden or shown 3306 if ( this.options.hide || this.options.show ) 3307 for ( var p in this.options.curAnim ) 3308 jQuery. attr(this.elem.style, p, this.options.orig[p]);3309 }3310 3311 if ( done ) 5673 if ( this.options.hide || this.options.show ) { 5674 for ( var p in this.options.curAnim ) { 5675 jQuery.style(this.elem, p, this.options.orig[p]); 5676 } 5677 } 5678 3312 5679 // Execute the complete function 3313 5680 this.options.complete.call( this.elem ); 5681 } 3314 5682 3315 5683 return false; 5684 3316 5685 } else { 3317 5686 var n = t - this.startTime; … … 3319 5688 3320 5689 // Perform the easing function, defaults to swing 3321 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); 5690 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop]; 5691 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear"); 5692 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration); 3322 5693 this.now = this.start + ((this.end - this.start) * this.pos); 3323 5694 … … 3328 5699 return true; 3329 5700 } 3330 3331 5701 }; 3332 5702 3333 5703 jQuery.extend( jQuery.fx, { 3334 speeds:{ 5704 tick: function() { 5705 var timers = jQuery.timers; 5706 5707 for ( var i = 0; i < timers.length; i++ ) { 5708 if ( !timers[i]() ) { 5709 timers.splice(i--, 1); 5710 } 5711 } 5712 5713 if ( !timers.length ) { 5714 jQuery.fx.stop(); 5715 } 5716 }, 5717 5718 stop: function() { 5719 clearInterval( timerId ); 5720 timerId = null; 5721 }, 5722 5723 speeds: { 3335 5724 slow: 600, 3336 5725 fast: 200, 3337 5726 // Default speed 3338 def: 400 3339 }, 5727 _default: 400 5728 }, 5729 3340 5730 step: { 3341 scrollLeft: function(fx){3342 fx.elem.scrollLeft = fx.now;5731 opacity: function( fx ) { 5732 jQuery.style(fx.elem, "opacity", fx.now); 3343 5733 }, 3344 5734 3345 scrollTop: function(fx){ 3346 fx.elem.scrollTop = fx.now; 3347 }, 3348 3349 opacity: function(fx){ 3350 jQuery.attr(fx.elem.style, "opacity", fx.now); 3351 }, 3352 3353 _default: function(fx){ 3354 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 5735 _default: function( fx ) { 5736 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { 5737 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit; 5738 } else { 5739 fx.elem[ fx.prop ] = fx.now; 5740 } 3355 5741 } 3356 5742 } 3357 5743 }); 3358 // The Offset Method 3359 // Originally By Brandon Aaron, part of the Dimension Plugin 3360 // http://jquery.com/plugins/project/dimensions 3361 jQuery.fn.offset = function() { 3362 var left = 0, top = 0, elem = this[0], results; 3363 3364 if ( elem ) with ( jQuery.browser ) { 3365 var parent = elem.parentNode, 3366 offsetChild = elem, 3367 offsetParent = elem.offsetParent, 3368 doc = elem.ownerDocument, 3369 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent), 3370 css = jQuery.curCSS, 3371 fixed = css(elem, "position") == "fixed"; 3372 3373 // Use getBoundingClientRect if available 3374 if ( elem.getBoundingClientRect ) { 3375 var box = elem.getBoundingClientRect(); 3376 3377 // Add the document scroll offsets 3378 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3379 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3380 3381 // IE adds the HTML element's border, by default it is medium which is 2px 3382 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; } 3383 // IE 7 standards mode, the border is always 2px 3384 // This border/offset is typically represented by the clientLeft and clientTop properties 3385 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS 3386 // Therefore this method will be off by 2px in IE while in quirksmode 3387 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop ); 3388 3389 // Otherwise loop through the offsetParents and parentNodes 5744 5745 if ( jQuery.expr && jQuery.expr.filters ) { 5746 jQuery.expr.filters.animated = function( elem ) { 5747 return jQuery.grep(jQuery.timers, function( fn ) { 5748 return elem === fn.elem; 5749 }).length; 5750 }; 5751 } 5752 5753 function genFx( type, num ) { 5754 var obj = {}; 5755 5756 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() { 5757 obj[ this ] = type; 5758 }); 5759 5760 return obj; 5761 } 5762 if ( "getBoundingClientRect" in document.documentElement ) { 5763 jQuery.fn.offset = function( options ) { 5764 var elem = this[0]; 5765 5766 if ( options ) { 5767 return this.each(function( i ) { 5768 jQuery.offset.setOffset( this, options, i ); 5769 }); 5770 } 5771 5772 if ( !elem || !elem.ownerDocument ) { 5773 return null; 5774 } 5775 5776 if ( elem === elem.ownerDocument.body ) { 5777 return jQuery.offset.bodyOffset( elem ); 5778 } 5779 5780 var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement, 5781 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, 5782 top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop, 5783 left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft; 5784 5785 return { top: top, left: left }; 5786 }; 5787 5788 } else { 5789 jQuery.fn.offset = function( options ) { 5790 var elem = this[0]; 5791 5792 if ( options ) { 5793 return this.each(function( i ) { 5794 jQuery.offset.setOffset( this, options, i ); 5795 }); 5796 } 5797 5798 if ( !elem || !elem.ownerDocument ) { 5799 return null; 5800 } 5801 5802 if ( elem === elem.ownerDocument.body ) { 5803 return jQuery.offset.bodyOffset( elem ); 5804 } 5805 5806 jQuery.offset.initialize(); 5807 5808 var offsetParent = elem.offsetParent, prevOffsetParent = elem, 5809 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement, 5810 body = doc.body, defaultView = doc.defaultView, 5811 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, 5812 top = elem.offsetTop, left = elem.offsetLeft; 5813 5814 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { 5815 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { 5816 break; 5817 } 5818 5819 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; 5820 top -= elem.scrollTop; 5821 left -= elem.scrollLeft; 5822 5823 if ( elem === offsetParent ) { 5824 top += elem.offsetTop; 5825 left += elem.offsetLeft; 5826 5827 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) { 5828 top += parseFloat( computedStyle.borderTopWidth ) || 0; 5829 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 5830 } 5831 5832 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent; 5833 } 5834 5835 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { 5836 top += parseFloat( computedStyle.borderTopWidth ) || 0; 5837 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 5838 } 5839 5840 prevComputedStyle = computedStyle; 5841 } 5842 5843 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { 5844 top += body.offsetTop; 5845 left += body.offsetLeft; 5846 } 5847 5848 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { 5849 top += Math.max( docElem.scrollTop, body.scrollTop ); 5850 left += Math.max( docElem.scrollLeft, body.scrollLeft ); 5851 } 5852 5853 return { top: top, left: left }; 5854 }; 5855 } 5856 5857 jQuery.offset = { 5858 initialize: function() { 5859 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0, 5860 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>"; 5861 5862 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } ); 5863 5864 container.innerHTML = html; 5865 body.insertBefore( container, body.firstChild ); 5866 innerDiv = container.firstChild; 5867 checkDiv = innerDiv.firstChild; 5868 td = innerDiv.nextSibling.firstChild.firstChild; 5869 5870 this.doesNotAddBorder = (checkDiv.offsetTop !== 5); 5871 this.doesAddBorderForTableAndCells = (td.offsetTop === 5); 5872 5873 checkDiv.style.position = "fixed", checkDiv.style.top = "20px"; 5874 // safari subtracts parent border width here which is 5px 5875 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15); 5876 checkDiv.style.position = checkDiv.style.top = ""; 5877 5878 innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative"; 5879 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); 5880 5881 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); 5882 5883 body.removeChild( container ); 5884 body = container = innerDiv = checkDiv = table = td = null; 5885 jQuery.offset.initialize = jQuery.noop; 5886 }, 5887 5888 bodyOffset: function( body ) { 5889 var top = body.offsetTop, left = body.offsetLeft; 5890 5891 jQuery.offset.initialize(); 5892 5893 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) { 5894 top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0; 5895 left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0; 5896 } 5897 5898 return { top: top, left: left }; 5899 }, 5900 5901 setOffset: function( elem, options, i ) { 5902 // set position first, in-case top/left are set even on static elem 5903 if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) { 5904 elem.style.position = "relative"; 5905 } 5906 var curElem = jQuery( elem ), 5907 curOffset = curElem.offset(), 5908 curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0, 5909 curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0; 5910 5911 if ( jQuery.isFunction( options ) ) { 5912 options = options.call( elem, i, curOffset ); 5913 } 5914 5915 var props = { 5916 top: (options.top - curOffset.top) + curTop, 5917 left: (options.left - curOffset.left) + curLeft 5918 }; 5919 5920 if ( "using" in options ) { 5921 options.using.call( elem, props ); 3390 5922 } else { 3391 3392 // Initial element offsets 3393 add( elem.offsetLeft, elem.offsetTop ); 3394 3395 // Get parent offsets 3396 while ( offsetParent ) { 3397 // Add offsetParent offsets 3398 add( offsetParent.offsetLeft, offsetParent.offsetTop ); 3399 3400 // Mozilla and Safari > 2 does not include the border on offset parents 3401 // However Mozilla adds the border for table or table cells 3402 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 ) 3403 border( offsetParent ); 3404 3405 // Add the document scroll offsets if position is fixed on any offsetParent 3406 if ( !fixed && css(offsetParent, "position") == "fixed" ) 3407 fixed = true; 3408 3409 // Set offsetChild to previous offsetParent unless it is the body element 3410 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent; 3411 // Get next offsetParent 3412 offsetParent = offsetParent.offsetParent; 3413 } 3414 3415 // Get parent scroll offsets 3416 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) { 3417 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug 3418 if ( !/^inline|table.*$/i.test(css(parent, "display")) ) 3419 // Subtract parent scroll offsets 3420 add( -parent.scrollLeft, -parent.scrollTop ); 3421 3422 // Mozilla does not add the border for a parent that has overflow != visible 3423 if ( mozilla && css(parent, "overflow") != "visible" ) 3424 border( parent ); 3425 3426 // Get next parent 3427 parent = parent.parentNode; 3428 } 3429 3430 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild 3431 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild 3432 if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) || 3433 (mozilla && css(offsetChild, "position") != "absolute") ) 3434 add( -doc.body.offsetLeft, -doc.body.offsetTop ); 3435 3436 // Add the document scroll offsets if position is fixed 3437 if ( fixed ) 3438 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3439 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3440 } 3441 3442 // Return an object with top and left properties 3443 results = { top: top, left: left }; 3444 } 3445 3446 function border(elem) { 3447 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) ); 3448 } 3449 3450 function add(l, t) { 3451 left += parseInt(l, 10) || 0; 3452 top += parseInt(t, 10) || 0; 3453 } 3454 3455 return results; 5923 curElem.css( props ); 5924 } 5925 } 3456 5926 }; 3457 5927 … … 3459 5929 jQuery.fn.extend({ 3460 5930 position: function() { 3461 var left = 0, top = 0, results;3462 3463 if ( this[0] ) {3464 // Get *real* offsetParent 3465 var offsetParent = this.offsetParent(),3466 3467 // Get correct offsets3468 offset = this.offset(),3469 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset(); 3470 3471 // Subtract element margins3472 // note: when an element has margin: auto the offsetLeft and marginLeft3473 // are the same in Safari causing offset.left to incorrectly be 0 3474 offset.top -= num( this, 'marginTop' );3475 offset.left -= num( this, 'marginLeft' );3476 3477 // Add offsetParent borders3478 parentOffset.top += num( offsetParent, 'borderTopWidth' );3479 parentOffset.left += num( offsetParent, 'borderLeftWidth' ); 3480 3481 // Subtract the two offsets3482 results = {3483 top: offset.top - parentOffset.top, 3484 left: offset.left - parentOffset.left3485 };3486 }3487 3488 return results;5931 if ( !this[0] ) { 5932 return null; 5933 } 5934 5935 var elem = this[0], 5936 5937 // Get *real* offsetParent 5938 offsetParent = this.offsetParent(), 5939 5940 // Get correct offsets 5941 offset = this.offset(), 5942 parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); 5943 5944 // Subtract element margins 5945 // note: when an element has margin: auto the offsetLeft and marginLeft 5946 // are the same in Safari causing offset.left to incorrectly be 0 5947 offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0; 5948 offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0; 5949 5950 // Add offsetParent borders 5951 parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0; 5952 parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0; 5953 5954 // Subtract the two offsets 5955 return { 5956 top: offset.top - parentOffset.top, 5957 left: offset.left - parentOffset.left 5958 }; 3489 5959 }, 3490 5960 3491 5961 offsetParent: function() { 3492 var offsetParent = this[0].offsetParent; 3493 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') ) 3494 offsetParent = offsetParent.offsetParent; 3495 return jQuery(offsetParent); 5962 return this.map(function() { 5963 var offsetParent = this.offsetParent || document.body; 5964 while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { 5965 offsetParent = offsetParent.offsetParent; 5966 } 5967 return offsetParent; 5968 }); 3496 5969 } 3497 5970 }); … … 3499 5972 3500 5973 // Create scrollLeft and scrollTop methods 3501 jQuery.each( [ 'Left', 'Top'], function(i, name) {3502 var method = 'scroll'+ name;3503 5974 jQuery.each( ["Left", "Top"], function( i, name ) { 5975 var method = "scroll" + name; 5976 3504 5977 jQuery.fn[ method ] = function(val) { 3505 if (!this[0]) return; 3506 3507 return val != undefined ? 3508 5978 var elem = this[0], win; 5979 5980 if ( !elem ) { 5981 return null; 5982 } 5983 5984 if ( val !== undefined ) { 3509 5985 // Set the scroll offset 3510 this.each(function() { 3511 this == window || this == document ? 3512 window.scrollTo( 3513 !i ? val : jQuery(window).scrollLeft(), 3514 i ? val : jQuery(window).scrollTop() 3515 ) : 5986 return this.each(function() { 5987 win = getWindow( this ); 5988 5989 if ( win ) { 5990 win.scrollTo( 5991 !i ? val : jQuery(win).scrollLeft(), 5992 i ? val : jQuery(win).scrollTop() 5993 ); 5994 5995 } else { 3516 5996 this[ method ] = val; 3517 }) : 5997 } 5998 }); 5999 } else { 6000 win = getWindow( elem ); 3518 6001 3519 6002 // Return the scroll offset 3520 this[0] == window || this[0] == document ?3521 self[ i ? 'pageYOffset' : 'pageXOffset'] ||3522 jQuery.boxModel && document.documentElement[ method ] ||3523 document.body[ method ] :3524 this[0][ method ];6003 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : 6004 jQuery.support.boxModel && win.document.documentElement[ method ] || 6005 win.document.body[ method ] : 6006 elem[ method ]; 6007 } 3525 6008 }; 3526 6009 }); 6010 6011 function getWindow( elem ) { 6012 return ("scrollTo" in elem && elem.document) ? 6013 elem : 6014 elem.nodeType === 9 ? 6015 elem.defaultView || elem.parentWindow : 6016 false; 6017 } 3527 6018 // Create innerHeight, innerWidth, outerHeight and outerWidth methods 3528 jQuery.each([ "Height", "Width" ], function(i, name){ 3529 3530 var tl = i ? "Left" : "Top", // top or left 3531 br = i ? "Right" : "Bottom"; // bottom or right 6019 jQuery.each([ "Height", "Width" ], function( i, name ) { 6020 6021 var type = name.toLowerCase(); 3532 6022 3533 6023 // innerHeight and innerWidth 3534 jQuery.fn["inner" + name] = function() {3535 return this[ name.toLowerCase() ]() +3536 num(this, "padding" + tl) +3537 nu m(this, "padding" + br);6024 jQuery.fn["inner" + name] = function() { 6025 return this[0] ? 6026 jQuery.css( this[0], type, false, "padding" ) : 6027 null; 3538 6028 }; 3539 6029 3540 6030 // outerHeight and outerWidth 3541 jQuery.fn["outer" + name] = function(margin) { 3542 return this["inner" + name]() + 3543 num(this, "border" + tl + "Width") + 3544 num(this, "border" + br + "Width") + 3545 (margin ? 3546 num(this, "margin" + tl) + num(this, "margin" + br) : 0); 6031 jQuery.fn["outer" + name] = function( margin ) { 6032 return this[0] ? 6033 jQuery.css( this[0], type, false, margin ? "margin" : "border" ) : 6034 null; 3547 6035 }; 3548 6036 3549 });})(); 6037 jQuery.fn[ type ] = function( size ) { 6038 // Get window width or height 6039 var elem = this[0]; 6040 if ( !elem ) { 6041 return size == null ? null : this; 6042 } 6043 6044 if ( jQuery.isFunction( size ) ) { 6045 return this.each(function( i ) { 6046 var self = jQuery( this ); 6047 self[ type ]( size.call( this, i, self[ type ]() ) ); 6048 }); 6049 } 6050 6051 return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window? 6052 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 6053 elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] || 6054 elem.document.body[ "client" + name ] : 6055 6056 // Get document width or height 6057 (elem.nodeType === 9) ? // is it a document 6058 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 6059 Math.max( 6060 elem.documentElement["client" + name], 6061 elem.body["scroll" + name], elem.documentElement["scroll" + name], 6062 elem.body["offset" + name], elem.documentElement["offset" + name] 6063 ) : 6064 6065 // Get or set width or height on the element 6066 size === undefined ? 6067 // Get width or height on the element 6068 jQuery.css( elem, type ) : 6069 6070 // Set the width or height on the element (default to pixels if value is unitless) 6071 this.css( type, typeof size === "string" ? size : size + "px" ); 6072 }; 6073 6074 }); 6075 // Expose jQuery to the global object 6076 window.jQuery = window.$ = jQuery; 6077 6078 })(window);
Note: See TracChangeset
for help on using the changeset viewer.