2 * jQuery JavaScript Library v1.5b1
5 * Copyright 2010, John Resig
6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://jquery.org/license
10 * http://sizzlejs.com/
11 * Copyright 2010, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
14 * Date: Fri Jan 14 14:56:21 2011 -0500
16 (function( window, undefined ) {
18 // Use the correct document accordingly with window argument (sandbox)
19 var document = window.document;
20 var jQuery = (function() {
22 // Define a local copy of jQuery
23 var jQuery = function( selector, context ) {
24 // The jQuery object is actually just the init constructor 'enhanced'
25 return new jQuery.fn.init( selector, context, rootjQuery );
28 // Map over jQuery in case of overwrite
29 _jQuery = window.jQuery,
31 // Map over the $ in case of overwrite
34 // A central reference to the root jQuery(document)
37 // A simple way to check for HTML strings or ID strings
38 // (both of which we optimize for)
39 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
41 // Is it a simple selector
42 isSimple = /^.[^:#\[\.,]*$/,
44 // Check if a string has a non-whitespace character in it
48 // Used for trimming whitespace
52 // Check for non-word characters
58 // Match a standalone tag
59 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
62 rvalidchars = /^[\],:{}\s]*$/,
63 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
64 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
65 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
68 rwebkit = /(webkit)[ \/]([\w.]+)/,
69 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
70 rmsie = /(msie) ([\w.]+)/,
71 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
73 // Keep a UserAgent string for use with jQuery.browser
74 userAgent = navigator.userAgent,
76 // For matching the engine and version of the browser
79 // Has the ready events already been bound?
82 // The deferred used on DOM ready
85 // The ready event handler
88 // Save a reference to some core methods
89 toString = Object.prototype.toString,
90 hasOwn = Object.prototype.hasOwnProperty,
91 push = Array.prototype.push,
92 slice = Array.prototype.slice,
93 trim = String.prototype.trim,
94 indexOf = Array.prototype.indexOf,
96 // [[Class]] -> type pairs
99 jQuery.fn = jQuery.prototype = {
101 init: function( selector, context, rootjQuery ) {
102 var match, elem, ret, doc;
104 // Handle $(""), $(null), or $(undefined)
109 // Handle $(DOMElement)
110 if ( selector.nodeType ) {
111 this.context = this[0] = selector;
116 // The body element only exists once, optimize finding it
117 if ( selector === "body" && !context && document.body ) {
118 this.context = document;
119 this[0] = document.body;
120 this.selector = "body";
125 // Handle HTML strings
126 if ( typeof selector === "string" ) {
127 // Are we dealing with HTML string or an ID?
128 match = quickExpr.exec( selector );
130 // Verify a match, and that no context was specified for #id
131 if ( match && (match[1] || !context) ) {
133 // HANDLE: $(html) -> $(array)
135 context = context instanceof jQuery ? context[0] : context;
136 doc = (context ? context.ownerDocument || context : document);
138 // If a single string is passed in and it's a single tag
139 // just do a createElement and skip the rest
140 ret = rsingleTag.exec( selector );
143 if ( jQuery.isPlainObject( context ) ) {
144 selector = [ document.createElement( ret[1] ) ];
145 jQuery.fn.attr.call( selector, context, true );
148 selector = [ doc.createElement( ret[1] ) ];
152 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
153 selector = (ret.cacheable ? jQuery(ret.fragment).clone()[0] : ret.fragment).childNodes;
156 return jQuery.merge( this, selector );
160 elem = document.getElementById( match[2] );
162 // Check parentNode to catch when Blackberry 4.6 returns
163 // nodes that are no longer in the document #6963
164 if ( elem && elem.parentNode ) {
165 // Handle the case where IE and Opera return items
166 // by name instead of ID
167 if ( elem.id !== match[2] ) {
168 return rootjQuery.find( selector );
171 // Otherwise, we inject the element directly into the jQuery object
176 this.context = document;
177 this.selector = selector;
182 } else if ( !context && !rnonword.test( selector ) ) {
183 this.selector = selector;
184 this.context = document;
185 selector = document.getElementsByTagName( selector );
186 return jQuery.merge( this, selector );
188 // HANDLE: $(expr, $(...))
189 } else if ( !context || context.jquery ) {
190 return (context || rootjQuery).find( selector );
192 // HANDLE: $(expr, context)
193 // (which is just equivalent to: $(context).find(expr)
195 return this.constructor( context ).find( selector );
198 // HANDLE: $(function)
199 // Shortcut for document ready
200 } else if ( jQuery.isFunction( selector ) ) {
201 return rootjQuery.ready( selector );
204 if (selector.selector !== undefined) {
205 this.selector = selector.selector;
206 this.context = selector.context;
209 return jQuery.makeArray( selector, this );
212 // Start with an empty selector
215 // The current version of jQuery being used
218 // The default length of a jQuery object is 0
221 // The number of elements contained in the matched element set
226 toArray: function() {
227 return slice.call( this, 0 );
230 // Get the Nth element in the matched element set OR
231 // Get the whole matched element set as a clean array
232 get: function( num ) {
235 // Return a 'clean' array
238 // Return just the object
239 ( num < 0 ? this[ this.length + num ] : this[ num ] );
242 // Take an array of elements and push it onto the stack
243 // (returning the new matched element set)
244 pushStack: function( elems, name, selector ) {
245 // Build a new jQuery matched element set
246 var ret = this.constructor();
248 if ( jQuery.isArray( elems ) ) {
249 push.apply( ret, elems );
252 jQuery.merge( ret, elems );
255 // Add the old object onto the stack (as a reference)
256 ret.prevObject = this;
258 ret.context = this.context;
260 if ( name === "find" ) {
261 ret.selector = this.selector + (this.selector ? " " : "") + selector;
263 ret.selector = this.selector + "." + name + "(" + selector + ")";
266 // Return the newly-formed element set
270 // Execute a callback for every element in the matched set.
271 // (You can seed the arguments with an array of args, but this is
272 // only used internally.)
273 each: function( callback, args ) {
274 return jQuery.each( this, callback, args );
278 // Attach the listeners
281 // Change ready & apply
282 return ( jQuery.fn.ready = readyList.done ).apply( this , arguments );
288 this.slice( i, +i + 1 );
296 return this.eq( -1 );
300 return this.pushStack( slice.apply( this, arguments ),
301 "slice", slice.call(arguments).join(",") );
304 map: function( callback ) {
305 return this.pushStack( jQuery.map(this, function( elem, i ) {
306 return callback.call( elem, i, elem );
311 return this.prevObject || this.constructor(null);
314 // For internal use only.
315 // Behaves like an Array's method, not like a jQuery method.
321 // Give the init function the jQuery prototype for later instantiation
322 jQuery.fn.init.prototype = jQuery.fn;
324 jQuery.extend = jQuery.fn.extend = function() {
325 var options, name, src, copy, copyIsArray, clone,
326 target = arguments[0] || {},
328 length = arguments.length,
331 // Handle a deep copy situation
332 if ( typeof target === "boolean" ) {
334 target = arguments[1] || {};
335 // skip the boolean and the target
339 // Handle case when target is a string or something (possible in deep copy)
340 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
344 // extend jQuery itself if only one argument is passed
345 if ( length === i ) {
350 for ( ; i < length; i++ ) {
351 // Only deal with non-null/undefined values
352 if ( (options = arguments[ i ]) != null ) {
353 // Extend the base object
354 for ( name in options ) {
355 src = target[ name ];
356 copy = options[ name ];
358 // Prevent never-ending loop
359 if ( target === copy ) {
363 // Recurse if we're merging plain objects or arrays
364 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
367 clone = src && jQuery.isArray(src) ? src : [];
370 clone = src && jQuery.isPlainObject(src) ? src : {};
373 // Never move original objects, clone them
374 target[ name ] = jQuery.extend( deep, clone, copy );
376 // Don't bring in undefined values
377 } else if ( copy !== undefined ) {
378 target[ name ] = copy;
384 // Return the modified object
389 noConflict: function( deep ) {
393 window.jQuery = _jQuery;
399 // Is the DOM ready to be used? Set to true once it occurs.
402 // A counter to track how many items to wait for before
403 // the ready event fires. See #6781
406 // Handle when the DOM is ready
407 ready: function( wait ) {
408 // A third-party is pushing the ready event forwards
409 if ( wait === true ) {
413 // Make sure that the DOM is not already loaded
414 if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
415 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
416 if ( !document.body ) {
417 return setTimeout( jQuery.ready, 1 );
420 // Remember that the DOM is ready
421 jQuery.isReady = true;
423 // If a normal DOM Ready event fired, decrement, and wait if need be
424 if ( wait !== true && --jQuery.readyWait > 0 ) {
428 // If there are functions bound, to execute
429 readyList.fire( document , [ jQuery ] );
431 // Trigger any bound ready events
432 if ( jQuery.fn.trigger ) {
433 jQuery( document ).trigger( "ready" ).unbind( "ready" );
438 bindReady: function() {
445 // Catch cases where $(document).ready() is called after the
446 // browser event has already occurred.
447 if ( document.readyState === "complete" ) {
448 // Handle it asynchronously to allow scripts the opportunity to delay ready
449 return setTimeout( jQuery.ready, 1 );
452 // Mozilla, Opera and webkit nightlies currently support this event
453 if ( document.addEventListener ) {
454 // Use the handy event callback
455 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
457 // A fallback to window.onload, that will always work
458 window.addEventListener( "load", jQuery.ready, false );
460 // If IE event model is used
461 } else if ( document.attachEvent ) {
462 // ensure firing before onload,
463 // maybe late but safe also for iframes
464 document.attachEvent("onreadystatechange", DOMContentLoaded);
466 // A fallback to window.onload, that will always work
467 window.attachEvent( "onload", jQuery.ready );
469 // If IE and not a frame
470 // continually check to see if the document is ready
471 var toplevel = false;
474 toplevel = window.frameElement == null;
477 if ( document.documentElement.doScroll && toplevel ) {
483 // See test/unit/core.js for details concerning isFunction.
484 // Since version 1.3, DOM methods and functions like alert
485 // aren't supported. They return false on IE (#2968).
486 isFunction: function( obj ) {
487 return jQuery.type(obj) === "function";
490 isArray: Array.isArray || function( obj ) {
491 return jQuery.type(obj) === "array";
494 // A crude way of determining if an object is a window
495 isWindow: function( obj ) {
496 return obj && typeof obj === "object" && "setInterval" in obj;
499 isNaN: function( obj ) {
500 return obj == null || !rdigit.test( obj ) || isNaN( obj );
503 type: function( obj ) {
506 class2type[ toString.call(obj) ] || "object";
509 isPlainObject: function( obj ) {
510 // Must be an Object.
511 // Because of IE, we also have to check the presence of the constructor property.
512 // Make sure that DOM nodes and window objects don't pass through, as well
513 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
517 // Not own constructor property must be Object
518 if ( obj.constructor &&
519 !hasOwn.call(obj, "constructor") &&
520 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
524 // Own properties are enumerated firstly, so to speed up,
525 // if last one is own, then all properties are own.
528 for ( key in obj ) {}
530 return key === undefined || hasOwn.call( obj, key );
533 isEmptyObject: function( obj ) {
534 for ( var name in obj ) {
540 error: function( msg ) {
544 parseJSON: function( data ) {
545 if ( typeof data !== "string" || !data ) {
549 // Make sure leading/trailing whitespace is removed (IE can't handle it)
550 data = jQuery.trim( data );
552 // Make sure the incoming data is actual JSON
553 // Logic borrowed from http://json.org/json2.js
554 if ( rvalidchars.test(data.replace(rvalidescape, "@")
555 .replace(rvalidtokens, "]")
556 .replace(rvalidbraces, "")) ) {
558 // Try to use the native JSON parser first
559 return window.JSON && window.JSON.parse ?
560 window.JSON.parse( data ) :
561 (new Function("return " + data))();
564 jQuery.error( "Invalid JSON: " + data );
568 // Cross-browser xml parsing
569 // (xml & tmp used internally)
570 parseXML: function( data , xml , tmp ) {
572 if ( window.DOMParser ) { // Standard
573 tmp = new DOMParser();
574 xml = tmp.parseFromString( data , "text/xml" );
576 xml = new ActiveXObject( "Microsoft.XMLDOM" );
581 tmp = xml.documentElement;
583 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
584 jQuery.error( "Invalid XML: " + data );
592 // Evalulates a script in a global context
593 globalEval: function( data ) {
594 if ( data && rnotwhite.test(data) ) {
595 // Inspired by code by Andrea Giammarchi
596 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
597 var head = document.getElementsByTagName("head")[0] || document.documentElement,
598 script = document.createElement("script");
600 script.type = "text/javascript";
602 if ( jQuery.support.scriptEval ) {
603 script.appendChild( document.createTextNode( data ) );
608 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
609 // This arises when a base node is used (#2709).
610 head.insertBefore( script, head.firstChild );
611 head.removeChild( script );
615 nodeName: function( elem, name ) {
616 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
619 // args is for internal usage only
620 each: function( object, callback, args ) {
622 length = object.length,
623 isObj = length === undefined || jQuery.isFunction(object);
627 for ( name in object ) {
628 if ( callback.apply( object[ name ], args ) === false ) {
633 for ( ; i < length; ) {
634 if ( callback.apply( object[ i++ ], args ) === false ) {
640 // A special, fast, case for the most common use of each
643 for ( name in object ) {
644 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
649 for ( var value = object[0];
650 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
657 // Use native String.trim function wherever possible
660 return text == null ?
665 // Otherwise use our own trimming functionality
667 return text == null ?
669 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
672 // results is for internal usage only
673 makeArray: function( array, results ) {
674 var ret = results || [];
676 if ( array != null ) {
677 // The window, strings (and functions) also have 'length'
678 // The extra typeof function check is to prevent crashes
679 // in Safari 2 (See: #3039)
680 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
681 var type = jQuery.type(array);
683 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
684 push.call( ret, array );
686 jQuery.merge( ret, array );
693 inArray: function( elem, array ) {
694 if ( array.indexOf ) {
695 return array.indexOf( elem );
698 for ( var i = 0, length = array.length; i < length; i++ ) {
699 if ( array[ i ] === elem ) {
707 merge: function( first, second ) {
708 var i = first.length,
711 if ( typeof second.length === "number" ) {
712 for ( var l = second.length; j < l; j++ ) {
713 first[ i++ ] = second[ j ];
717 while ( second[j] !== undefined ) {
718 first[ i++ ] = second[ j++ ];
727 grep: function( elems, callback, inv ) {
728 var ret = [], retVal;
731 // Go through the array, only saving the items
732 // that pass the validator function
733 for ( var i = 0, length = elems.length; i < length; i++ ) {
734 retVal = !!callback( elems[ i ], i );
735 if ( inv !== retVal ) {
736 ret.push( elems[ i ] );
743 // arg is for internal usage only
744 map: function( elems, callback, arg ) {
747 // Go through the array, translating each of the items to their
748 // new value (or values).
749 for ( var i = 0, length = elems.length; i < length; i++ ) {
750 value = callback( elems[ i ], i, arg );
752 if ( value != null ) {
753 ret[ ret.length ] = value;
757 // Flatten any nested arrays
758 return ret.concat.apply( [], ret );
761 // A global GUID counter for objects
764 proxy: function( fn, proxy, thisObject ) {
765 if ( arguments.length === 2 ) {
766 if ( typeof proxy === "string" ) {
768 fn = thisObject[ proxy ];
771 } else if ( proxy && !jQuery.isFunction( proxy ) ) {
777 if ( !proxy && fn ) {
779 return fn.apply( thisObject || this, arguments );
783 // Set the guid of unique handler to the same of original handler, so it can be removed
785 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
788 // So proxy can be declared as an argument
792 // Mutifunctional method to get and set values to a collection
793 // The value/s can be optionally by executed if its a function
794 access: function( elems, key, value, exec, fn, pass ) {
795 var length = elems.length;
797 // Setting many attributes
798 if ( typeof key === "object" ) {
799 for ( var k in key ) {
800 jQuery.access( elems, k, key[k], exec, fn, value );
805 // Setting one attribute
806 if ( value !== undefined ) {
807 // Optionally, function values get executed if exec is true
808 exec = !pass && exec && jQuery.isFunction(value);
810 for ( var i = 0; i < length; i++ ) {
811 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
817 // Getting an attribute
818 return length ? fn( elems[0], key ) : undefined;
822 return (new Date()).getTime();
825 // Create a simple deferred (one callbacks list)
826 _Deferred: function() {
828 var // callbacks list
830 // stored [ context , args ]
832 // to avoid firing when already doing so
834 // flag to know if the deferred has been cancelled
836 // the deferred itself
839 // done( f1, f2, ...)
844 var args = arguments,
856 for ( i = 0, length = args.length ; i < length ; i++ ) {
858 type = jQuery.type( elem );
859 if ( type === "array" ) {
860 deferred.done.apply( deferred , elem );
861 } else if ( type === "function" ) {
862 callbacks.push( elem );
867 deferred.fire( _fired[ 0 ] , _fired[ 1 ] );
874 // resolve with given context and args
875 fire: function( context , args ) {
876 if ( ! cancelled && ! fired && ! firing ) {
881 while( callbacks[ 0 ] ) {
882 callbacks.shift().apply( context , args );
886 fired = [ context , args ];
893 // resolve with this as context and given arguments
894 resolve: function() {
895 deferred.fire( jQuery.isFunction( this.promise ) ? this.promise() : this , arguments );
899 // Has this deferred been resolved?
900 isResolved: function() {
901 return !!( firing || fired );
915 // Full fledged deferred (two callbacks list)
916 // Typical success/error system
917 Deferred: function( func ) {
919 var deferred = jQuery._Deferred(),
920 failDeferred = jQuery._Deferred();
922 // Add errorDeferred methods and redefine cancel
923 jQuery.extend( deferred , {
925 then: function( doneCallbacks , failCallbacks ) {
926 deferred.done( doneCallbacks ).fail( failCallbacks );
929 fail: failDeferred.done,
930 fireReject: failDeferred.fire,
931 reject: failDeferred.resolve,
932 isRejected: failDeferred.isResolved,
933 // Get a promise for this deferred
934 // If obj is provided, the promise aspect is added to the object
935 promise: function( obj ) {
937 jQuery.each( "then done fail isResolved isRejected".split( " " ) , function( _ , method ) {
938 obj[ method ] = deferred[ method ];
940 obj.promise = function() {
948 // Make sure only one callback list will be used
949 deferred.then( failDeferred.cancel , deferred.cancel );
952 delete deferred.cancel;
954 // Call given func if any
956 func.call( deferred , deferred );
963 when: function( object ) {
964 object = object && jQuery.isFunction( object.promise ) ?
966 jQuery.Deferred().resolve( object );
967 return object.promise();
970 // Use of jQuery.browser is frowned upon.
971 // More details: http://docs.jquery.com/Utilities/jQuery.browser
972 uaMatch: function( ua ) {
973 ua = ua.toLowerCase();
975 var match = rwebkit.exec( ua ) ||
978 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
981 return { browser: match[1] || "", version: match[2] || "0" };
984 subclass: function(){
985 function jQuerySubclass( selector, context ) {
986 return new jQuerySubclass.fn.init( selector, context );
988 jQuerySubclass.superclass = this;
989 jQuerySubclass.fn = jQuerySubclass.prototype = this();
990 jQuerySubclass.fn.constructor = jQuerySubclass;
991 jQuerySubclass.subclass = this.subclass;
992 jQuerySubclass.fn.init = function init( selector, context ) {
993 if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){
994 context = jQuerySubclass(context);
996 return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
998 jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
999 var rootjQuerySubclass = jQuerySubclass(document);
1000 return jQuerySubclass;
1006 // Create readyList deferred
1007 readyList = jQuery._Deferred();
1009 // Populate the class2type map
1010 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
1011 class2type[ "[object " + name + "]" ] = name.toLowerCase();
1014 browserMatch = jQuery.uaMatch( userAgent );
1015 if ( browserMatch.browser ) {
1016 jQuery.browser[ browserMatch.browser ] = true;
1017 jQuery.browser.version = browserMatch.version;
1020 // Deprecated, use jQuery.browser.webkit instead
1021 if ( jQuery.browser.webkit ) {
1022 jQuery.browser.safari = true;
1026 jQuery.inArray = function( elem, array ) {
1027 return indexOf.call( array, elem );
1031 // Verify that \s matches non-breaking spaces
1032 // (IE fails on this test)
1033 if ( !rwhite.test( "\xA0" ) ) {
1034 trimLeft = /^[\s\xA0]+/;
1035 trimRight = /[\s\xA0]+$/;
1038 // All jQuery objects should point back to these
1039 rootjQuery = jQuery(document);
1041 // Cleanup functions for the document ready method
1042 if ( document.addEventListener ) {
1043 DOMContentLoaded = function() {
1044 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
1048 } else if ( document.attachEvent ) {
1049 DOMContentLoaded = function() {
1050 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
1051 if ( document.readyState === "complete" ) {
1052 document.detachEvent( "onreadystatechange", DOMContentLoaded );
1058 // The DOM ready check for Internet Explorer
1059 function doScrollCheck() {
1060 if ( jQuery.isReady ) {
1065 // If IE is used, use the trick by Diego Perini
1066 // http://javascript.nwbox.com/IEContentLoaded/
1067 document.documentElement.doScroll("left");
1069 setTimeout( doScrollCheck, 1 );
1073 // and execute any waiting functions
1077 // Expose jQuery to the global object
1078 return (window.jQuery = window.$ = jQuery);
1085 jQuery.support = {};
1087 var root = document.documentElement,
1088 script = document.createElement("script"),
1089 div = document.createElement("div"),
1090 id = "script" + jQuery.now();
1092 div.style.display = "none";
1093 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1095 var all = div.getElementsByTagName("*"),
1096 a = div.getElementsByTagName("a")[0],
1097 select = document.createElement("select"),
1098 opt = select.appendChild( document.createElement("option") );
1100 // Can't get basic test support
1101 if ( !all || !all.length || !a ) {
1106 // IE strips leading whitespace when .innerHTML is used
1107 leadingWhitespace: div.firstChild.nodeType === 3,
1109 // Make sure that tbody elements aren't automatically inserted
1110 // IE will insert them into empty tables
1111 tbody: !div.getElementsByTagName("tbody").length,
1113 // Make sure that link elements get serialized correctly by innerHTML
1114 // This requires a wrapper element in IE
1115 htmlSerialize: !!div.getElementsByTagName("link").length,
1117 // Get the style information from getAttribute
1118 // (IE uses .cssText insted)
1119 style: /red/.test( a.getAttribute("style") ),
1121 // Make sure that URLs aren't manipulated
1122 // (IE normalizes it by default)
1123 hrefNormalized: a.getAttribute("href") === "/a",
1125 // Make sure that element opacity exists
1126 // (IE uses filter instead)
1127 // Use a regex to work around a WebKit issue. See #5145
1128 opacity: /^0.55$/.test( a.style.opacity ),
1130 // Verify style float existence
1131 // (IE uses styleFloat instead of cssFloat)
1132 cssFloat: !!a.style.cssFloat,
1134 // Make sure that if no value is specified for a checkbox
1135 // that it defaults to "on".
1136 // (WebKit defaults to "" instead)
1137 checkOn: div.getElementsByTagName("input")[0].value === "on",
1139 // Make sure that a selected-by-default option has a working selected property.
1140 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1141 optSelected: opt.selected,
1143 // Will be defined later
1144 deleteExpando: true,
1150 inlineBlockNeedsLayout: false,
1151 shrinkWrapBlocks: false,
1152 reliableHiddenOffsets: true
1155 // Make sure that the options inside disabled selects aren't marked as disabled
1156 // (WebKit marks them as diabled)
1157 select.disabled = true;
1158 jQuery.support.optDisabled = !opt.disabled;
1160 script.type = "text/javascript";
1162 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
1165 root.insertBefore( script, root.firstChild );
1167 // Make sure that the execution of code works by injecting a script
1168 // tag with appendChild/createTextNode
1169 // (IE doesn't support this, fails, and uses .text instead)
1170 if ( window[ id ] ) {
1171 jQuery.support.scriptEval = true;
1172 delete window[ id ];
1175 // Test to see if it's possible to delete an expando from an element
1176 // Fails in Internet Explorer
1181 jQuery.support.deleteExpando = false;
1184 root.removeChild( script );
1186 if ( div.attachEvent && div.fireEvent ) {
1187 div.attachEvent("onclick", function click() {
1188 // Cloning a node shouldn't copy over any
1189 // bound event handlers (IE does this)
1190 jQuery.support.noCloneEvent = false;
1191 div.detachEvent("onclick", click);
1193 div.cloneNode(true).fireEvent("onclick");
1196 div = document.createElement("div");
1197 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
1199 var fragment = document.createDocumentFragment();
1200 fragment.appendChild( div.firstChild );
1202 // WebKit doesn't clone checked state correctly in fragments
1203 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
1205 // Figure out if the W3C box model works as expected
1206 // document.body must exist before we can do this
1208 var div = document.createElement("div");
1209 div.style.width = div.style.paddingLeft = "1px";
1211 document.body.appendChild( div );
1212 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
1214 if ( "zoom" in div.style ) {
1215 // Check if natively block-level elements act like inline-block
1216 // elements when setting their display to 'inline' and giving
1218 // (IE < 8 does this)
1219 div.style.display = "inline";
1221 jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
1223 // Check if elements with layout shrink-wrap their children
1225 div.style.display = "";
1226 div.innerHTML = "<div style='width:4px;'></div>";
1227 jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
1230 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1231 var tds = div.getElementsByTagName("td");
1233 // Check if table cells still have offsetWidth/Height when they are set
1234 // to display:none and there are still other visible table cells in a
1235 // table row; if so, offsetWidth/Height are not reliable for use when
1236 // determining if an element has been hidden directly using
1237 // display:none (it is still safe to use offsets if a parent element is
1238 // hidden; don safety goggles and see bug #4512 for more information).
1239 // (only IE 8 fails this test)
1240 jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
1242 tds[0].style.display = "";
1243 tds[1].style.display = "none";
1245 // Check if empty table cells still have offsetWidth/Height
1246 // (IE < 8 fail this test)
1247 jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
1250 document.body.removeChild( div ).style.display = "none";
1254 // Technique from Juriy Zaytsev
1255 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1256 var eventSupported = function( eventName ) {
1257 var el = document.createElement("div");
1258 eventName = "on" + eventName;
1260 var isSupported = (eventName in el);
1261 if ( !isSupported ) {
1262 el.setAttribute(eventName, "return;");
1263 isSupported = typeof el[eventName] === "function";
1270 jQuery.support.submitBubbles = eventSupported("submit");
1271 jQuery.support.changeBubbles = eventSupported("change");
1273 // release memory in IE
1274 root = script = div = all = a = null;
1279 var windowData = {},
1280 rbrace = /^(?:\{.*\}|\[.*\])$/;
1285 // Please use with caution
1288 // Unique for each copy of jQuery on the page
1289 // Non-digits removed to match rinlinejQuery
1290 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1292 // The following elements throw uncatchable exceptions if you
1293 // attempt to add expando properties to them.
1296 // Ban all objects except for Flash (which handle expandos)
1297 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1301 hasData: function( elem ) {
1302 if ( elem.nodeType ) {
1303 elem = jQuery.cache[ elem[jQuery.expando] ];
1306 return !!elem && !jQuery.isEmptyObject(elem);
1309 data: function( elem, name, data ) {
1310 if ( !jQuery.acceptData( elem ) ) {
1314 elem = elem == window ?
1318 var isNode = elem.nodeType,
1319 id = isNode ? elem[ jQuery.expando ] : null,
1320 cache = jQuery.cache, thisCache;
1322 if ( isNode && !id && typeof name === "string" && data === undefined ) {
1326 // Get the data from the object directly
1330 // Compute a unique ID for the element
1332 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1335 // Avoid generating a new cache unless none exists and we
1336 // want to manipulate it.
1337 if ( typeof name === "object" ) {
1339 cache[ id ] = jQuery.extend(cache[ id ], name);
1342 jQuery.extend( cache, name );
1345 } else if ( isNode && !cache[ id ] ) {
1349 thisCache = isNode ? cache[ id ] : cache;
1351 // Prevent overriding the named cache with undefined values
1352 if ( data !== undefined ) {
1353 thisCache[ name ] = data;
1356 return typeof name === "string" ? thisCache[ name ] : thisCache;
1359 removeData: function( elem, name ) {
1360 if ( !jQuery.acceptData( elem ) ) {
1364 elem = elem == window ?
1368 var isNode = elem.nodeType,
1369 id = isNode ? elem[ jQuery.expando ] : elem,
1370 cache = jQuery.cache,
1371 thisCache = isNode ? cache[ id ] : id;
1373 // If we want to remove a specific section of the element's data
1376 // Remove the section of cache data
1377 delete thisCache[ name ];
1379 // If we've removed all the data, remove the element's cache
1380 if ( isNode && jQuery.isEmptyObject(thisCache) ) {
1381 jQuery.removeData( elem );
1385 // Otherwise, we want to remove all of the element's data
1387 if ( isNode && jQuery.support.deleteExpando ) {
1388 delete elem[ jQuery.expando ];
1390 } else if ( elem.removeAttribute ) {
1391 elem.removeAttribute( jQuery.expando );
1393 // Completely remove the data cache
1394 } else if ( isNode ) {
1397 // Remove all fields from the object
1399 for ( var n in elem ) {
1406 // A method for determining if a DOM node can handle the data expando
1407 acceptData: function( elem ) {
1408 if ( elem.nodeName ) {
1409 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1412 return !(match === true || elem.getAttribute("classid") !== match);
1421 data: function( key, value ) {
1424 if ( typeof key === "undefined" ) {
1425 if ( this.length ) {
1426 data = jQuery.data( this[0] );
1428 if ( this[0].nodeType === 1 ) {
1429 var attr = this[0].attributes, name;
1430 for ( var i = 0, l = attr.length; i < l; i++ ) {
1431 name = attr[i].name;
1433 if ( name.indexOf( "data-" ) === 0 ) {
1434 name = name.substr( 5 );
1435 dataAttr( this[0], name, data[ name ] );
1443 } else if ( typeof key === "object" ) {
1444 return this.each(function() {
1445 jQuery.data( this, key );
1449 var parts = key.split(".");
1450 parts[1] = parts[1] ? "." + parts[1] : "";
1452 if ( value === undefined ) {
1453 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1455 // Try to fetch any internally stored data first
1456 if ( data === undefined && this.length ) {
1457 data = jQuery.data( this[0], key );
1458 data = dataAttr( this[0], key, data );
1461 return data === undefined && parts[1] ?
1462 this.data( parts[0] ) :
1466 return this.each(function() {
1467 var $this = jQuery( this ),
1468 args = [ parts[0], value ];
1470 $this.triggerHandler( "setData" + parts[1] + "!", args );
1471 jQuery.data( this, key, value );
1472 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1477 removeData: function( key ) {
1478 return this.each(function() {
1479 jQuery.removeData( this, key );
1484 function dataAttr( elem, key, data ) {
1485 // If nothing was found internally, try to fetch any
1486 // data from the HTML5 data-* attribute
1487 if ( data === undefined && elem.nodeType === 1 ) {
1488 data = elem.getAttribute( "data-" + key );
1490 if ( typeof data === "string" ) {
1492 data = data === "true" ? true :
1493 data === "false" ? false :
1494 data === "null" ? null :
1495 !jQuery.isNaN( data ) ? parseFloat( data ) :
1496 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1500 // Make sure we set the data so it isn't changed later
1501 jQuery.data( elem, key, data );
1515 queue: function( elem, type, data ) {
1520 type = (type || "fx") + "queue";
1521 var q = jQuery.data( elem, type );
1523 // Speed up dequeue by getting out quickly if this is just a lookup
1528 if ( !q || jQuery.isArray(data) ) {
1529 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1538 dequeue: function( elem, type ) {
1539 type = type || "fx";
1541 var queue = jQuery.queue( elem, type ),
1544 // If the fx queue is dequeued, always remove the progress sentinel
1545 if ( fn === "inprogress" ) {
1550 // Add a progress sentinel to prevent the fx queue from being
1551 // automatically dequeued
1552 if ( type === "fx" ) {
1553 queue.unshift("inprogress");
1556 fn.call(elem, function() {
1557 jQuery.dequeue(elem, type);
1564 queue: function( type, data ) {
1565 if ( typeof type !== "string" ) {
1570 if ( data === undefined ) {
1571 return jQuery.queue( this[0], type );
1573 return this.each(function( i ) {
1574 var queue = jQuery.queue( this, type, data );
1576 if ( type === "fx" && queue[0] !== "inprogress" ) {
1577 jQuery.dequeue( this, type );
1581 dequeue: function( type ) {
1582 return this.each(function() {
1583 jQuery.dequeue( this, type );
1587 // Based off of the plugin by Clint Helfers, with permission.
1588 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1589 delay: function( time, type ) {
1590 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1591 type = type || "fx";
1593 return this.queue( type, function() {
1595 setTimeout(function() {
1596 jQuery.dequeue( elem, type );
1601 clearQueue: function( type ) {
1602 return this.queue( type || "fx", [] );
1609 var rclass = /[\n\t\r]/g,
1612 rspecialurl = /^(?:href|src|style)$/,
1613 rtype = /^(?:button|input)$/i,
1614 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1615 rclickable = /^a(?:rea)?$/i,
1616 rradiocheck = /^(?:radio|checkbox)$/i;
1620 "class": "className",
1621 readonly: "readOnly",
1622 maxlength: "maxLength",
1623 cellspacing: "cellSpacing",
1626 tabindex: "tabIndex",
1628 frameborder: "frameBorder"
1632 attr: function( name, value ) {
1633 return jQuery.access( this, name, value, true, jQuery.attr );
1636 removeAttr: function( name, fn ) {
1637 return this.each(function(){
1638 jQuery.attr( this, name, "" );
1639 if ( this.nodeType === 1 ) {
1640 this.removeAttribute( name );
1645 addClass: function( value ) {
1646 if ( jQuery.isFunction(value) ) {
1647 return this.each(function(i) {
1648 var self = jQuery(this);
1649 self.addClass( value.call(this, i, self.attr("class")) );
1653 if ( value && typeof value === "string" ) {
1654 var classNames = (value || "").split( rspaces );
1656 for ( var i = 0, l = this.length; i < l; i++ ) {
1659 if ( elem.nodeType === 1 ) {
1660 if ( !elem.className ) {
1661 elem.className = value;
1664 var className = " " + elem.className + " ",
1665 setClass = elem.className;
1667 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1668 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1669 setClass += " " + classNames[c];
1672 elem.className = jQuery.trim( setClass );
1681 removeClass: function( value ) {
1682 if ( jQuery.isFunction(value) ) {
1683 return this.each(function(i) {
1684 var self = jQuery(this);
1685 self.removeClass( value.call(this, i, self.attr("class")) );
1689 if ( (value && typeof value === "string") || value === undefined ) {
1690 var classNames = (value || "").split( rspaces );
1692 for ( var i = 0, l = this.length; i < l; i++ ) {
1695 if ( elem.nodeType === 1 && elem.className ) {
1697 var className = (" " + elem.className + " ").replace(rclass, " ");
1698 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1699 className = className.replace(" " + classNames[c] + " ", " ");
1701 elem.className = jQuery.trim( className );
1704 elem.className = "";
1713 toggleClass: function( value, stateVal ) {
1714 var type = typeof value,
1715 isBool = typeof stateVal === "boolean";
1717 if ( jQuery.isFunction( value ) ) {
1718 return this.each(function(i) {
1719 var self = jQuery(this);
1720 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1724 return this.each(function() {
1725 if ( type === "string" ) {
1726 // toggle individual class names
1729 self = jQuery( this ),
1731 classNames = value.split( rspaces );
1733 while ( (className = classNames[ i++ ]) ) {
1734 // check each className given, space seperated list
1735 state = isBool ? state : !self.hasClass( className );
1736 self[ state ? "addClass" : "removeClass" ]( className );
1739 } else if ( type === "undefined" || type === "boolean" ) {
1740 if ( this.className ) {
1741 // store className if set
1742 jQuery.data( this, "__className__", this.className );
1745 // toggle whole className
1746 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1751 hasClass: function( selector ) {
1752 var className = " " + selector + " ";
1753 for ( var i = 0, l = this.length; i < l; i++ ) {
1754 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1762 val: function( value ) {
1763 if ( !arguments.length ) {
1767 if ( jQuery.nodeName( elem, "option" ) ) {
1768 // attributes.value is undefined in Blackberry 4.7 but
1769 // uses .value. See #6932
1770 var val = elem.attributes.value;
1771 return !val || val.specified ? elem.value : elem.text;
1774 // We need to handle select boxes special
1775 if ( jQuery.nodeName( elem, "select" ) ) {
1776 var index = elem.selectedIndex,
1778 options = elem.options,
1779 one = elem.type === "select-one";
1781 // Nothing was selected
1786 // Loop through all the selected options
1787 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1788 var option = options[ i ];
1790 // Don't return options that are disabled or in a disabled optgroup
1791 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
1792 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
1794 // Get the specific value for the option
1795 value = jQuery(option).val();
1797 // We don't need an array for one selects
1802 // Multi-Selects return an array
1803 values.push( value );
1810 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1811 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1812 return elem.getAttribute("value") === null ? "on" : elem.value;
1815 // Everything else, we just grab the value
1816 return (elem.value || "").replace(rreturn, "");
1823 var isFunction = jQuery.isFunction(value);
1825 return this.each(function(i) {
1826 var self = jQuery(this), val = value;
1828 if ( this.nodeType !== 1 ) {
1833 val = value.call(this, i, self.val());
1836 // Treat null/undefined as ""; convert numbers to string
1837 if ( val == null ) {
1839 } else if ( typeof val === "number" ) {
1841 } else if ( jQuery.isArray(val) ) {
1842 val = jQuery.map(val, function (value) {
1843 return value == null ? "" : value + "";
1847 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1848 this.checked = jQuery.inArray( self.val(), val ) >= 0;
1850 } else if ( jQuery.nodeName( this, "select" ) ) {
1851 var values = jQuery.makeArray(val);
1853 jQuery( "option", this ).each(function() {
1854 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1857 if ( !values.length ) {
1858 this.selectedIndex = -1;
1880 attr: function( elem, name, value, pass ) {
1881 // don't get/set attributes on text, comment and attribute nodes
1882 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
1886 if ( pass && name in jQuery.attrFn ) {
1887 return jQuery(elem)[name](value);
1890 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1891 // Whether we are setting (or getting)
1892 set = value !== undefined;
1894 // Try to normalize/fix the name
1895 name = notxml && jQuery.props[ name ] || name;
1897 // Only do all the following if this is a node (faster for style)
1898 if ( elem.nodeType === 1 ) {
1899 // These attributes require special treatment
1900 var special = rspecialurl.test( name );
1902 // Safari mis-reports the default selected property of an option
1903 // Accessing the parent's selectedIndex property fixes it
1904 if ( name === "selected" && !jQuery.support.optSelected ) {
1905 var parent = elem.parentNode;
1907 parent.selectedIndex;
1909 // Make sure that it also works with optgroups, see #5701
1910 if ( parent.parentNode ) {
1911 parent.parentNode.selectedIndex;
1916 // If applicable, access the attribute via the DOM 0 way
1917 // 'in' checks fail in Blackberry 4.7 #6931
1918 if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
1920 // We can't allow the type property to be changed (since it causes problems in IE)
1921 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1922 jQuery.error( "type property can't be changed" );
1925 if ( value === null ) {
1926 if ( elem.nodeType === 1 ) {
1927 elem.removeAttribute( name );
1931 elem[ name ] = value;
1935 // browsers index elements by id/name on forms, give priority to attributes.
1936 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1937 return elem.getAttributeNode( name ).nodeValue;
1940 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1941 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1942 if ( name === "tabIndex" ) {
1943 var attributeNode = elem.getAttributeNode( "tabIndex" );
1945 return attributeNode && attributeNode.specified ?
1946 attributeNode.value :
1947 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1952 return elem[ name ];
1955 if ( !jQuery.support.style && notxml && name === "style" ) {
1957 elem.style.cssText = "" + value;
1960 return elem.style.cssText;
1964 // convert the value to a string (all browsers do this but IE) see #1070
1965 elem.setAttribute( name, "" + value );
1968 // Ensure that missing attributes return undefined
1969 // Blackberry 4.7 returns "" from getAttribute #6938
1970 if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
1974 var attr = !jQuery.support.hrefNormalized && notxml && special ?
1975 // Some attributes require a special call on IE
1976 elem.getAttribute( name, 2 ) :
1977 elem.getAttribute( name );
1979 // Non-existent attributes return null, we normalize to undefined
1980 return attr === null ? undefined : attr;
1982 // Handle everything which isn't a DOM element node
1984 elem[ name ] = value;
1986 return elem[ name ];
1993 var rnamespaces = /\.(.*)$/,
1994 rformElems = /^(?:textarea|input|select)$/i,
1997 rescape = /[^\w\s.|`]/g,
1998 fcleanup = function( nm ) {
1999 return nm.replace(rescape, "\\$&");
2001 focusCounts = { focusin: 0, focusout: 0 };
2004 * A number of helper functions used for managing events.
2005 * Many of the ideas behind this code originated from
2006 * Dean Edwards' addEvent library.
2010 // Bind an event to an element
2011 // Original by Dean Edwards
2012 add: function( elem, types, handler, data ) {
2013 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2017 // For whatever reason, IE has trouble passing the window object
2018 // around, causing it to be cloned in the process
2019 if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
2023 if ( handler === false ) {
2024 handler = returnFalse;
2025 } else if ( !handler ) {
2026 // Fixes bug #7229. Fix recommended by jdalton
2030 var handleObjIn, handleObj;
2032 if ( handler.handler ) {
2033 handleObjIn = handler;
2034 handler = handleObjIn.handler;
2037 // Make sure that the function being executed has a unique ID
2038 if ( !handler.guid ) {
2039 handler.guid = jQuery.guid++;
2042 // Init the element's event structure
2043 var elemData = jQuery.data( elem );
2045 // If no elemData is found then we must be trying to bind to one of the
2046 // banned noData elements
2051 // Use a key less likely to result in collisions for plain JS objects.
2053 var eventKey = elem.nodeType ? "events" : "__events__",
2054 events = elemData[ eventKey ],
2055 eventHandle = elemData.handle;
2057 if ( typeof events === "function" ) {
2058 // On plain objects events is a fn that holds the the data
2059 // which prevents this data from being JSON serialized
2060 // the function does not need to be called, it just contains the data
2061 eventHandle = events.handle;
2062 events = events.events;
2064 } else if ( !events ) {
2065 if ( !elem.nodeType ) {
2066 // On plain objects, create a fn that acts as the holder
2067 // of the values to avoid JSON serialization of event data
2068 elemData[ eventKey ] = elemData = function(){};
2071 elemData.events = events = {};
2074 if ( !eventHandle ) {
2075 elemData.handle = eventHandle = function() {
2076 // Handle the second event of a trigger and when
2077 // an event is called after a page has unloaded
2078 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2079 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2084 // Add elem as a property of the handle function
2085 // This is to prevent a memory leak with non-native events in IE.
2086 eventHandle.elem = elem;
2088 // Handle multiple events separated by a space
2089 // jQuery(...).bind("mouseover mouseout", fn);
2090 types = types.split(" ");
2092 var type, i = 0, namespaces;
2094 while ( (type = types[ i++ ]) ) {
2095 handleObj = handleObjIn ?
2096 jQuery.extend({}, handleObjIn) :
2097 { handler: handler, data: data };
2099 // Namespaced event handlers
2100 if ( type.indexOf(".") > -1 ) {
2101 namespaces = type.split(".");
2102 type = namespaces.shift();
2103 handleObj.namespace = namespaces.slice(0).sort().join(".");
2107 handleObj.namespace = "";
2110 handleObj.type = type;
2111 if ( !handleObj.guid ) {
2112 handleObj.guid = handler.guid;
2115 // Get the current list of functions bound to this event
2116 var handlers = events[ type ],
2117 special = jQuery.event.special[ type ] || {};
2119 // Init the event handler queue
2121 handlers = events[ type ] = [];
2123 // Check for a special event handler
2124 // Only use addEventListener/attachEvent if the special
2125 // events handler returns false
2126 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2127 // Bind the global event handler to the element
2128 if ( elem.addEventListener ) {
2129 elem.addEventListener( type, eventHandle, false );
2131 } else if ( elem.attachEvent ) {
2132 elem.attachEvent( "on" + type, eventHandle );
2137 if ( special.add ) {
2138 special.add.call( elem, handleObj );
2140 if ( !handleObj.handler.guid ) {
2141 handleObj.handler.guid = handler.guid;
2145 // Add the function to the element's handler list
2146 handlers.push( handleObj );
2148 // Keep track of which events have been used, for global triggering
2149 jQuery.event.global[ type ] = true;
2152 // Nullify elem to prevent memory leaks in IE
2158 // Detach an event or set of events from an element
2159 remove: function( elem, types, handler, pos ) {
2160 // don't do events on text and comment nodes
2161 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2165 if ( handler === false ) {
2166 handler = returnFalse;
2169 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2170 eventKey = elem.nodeType ? "events" : "__events__",
2171 elemData = jQuery.data( elem ),
2172 events = elemData && elemData[ eventKey ];
2174 if ( !elemData || !events ) {
2178 if ( typeof events === "function" ) {
2180 events = events.events;
2183 // types is actually an event object here
2184 if ( types && types.type ) {
2185 handler = types.handler;
2189 // Unbind all events for the element
2190 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2191 types = types || "";
2193 for ( type in events ) {
2194 jQuery.event.remove( elem, type + types );
2200 // Handle multiple events separated by a space
2201 // jQuery(...).unbind("mouseover mouseout", fn);
2202 types = types.split(" ");
2204 while ( (type = types[ i++ ]) ) {
2207 all = type.indexOf(".") < 0;
2211 // Namespaced event handlers
2212 namespaces = type.split(".");
2213 type = namespaces.shift();
2215 namespace = new RegExp("(^|\\.)" +
2216 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2219 eventType = events[ type ];
2226 for ( j = 0; j < eventType.length; j++ ) {
2227 handleObj = eventType[ j ];
2229 if ( all || namespace.test( handleObj.namespace ) ) {
2230 jQuery.event.remove( elem, origType, handleObj.handler, j );
2231 eventType.splice( j--, 1 );
2238 special = jQuery.event.special[ type ] || {};
2240 for ( j = pos || 0; j < eventType.length; j++ ) {
2241 handleObj = eventType[ j ];
2243 if ( handler.guid === handleObj.guid ) {
2244 // remove the given handler for the given type
2245 if ( all || namespace.test( handleObj.namespace ) ) {
2246 if ( pos == null ) {
2247 eventType.splice( j--, 1 );
2250 if ( special.remove ) {
2251 special.remove.call( elem, handleObj );
2255 if ( pos != null ) {
2261 // remove generic event handler if no more handlers exist
2262 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2263 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2264 jQuery.removeEvent( elem, type, elemData.handle );
2268 delete events[ type ];
2272 // Remove the expando if it's no longer used
2273 if ( jQuery.isEmptyObject( events ) ) {
2274 var handle = elemData.handle;
2279 delete elemData.events;
2280 delete elemData.handle;
2282 if ( typeof elemData === "function" ) {
2283 jQuery.removeData( elem, eventKey );
2285 } else if ( jQuery.isEmptyObject( elemData ) ) {
2286 jQuery.removeData( elem );
2291 // bubbling is internal
2292 trigger: function( event, data, elem /*, bubbling */ ) {
2293 // Event object or event type
2294 var type = event.type || event,
2295 bubbling = arguments[3];
2298 event = typeof event === "object" ?
2299 // jQuery.Event object
2300 event[ jQuery.expando ] ? event :
2302 jQuery.extend( jQuery.Event(type), event ) :
2303 // Just the event type (string)
2306 if ( type.indexOf("!") >= 0 ) {
2307 event.type = type = type.slice(0, -1);
2308 event.exclusive = true;
2311 // Handle a global trigger
2313 // Don't bubble custom events when global (to avoid too much overhead)
2314 event.stopPropagation();
2316 // Only trigger if we've ever bound an event for it
2317 if ( jQuery.event.global[ type ] ) {
2318 jQuery.each( jQuery.cache, function() {
2319 if ( this.events && this.events[type] ) {
2320 jQuery.event.trigger( event, data, this.handle.elem );
2326 // Handle triggering a single element
2328 // don't do events on text and comment nodes
2329 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
2333 // Clean up in case it is reused
2334 event.result = undefined;
2335 event.target = elem;
2337 // Clone the incoming data, if any
2338 data = jQuery.makeArray( data );
2339 data.unshift( event );
2342 event.currentTarget = elem;
2344 // Trigger the event, it is assumed that "handle" is a function
2345 var handle = elem.nodeType ?
2346 jQuery.data( elem, "handle" ) :
2347 (jQuery.data( elem, "__events__" ) || {}).handle;
2350 handle.apply( elem, data );
2353 var parent = elem.parentNode || elem.ownerDocument;
2355 // Trigger an inline bound script
2357 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
2358 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
2359 event.result = false;
2360 event.preventDefault();
2364 // prevent IE from throwing an error for some elements with some event types, see #3533
2365 } catch (inlineError) {}
2367 if ( !event.isPropagationStopped() && parent ) {
2368 jQuery.event.trigger( event, data, parent, true );
2370 } else if ( !event.isDefaultPrevented() ) {
2372 target = event.target,
2373 targetType = type.replace( rnamespaces, "" ),
2374 isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
2375 special = jQuery.event.special[ targetType ] || {};
2377 if ( (!special._default || special._default.call( elem, event ) === false) &&
2378 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
2381 if ( target[ targetType ] ) {
2382 // Make sure that we don't accidentally re-trigger the onFOO events
2383 old = target[ "on" + targetType ];
2386 target[ "on" + targetType ] = null;
2389 jQuery.event.triggered = true;
2390 target[ targetType ]();
2393 // prevent IE from throwing an error for some elements with some event types, see #3533
2394 } catch (triggerError) {}
2397 target[ "on" + targetType ] = old;
2400 jQuery.event.triggered = false;
2405 handle: function( event ) {
2406 var all, handlers, namespaces, namespace_re, events,
2407 namespace_sort = [],
2408 args = jQuery.makeArray( arguments );
2410 event = args[0] = jQuery.event.fix( event || window.event );
2411 event.currentTarget = this;
2413 // Namespaced event handlers
2414 all = event.type.indexOf(".") < 0 && !event.exclusive;
2417 namespaces = event.type.split(".");
2418 event.type = namespaces.shift();
2419 namespace_sort = namespaces.slice(0).sort();
2420 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
2423 event.namespace = event.namespace || namespace_sort.join(".");
2425 events = jQuery.data(this, this.nodeType ? "events" : "__events__");
2427 if ( typeof events === "function" ) {
2428 events = events.events;
2431 handlers = (events || {})[ event.type ];
2433 if ( events && handlers ) {
2434 // Clone the handlers to prevent manipulation
2435 handlers = handlers.slice(0);
2437 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2438 var handleObj = handlers[ j ];
2440 // Filter the functions by class
2441 if ( all || namespace_re.test( handleObj.namespace ) ) {
2442 // Pass in a reference to the handler function itself
2443 // So that we can later remove it
2444 event.handler = handleObj.handler;
2445 event.data = handleObj.data;
2446 event.handleObj = handleObj;
2448 var ret = handleObj.handler.apply( this, args );
2450 if ( ret !== undefined ) {
2452 if ( ret === false ) {
2453 event.preventDefault();
2454 event.stopPropagation();
2458 if ( event.isImmediatePropagationStopped() ) {
2465 return event.result;
2468 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2470 fix: function( event ) {
2471 if ( event[ jQuery.expando ] ) {
2475 // store a copy of the original event object
2476 // and "clone" to set read-only properties
2477 var originalEvent = event;
2478 event = jQuery.Event( originalEvent );
2480 for ( var i = this.props.length, prop; i; ) {
2481 prop = this.props[ --i ];
2482 event[ prop ] = originalEvent[ prop ];
2485 // Fix target property, if necessary
2486 if ( !event.target ) {
2487 // Fixes #1925 where srcElement might not be defined either
2488 event.target = event.srcElement || document;
2491 // check if target is a textnode (safari)
2492 if ( event.target.nodeType === 3 ) {
2493 event.target = event.target.parentNode;
2496 // Add relatedTarget, if necessary
2497 if ( !event.relatedTarget && event.fromElement ) {
2498 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2501 // Calculate pageX/Y if missing and clientX/Y available
2502 if ( event.pageX == null && event.clientX != null ) {
2503 var doc = document.documentElement,
2504 body = document.body;
2506 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2507 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
2510 // Add which for key events
2511 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2512 event.which = event.charCode != null ? event.charCode : event.keyCode;
2515 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2516 if ( !event.metaKey && event.ctrlKey ) {
2517 event.metaKey = event.ctrlKey;
2520 // Add which for click: 1 === left; 2 === middle; 3 === right
2521 // Note: button is not normalized, so don't use it
2522 if ( !event.which && event.button !== undefined ) {
2523 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2529 // Deprecated, use jQuery.guid instead
2532 // Deprecated, use jQuery.proxy instead
2533 proxy: jQuery.proxy,
2537 // Make sure the ready event is setup
2538 setup: jQuery.bindReady,
2539 teardown: jQuery.noop
2543 add: function( handleObj ) {
2544 jQuery.event.add( this,
2545 liveConvert( handleObj.origType, handleObj.selector ),
2546 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
2549 remove: function( handleObj ) {
2550 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
2555 setup: function( data, namespaces, eventHandle ) {
2556 // We only want to do this special case on windows
2557 if ( jQuery.isWindow( this ) ) {
2558 this.onbeforeunload = eventHandle;
2562 teardown: function( namespaces, eventHandle ) {
2563 if ( this.onbeforeunload === eventHandle ) {
2564 this.onbeforeunload = null;
2571 jQuery.removeEvent = document.removeEventListener ?
2572 function( elem, type, handle ) {
2573 if ( elem.removeEventListener ) {
2574 elem.removeEventListener( type, handle, false );
2577 function( elem, type, handle ) {
2578 if ( elem.detachEvent ) {
2579 elem.detachEvent( "on" + type, handle );
2583 jQuery.Event = function( src ) {
2584 // Allow instantiation without the 'new' keyword
2585 if ( !this.preventDefault ) {
2586 return new jQuery.Event( src );
2590 if ( src && src.type ) {
2591 this.originalEvent = src;
2592 this.type = src.type;
2594 // Events bubbling up the document may have been marked as prevented
2595 // by a handler lower down the tree; reflect the correct value.
2596 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
2597 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
2604 // timeStamp is buggy for some events on Firefox(#3843)
2605 // So we won't rely on the native value
2606 this.timeStamp = jQuery.now();
2609 this[ jQuery.expando ] = true;
2612 function returnFalse() {
2615 function returnTrue() {
2619 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2620 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2621 jQuery.Event.prototype = {
2622 preventDefault: function() {
2623 this.isDefaultPrevented = returnTrue;
2625 var e = this.originalEvent;
2630 // if preventDefault exists run it on the original event
2631 if ( e.preventDefault ) {
2634 // otherwise set the returnValue property of the original event to false (IE)
2636 e.returnValue = false;
2639 stopPropagation: function() {
2640 this.isPropagationStopped = returnTrue;
2642 var e = this.originalEvent;
2646 // if stopPropagation exists run it on the original event
2647 if ( e.stopPropagation ) {
2648 e.stopPropagation();
2650 // otherwise set the cancelBubble property of the original event to true (IE)
2651 e.cancelBubble = true;
2653 stopImmediatePropagation: function() {
2654 this.isImmediatePropagationStopped = returnTrue;
2655 this.stopPropagation();
2657 isDefaultPrevented: returnFalse,
2658 isPropagationStopped: returnFalse,
2659 isImmediatePropagationStopped: returnFalse
2662 // Checks if an event happened on an element within another element
2663 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2664 var withinElement = function( event ) {
2665 // Check if mouse(over|out) are still within the same parent element
2666 var parent = event.relatedTarget;
2668 // Firefox sometimes assigns relatedTarget a XUL element
2669 // which we cannot access the parentNode property of
2671 // Traverse up the tree
2672 while ( parent && parent !== this ) {
2673 parent = parent.parentNode;
2676 if ( parent !== this ) {
2677 // set the correct event type
2678 event.type = event.data;
2680 // handle event if we actually just moused on to a non sub-element
2681 jQuery.event.handle.apply( this, arguments );
2684 // assuming we've left the element since we most likely mousedover a xul element
2688 // In case of event delegation, we only need to rename the event.type,
2689 // liveHandler will take care of the rest.
2690 delegate = function( event ) {
2691 event.type = event.data;
2692 jQuery.event.handle.apply( this, arguments );
2695 // Create mouseenter and mouseleave events
2697 mouseenter: "mouseover",
2698 mouseleave: "mouseout"
2699 }, function( orig, fix ) {
2700 jQuery.event.special[ orig ] = {
2701 setup: function( data ) {
2702 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2704 teardown: function( data ) {
2705 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2710 // submit delegation
2711 if ( !jQuery.support.submitBubbles ) {
2713 jQuery.event.special.submit = {
2714 setup: function( data, namespaces ) {
2715 if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) {
2716 jQuery.event.add(this, "click.specialSubmit", function( e ) {
2717 var elem = e.target,
2720 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2721 e.liveFired = undefined;
2722 return trigger( "submit", this, arguments );
2726 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2727 var elem = e.target,
2730 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2731 e.liveFired = undefined;
2732 return trigger( "submit", this, arguments );
2741 teardown: function( namespaces ) {
2742 jQuery.event.remove( this, ".specialSubmit" );
2748 // change delegation, happens here so we have bind.
2749 if ( !jQuery.support.changeBubbles ) {
2753 getVal = function( elem ) {
2754 var type = elem.type, val = elem.value;
2756 if ( type === "radio" || type === "checkbox" ) {
2759 } else if ( type === "select-multiple" ) {
2760 val = elem.selectedIndex > -1 ?
2761 jQuery.map( elem.options, function( elem ) {
2762 return elem.selected;
2766 } else if ( elem.nodeName.toLowerCase() === "select" ) {
2767 val = elem.selectedIndex;
2773 testChange = function testChange( e ) {
2774 var elem = e.target, data, val;
2776 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
2780 data = jQuery.data( elem, "_change_data" );
2783 // the current data will be also retrieved by beforeactivate
2784 if ( e.type !== "focusout" || elem.type !== "radio" ) {
2785 jQuery.data( elem, "_change_data", val );
2788 if ( data === undefined || val === data ) {
2792 if ( data != null || val ) {
2794 e.liveFired = undefined;
2795 return jQuery.event.trigger( e, arguments[1], elem );
2799 jQuery.event.special.change = {
2801 focusout: testChange,
2803 beforedeactivate: testChange,
2805 click: function( e ) {
2806 var elem = e.target, type = elem.type;
2808 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2809 return testChange.call( this, e );
2813 // Change has to be called before submit
2814 // Keydown will be called before keypress, which is used in submit-event delegation
2815 keydown: function( e ) {
2816 var elem = e.target, type = elem.type;
2818 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2819 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2820 type === "select-multiple" ) {
2821 return testChange.call( this, e );
2825 // Beforeactivate happens also before the previous element is blurred
2826 // with this event you can't trigger a change event, but you can store
2828 beforeactivate: function( e ) {
2829 var elem = e.target;
2830 jQuery.data( elem, "_change_data", getVal(elem) );
2834 setup: function( data, namespaces ) {
2835 if ( this.type === "file" ) {
2839 for ( var type in changeFilters ) {
2840 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
2843 return rformElems.test( this.nodeName );
2846 teardown: function( namespaces ) {
2847 jQuery.event.remove( this, ".specialChange" );
2849 return rformElems.test( this.nodeName );
2853 changeFilters = jQuery.event.special.change.filters;
2855 // Handle when the input is .focus()'d
2856 changeFilters.focus = changeFilters.beforeactivate;
2859 function trigger( type, elem, args ) {
2860 args[0].type = type;
2861 return jQuery.event.handle.apply( elem, args );
2864 // Create "bubbling" focus and blur events
2865 if ( document.addEventListener ) {
2866 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2867 jQuery.event.special[ fix ] = {
2869 if ( focusCounts[fix]++ === 0 ) {
2870 document.addEventListener( orig, handler, true );
2873 teardown: function() {
2874 if ( --focusCounts[fix] === 0 ) {
2875 document.removeEventListener( orig, handler, true );
2880 function handler( e ) {
2881 e = jQuery.event.fix( e );
2883 return jQuery.event.trigger( e, null, e.target );
2888 jQuery.each(["bind", "one"], function( i, name ) {
2889 jQuery.fn[ name ] = function( type, data, fn ) {
2890 // Handle object literals
2891 if ( typeof type === "object" ) {
2892 for ( var key in type ) {
2893 this[ name ](key, data, type[key], fn);
2898 if ( jQuery.isFunction( data ) || data === false ) {
2903 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2904 jQuery( this ).unbind( event, handler );
2905 return fn.apply( this, arguments );
2908 if ( type === "unload" && name !== "one" ) {
2909 this.one( type, data, fn );
2912 for ( var i = 0, l = this.length; i < l; i++ ) {
2913 jQuery.event.add( this[i], type, handler, data );
2922 unbind: function( type, fn ) {
2923 // Handle object literals
2924 if ( typeof type === "object" && !type.preventDefault ) {
2925 for ( var key in type ) {
2926 this.unbind(key, type[key]);
2930 for ( var i = 0, l = this.length; i < l; i++ ) {
2931 jQuery.event.remove( this[i], type, fn );
2938 delegate: function( selector, types, data, fn ) {
2939 return this.live( types, data, fn, selector );
2942 undelegate: function( selector, types, fn ) {
2943 if ( arguments.length === 0 ) {
2944 return this.unbind( "live" );
2947 return this.die( types, null, fn, selector );
2951 trigger: function( type, data ) {
2952 return this.each(function() {
2953 jQuery.event.trigger( type, data, this );
2957 triggerHandler: function( type, data ) {
2959 var event = jQuery.Event( type );
2960 event.preventDefault();
2961 event.stopPropagation();
2962 jQuery.event.trigger( event, data, this[0] );
2963 return event.result;
2967 toggle: function( fn ) {
2968 // Save reference to arguments for access in closure
2969 var args = arguments,
2972 // link all the functions, so any of them can unbind this click handler
2973 while ( i < args.length ) {
2974 jQuery.proxy( fn, args[ i++ ] );
2977 return this.click( jQuery.proxy( fn, function( event ) {
2978 // Figure out which function to execute
2979 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2980 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2982 // Make sure that clicks stop
2983 event.preventDefault();
2985 // and execute the function
2986 return args[ lastToggle ].apply( this, arguments ) || false;
2990 hover: function( fnOver, fnOut ) {
2991 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2998 mouseenter: "mouseover",
2999 mouseleave: "mouseout"
3002 jQuery.each(["live", "die"], function( i, name ) {
3003 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3004 var type, i = 0, match, namespaces, preType,
3005 selector = origSelector || this.selector,
3006 context = origSelector ? this : jQuery( this.context );
3008 if ( typeof types === "object" && !types.preventDefault ) {
3009 for ( var key in types ) {
3010 context[ name ]( key, data, types[key], selector );
3016 if ( jQuery.isFunction( data ) ) {
3021 types = (types || "").split(" ");
3023 while ( (type = types[ i++ ]) != null ) {
3024 match = rnamespaces.exec( type );
3028 namespaces = match[0];
3029 type = type.replace( rnamespaces, "" );
3032 if ( type === "hover" ) {
3033 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3039 if ( type === "focus" || type === "blur" ) {
3040 types.push( liveMap[ type ] + namespaces );
3041 type = type + namespaces;
3044 type = (liveMap[ type ] || type) + namespaces;
3047 if ( name === "live" ) {
3048 // bind live handler
3049 for ( var j = 0, l = context.length; j < l; j++ ) {
3050 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3051 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3055 // unbind live handler
3056 context.unbind( "live." + liveConvert( type, selector ), fn );
3064 function liveHandler( event ) {
3065 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3068 events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
3070 if ( typeof events === "function" ) {
3071 events = events.events;
3074 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3075 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3079 if ( event.namespace ) {
3080 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3083 event.liveFired = this;
3085 var live = events.live.slice(0);
3087 for ( j = 0; j < live.length; j++ ) {
3088 handleObj = live[j];
3090 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3091 selectors.push( handleObj.selector );
3094 live.splice( j--, 1 );
3098 match = jQuery( event.target ).closest( selectors, event.currentTarget );
3100 for ( i = 0, l = match.length; i < l; i++ ) {
3103 for ( j = 0; j < live.length; j++ ) {
3104 handleObj = live[j];
3106 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
3110 // Those two events require additional checking
3111 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3112 event.type = handleObj.preType;
3113 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3116 if ( !related || related !== elem ) {
3117 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3123 for ( i = 0, l = elems.length; i < l; i++ ) {
3126 if ( maxLevel && match.level > maxLevel ) {
3130 event.currentTarget = match.elem;
3131 event.data = match.handleObj.data;
3132 event.handleObj = match.handleObj;
3134 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3136 if ( ret === false || event.isPropagationStopped() ) {
3137 maxLevel = match.level;
3139 if ( ret === false ) {
3142 if ( event.isImmediatePropagationStopped() ) {
3151 function liveConvert( type, selector ) {
3152 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
3155 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3156 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3157 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3159 // Handle event binding
3160 jQuery.fn[ name ] = function( data, fn ) {
3166 return arguments.length > 0 ?
3167 this.bind( name, data, fn ) :
3168 this.trigger( name );
3171 if ( jQuery.attrFn ) {
3172 jQuery.attrFn[ name ] = true;
3178 * Sizzle CSS Selector Engine - v1.0
3179 * Copyright 2009, The Dojo Foundation
3180 * Released under the MIT, BSD, and GPL Licenses.
3181 * More information: http://sizzlejs.com/
3185 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3187 toString = Object.prototype.toString,
3188 hasDuplicate = false,
3189 baseHasDuplicate = true;
3191 // Here we check if the JavaScript engine is using some sort of
3192 // optimization where it does not always call our comparision
3193 // function. If that is the case, discard the hasDuplicate value.
3194 // Thus far that includes Google Chrome.
3195 [0, 0].sort(function() {
3196 baseHasDuplicate = false;
3200 var Sizzle = function( selector, context, results, seed ) {
3201 results = results || [];
3202 context = context || document;
3204 var origContext = context;
3206 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3210 if ( !selector || typeof selector !== "string" ) {
3214 var m, set, checkSet, extra, ret, cur, pop, i,
3216 contextXML = Sizzle.isXML( context ),
3220 // Reset the position of the chunker regexp (start from head)
3223 m = chunker.exec( soFar );
3237 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3239 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3240 set = posProcess( parts[0] + parts[1], context );
3243 set = Expr.relative[ parts[0] ] ?
3245 Sizzle( parts.shift(), context );
3247 while ( parts.length ) {
3248 selector = parts.shift();
3250 if ( Expr.relative[ selector ] ) {
3251 selector += parts.shift();
3254 set = posProcess( selector, set );
3259 // Take a shortcut and set the context if the root selector is an ID
3260 // (but not if it'll be faster if the inner selector is an ID)
3261 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3262 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3264 ret = Sizzle.find( parts.shift(), context, contextXML );
3265 context = ret.expr ?
3266 Sizzle.filter( ret.expr, ret.set )[0] :
3272 { expr: parts.pop(), set: makeArray(seed) } :
3273 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3276 Sizzle.filter( ret.expr, ret.set ) :
3279 if ( parts.length > 0 ) {
3280 checkSet = makeArray( set );
3286 while ( parts.length ) {
3290 if ( !Expr.relative[ cur ] ) {
3296 if ( pop == null ) {
3300 Expr.relative[ cur ]( checkSet, pop, contextXML );
3304 checkSet = parts = [];
3313 Sizzle.error( cur || selector );
3316 if ( toString.call(checkSet) === "[object Array]" ) {
3318 results.push.apply( results, checkSet );
3320 } else if ( context && context.nodeType === 1 ) {
3321 for ( i = 0; checkSet[i] != null; i++ ) {
3322 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3323 results.push( set[i] );
3328 for ( i = 0; checkSet[i] != null; i++ ) {
3329 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3330 results.push( set[i] );
3336 makeArray( checkSet, results );
3340 Sizzle( extra, origContext, results, seed );
3341 Sizzle.uniqueSort( results );
3347 Sizzle.uniqueSort = function( results ) {
3349 hasDuplicate = baseHasDuplicate;
3350 results.sort( sortOrder );
3352 if ( hasDuplicate ) {
3353 for ( var i = 1; i < results.length; i++ ) {
3354 if ( results[i] === results[ i - 1 ] ) {
3355 results.splice( i--, 1 );
3364 Sizzle.matches = function( expr, set ) {
3365 return Sizzle( expr, null, null, set );
3368 Sizzle.matchesSelector = function( node, expr ) {
3369 return Sizzle( expr, null, null, [node] ).length > 0;
3372 Sizzle.find = function( expr, context, isXML ) {
3379 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3381 type = Expr.order[i];
3383 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3384 var left = match[1];
3385 match.splice( 1, 1 );
3387 if ( left.substr( left.length - 1 ) !== "\\" ) {
3388 match[1] = (match[1] || "").replace(/\\/g, "");
3389 set = Expr.find[ type ]( match, context, isXML );
3391 if ( set != null ) {
3392 expr = expr.replace( Expr.match[ type ], "" );
3400 set = context.getElementsByTagName( "*" );
3403 return { set: set, expr: expr };
3406 Sizzle.filter = function( expr, set, inplace, not ) {
3407 var match, anyFound,
3411 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3413 while ( expr && set.length ) {
3414 for ( var type in Expr.filter ) {
3415 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3417 filter = Expr.filter[ type ],
3424 if ( left.substr( left.length - 1 ) === "\\" ) {
3428 if ( curLoop === result ) {
3432 if ( Expr.preFilter[ type ] ) {
3433 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3436 anyFound = found = true;
3438 } else if ( match === true ) {
3444 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3446 found = filter( item, match, i, curLoop );
3447 var pass = not ^ !!found;
3449 if ( inplace && found != null ) {
3457 } else if ( pass ) {
3458 result.push( item );
3465 if ( found !== undefined ) {
3470 expr = expr.replace( Expr.match[ type ], "" );
3481 // Improper expression
3482 if ( expr === old ) {
3483 if ( anyFound == null ) {
3484 Sizzle.error( expr );
3497 Sizzle.error = function( msg ) {
3498 throw "Syntax error, unrecognized expression: " + msg;
3501 var Expr = Sizzle.selectors = {
3502 order: [ "ID", "NAME", "TAG" ],
3505 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3506 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3507 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3508 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
3509 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3510 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
3511 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3512 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3518 "class": "className",
3523 href: function( elem ) {
3524 return elem.getAttribute( "href" );
3529 "+": function(checkSet, part){
3530 var isPartStr = typeof part === "string",
3531 isTag = isPartStr && !/\W/.test( part ),
3532 isPartStrNotTag = isPartStr && !isTag;
3535 part = part.toLowerCase();
3538 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
3539 if ( (elem = checkSet[i]) ) {
3540 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
3542 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
3548 if ( isPartStrNotTag ) {
3549 Sizzle.filter( part, checkSet, true );
3553 ">": function( checkSet, part ) {
3555 isPartStr = typeof part === "string",
3557 l = checkSet.length;
3559 if ( isPartStr && !/\W/.test( part ) ) {
3560 part = part.toLowerCase();
3562 for ( ; i < l; i++ ) {
3566 var parent = elem.parentNode;
3567 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
3572 for ( ; i < l; i++ ) {
3576 checkSet[i] = isPartStr ?
3578 elem.parentNode === part;
3583 Sizzle.filter( part, checkSet, true );
3588 "": function(checkSet, part, isXML){
3593 if ( typeof part === "string" && !/\W/.test(part) ) {
3594 part = part.toLowerCase();
3596 checkFn = dirNodeCheck;
3599 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
3602 "~": function( checkSet, part, isXML ) {
3607 if ( typeof part === "string" && !/\W/.test( part ) ) {
3608 part = part.toLowerCase();
3610 checkFn = dirNodeCheck;
3613 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
3618 ID: function( match, context, isXML ) {
3619 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3620 var m = context.getElementById(match[1]);
3621 // Check parentNode to catch when Blackberry 4.6 returns
3622 // nodes that are no longer in the document #6963
3623 return m && m.parentNode ? [m] : [];
3627 NAME: function( match, context ) {
3628 if ( typeof context.getElementsByName !== "undefined" ) {
3630 results = context.getElementsByName( match[1] );
3632 for ( var i = 0, l = results.length; i < l; i++ ) {
3633 if ( results[i].getAttribute("name") === match[1] ) {
3634 ret.push( results[i] );
3638 return ret.length === 0 ? null : ret;
3642 TAG: function( match, context ) {
3643 return context.getElementsByTagName( match[1] );
3647 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
3648 match = " " + match[1].replace(/\\/g, "") + " ";
3654 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3656 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
3658 result.push( elem );
3661 } else if ( inplace ) {
3670 ID: function( match ) {
3671 return match[1].replace(/\\/g, "");
3674 TAG: function( match, curLoop ) {
3675 return match[1].toLowerCase();
3678 CHILD: function( match ) {
3679 if ( match[1] === "nth" ) {
3681 Sizzle.error( match[0] );
3684 match[2] = match[2].replace(/^\+|\s*/g, '');
3686 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3687 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
3688 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3689 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3691 // calculate the numbers (first)n+(last) including if they are negative
3692 match[2] = (test[1] + (test[2] || 1)) - 0;
3693 match[3] = test[3] - 0;
3695 else if ( match[2] ) {
3696 Sizzle.error( match[0] );
3699 // TODO: Move to normal caching system
3705 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
3706 var name = match[1].replace(/\\/g, "");
3708 if ( !isXML && Expr.attrMap[name] ) {
3709 match[1] = Expr.attrMap[name];
3712 if ( match[2] === "~=" ) {
3713 match[4] = " " + match[4] + " ";
3719 PSEUDO: function( match, curLoop, inplace, result, not ) {
3720 if ( match[1] === "not" ) {
3721 // If we're dealing with a complex expression, or a simple one
3722 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
3723 match[3] = Sizzle(match[3], null, null, curLoop);
3726 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
3729 result.push.apply( result, ret );
3735 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
3742 POS: function( match ) {
3743 match.unshift( true );
3750 enabled: function( elem ) {
3751 return elem.disabled === false && elem.type !== "hidden";
3754 disabled: function( elem ) {
3755 return elem.disabled === true;
3758 checked: function( elem ) {
3759 return elem.checked === true;
3762 selected: function( elem ) {
3763 // Accessing this property makes selected-by-default
3764 // options in Safari work properly
3765 elem.parentNode.selectedIndex;
3767 return elem.selected === true;
3770 parent: function( elem ) {
3771 return !!elem.firstChild;
3774 empty: function( elem ) {
3775 return !elem.firstChild;
3778 has: function( elem, i, match ) {
3779 return !!Sizzle( match[3], elem ).length;
3782 header: function( elem ) {
3783 return (/h\d/i).test( elem.nodeName );
3786 text: function( elem ) {
3787 return "text" === elem.type;
3789 radio: function( elem ) {
3790 return "radio" === elem.type;
3793 checkbox: function( elem ) {
3794 return "checkbox" === elem.type;
3797 file: function( elem ) {
3798 return "file" === elem.type;
3800 password: function( elem ) {
3801 return "password" === elem.type;
3804 submit: function( elem ) {
3805 return "submit" === elem.type;
3808 image: function( elem ) {
3809 return "image" === elem.type;
3812 reset: function( elem ) {
3813 return "reset" === elem.type;
3816 button: function( elem ) {
3817 return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3820 input: function( elem ) {
3821 return (/input|select|textarea|button/i).test( elem.nodeName );
3825 first: function( elem, i ) {
3829 last: function( elem, i, match, array ) {
3830 return i === array.length - 1;
3833 even: function( elem, i ) {
3837 odd: function( elem, i ) {
3841 lt: function( elem, i, match ) {
3842 return i < match[3] - 0;
3845 gt: function( elem, i, match ) {
3846 return i > match[3] - 0;
3849 nth: function( elem, i, match ) {
3850 return match[3] - 0 === i;
3853 eq: function( elem, i, match ) {
3854 return match[3] - 0 === i;
3858 PSEUDO: function( elem, match, i, array ) {
3859 var name = match[1],
3860 filter = Expr.filters[ name ];
3863 return filter( elem, i, match, array );
3865 } else if ( name === "contains" ) {
3866 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
3868 } else if ( name === "not" ) {
3871 for ( var j = 0, l = not.length; j < l; j++ ) {
3872 if ( not[j] === elem ) {
3880 Sizzle.error( name );
3884 CHILD: function( elem, match ) {
3885 var type = match[1],
3891 while ( (node = node.previousSibling) ) {
3892 if ( node.nodeType === 1 ) {
3897 if ( type === "first" ) {
3904 while ( (node = node.nextSibling) ) {
3905 if ( node.nodeType === 1 ) {
3913 var first = match[2],
3916 if ( first === 1 && last === 0 ) {
3920 var doneName = match[0],
3921 parent = elem.parentNode;
3923 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3926 for ( node = parent.firstChild; node; node = node.nextSibling ) {
3927 if ( node.nodeType === 1 ) {
3928 node.nodeIndex = ++count;
3932 parent.sizcache = doneName;
3935 var diff = elem.nodeIndex - last;
3937 if ( first === 0 ) {
3941 return ( diff % first === 0 && diff / first >= 0 );
3946 ID: function( elem, match ) {
3947 return elem.nodeType === 1 && elem.getAttribute("id") === match;
3950 TAG: function( elem, match ) {
3951 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3954 CLASS: function( elem, match ) {
3955 return (" " + (elem.className || elem.getAttribute("class")) + " ")
3956 .indexOf( match ) > -1;
3959 ATTR: function( elem, match ) {
3960 var name = match[1],
3961 result = Expr.attrHandle[ name ] ?
3962 Expr.attrHandle[ name ]( elem ) :
3963 elem[ name ] != null ?
3965 elem.getAttribute( name ),
3966 value = result + "",
3970 return result == null ?
3975 value.indexOf(check) >= 0 :
3977 (" " + value + " ").indexOf(check) >= 0 :
3979 value && result !== false :
3983 value.indexOf(check) === 0 :
3985 value.substr(value.length - check.length) === check :
3987 value === check || value.substr(0, check.length + 1) === check + "-" :
3991 POS: function( elem, match, i, array ) {
3992 var name = match[2],
3993 filter = Expr.setFilters[ name ];
3996 return filter( elem, i, match, array );
4002 var origPOS = Expr.match.POS,
4003 fescape = function(all, num){
4004 return "\\" + (num - 0 + 1);
4007 for ( var type in Expr.match ) {
4008 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4009 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4012 var makeArray = function( array, results ) {
4013 array = Array.prototype.slice.call( array, 0 );
4016 results.push.apply( results, array );
4023 // Perform a simple check to determine if the browser is capable of
4024 // converting a NodeList to an array using builtin methods.
4025 // Also verifies that the returned array holds DOM nodes
4026 // (which is not the case in the Blackberry browser)
4028 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4030 // Provide a fallback method if it does not work
4032 makeArray = function( array, results ) {
4034 ret = results || [];
4036 if ( toString.call(array) === "[object Array]" ) {
4037 Array.prototype.push.apply( ret, array );
4040 if ( typeof array.length === "number" ) {
4041 for ( var l = array.length; i < l; i++ ) {
4042 ret.push( array[i] );
4046 for ( ; array[i]; i++ ) {
4047 ret.push( array[i] );
4056 var sortOrder, siblingCheck;
4058 if ( document.documentElement.compareDocumentPosition ) {
4059 sortOrder = function( a, b ) {
4061 hasDuplicate = true;
4065 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4066 return a.compareDocumentPosition ? -1 : 1;
4069 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4073 sortOrder = function( a, b ) {
4081 // The nodes are identical, we can exit early
4083 hasDuplicate = true;
4086 // If the nodes are siblings (or identical) we can do a quick check
4087 } else if ( aup === bup ) {
4088 return siblingCheck( a, b );
4090 // If no parents were found then the nodes are disconnected
4091 } else if ( !aup ) {
4094 } else if ( !bup ) {
4098 // Otherwise they're somewhere else in the tree so we need
4099 // to build up a full list of the parentNodes for comparison
4102 cur = cur.parentNode;
4109 cur = cur.parentNode;
4115 // Start walking down the tree looking for a discrepancy
4116 for ( var i = 0; i < al && i < bl; i++ ) {
4117 if ( ap[i] !== bp[i] ) {
4118 return siblingCheck( ap[i], bp[i] );
4122 // We ended someplace up the tree so do a sibling check
4124 siblingCheck( a, bp[i], -1 ) :
4125 siblingCheck( ap[i], b, 1 );
4128 siblingCheck = function( a, b, ret ) {
4133 var cur = a.nextSibling;
4140 cur = cur.nextSibling;
4147 // Utility function for retreiving the text value of an array of DOM nodes
4148 Sizzle.getText = function( elems ) {
4151 for ( var i = 0; elems[i]; i++ ) {
4154 // Get the text from text nodes and CDATA nodes
4155 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4156 ret += elem.nodeValue;
4158 // Traverse everything else, except comment nodes
4159 } else if ( elem.nodeType !== 8 ) {
4160 ret += Sizzle.getText( elem.childNodes );
4167 // Check to see if the browser returns elements by name when
4168 // querying by getElementById (and provide a workaround)
4170 // We're going to inject a fake input element with a specified name
4171 var form = document.createElement("div"),
4172 id = "script" + (new Date()).getTime(),
4173 root = document.documentElement;
4175 form.innerHTML = "<a name='" + id + "'/>";
4177 // Inject it into the root element, check its status, and remove it quickly
4178 root.insertBefore( form, root.firstChild );
4180 // The workaround has to do additional checks after a getElementById
4181 // Which slows things down for other browsers (hence the branching)
4182 if ( document.getElementById( id ) ) {
4183 Expr.find.ID = function( match, context, isXML ) {
4184 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4185 var m = context.getElementById(match[1]);
4188 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4195 Expr.filter.ID = function( elem, match ) {
4196 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4198 return elem.nodeType === 1 && node && node.nodeValue === match;
4202 root.removeChild( form );
4204 // release memory in IE
4209 // Check to see if the browser returns only elements
4210 // when doing getElementsByTagName("*")
4212 // Create a fake element
4213 var div = document.createElement("div");
4214 div.appendChild( document.createComment("") );
4216 // Make sure no comments are found
4217 if ( div.getElementsByTagName("*").length > 0 ) {
4218 Expr.find.TAG = function( match, context ) {
4219 var results = context.getElementsByTagName( match[1] );
4221 // Filter out possible comments
4222 if ( match[1] === "*" ) {
4225 for ( var i = 0; results[i]; i++ ) {
4226 if ( results[i].nodeType === 1 ) {
4227 tmp.push( results[i] );
4238 // Check to see if an attribute returns normalized href attributes
4239 div.innerHTML = "<a href='#'></a>";
4241 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4242 div.firstChild.getAttribute("href") !== "#" ) {
4244 Expr.attrHandle.href = function( elem ) {
4245 return elem.getAttribute( "href", 2 );
4249 // release memory in IE
4253 if ( document.querySelectorAll ) {
4255 var oldSizzle = Sizzle,
4256 div = document.createElement("div"),
4259 div.innerHTML = "<p class='TEST'></p>";
4261 // Safari can't handle uppercase or unicode characters when
4263 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4267 Sizzle = function( query, context, extra, seed ) {
4268 context = context || document;
4270 // Make sure that attribute selectors are quoted
4271 query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4273 // Only use querySelectorAll on non-XML documents
4274 // (ID selectors don't work in non-HTML documents)
4275 if ( !seed && !Sizzle.isXML(context) ) {
4276 if ( context.nodeType === 9 ) {
4278 return makeArray( context.querySelectorAll(query), extra );
4279 } catch(qsaError) {}
4281 // qSA works strangely on Element-rooted queries
4282 // We can work around this by specifying an extra ID on the root
4283 // and working up from there (Thanks to Andrew Dupont for the technique)
4284 // IE 8 doesn't work on object elements
4285 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4286 var old = context.getAttribute( "id" ),
4288 hasParent = context.parentNode,
4289 relativeHierarchySelector = /^\s*[+~]/.test( query );
4292 context.setAttribute( "id", nid );
4294 nid = nid.replace( /'/g, "\\$&" );
4296 if ( relativeHierarchySelector && hasParent ) {
4297 context = context.parentNode;
4301 if ( !relativeHierarchySelector || hasParent ) {
4302 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4305 } catch(pseudoError) {
4308 context.removeAttribute( "id" );
4314 return oldSizzle(query, context, extra, seed);
4317 for ( var prop in oldSizzle ) {
4318 Sizzle[ prop ] = oldSizzle[ prop ];
4321 // release memory in IE
4327 var html = document.documentElement,
4328 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
4329 pseudoWorks = false;
4332 // This should fail with an exception
4333 // Gecko does not error, returns false instead
4334 matches.call( document.documentElement, "[test!='']:sizzle" );
4336 } catch( pseudoError ) {
4341 Sizzle.matchesSelector = function( node, expr ) {
4342 // Make sure that attribute selectors are quoted
4343 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4345 if ( !Sizzle.isXML( node ) ) {
4347 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4348 return matches.call( node, expr );
4353 return Sizzle(expr, null, null, [node]).length > 0;
4359 var div = document.createElement("div");
4361 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4363 // Opera can't find a second classname (in 9.6)
4364 // Also, make sure that getElementsByClassName actually exists
4365 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4369 // Safari caches class attributes, doesn't catch changes (in 3.2)
4370 div.lastChild.className = "e";
4372 if ( div.getElementsByClassName("e").length === 1 ) {
4376 Expr.order.splice(1, 0, "CLASS");
4377 Expr.find.CLASS = function( match, context, isXML ) {
4378 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4379 return context.getElementsByClassName(match[1]);
4383 // release memory in IE
4387 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4388 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4389 var elem = checkSet[i];
4397 if ( elem.sizcache === doneName ) {
4398 match = checkSet[elem.sizset];
4402 if ( elem.nodeType === 1 && !isXML ){
4403 elem.sizcache = doneName;
4407 if ( elem.nodeName.toLowerCase() === cur ) {
4415 checkSet[i] = match;
4420 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4421 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4422 var elem = checkSet[i];
4430 if ( elem.sizcache === doneName ) {
4431 match = checkSet[elem.sizset];
4435 if ( elem.nodeType === 1 ) {
4437 elem.sizcache = doneName;
4441 if ( typeof cur !== "string" ) {
4442 if ( elem === cur ) {
4447 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4456 checkSet[i] = match;
4461 if ( document.documentElement.contains ) {
4462 Sizzle.contains = function( a, b ) {
4463 return a !== b && (a.contains ? a.contains(b) : true);
4466 } else if ( document.documentElement.compareDocumentPosition ) {
4467 Sizzle.contains = function( a, b ) {
4468 return !!(a.compareDocumentPosition(b) & 16);
4472 Sizzle.contains = function() {
4477 Sizzle.isXML = function( elem ) {
4478 // documentElement is verified for cases where it doesn't yet exist
4479 // (such as loading iframes in IE - #4833)
4480 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
4482 return documentElement ? documentElement.nodeName !== "HTML" : false;
4485 var posProcess = function( selector, context ) {
4489 root = context.nodeType ? [context] : context;
4491 // Position selectors must be done after the filter
4492 // And so must :not(positional) so we move all PSEUDOs to the end
4493 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4495 selector = selector.replace( Expr.match.PSEUDO, "" );
4498 selector = Expr.relative[selector] ? selector + "*" : selector;
4500 for ( var i = 0, l = root.length; i < l; i++ ) {
4501 Sizzle( selector, root[i], tmpSet );
4504 return Sizzle.filter( later, tmpSet );
4508 jQuery.find = Sizzle;
4509 jQuery.expr = Sizzle.selectors;
4510 jQuery.expr[":"] = jQuery.expr.filters;
4511 jQuery.unique = Sizzle.uniqueSort;
4512 jQuery.text = Sizzle.getText;
4513 jQuery.isXMLDoc = Sizzle.isXML;
4514 jQuery.contains = Sizzle.contains;
4520 var runtil = /Until$/,
4521 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
4522 // Note: This RegExp should be improved, or likely pulled from Sizzle
4523 rmultiselector = /,/,
4524 isSimple = /^.[^:#\[\.,]*$/,
4525 slice = Array.prototype.slice,
4526 POS = jQuery.expr.match.POS,
4527 // methods guaranteed to produce a unique set when starting from a unique set
4528 guaranteedUnique = {
4536 find: function( selector ) {
4537 var ret = this.pushStack( "", "find", selector ),
4540 for ( var i = 0, l = this.length; i < l; i++ ) {
4541 length = ret.length;
4542 jQuery.find( selector, this[i], ret );
4545 // Make sure that the results are unique
4546 for ( var n = length; n < ret.length; n++ ) {
4547 for ( var r = 0; r < length; r++ ) {
4548 if ( ret[r] === ret[n] ) {
4560 has: function( target ) {
4561 var targets = jQuery( target );
4562 return this.filter(function() {
4563 for ( var i = 0, l = targets.length; i < l; i++ ) {
4564 if ( jQuery.contains( this, targets[i] ) ) {
4571 not: function( selector ) {
4572 return this.pushStack( winnow(this, selector, false), "not", selector);
4575 filter: function( selector ) {
4576 return this.pushStack( winnow(this, selector, true), "filter", selector );
4579 is: function( selector ) {
4580 return !!selector && jQuery.filter( selector, this ).length > 0;
4583 closest: function( selectors, context ) {
4584 var ret = [], i, l, cur = this[0];
4586 if ( jQuery.isArray( selectors ) ) {
4587 var match, selector,
4591 if ( cur && selectors.length ) {
4592 for ( i = 0, l = selectors.length; i < l; i++ ) {
4593 selector = selectors[i];
4595 if ( !matches[selector] ) {
4596 matches[selector] = jQuery.expr.match.POS.test( selector ) ?
4597 jQuery( selector, context || this.context ) :
4602 while ( cur && cur.ownerDocument && cur !== context ) {
4603 for ( selector in matches ) {
4604 match = matches[selector];
4606 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
4607 ret.push({ selector: selector, elem: cur, level: level });
4611 cur = cur.parentNode;
4619 var pos = POS.test( selectors ) ?
4620 jQuery( selectors, context || this.context ) : null;
4622 for ( i = 0, l = this.length; i < l; i++ ) {
4626 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
4631 cur = cur.parentNode;
4632 if ( !cur || !cur.ownerDocument || cur === context ) {
4639 ret = ret.length > 1 ? jQuery.unique(ret) : ret;
4641 return this.pushStack( ret, "closest", selectors );
4644 // Determine the position of an element within
4645 // the matched set of elements
4646 index: function( elem ) {
4647 if ( !elem || typeof elem === "string" ) {
4648 return jQuery.inArray( this[0],
4649 // If it receives a string, the selector is used
4650 // If it receives nothing, the siblings are used
4651 elem ? jQuery( elem ) : this.parent().children() );
4653 // Locate the position of the desired element
4654 return jQuery.inArray(
4655 // If it receives a jQuery object, the first element is used
4656 elem.jquery ? elem[0] : elem, this );
4659 add: function( selector, context ) {
4660 var set = typeof selector === "string" ?
4661 jQuery( selector, context || this.context ) :
4662 jQuery.makeArray( selector ),
4663 all = jQuery.merge( this.get(), set );
4665 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
4667 jQuery.unique( all ) );
4670 andSelf: function() {
4671 return this.add( this.prevObject );
4675 // A painfully simple check to see if an element is disconnected
4676 // from a document (should be improved, where feasible).
4677 function isDisconnected( node ) {
4678 return !node || !node.parentNode || node.parentNode.nodeType === 11;
4682 parent: function( elem ) {
4683 var parent = elem.parentNode;
4684 return parent && parent.nodeType !== 11 ? parent : null;
4686 parents: function( elem ) {
4687 return jQuery.dir( elem, "parentNode" );
4689 parentsUntil: function( elem, i, until ) {
4690 return jQuery.dir( elem, "parentNode", until );
4692 next: function( elem ) {
4693 return jQuery.nth( elem, 2, "nextSibling" );
4695 prev: function( elem ) {
4696 return jQuery.nth( elem, 2, "previousSibling" );
4698 nextAll: function( elem ) {
4699 return jQuery.dir( elem, "nextSibling" );
4701 prevAll: function( elem ) {
4702 return jQuery.dir( elem, "previousSibling" );
4704 nextUntil: function( elem, i, until ) {
4705 return jQuery.dir( elem, "nextSibling", until );
4707 prevUntil: function( elem, i, until ) {
4708 return jQuery.dir( elem, "previousSibling", until );
4710 siblings: function( elem ) {
4711 return jQuery.sibling( elem.parentNode.firstChild, elem );
4713 children: function( elem ) {
4714 return jQuery.sibling( elem.firstChild );
4716 contents: function( elem ) {
4717 return jQuery.nodeName( elem, "iframe" ) ?
4718 elem.contentDocument || elem.contentWindow.document :
4719 jQuery.makeArray( elem.childNodes );
4721 }, function( name, fn ) {
4722 jQuery.fn[ name ] = function( until, selector ) {
4723 var ret = jQuery.map( this, fn, until ),
4724 args = slice.call(arguments);
4726 if ( !runtil.test( name ) ) {
4730 if ( selector && typeof selector === "string" ) {
4731 ret = jQuery.filter( selector, ret );
4734 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
4736 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
4737 ret = ret.reverse();
4740 return this.pushStack( ret, name, args.join(",") );
4745 filter: function( expr, elems, not ) {
4747 expr = ":not(" + expr + ")";
4750 return elems.length === 1 ?
4751 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
4752 jQuery.find.matches(expr, elems);
4755 dir: function( elem, dir, until ) {
4759 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
4760 if ( cur.nodeType === 1 ) {
4761 matched.push( cur );
4768 nth: function( cur, result, dir, elem ) {
4769 result = result || 1;
4772 for ( ; cur; cur = cur[dir] ) {
4773 if ( cur.nodeType === 1 && ++num === result ) {
4781 sibling: function( n, elem ) {
4784 for ( ; n; n = n.nextSibling ) {
4785 if ( n.nodeType === 1 && n !== elem ) {
4794 // Implement the identical functionality for filter and not
4795 function winnow( elements, qualifier, keep ) {
4796 if ( jQuery.isFunction( qualifier ) ) {
4797 return jQuery.grep(elements, function( elem, i ) {
4798 var retVal = !!qualifier.call( elem, i, elem );
4799 return retVal === keep;
4802 } else if ( qualifier.nodeType ) {
4803 return jQuery.grep(elements, function( elem, i ) {
4804 return (elem === qualifier) === keep;
4807 } else if ( typeof qualifier === "string" ) {
4808 var filtered = jQuery.grep(elements, function( elem ) {
4809 return elem.nodeType === 1;
4812 if ( isSimple.test( qualifier ) ) {
4813 return jQuery.filter(qualifier, filtered, !keep);
4815 qualifier = jQuery.filter( qualifier, filtered );
4819 return jQuery.grep(elements, function( elem, i ) {
4820 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
4827 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
4828 rleadingWhitespace = /^\s+/,
4829 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
4830 rtagName = /<([\w:]+)/,
4832 rhtml = /<|&#?\w+;/,
4833 rnocache = /<(?:script|object|embed|option|style)/i,
4834 // checked="checked" or checked (html5)
4835 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4837 option: [ 1, "<select multiple='multiple'>", "</select>" ],
4838 legend: [ 1, "<fieldset>", "</fieldset>" ],
4839 thead: [ 1, "<table>", "</table>" ],
4840 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4841 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4842 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4843 area: [ 1, "<map>", "</map>" ],
4844 _default: [ 0, "", "" ]
4847 wrapMap.optgroup = wrapMap.option;
4848 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4849 wrapMap.th = wrapMap.td;
4851 // IE can't serialize <link> and <script> tags normally
4852 if ( !jQuery.support.htmlSerialize ) {
4853 wrapMap._default = [ 1, "div<div>", "</div>" ];
4857 text: function( text ) {
4858 if ( jQuery.isFunction(text) ) {
4859 return this.each(function(i) {
4860 var self = jQuery( this );
4862 self.text( text.call(this, i, self.text()) );
4866 if ( typeof text !== "object" && text !== undefined ) {
4867 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
4870 return jQuery.text( this );
4873 wrapAll: function( html ) {
4874 if ( jQuery.isFunction( html ) ) {
4875 return this.each(function(i) {
4876 jQuery(this).wrapAll( html.call(this, i) );
4881 // The elements to wrap the target around
4882 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
4884 if ( this[0].parentNode ) {
4885 wrap.insertBefore( this[0] );
4888 wrap.map(function() {
4891 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
4892 elem = elem.firstChild;
4902 wrapInner: function( html ) {
4903 if ( jQuery.isFunction( html ) ) {
4904 return this.each(function(i) {
4905 jQuery(this).wrapInner( html.call(this, i) );
4909 return this.each(function() {
4910 var self = jQuery( this ),
4911 contents = self.contents();
4913 if ( contents.length ) {
4914 contents.wrapAll( html );
4917 self.append( html );
4922 wrap: function( html ) {
4923 return this.each(function() {
4924 jQuery( this ).wrapAll( html );
4928 unwrap: function() {
4929 return this.parent().each(function() {
4930 if ( !jQuery.nodeName( this, "body" ) ) {
4931 jQuery( this ).replaceWith( this.childNodes );
4936 append: function() {
4937 return this.domManip(arguments, true, function( elem ) {
4938 if ( this.nodeType === 1 ) {
4939 this.appendChild( elem );
4944 prepend: function() {
4945 return this.domManip(arguments, true, function( elem ) {
4946 if ( this.nodeType === 1 ) {
4947 this.insertBefore( elem, this.firstChild );
4952 before: function() {
4953 if ( this[0] && this[0].parentNode ) {
4954 return this.domManip(arguments, false, function( elem ) {
4955 this.parentNode.insertBefore( elem, this );
4957 } else if ( arguments.length ) {
4958 var set = jQuery(arguments[0]);
4959 set.push.apply( set, this.toArray() );
4960 return this.pushStack( set, "before", arguments );
4965 if ( this[0] && this[0].parentNode ) {
4966 return this.domManip(arguments, false, function( elem ) {
4967 this.parentNode.insertBefore( elem, this.nextSibling );
4969 } else if ( arguments.length ) {
4970 var set = this.pushStack( this, "after", arguments );
4971 set.push.apply( set, jQuery(arguments[0]).toArray() );
4976 // keepData is for internal use only--do not document
4977 remove: function( selector, keepData ) {
4978 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4979 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
4980 if ( !keepData && elem.nodeType === 1 ) {
4981 jQuery.cleanData( elem.getElementsByTagName("*") );
4982 jQuery.cleanData( [ elem ] );
4985 if ( elem.parentNode ) {
4986 elem.parentNode.removeChild( elem );
4995 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4996 // Remove element nodes and prevent memory leaks
4997 if ( elem.nodeType === 1 ) {
4998 jQuery.cleanData( elem.getElementsByTagName("*") );
5001 // Remove any remaining nodes
5002 while ( elem.firstChild ) {
5003 elem.removeChild( elem.firstChild );
5010 clone: function( events ) {
5012 var ret = this.map(function() {
5013 var clone = this.cloneNode(true);
5014 if ( !jQuery.support.noCloneEvent && (this.nodeType === 1 || this.nodeType === 11) && !jQuery.isXMLDoc(this) ) {
5015 // IE copies events bound via attachEvent when using cloneNode.
5016 // Calling detachEvent on the clone will also remove the events
5017 // from the original. In order to get around this, we use some
5018 // proprietary methods to clear the events. Thanks to MooTools
5019 // guys for this hotness.
5021 // Using Sizzle here is crazy slow, so we use getElementsByTagName
5023 var srcElements = this.getElementsByTagName("*"),
5024 destElements = clone.getElementsByTagName("*");
5026 // Weird iteration because IE will replace the length property
5027 // with an element if you are cloning the body and one of the
5028 // elements on the page has a name or id of "length"
5029 for ( var i = 0; srcElements[i]; ++i ) {
5030 cloneFixAttributes( srcElements[i], destElements[i] );
5033 cloneFixAttributes( this, clone );
5039 // Copy the events from the original to the clone
5040 if ( events === true ) {
5041 cloneCopyEvent( this, ret );
5042 cloneCopyEvent( this.find("*"), ret.find("*") );
5045 // Return the cloned set
5049 html: function( value ) {
5050 if ( value === undefined ) {
5051 return this[0] && this[0].nodeType === 1 ?
5052 this[0].innerHTML.replace(rinlinejQuery, "") :
5055 // See if we can take a shortcut and just use innerHTML
5056 } else if ( typeof value === "string" && !rnocache.test( value ) &&
5057 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5058 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5060 value = value.replace(rxhtmlTag, "<$1></$2>");
5063 for ( var i = 0, l = this.length; i < l; i++ ) {
5064 // Remove element nodes and prevent memory leaks
5065 if ( this[i].nodeType === 1 ) {
5066 jQuery.cleanData( this[i].getElementsByTagName("*") );
5067 this[i].innerHTML = value;
5071 // If using innerHTML throws an exception, use the fallback method
5073 this.empty().append( value );
5076 } else if ( jQuery.isFunction( value ) ) {
5077 this.each(function(i){
5078 var self = jQuery( this );
5080 self.html( value.call(this, i, self.html()) );
5084 this.empty().append( value );
5090 replaceWith: function( value ) {
5091 if ( this[0] && this[0].parentNode ) {
5092 // Make sure that the elements are removed from the DOM before they are inserted
5093 // this can help fix replacing a parent with child elements
5094 if ( jQuery.isFunction( value ) ) {
5095 return this.each(function(i) {
5096 var self = jQuery(this), old = self.html();
5097 self.replaceWith( value.call( this, i, old ) );
5101 if ( typeof value !== "string" ) {
5102 value = jQuery( value ).detach();
5105 return this.each(function() {
5106 var next = this.nextSibling,
5107 parent = this.parentNode;
5109 jQuery( this ).remove();
5112 jQuery(next).before( value );
5114 jQuery(parent).append( value );
5118 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
5122 detach: function( selector ) {
5123 return this.remove( selector, true );
5126 domManip: function( args, table, callback ) {
5127 var results, first, fragment, parent,
5131 // We can't cloneNode fragments that contain checked, in WebKit
5132 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5133 return this.each(function() {
5134 jQuery(this).domManip( args, table, callback, true );
5138 if ( jQuery.isFunction(value) ) {
5139 return this.each(function(i) {
5140 var self = jQuery(this);
5141 args[0] = value.call(this, i, table ? self.html() : undefined);
5142 self.domManip( args, table, callback );
5147 parent = value && value.parentNode;
5149 // If we're in a fragment, just use that instead of building a new one
5150 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5151 results = { fragment: parent };
5154 results = jQuery.buildFragment( args, this, scripts );
5157 fragment = results.fragment;
5159 if ( fragment.childNodes.length === 1 ) {
5160 first = fragment = fragment.firstChild;
5162 first = fragment.firstChild;
5166 table = table && jQuery.nodeName( first, "tr" );
5168 for ( var i = 0, l = this.length; i < l; i++ ) {
5171 root(this[i], first) :
5173 i > 0 || results.cacheable || this.length > 1 ?
5174 jQuery(fragment).clone(true)[0] :
5180 if ( scripts.length ) {
5181 jQuery.each( scripts, evalScript );
5189 function root( elem, cur ) {
5190 return jQuery.nodeName(elem, "table") ?
5191 (elem.getElementsByTagName("tbody")[0] ||
5192 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5196 function cloneCopyEvent(orig, ret) {
5197 ret.each(function (nodeIndex) {
5198 if ( this.nodeType !== 1 || !jQuery.hasData(orig[nodeIndex]) ) {
5202 // XXX remove for 1.5 RC or merge back in if there is actually a reason for this check that has been
5203 // unexposed by unit tests
5204 if ( this.nodeName !== (orig[nodeIndex] && orig[nodeIndex].nodeName) ) {
5205 throw "Cloned data mismatch";
5208 var oldData = jQuery.data( orig[nodeIndex] ),
5209 curData = jQuery.data( this, oldData ),
5210 events = oldData && oldData.events;
5213 delete curData.handle;
5214 curData.events = {};
5216 for ( var type in events ) {
5217 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5218 jQuery.event.add( this, type, events[ type ][ i ], events[ type ][ i ].data );
5225 function cloneFixAttributes(src, dest) {
5226 // We do not need to do anything for non-Elements
5227 if ( dest.nodeType !== 1 ) {
5231 var nodeName = dest.nodeName.toLowerCase();
5233 // clearAttributes removes the attributes, which we don't want,
5234 // but also removes the attachEvent events, which we *do* want
5235 dest.clearAttributes();
5237 // mergeAttributes, in contrast, only merges back on the
5238 // original attributes, not the events
5239 dest.mergeAttributes(src);
5241 // IE6-8 fail to clone children inside object elements that use
5242 // the proprietary classid attribute value (rather than the type
5243 // attribute) to identify the type of content to display
5244 if ( nodeName === "object" ) {
5245 dest.outerHTML = src.outerHTML;
5247 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5248 // IE6-8 fails to persist the checked state of a cloned checkbox
5249 // or radio button. Worse, IE6-7 fail to give the cloned element
5250 // a checked appearance if the defaultChecked value isn't also set
5251 if ( src.checked ) {
5252 dest.defaultChecked = dest.checked = src.checked;
5255 // IE6-7 get confused and end up setting the value of a cloned
5256 // checkbox/radio button to an empty string instead of "on"
5257 if ( dest.value !== src.value ) {
5258 dest.value = src.value;
5261 // IE6-8 fails to return the selected option to the default selected
5262 // state when cloning options
5263 } else if ( nodeName === "option" ) {
5264 dest.selected = src.defaultSelected;
5266 // IE6-8 fails to set the defaultValue to the correct value when
5267 // cloning other types of input fields
5268 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5269 dest.defaultValue = src.defaultValue;
5272 // Event data gets referenced instead of copied if the expando
5274 dest.removeAttribute( jQuery.expando );
5277 jQuery.buildFragment = function( args, nodes, scripts ) {
5278 var fragment, cacheable, cacheresults,
5279 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5281 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5282 // Cloning options loses the selected state, so don't cache them
5283 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5284 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5285 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5286 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5289 cacheresults = jQuery.fragments[ args[0] ];
5290 if ( cacheresults ) {
5291 if ( cacheresults !== 1 ) {
5292 fragment = cacheresults;
5298 fragment = doc.createDocumentFragment();
5299 jQuery.clean( args, doc, fragment, scripts );
5303 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5306 return { fragment: fragment, cacheable: cacheable };
5309 jQuery.fragments = {};
5313 prependTo: "prepend",
5314 insertBefore: "before",
5315 insertAfter: "after",
5316 replaceAll: "replaceWith"
5317 }, function( name, original ) {
5318 jQuery.fn[ name ] = function( selector ) {
5320 insert = jQuery( selector ),
5321 parent = this.length === 1 && this[0].parentNode;
5323 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5324 insert[ original ]( this[0] );
5328 for ( var i = 0, l = insert.length; i < l; i++ ) {
5329 var elems = (i > 0 ? this.clone(true) : this).get();
5330 jQuery( insert[i] )[ original ]( elems );
5331 ret = ret.concat( elems );
5334 return this.pushStack( ret, name, insert.selector );
5340 clean: function( elems, context, fragment, scripts ) {
5341 context = context || document;
5343 // !context.createElement fails in IE with an error but returns typeof 'object'
5344 if ( typeof context.createElement === "undefined" ) {
5345 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
5350 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5351 if ( typeof elem === "number" ) {
5359 // Convert html string into DOM nodes
5360 if ( typeof elem === "string" && !rhtml.test( elem ) ) {
5361 elem = context.createTextNode( elem );
5363 } else if ( typeof elem === "string" ) {
5364 // Fix "XHTML"-style tags in all browsers
5365 elem = elem.replace(rxhtmlTag, "<$1></$2>");
5367 // Trim whitespace, otherwise indexOf won't work as expected
5368 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
5369 wrap = wrapMap[ tag ] || wrapMap._default,
5371 div = context.createElement("div");
5373 // Go to html and back, then peel off extra wrappers
5374 div.innerHTML = wrap[1] + elem + wrap[2];
5376 // Move to the right depth
5378 div = div.lastChild;
5381 // Remove IE's autoinserted <tbody> from table fragments
5382 if ( !jQuery.support.tbody ) {
5384 // String was a <table>, *may* have spurious <tbody>
5385 var hasBody = rtbody.test(elem),
5386 tbody = tag === "table" && !hasBody ?
5387 div.firstChild && div.firstChild.childNodes :
5389 // String was a bare <thead> or <tfoot>
5390 wrap[1] === "<table>" && !hasBody ?
5394 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
5395 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
5396 tbody[ j ].parentNode.removeChild( tbody[ j ] );
5402 // IE completely kills leading whitespace when innerHTML is used
5403 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
5404 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
5407 elem = div.childNodes;
5410 if ( elem.nodeType ) {
5413 ret = jQuery.merge( ret, elem );
5418 for ( i = 0; ret[i]; i++ ) {
5419 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
5420 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
5423 if ( ret[i].nodeType === 1 ) {
5424 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
5426 fragment.appendChild( ret[i] );
5434 cleanData: function( elems ) {
5435 var data, id, cache = jQuery.cache,
5436 special = jQuery.event.special,
5437 deleteExpando = jQuery.support.deleteExpando;
5439 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5440 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
5444 id = elem[ jQuery.expando ];
5449 if ( data && data.events ) {
5450 for ( var type in data.events ) {
5451 if ( special[ type ] ) {
5452 jQuery.event.remove( elem, type );
5455 jQuery.removeEvent( elem, type, data.handle );
5459 // Null the DOM reference to avoid IE6/7/8 leak (#7054)
5460 if ( data.handle ) {
5461 data.handle.elem = null;
5465 if ( deleteExpando ) {
5466 delete elem[ jQuery.expando ];
5468 } else if ( elem.removeAttribute ) {
5469 elem.removeAttribute( jQuery.expando );
5478 function evalScript( i, elem ) {
5486 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
5489 if ( elem.parentNode ) {
5490 elem.parentNode.removeChild( elem );
5497 var ralpha = /alpha\([^)]*\)/i,
5498 ropacity = /opacity=([^)]*)/,
5499 rdashAlpha = /-([a-z])/ig,
5500 rupper = /([A-Z])/g,
5501 rnumpx = /^-?\d+(?:px)?$/i,
5504 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5505 cssWidth = [ "Left", "Right" ],
5506 cssHeight = [ "Top", "Bottom" ],
5512 fcamelCase = function( all, letter ) {
5513 return letter.toUpperCase();
5516 jQuery.fn.css = function( name, value ) {
5517 // Setting 'undefined' is a no-op
5518 if ( arguments.length === 2 && value === undefined ) {
5522 return jQuery.access( this, name, value, true, function( elem, name, value ) {
5523 return value !== undefined ?
5524 jQuery.style( elem, name, value ) :
5525 jQuery.css( elem, name );
5530 // Add in style property hooks for overriding the default
5531 // behavior of getting and setting a style property
5534 get: function( elem, computed ) {
5536 // We should always get a number back from opacity
5537 var ret = curCSS( elem, "opacity", "opacity" );
5538 return ret === "" ? "1" : ret;
5541 return elem.style.opacity;
5547 // Exclude the following css properties to add px
5556 // Add in properties whose names you wish to fix before
5557 // setting or getting the value
5559 // normalize float css property
5560 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
5563 // Get and set the style property on a DOM Node
5564 style: function( elem, name, value, extra ) {
5565 // Don't set styles on text and comment nodes
5566 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5570 // Make sure that we're working with the right name
5571 var ret, origName = jQuery.camelCase( name ),
5572 style = elem.style, hooks = jQuery.cssHooks[ origName ];
5574 name = jQuery.cssProps[ origName ] || origName;
5576 // Check if we're setting a value
5577 if ( value !== undefined ) {
5578 // Make sure that NaN and null values aren't set. See: #7116
5579 if ( typeof value === "number" && isNaN( value ) || value == null ) {
5583 // If a number was passed in, add 'px' to the (except for certain CSS properties)
5584 if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
5588 // If a hook was provided, use that value, otherwise just set the specified value
5589 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
5590 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
5593 style[ name ] = value;
5598 // If a hook was provided get the non-computed value from there
5599 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
5603 // Otherwise just get the value from the style object
5604 return style[ name ];
5608 css: function( elem, name, extra ) {
5609 // Make sure that we're working with the right name
5610 var ret, origName = jQuery.camelCase( name ),
5611 hooks = jQuery.cssHooks[ origName ];
5613 name = jQuery.cssProps[ origName ] || origName;
5615 // If a hook was provided get the computed value from there
5616 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
5619 // Otherwise, if a way to get the computed value exists, use that
5620 } else if ( curCSS ) {
5621 return curCSS( elem, name, origName );
5625 // A method for quickly swapping in/out CSS properties to get correct calculations
5626 swap: function( elem, options, callback ) {
5629 // Remember the old values, and insert the new ones
5630 for ( var name in options ) {
5631 old[ name ] = elem.style[ name ];
5632 elem.style[ name ] = options[ name ];
5635 callback.call( elem );
5637 // Revert the old values
5638 for ( name in options ) {
5639 elem.style[ name ] = old[ name ];
5643 camelCase: function( string ) {
5644 return string.replace( rdashAlpha, fcamelCase );
5648 // DEPRECATED, Use jQuery.css() instead
5649 jQuery.curCSS = jQuery.css;
5651 jQuery.each(["height", "width"], function( i, name ) {
5652 jQuery.cssHooks[ name ] = {
5653 get: function( elem, computed, extra ) {
5657 if ( elem.offsetWidth !== 0 ) {
5658 val = getWH( elem, name, extra );
5661 jQuery.swap( elem, cssShow, function() {
5662 val = getWH( elem, name, extra );
5667 val = curCSS( elem, name, name );
5669 if ( val === "0px" && currentStyle ) {
5670 val = currentStyle( elem, name, name );
5673 if ( val != null ) {
5674 // Should return "auto" instead of 0, use 0 for
5675 // temporary backwards-compat
5676 return val === "" || val === "auto" ? "0px" : val;
5680 if ( val < 0 || val == null ) {
5681 val = elem.style[ name ];
5683 // Should return "auto" instead of 0, use 0 for
5684 // temporary backwards-compat
5685 return val === "" || val === "auto" ? "0px" : val;
5688 return typeof val === "string" ? val : val + "px";
5692 set: function( elem, value ) {
5693 if ( rnumpx.test( value ) ) {
5694 // ignore negative width and height values #1599
5695 value = parseFloat(value);
5698 return value + "px";
5708 if ( !jQuery.support.opacity ) {
5709 jQuery.cssHooks.opacity = {
5710 get: function( elem, computed ) {
5711 // IE uses filters for opacity
5712 return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
5713 (parseFloat(RegExp.$1) / 100) + "" :
5714 computed ? "1" : "";
5717 set: function( elem, value ) {
5718 var style = elem.style;
5720 // IE has trouble with opacity if it does not have layout
5721 // Force it by setting the zoom level
5724 // Set the alpha filter to set the opacity
5725 var opacity = jQuery.isNaN(value) ?
5727 "alpha(opacity=" + value * 100 + ")",
5728 filter = style.filter || "";
5730 style.filter = ralpha.test(filter) ?
5731 filter.replace(ralpha, opacity) :
5732 style.filter + ' ' + opacity;
5737 if ( document.defaultView && document.defaultView.getComputedStyle ) {
5738 getComputedStyle = function( elem, newName, name ) {
5739 var ret, defaultView, computedStyle;
5741 name = name.replace( rupper, "-$1" ).toLowerCase();
5743 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
5747 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
5748 ret = computedStyle.getPropertyValue( name );
5749 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
5750 ret = jQuery.style( elem, name );
5758 if ( document.documentElement.currentStyle ) {
5759 currentStyle = function( elem, name ) {
5761 ret = elem.currentStyle && elem.currentStyle[ name ],
5764 // From the awesome hack by Dean Edwards
5765 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
5767 // If we're not dealing with a regular pixel number
5768 // but a number that has a weird ending, we need to convert it to pixels
5769 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
5770 // Remember the original values
5772 rsLeft = elem.runtimeStyle.left;
5774 // Put in the new values to get a computed value out
5775 elem.runtimeStyle.left = elem.currentStyle.left;
5776 style.left = name === "fontSize" ? "1em" : (ret || 0);
5777 ret = style.pixelLeft + "px";
5779 // Revert the changed values
5781 elem.runtimeStyle.left = rsLeft;
5784 return ret === "" ? "auto" : ret;
5788 curCSS = getComputedStyle || currentStyle;
5790 function getWH( elem, name, extra ) {
5791 var which = name === "width" ? cssWidth : cssHeight,
5792 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
5794 if ( extra === "border" ) {
5798 jQuery.each( which, function() {
5800 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
5803 if ( extra === "margin" ) {
5804 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
5807 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
5814 if ( jQuery.expr && jQuery.expr.filters ) {
5815 jQuery.expr.filters.hidden = function( elem ) {
5816 var width = elem.offsetWidth,
5817 height = elem.offsetHeight;
5819 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
5822 jQuery.expr.filters.visible = function( elem ) {
5823 return !jQuery.expr.filters.hidden( elem );
5833 rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL
5834 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
5835 rnoContent = /^(?:GET|HEAD)$/,
5837 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5838 rselectTextarea = /^(?:select|textarea)/i,
5839 rts = /([?&])_=[^&]*/,
5840 rurl = /^(\w+:)?\/\/([^\/?#:]+)(?::(\d+))?/,
5844 sliceFunc = Array.prototype.slice,
5846 // Keep a copy of the old load method
5847 _load = jQuery.fn.load;
5850 load: function( url, params, callback ) {
5851 if ( typeof url !== "string" && _load ) {
5852 return _load.apply( this, arguments );
5854 // Don't do a request if no elements are being requested
5855 } else if ( !this.length ) {
5859 var off = url.indexOf(" ");
5861 var selector = url.slice(off, url.length);
5862 url = url.slice(0, off);
5865 // Default to a GET request
5868 // If the second parameter was provided
5870 // If it's a function
5871 if ( jQuery.isFunction( params ) ) {
5872 // We assume that it's the callback
5876 // Otherwise, build a param string
5877 } else if ( typeof params === "object" ) {
5878 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
5885 // Request the remote document
5891 // Complete callback (responseText is used internally)
5892 complete: function( jXHR, status, responseText ) {
5893 // Store the response as specified by the jXHR object
5894 responseText = jXHR.responseText;
5895 // If successful, inject the HTML into all the matched elements
5896 if ( jXHR.isResolved() ) {
5897 // #4825: Get the actual response in case
5898 // a dataFilter is present in ajaxSettings
5899 jXHR.done(function( r ) {
5902 // See if a selector was specified
5903 self.html( selector ?
5904 // Create a dummy div to hold the results
5906 // inject the contents of the document in, removing the scripts
5907 // to avoid any 'Permission Denied' errors in IE
5908 .append(responseText.replace(rscript, ""))
5910 // Locate the specified elements
5913 // If not, just inject the full result
5918 self.each( callback, [responseText, status, jXHR] );
5926 serialize: function() {
5927 return jQuery.param(this.serializeArray());
5930 serializeArray: function() {
5931 return this.map(function(){
5932 return this.elements ? jQuery.makeArray(this.elements) : this;
5935 return this.name && !this.disabled &&
5936 (this.checked || rselectTextarea.test(this.nodeName) ||
5937 rinput.test(this.type));
5939 .map(function(i, elem){
5940 var val = jQuery(this).val();
5942 return val == null ?
5944 jQuery.isArray(val) ?
5945 jQuery.map( val, function(val, i){
5946 return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
5948 { name: elem.name, value: val.replace(rCRLF, "\r\n") };
5953 // Attach a bunch of functions for handling common AJAX events
5954 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function(i,o){
5955 jQuery.fn[o] = function(f){
5956 return this.bind(o, f);
5960 jQuery.each( [ "get", "post" ], function( i, method ) {
5961 jQuery[ method ] = function( url, data, callback, type ) {
5962 // shift arguments if data argument was omited
5963 if ( jQuery.isFunction( data ) ) {
5964 type = type || callback;
5969 return jQuery.ajax({
5981 getScript: function( url, callback ) {
5982 return jQuery.get(url, null, callback, "script");
5985 getJSON: function( url, data, callback ) {
5986 return jQuery.get(url, data, callback, "json");
5989 ajaxSetup: function( settings ) {
5990 jQuery.extend( true, jQuery.ajaxSettings, settings );
5998 contentType: "application/x-www-form-urlencoded",
6012 return new window.XMLHttpRequest();
6016 xml: "application/xml, text/xml",
6019 json: "application/json, text/javascript",
6030 // 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example)
6031 // 2) These are called:
6032 // * BEFORE asking for a transport
6033 // * AFTER param serialization (s.data is a string if s.processData is true)
6034 // 3) key is the dataType
6035 // 4) the catchall symbol "*" can be used
6036 // 5) execution will start with transport dataType and THEN continue down to "*" if needed
6039 // Transports bindings
6040 // 1) key is the dataType
6041 // 2) the catchall symbol "*" can be used
6042 // 3) selection will start with transport dataType and THEN go to "*" if needed
6045 // List of data converters
6046 // 1) key format is "source_type destination_type" (a single space in-between)
6047 // 2) the catchall symbol "*" can be used for source_type
6050 // Convert anything to text
6051 "* text": window.String,
6053 // Text to html (true = no transformation)
6056 // Evaluate text as a json expression
6057 "text json": jQuery.parseJSON,
6059 // Parse text as xml
6060 "text xml": jQuery.parseXML
6065 // (s is used internally)
6066 ajax: function( url , options , s ) {
6069 if ( arguments.length === 1 ) {
6071 url = options ? options.url : undefined;
6074 // Force options to be an object
6075 options = options || {};
6077 // Get the url if provided separately
6078 options.url = url || options.url;
6080 // Create the final options object
6081 s = jQuery.extend( true , {} , jQuery.ajaxSettings , options );
6083 // We force the original context
6084 // (plain objects used as context get extended)
6085 s.context = options.context;
6088 jQuery_lastModified = jQuery.lastModified,
6089 jQuery_etag = jQuery.etag,
6090 // Callbacks contexts
6091 callbackContext = s.context || s,
6092 globalEventContext = s.context ? jQuery( s.context ) : jQuery.event,
6094 deferred = jQuery.Deferred(),
6095 completeDeferred = jQuery._Deferred(),
6096 // Status-dependent callbacks
6097 statusCode = s.statusCode || {},
6098 // Headers (they are sent all at once)
6099 requestHeaders = {},
6101 responseHeadersString,
6107 // Cross-domain detection vars
6108 loc = document.location,
6119 // Caches the header
6120 setRequestHeader: function(name,value) {
6121 if ( state === 0 ) {
6122 requestHeaders[ name.toLowerCase() ] = value;
6128 getAllResponseHeaders: function() {
6129 return state === 2 ? responseHeadersString : null;
6132 // Builds headers hashtable if needed
6133 // (match is used internally)
6134 getResponseHeader: function( key , match ) {
6136 if ( state !== 2 ) {
6140 if ( responseHeaders === undefined ) {
6142 responseHeaders = {};
6144 if ( typeof responseHeadersString === "string" ) {
6146 while( ( match = rheaders.exec( responseHeadersString ) ) ) {
6147 responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
6151 return responseHeaders[ key.toLowerCase() ];
6154 // Cancel the request
6155 abort: function( statusText ) {
6156 if ( transport && state !== 2 ) {
6157 transport.abort( statusText || "abort" );
6158 done( 0 , statusText );
6164 // Callback for when everything is done
6165 // It is defined here because jslint complains if it is declared
6166 // at the end of the function (which would be more logical and readable)
6167 function done( status , statusText , response , headers) {
6170 if ( state === 2 ) {
6174 // State is "done" now
6178 jXHR.readyState = status ? 4 : 0;
6180 // Cache response headers
6181 responseHeadersString = headers || "";
6183 // Clear timeout if it exists
6184 if ( timeoutTimer ) {
6185 clearTimeout(timeoutTimer);
6188 var // Reference url
6190 // and ifModified status
6191 ifModified = s.ifModified,
6200 // If successful, handle type chaining
6201 if ( status >= 200 && status < 300 || status === 304 ) {
6203 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
6204 if ( s.ifModified ) {
6206 var lastModified = jXHR.getResponseHeader("Last-Modified"),
6207 etag = jXHR.getResponseHeader("Etag");
6210 jQuery_lastModified[ s.url ] = lastModified;
6213 jQuery_etag[ s.url ] = etag;
6218 if ( status === 304 ) {
6220 // Set the statusText accordingly
6221 statusText = "notmodified";
6222 // Mark as a success
6228 // Set the statusText accordingly
6229 statusText = "success";
6231 // Chain data conversions and determine the final value
6232 // (if an exception is thrown in the process, it'll be notified as an error)
6238 // Previous dataType
6240 // Conversion function
6242 // Conversion functions (when text is used in-between)
6245 // Local references to dataTypes & converters
6246 dataTypes = s.dataTypes,
6247 converters = s.converters,
6248 // DataType to responseXXX field mapping
6254 // For each dataType in the chain
6255 for( i = 0 ; i < dataTypes.length ; i++ ) {
6257 current = dataTypes[ i ];
6259 // If a responseXXX field for this dataType exists
6260 // and if it hasn't been set yet
6261 if ( responses[ current ] ) {
6263 jXHR[ "response" + responses[ current ] ] = response;
6265 responses[ current ] = 0;
6268 // If this is not the first element
6271 // Get the dataType to convert from
6272 prev = dataTypes[ i - 1 ];
6274 // If no catch-all and dataTypes are actually different
6275 if ( prev !== "*" && current !== "*" && prev !== current ) {
6277 // Get the converter
6278 conv = converters[ prev + " " + current ] ||
6279 converters[ "* " + current ];
6283 // If there is no direct converter and none of the dataTypes is text
6284 if ( ! conv && prev !== "text" && current !== "text" ) {
6285 // Try with text in-between
6286 conv1 = converters[ prev + " text" ] || converters[ "* text" ];
6287 conv2 = converters[ "text " + current ];
6288 // Revert back to a single converter
6289 // if one of the converter is an equivalence
6290 if ( conv1 === true ) {
6292 } else if ( conv2 === true ) {
6296 // If we found no converter, dispatch an error
6297 if ( ! ( conv || conv1 && conv2 ) ) {
6300 // If found converter is not an equivalence
6301 if ( conv !== true ) {
6302 // Convert with 1 or 2 converters accordingly
6303 response = conv ? conv( response ) : conv2( conv1( response ) );
6306 // If it is the first element of the chain
6307 // and we have a dataFilter
6308 } else if ( s.dataFilter ) {
6309 // Apply the dataFilter
6310 response = s.dataFilter( response , current );
6311 // Get dataTypes again in case the filter changed them
6312 dataTypes = s.dataTypes;
6317 // We have a real success
6321 // If an exception was thrown
6324 // We have a parsererror
6325 statusText = "parsererror";
6331 // if not success, mark it as an error
6334 error = statusText = statusText || "error";
6336 // Set responseText if needed
6338 jXHR.responseText = response;
6342 // Set data for the fake xhr object
6343 jXHR.status = status;
6344 jXHR.statusText = statusText;
6348 deferred.fire( callbackContext , [ success , statusText , jXHR ] );
6350 deferred.fireReject( callbackContext , [ jXHR , statusText , error ] );
6353 // Status-dependent callbacks
6354 jXHR.statusCode( statusCode );
6357 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) ,
6358 [ jXHR , s , isSuccess ? success : error ] );
6362 completeDeferred.fire( callbackContext, [ jXHR , statusText ] );
6365 globalEventContext.trigger( "ajaxComplete" , [ jXHR , s] );
6366 // Handle the global AJAX counter
6367 if ( ! --jQuery.active ) {
6368 jQuery.event.trigger( "ajaxStop" );
6374 deferred.promise( jXHR );
6375 jXHR.success = jXHR.done;
6376 jXHR.error = jXHR.fail;
6377 jXHR.complete = completeDeferred.done;
6379 // Status-dependent callbacks
6380 jXHR.statusCode = function( map ) {
6382 var resolved = jXHR.isResolved(),
6384 if ( resolved || jXHR.isRejected() ) {
6385 tmp = map[ jXHR.status ];
6387 if ( map === statusCode ) {
6388 delete statusCode[ jXHR.status ];
6390 jXHR[ resolved ? "done" : "fail" ]( tmp );
6394 statusCode[ tmp ] = [ statusCode[ tmp ] , map[ tmp ] ];
6401 // Remove hash character (#7531: and string promotion)
6402 s.url = ( "" + s.url ).replace( rhash , "" );
6404 // Uppercase the type
6405 s.type = s.type.toUpperCase();
6407 // Determine if request has content
6408 s.hasContent = ! rnoContent.test( s.type );
6410 // Extract dataTypes list
6411 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( /\s+/ );
6413 // Determine if a cross-domain request is in order
6414 if ( ! s.crossDomain ) {
6415 parts = rurl.exec( s.url.toLowerCase() );
6418 ( parts[ 1 ] && parts[ 1 ] != loc.protocol ||
6419 parts[ 2 ] != loc.hostname ||
6420 ( parts[ 3 ] || 80 ) != ( loc.port || 80 ) )
6424 // Convert data if not already a string
6425 if ( s.data && s.processData && typeof s.data != "string" ) {
6426 s.data = jQuery.param( s.data , s.traditional );
6430 transport = jQuery.ajaxPrefilter( s , options ).ajaxTransport( s );
6432 // Watch for a new set of requests
6433 if ( s.global && jQuery.active++ === 0 ) {
6434 jQuery.event.trigger( "ajaxStart" );
6437 // If no transport, we auto-abort
6438 if ( ! transport ) {
6440 done( 0 , "transport not found" );
6445 // More options handling for requests with no content
6446 if ( ! s.hasContent ) {
6448 // If data is available, append data to url
6450 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
6453 // Add anti-cache in url if needed
6454 if ( s.cache === false ) {
6456 var ts = jQuery.now(),
6457 // try replacing _= if it is there
6458 ret = s.url.replace( rts , "$1_=" + ts );
6460 // if nothing was replaced, add timestamp to the end
6461 s.url = ret + ( (ret == s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "");
6465 // Set the correct header, if data is being sent
6466 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
6467 requestHeaders[ "content-type" ] = s.contentType;
6470 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
6471 if ( s.ifModified ) {
6472 if ( jQuery_lastModified[ s.url ] ) {
6473 requestHeaders[ "if-modified-since" ] = jQuery_lastModified[ s.url ];
6475 if ( jQuery_etag[ s.url ] ) {
6476 requestHeaders[ "if-none-match" ] = jQuery_etag[ s.url ];
6480 // Set the Accepts header for the server, depending on the dataType
6481 requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
6482 s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
6485 // Check for headers option
6486 for ( i in s.headers ) {
6487 requestHeaders[ i.toLowerCase() ] = s.headers[ i ];
6490 // Allow custom headers/mimetypes and early abort
6491 if ( s.beforeSend && ( s.beforeSend.call( callbackContext , jXHR , s ) === false || state === 2 ) ) {
6493 // Abort if not done already
6494 done( 0 , "abort" );
6499 // Set state as sending
6501 jXHR.readyState = 1;
6503 // Install callbacks on deferreds
6504 for ( i in { success:1, error:1, complete:1 } ) {
6505 jXHR[ i ]( s[ i ] );
6508 // Send global event
6510 globalEventContext.trigger( "ajaxSend" , [ jXHR , s ] );
6514 if ( s.async && s.timeout > 0 ) {
6515 timeoutTimer = setTimeout(function(){
6516 jXHR.abort( "timeout" );
6522 transport.send(requestHeaders, done);
6524 // Propagate exception as error if not done
6525 if ( status === 1 ) {
6527 done(0, "error", "" + e);
6530 // Simply rethrow otherwise
6541 // Serialize an array of form elements or a set of
6542 // key/values into a query string
6543 param: function( a, traditional ) {
6545 add = function( key, value ) {
6546 // If value is a function, invoke it and return its value
6547 value = jQuery.isFunction(value) ? value() : value;
6548 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
6551 // Set traditional to true for jQuery <= 1.3.2 behavior.
6552 if ( traditional === undefined ) {
6553 traditional = jQuery.ajaxSettings.traditional;
6556 // If an array was passed in, assume that it is an array of form elements.
6557 if ( jQuery.isArray(a) || a.jquery ) {
6558 // Serialize the form elements
6559 jQuery.each( a, function() {
6560 add( this.name, this.value );
6564 // If traditional, encode the "old" way (the way 1.3.2 or older
6565 // did it), otherwise encode params recursively.
6566 for ( var prefix in a ) {
6567 buildParams( prefix, a[prefix], traditional, add );
6571 // Return the resulting serialization
6572 return s.join("&").replace(r20, "+");
6576 function buildParams( prefix, obj, traditional, add ) {
6577 if ( jQuery.isArray(obj) && obj.length ) {
6578 // Serialize array item.
6579 jQuery.each( obj, function( i, v ) {
6580 if ( traditional || rbracket.test( prefix ) ) {
6581 // Treat each array item as a scalar.
6585 // If array item is non-scalar (array or object), encode its
6586 // numeric index to resolve deserialization ambiguity issues.
6587 // Note that rack (as of 1.0.0) can't currently deserialize
6588 // nested arrays properly, and attempting to do so may cause
6589 // a server error. Possible fixes are to modify rack's
6590 // deserialization algorithm or to provide an option or flag
6591 // to force array serialization to be shallow.
6592 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
6596 } else if ( !traditional && obj != null && typeof obj === "object" ) {
6597 // If we see an array here, it is empty and should be treated as an empty
6599 if ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) {
6602 // Serialize object item.
6604 jQuery.each( obj, function( k, v ) {
6605 buildParams( prefix + "[" + k + "]", v, traditional, add );
6610 // Serialize scalar item.
6615 // This is still on the jQuery object... for now
6616 // Want to move this to jQuery.ajax some day
6619 // Counter for holding the number of active queries
6622 // Last-Modified header cache for next request
6628 //Execute or select from functions in a given structure of options
6629 function ajax_selectOrExecute( structure , s ) {
6631 var dataTypes = s.dataTypes,
6639 noSelect = structure !== "transports";
6641 function initSearch( dataType ) {
6643 flag = transportDataType !== dataType && ! checked[ dataType ];
6647 checked[ dataType ] = 1;
6648 transportDataType = dataType;
6649 list = s[ structure ][ dataType ];
6651 length = list ? list.length : 0 ;
6657 initSearch( dataTypes[ 0 ] );
6659 for ( i = 0 ; ( noSelect || ! selected ) && i <= length ; i++ ) {
6661 if ( i === length ) {
6667 selected = list[ i ]( s , determineDataType );
6669 // If we got redirected to another dataType
6670 // Search there (if not in progress or already tried)
6671 if ( typeof( selected ) === "string" &&
6672 initSearch( selected ) ) {
6674 dataTypes.unshift( selected );
6680 return noSelect ? jQuery : selected;
6683 // Add an element to one of the structures in ajaxSettings
6684 function ajax_addElement( structure , args ) {
6688 length = args.length,
6689 dataTypes = [ "*" ],
6699 first = jQuery.type( args[ 0 ] );
6701 if ( first === "object" ) {
6702 return ajax_selectOrExecute( structure , args[ 0 ] );
6705 structure = jQuery.ajaxSettings[ structure ];
6707 if ( first !== "function" ) {
6709 dataTypes = args[ 0 ].toLowerCase().split(/\s+/);
6710 dLength = dataTypes.length;
6715 if ( dLength && start < length ) {
6717 functors = sliceFunc.call( args , start );
6719 for( i = 0 ; i < dLength ; i++ ) {
6721 dataType = dataTypes[ i ];
6723 first = /^\+/.test( dataType );
6726 dataType = dataType.substr(1);
6729 if ( dataType !== "" ) {
6731 append = Array.prototype[ first ? "unshift" : "push" ];
6732 list = structure[ dataType ] = structure[ dataType ] || [];
6733 append.apply( list , functors );
6742 // Install prefilter & transport methods
6743 jQuery.each( [ "Prefilter" , "Transport" ] , function( _ , name ) {
6744 _ = name.toLowerCase() + "s";
6745 jQuery[ "ajax" + name ] = function() {
6746 return ajax_addElement( _ , arguments );
6750 // Utility function that handles dataType when response is received
6751 // (for those transports that can give text or xml responses)
6752 function determineDataType( s , ct , text , xml ) {
6754 var contents = s.contents,
6757 dataTypes = s.dataTypes,
6758 transportDataType = dataTypes[0],
6761 // Auto (xml, json, script or text determined given headers)
6762 if ( transportDataType === "*" ) {
6764 for ( type in contents ) {
6765 if ( ( regexp = contents[ type ] ) && regexp.test( ct ) ) {
6766 transportDataType = dataTypes[0] = type;
6772 // xml and parsed as such
6773 if ( transportDataType === "xml" &&
6775 xml.documentElement /* #4958 */ ) {
6779 // Text response was provided
6784 // If it's not really text, defer to converters
6785 if ( transportDataType !== "text" ) {
6786 dataTypes.unshift( "text" );
6795 * Create the request object; Microsoft failed to properly
6796 * implement the XMLHttpRequest in IE7 (can't request local files),
6797 * so we use the ActiveXObject when it is available
6798 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
6799 * we need a fallback.
6801 if ( window.ActiveXObject ) {
6802 jQuery.ajaxSettings.xhr = function() {
6803 if ( window.location.protocol !== "file:" ) {
6805 return new window.XMLHttpRequest();
6806 } catch( xhrError ) {}
6810 return new window.ActiveXObject("Microsoft.XMLHTTP");
6811 } catch( activeError ) {}
6815 var testXHR = jQuery.ajaxSettings.xhr();
6817 // Does this browser support XHR requests?
6818 jQuery.support.ajax = !!testXHR;
6820 // Does this browser support crossDomain XHR requests
6821 jQuery.support.cors = testXHR && "withCredentials" in testXHR;
6826 var jsc = jQuery.now(),
6827 jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i,
6828 rquery_jsonp = /\?/;
6830 // Default jsonp settings
6833 jsonpCallback: function() {
6834 return "jsonp" + jsc++;
6837 // Normalize jsonp queries
6838 // 1) put callback parameter in url or data
6839 // 2) sneakily ensure transportDataType is always jsonp for jsonp requests
6840 }).ajaxPrefilter("json jsonp", function(s, originalSettings) {
6842 if ( s.dataTypes[ 0 ] === "jsonp" ||
6843 originalSettings.jsonp ||
6844 originalSettings.jsonpCallback ||
6846 typeof(s.data) === "string" && jsre.test(s.data) ) {
6848 var jsonpCallback = s.jsonpCallback =
6849 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
6850 url = s.url.replace(jsre, "$1" + jsonpCallback + "$2"),
6851 data = s.url === url && typeof(s.data) === "string" ? s.data.replace(jsre, "$1" + jsonpCallback + "$2") : s.data;
6853 if ( url === s.url && data === s.data ) {
6854 url += (rquery_jsonp.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
6859 s.dataTypes[ 0 ] = "jsonp";
6862 // Bind transport to jsonp dataType
6863 }).ajaxTransport("jsonp", function(s) {
6865 // Put callback in place
6866 var responseContainer,
6867 jsonpCallback = s.jsonpCallback,
6868 previous = window[ jsonpCallback ];
6870 window [ jsonpCallback ] = function( response ) {
6871 responseContainer = [response];
6874 s.complete = [function() {
6876 // Set callback back to previous value
6877 window[ jsonpCallback ] = previous;
6879 // Call if it was a function and we have a response
6881 if ( responseContainer && jQuery.isFunction ( previous ) ) {
6882 window[ jsonpCallback ] ( responseContainer[0] );
6885 // else, more memory leak avoidance
6886 try{ delete window[ jsonpCallback ]; } catch(e){}
6891 // Sneakily ensure this will be handled as json
6892 s.dataTypes[ 0 ] = "json";
6894 // Use data converter to retrieve json after script execution
6895 s.converters["script json"] = function() {
6896 if ( ! responseContainer ) {
6897 jQuery.error( jsonpCallback + " was not called" );
6899 return responseContainer[ 0 ];
6902 // Delegate to script transport
6909 // Install script dataType
6913 script: "text/javascript, application/javascript"
6917 script: /javascript/
6921 "text script": jQuery.globalEval
6924 // Bind script tag hack transport
6925 }).ajaxTransport("script", function(s) {
6927 // Handle cache special case
6928 if ( s.cache === undefined ) {
6932 // This transport only deals with cross domain get requests
6933 if ( s.crossDomain && s.async && ( s.type === "GET" || ! s.data ) ) {
6938 head = document.getElementsByTagName("head")[0] || document.documentElement;
6942 send: function(_, callback) {
6944 script = document.createElement("script");
6946 script.async = "async";
6948 if ( s.scriptCharset ) {
6949 script.charset = s.scriptCharset;
6954 // Attach handlers for all browsers
6955 script.onload = script.onreadystatechange = function( _ , isAbort ) {
6957 if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) {
6959 // Handle memory leak in IE
6960 script.onload = script.onreadystatechange = null;
6962 // Remove the script
6963 if ( head && script.parentNode ) {
6964 head.removeChild( script );
6967 // Dereference the script
6970 // Callback if not abort
6972 callback( 200, "success" );
6976 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
6977 // This arises when a base node is used (#2709 and #4378).
6978 head.insertBefore( script, head.firstChild );
6993 var // Next active xhr id
6994 xhrId = jQuery.now(),
7000 xhrUnloadAbortInstalled;
7003 jQuery.ajaxTransport( function( s , determineDataType ) {
7005 // Cross domain only allowed if supported through XMLHttpRequest
7006 if ( ! s.crossDomain || jQuery.support.cors ) {
7012 send: function(headers, complete) {
7014 // #5280: we need to abort on unload or IE will keep connections alive
7015 if ( ! xhrUnloadAbortInstalled ) {
7017 xhrUnloadAbortInstalled = 1;
7019 jQuery(window).bind( "unload" , function() {
7021 // Abort all pending requests
7022 jQuery.each(xhrs, function(_, xhr) {
7023 if ( xhr.onreadystatechange ) {
7024 xhr.onreadystatechange( 1 );
7036 // Passing null username, generates a login popup on Opera (#2865)
7038 xhr.open(s.type, s.url, s.async, s.username, s.password);
7040 xhr.open(s.type, s.url, s.async);
7043 // Requested-With header
7044 // Not set for crossDomain requests with no content
7045 // (see why at http://trac.dojotoolkit.org/ticket/9486)
7046 // Won't change header if already provided
7047 if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
7048 headers["x-requested-with"] = "XMLHttpRequest";
7051 // Need an extra try/catch for cross domain requests in Firefox 3
7054 jQuery.each(headers, function(key,value) {
7055 xhr.setRequestHeader(key,value);
7060 // Do send the request
7062 xhr.send( ( s.hasContent && s.data ) || null );
7064 complete(0, "error", "" + e);
7069 callback = function( _ , isAbort ) {
7071 // Was never called and is aborted or complete
7072 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7077 // Do not keep as active anymore
7078 // and store back into pool
7080 xhr.onreadystatechange = jQuery.noop;
7081 delete xhrs[ handle ];
7087 // Abort it manually if needed
7088 if ( xhr.readyState !== 4 ) {
7094 var status = xhr.status,
7097 responseHeaders = xhr.getAllResponseHeaders();
7099 try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
7101 statusText = xhr.statusText;
7105 statusText = ""; // We normalize with Webkit giving an empty statusText
7109 // Filter status for non standard behaviours
7110 // (so many they seem to be the actual "standard")
7112 // Opera returns 0 when it should be 304
7113 // Webkit returns 0 for failing cross-domain no matter the real status
7116 ! s.crossDomain || statusText ? // Webkit, Firefox: filter out faulty cross-domain requests
7118 responseHeaders ? // Opera: filter out real aborts #6060
7124 302 // We assume 302 but could be anything cross-domain related
7128 status == 1223 ? // IE sometimes returns 1223 when it should be 204 (see #1450)
7134 // Guess response & update dataType accordingly
7138 xhr.getResponseHeader("content-type"),
7143 complete(status,statusText,response,responseHeaders);
7148 // if we're in sync mode
7149 // or it's in cache and has been retrieved directly (IE6 & IE7)
7150 // we need to manually fire the callback
7151 if ( ! s.async || xhr.readyState === 4 ) {
7157 // Add to list of active xhrs
7159 xhrs[ handle ] = xhr;
7160 xhr.onreadystatechange = callback;
7176 var elemdisplay = {},
7177 rfxtypes = /^(?:toggle|show|hide)$/,
7178 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
7181 // height animations
7182 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
7184 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
7185 // opacity animations
7190 show: function( speed, easing, callback ) {
7193 if ( speed || speed === 0 ) {
7194 return this.animate( genFx("show", 3), speed, easing, callback);
7197 for ( var i = 0, j = this.length; i < j; i++ ) {
7199 display = elem.style.display;
7201 // Reset the inline display of this element to learn if it is
7202 // being hidden by cascaded rules or not
7203 if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
7204 display = elem.style.display = "";
7207 // Set elements which have been overridden with display: none
7208 // in a stylesheet to whatever the default browser style is
7209 // for such an element
7210 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
7211 jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
7215 // Set the display of most of the elements in a second loop
7216 // to avoid the constant reflow
7217 for ( i = 0; i < j; i++ ) {
7219 display = elem.style.display;
7221 if ( display === "" || display === "none" ) {
7222 elem.style.display = jQuery.data(elem, "olddisplay") || "";
7230 hide: function( speed, easing, callback ) {
7231 if ( speed || speed === 0 ) {
7232 return this.animate( genFx("hide", 3), speed, easing, callback);
7235 for ( var i = 0, j = this.length; i < j; i++ ) {
7236 var display = jQuery.css( this[i], "display" );
7238 if ( display !== "none" && !jQuery.data( this[i], "olddisplay" ) ) {
7239 jQuery.data( this[i], "olddisplay", display );
7243 // Set the display of the elements in a second loop
7244 // to avoid the constant reflow
7245 for ( i = 0; i < j; i++ ) {
7246 this[i].style.display = "none";
7253 // Save the old toggle function
7254 _toggle: jQuery.fn.toggle,
7256 toggle: function( fn, fn2, callback ) {
7257 var bool = typeof fn === "boolean";
7259 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
7260 this._toggle.apply( this, arguments );
7262 } else if ( fn == null || bool ) {
7263 this.each(function() {
7264 var state = bool ? fn : jQuery(this).is(":hidden");
7265 jQuery(this)[ state ? "show" : "hide" ]();
7269 this.animate(genFx("toggle", 3), fn, fn2, callback);
7275 fadeTo: function( speed, to, easing, callback ) {
7276 return this.filter(":hidden").css("opacity", 0).show().end()
7277 .animate({opacity: to}, speed, easing, callback);
7280 animate: function( prop, speed, easing, callback ) {
7281 var optall = jQuery.speed(speed, easing, callback);
7283 if ( jQuery.isEmptyObject( prop ) ) {
7284 return this.each( optall.complete );
7287 return this[ optall.queue === false ? "each" : "queue" ](function() {
7288 // XXX 'this' does not always have a nodeName when running the
7291 var opt = jQuery.extend({}, optall), p,
7292 isElement = this.nodeType === 1,
7293 hidden = isElement && jQuery(this).is(":hidden"),
7297 var name = jQuery.camelCase( p );
7300 prop[ name ] = prop[ p ];
7305 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
7306 return opt.complete.call(this);
7309 if ( isElement && ( p === "height" || p === "width" ) ) {
7310 // Make sure that nothing sneaks out
7311 // Record all 3 overflow attributes because IE does not
7312 // change the overflow attribute when overflowX and
7313 // overflowY are set to the same value
7314 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
7316 // Set display property to inline-block for height/width
7317 // animations on inline elements that are having width/height
7319 if ( jQuery.css( this, "display" ) === "inline" &&
7320 jQuery.css( this, "float" ) === "none" ) {
7321 if ( !jQuery.support.inlineBlockNeedsLayout ) {
7322 this.style.display = "inline-block";
7325 var display = defaultDisplay(this.nodeName);
7327 // inline-level elements accept inline-block;
7328 // block-level elements need to be inline with layout
7329 if ( display === "inline" ) {
7330 this.style.display = "inline-block";
7333 this.style.display = "inline";
7334 this.style.zoom = 1;
7340 if ( jQuery.isArray( prop[p] ) ) {
7341 // Create (if needed) and add to specialEasing
7342 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
7343 prop[p] = prop[p][0];
7347 if ( opt.overflow != null ) {
7348 this.style.overflow = "hidden";
7351 opt.curAnim = jQuery.extend({}, prop);
7353 jQuery.each( prop, function( name, val ) {
7354 var e = new jQuery.fx( self, opt, name );
7356 if ( rfxtypes.test(val) ) {
7357 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
7360 var parts = rfxnum.exec(val),
7361 start = e.cur() || 0;
7364 var end = parseFloat( parts[2] ),
7365 unit = parts[3] || "px";
7367 // We need to compute starting value
7368 if ( unit !== "px" ) {
7369 jQuery.style( self, name, (end || 1) + unit);
7370 start = ((end || 1) / e.cur()) * start;
7371 jQuery.style( self, name, start + unit);
7374 // If a +=/-= token was provided, we're doing a relative animation
7376 end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
7379 e.custom( start, end, unit );
7382 e.custom( start, val, "" );
7387 // For JS strict compliance
7392 stop: function( clearQueue, gotoEnd ) {
7393 var timers = jQuery.timers;
7399 this.each(function() {
7400 // go in reverse order so anything added to the queue during the loop is ignored
7401 for ( var i = timers.length - 1; i >= 0; i-- ) {
7402 if ( timers[i].elem === this ) {
7404 // force the next step to be the last
7408 timers.splice(i, 1);
7413 // start the next in the queue if the last step wasn't forced
7423 function genFx( type, num ) {
7426 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
7433 // Generate shortcuts for custom animations
7435 slideDown: genFx("show", 1),
7436 slideUp: genFx("hide", 1),
7437 slideToggle: genFx("toggle", 1),
7438 fadeIn: { opacity: "show" },
7439 fadeOut: { opacity: "hide" },
7440 fadeToggle: { opacity: "toggle" }
7441 }, function( name, props ) {
7442 jQuery.fn[ name ] = function( speed, easing, callback ) {
7443 return this.animate( props, speed, easing, callback );
7448 speed: function( speed, easing, fn ) {
7449 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
7450 complete: fn || !fn && easing ||
7451 jQuery.isFunction( speed ) && speed,
7453 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
7456 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7457 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
7460 opt.old = opt.complete;
7461 opt.complete = function() {
7462 if ( opt.queue !== false ) {
7463 jQuery(this).dequeue();
7465 if ( jQuery.isFunction( opt.old ) ) {
7466 opt.old.call( this );
7474 linear: function( p, n, firstNum, diff ) {
7475 return firstNum + diff * p;
7477 swing: function( p, n, firstNum, diff ) {
7478 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
7484 fx: function( elem, options, prop ) {
7485 this.options = options;
7489 if ( !options.orig ) {
7496 jQuery.fx.prototype = {
7497 // Simple function for setting a style value
7498 update: function() {
7499 if ( this.options.step ) {
7500 this.options.step.call( this.elem, this.now, this );
7503 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
7506 // Get the current size
7508 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
7509 return this.elem[ this.prop ];
7512 var r = parseFloat( jQuery.css( this.elem, this.prop ) );
7516 // Start an animation from one number to another
7517 custom: function( from, to, unit ) {
7521 this.startTime = jQuery.now();
7524 this.unit = unit || this.unit || "px";
7525 this.now = this.start;
7526 this.pos = this.state = 0;
7528 function t( gotoEnd ) {
7529 return self.step(gotoEnd);
7534 if ( t() && jQuery.timers.push(t) && !timerId ) {
7535 timerId = setInterval(fx.tick, fx.interval);
7539 // Simple 'show' function
7541 // Remember where we started, so that we can go back to it later
7542 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
7543 this.options.show = true;
7545 // Begin the animation
7546 // Make sure that we start at a small width/height to avoid any
7548 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
7550 // Start by showing the element
7551 jQuery( this.elem ).show();
7554 // Simple 'hide' function
7556 // Remember where we started, so that we can go back to it later
7557 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
7558 this.options.hide = true;
7560 // Begin the animation
7561 this.custom(this.cur(), 0);
7564 // Each step of an animation
7565 step: function( gotoEnd ) {
7566 var t = jQuery.now(), done = true;
7568 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
7569 this.now = this.end;
7570 this.pos = this.state = 1;
7573 this.options.curAnim[ this.prop ] = true;
7575 for ( var i in this.options.curAnim ) {
7576 if ( this.options.curAnim[i] !== true ) {
7582 // Reset the overflow
7583 if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
7584 var elem = this.elem,
7585 options = this.options;
7587 jQuery.each( [ "", "X", "Y" ], function (index, value) {
7588 elem.style[ "overflow" + value ] = options.overflow[index];
7592 // Hide the element if the "hide" operation was done
7593 if ( this.options.hide ) {
7594 jQuery(this.elem).hide();
7597 // Reset the properties, if the item has been hidden or shown
7598 if ( this.options.hide || this.options.show ) {
7599 for ( var p in this.options.curAnim ) {
7600 jQuery.style( this.elem, p, this.options.orig[p] );
7604 // Execute the complete function
7605 this.options.complete.call( this.elem );
7611 var n = t - this.startTime;
7612 this.state = n / this.options.duration;
7614 // Perform the easing function, defaults to swing
7615 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
7616 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
7617 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
7618 this.now = this.start + ((this.end - this.start) * this.pos);
7620 // Perform the next step of the animation
7628 jQuery.extend( jQuery.fx, {
7630 var timers = jQuery.timers;
7632 for ( var i = 0; i < timers.length; i++ ) {
7633 if ( !timers[i]() ) {
7634 timers.splice(i--, 1);
7638 if ( !timers.length ) {
7646 clearInterval( timerId );
7658 opacity: function( fx ) {
7659 jQuery.style( fx.elem, "opacity", fx.now );
7662 _default: function( fx ) {
7663 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
7664 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
7666 fx.elem[ fx.prop ] = fx.now;
7672 if ( jQuery.expr && jQuery.expr.filters ) {
7673 jQuery.expr.filters.animated = function( elem ) {
7674 return jQuery.grep(jQuery.timers, function( fn ) {
7675 return elem === fn.elem;
7680 function defaultDisplay( nodeName ) {
7681 if ( !elemdisplay[ nodeName ] ) {
7682 var elem = jQuery("<" + nodeName + ">").appendTo("body"),
7683 display = elem.css("display");
7687 if ( display === "none" || display === "" ) {
7691 elemdisplay[ nodeName ] = display;
7694 return elemdisplay[ nodeName ];
7700 var rtable = /^t(?:able|d|h)$/i,
7701 rroot = /^(?:body|html)$/i;
7703 if ( "getBoundingClientRect" in document.documentElement ) {
7704 jQuery.fn.offset = function( options ) {
7705 var elem = this[0], box;
7708 return this.each(function( i ) {
7709 jQuery.offset.setOffset( this, options, i );
7713 if ( !elem || !elem.ownerDocument ) {
7717 if ( elem === elem.ownerDocument.body ) {
7718 return jQuery.offset.bodyOffset( elem );
7722 box = elem.getBoundingClientRect();
7725 var doc = elem.ownerDocument,
7726 docElem = doc.documentElement;
7728 // Make sure we're not dealing with a disconnected DOM node
7729 if ( !box || !jQuery.contains( docElem, elem ) ) {
7730 return box || { top: 0, left: 0 };
7733 var body = doc.body,
7734 win = getWindow(doc),
7735 clientTop = docElem.clientTop || body.clientTop || 0,
7736 clientLeft = docElem.clientLeft || body.clientLeft || 0,
7737 scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ),
7738 scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
7739 top = box.top + scrollTop - clientTop,
7740 left = box.left + scrollLeft - clientLeft;
7742 return { top: top, left: left };
7746 jQuery.fn.offset = function( options ) {
7750 return this.each(function( i ) {
7751 jQuery.offset.setOffset( this, options, i );
7755 if ( !elem || !elem.ownerDocument ) {
7759 if ( elem === elem.ownerDocument.body ) {
7760 return jQuery.offset.bodyOffset( elem );
7763 jQuery.offset.initialize();
7766 offsetParent = elem.offsetParent,
7767 prevOffsetParent = elem,
7768 doc = elem.ownerDocument,
7769 docElem = doc.documentElement,
7771 defaultView = doc.defaultView,
7772 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
7773 top = elem.offsetTop,
7774 left = elem.offsetLeft;
7776 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
7777 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
7781 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
7782 top -= elem.scrollTop;
7783 left -= elem.scrollLeft;
7785 if ( elem === offsetParent ) {
7786 top += elem.offsetTop;
7787 left += elem.offsetLeft;
7789 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
7790 top += parseFloat( computedStyle.borderTopWidth ) || 0;
7791 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
7794 prevOffsetParent = offsetParent;
7795 offsetParent = elem.offsetParent;
7798 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
7799 top += parseFloat( computedStyle.borderTopWidth ) || 0;
7800 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
7803 prevComputedStyle = computedStyle;
7806 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
7807 top += body.offsetTop;
7808 left += body.offsetLeft;
7811 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
7812 top += Math.max( docElem.scrollTop, body.scrollTop );
7813 left += Math.max( docElem.scrollLeft, body.scrollLeft );
7816 return { top: top, left: left };
7821 initialize: function() {
7822 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
7823 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>";
7825 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
7827 container.innerHTML = html;
7828 body.insertBefore( container, body.firstChild );
7829 innerDiv = container.firstChild;
7830 checkDiv = innerDiv.firstChild;
7831 td = innerDiv.nextSibling.firstChild.firstChild;
7833 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
7834 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
7836 checkDiv.style.position = "fixed";
7837 checkDiv.style.top = "20px";
7839 // safari subtracts parent border width here which is 5px
7840 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
7841 checkDiv.style.position = checkDiv.style.top = "";
7843 innerDiv.style.overflow = "hidden";
7844 innerDiv.style.position = "relative";
7846 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
7848 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
7850 body.removeChild( container );
7851 body = container = innerDiv = checkDiv = table = td = null;
7852 jQuery.offset.initialize = jQuery.noop;
7855 bodyOffset: function( body ) {
7856 var top = body.offsetTop,
7857 left = body.offsetLeft;
7859 jQuery.offset.initialize();
7861 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
7862 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
7863 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
7866 return { top: top, left: left };
7869 setOffset: function( elem, options, i ) {
7870 var position = jQuery.css( elem, "position" );
7872 // set position first, in-case top/left are set even on static elem
7873 if ( position === "static" ) {
7874 elem.style.position = "relative";
7877 var curElem = jQuery( elem ),
7878 curOffset = curElem.offset(),
7879 curCSSTop = jQuery.css( elem, "top" ),
7880 curCSSLeft = jQuery.css( elem, "left" ),
7881 calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
7882 props = {}, curPosition = {}, curTop, curLeft;
7884 // need to be able to calculate position if either top or left is auto and position is absolute
7885 if ( calculatePosition ) {
7886 curPosition = curElem.position();
7889 curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0;
7890 curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
7892 if ( jQuery.isFunction( options ) ) {
7893 options = options.call( elem, i, curOffset );
7896 if (options.top != null) {
7897 props.top = (options.top - curOffset.top) + curTop;
7899 if (options.left != null) {
7900 props.left = (options.left - curOffset.left) + curLeft;
7903 if ( "using" in options ) {
7904 options.using.call( elem, props );
7906 curElem.css( props );
7913 position: function() {
7920 // Get *real* offsetParent
7921 offsetParent = this.offsetParent(),
7923 // Get correct offsets
7924 offset = this.offset(),
7925 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
7927 // Subtract element margins
7928 // note: when an element has margin: auto the offsetLeft and marginLeft
7929 // are the same in Safari causing offset.left to incorrectly be 0
7930 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
7931 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
7933 // Add offsetParent borders
7934 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
7935 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
7937 // Subtract the two offsets
7939 top: offset.top - parentOffset.top,
7940 left: offset.left - parentOffset.left
7944 offsetParent: function() {
7945 return this.map(function() {
7946 var offsetParent = this.offsetParent || document.body;
7947 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
7948 offsetParent = offsetParent.offsetParent;
7950 return offsetParent;
7956 // Create scrollLeft and scrollTop methods
7957 jQuery.each( ["Left", "Top"], function( i, name ) {
7958 var method = "scroll" + name;
7960 jQuery.fn[ method ] = function(val) {
7961 var elem = this[0], win;
7967 if ( val !== undefined ) {
7968 // Set the scroll offset
7969 return this.each(function() {
7970 win = getWindow( this );
7974 !i ? val : jQuery(win).scrollLeft(),
7975 i ? val : jQuery(win).scrollTop()
7979 this[ method ] = val;
7983 win = getWindow( elem );
7985 // Return the scroll offset
7986 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
7987 jQuery.support.boxModel && win.document.documentElement[ method ] ||
7988 win.document.body[ method ] :
7994 function getWindow( elem ) {
7995 return jQuery.isWindow( elem ) ?
7997 elem.nodeType === 9 ?
7998 elem.defaultView || elem.parentWindow :
8005 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
8006 jQuery.each([ "Height", "Width" ], function( i, name ) {
8008 var type = name.toLowerCase();
8010 // innerHeight and innerWidth
8011 jQuery.fn["inner" + name] = function() {
8013 parseFloat( jQuery.css( this[0], type, "padding" ) ) :
8017 // outerHeight and outerWidth
8018 jQuery.fn["outer" + name] = function( margin ) {
8020 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
8024 jQuery.fn[ type ] = function( size ) {
8025 // Get window width or height
8028 return size == null ? null : this;
8031 if ( jQuery.isFunction( size ) ) {
8032 return this.each(function( i ) {
8033 var self = jQuery( this );
8034 self[ type ]( size.call( this, i, self[ type ]() ) );
8038 if ( jQuery.isWindow( elem ) ) {
8039 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
8040 return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
8041 elem.document.body[ "client" + name ];
8043 // Get document width or height
8044 } else if ( elem.nodeType === 9 ) {
8045 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
8047 elem.documentElement["client" + name],
8048 elem.body["scroll" + name], elem.documentElement["scroll" + name],
8049 elem.body["offset" + name], elem.documentElement["offset" + name]
8052 // Get or set width or height on the element
8053 } else if ( size === undefined ) {
8054 var orig = jQuery.css( elem, type ),
8055 ret = parseFloat( orig );
8057 return jQuery.isNaN( ret ) ? orig : ret;
8059 // Set the width or height on the element (default to pixels if value is unitless)
8061 return this.css( type, typeof size === "string" ? size : size + "px" );