2 * jQuery JavaScript Library v1.6.1
5 * Copyright 2011, John Resig
6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://jquery.org/license
10 * http://sizzlejs.com/
11 * Copyright 2011, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
14 * Date: Thu May 12 15:04:36 2011 -0400
16 (function( window, undefined ) {
18 // Use the correct document accordingly with window argument (sandbox)
19 var document = window.document,
20 navigator = window.navigator,
21 location = window.location;
22 var jQuery = (function() {
24 // Define a local copy of jQuery
25 var jQuery = function( selector, context ) {
26 // The jQuery object is actually just the init constructor 'enhanced'
27 return new jQuery.fn.init( selector, context, rootjQuery );
30 // Map over jQuery in case of overwrite
31 _jQuery = window.jQuery,
33 // Map over the $ in case of overwrite
36 // A central reference to the root jQuery(document)
39 // A simple way to check for HTML strings or ID strings
40 // (both of which we optimize for)
41 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
43 // Check if a string has a non-whitespace character in it
46 // Used for trimming whitespace
53 // Match a standalone tag
54 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
57 rvalidchars = /^[\],:{}\s]*$/,
58 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
59 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
60 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
63 rwebkit = /(webkit)[ \/]([\w.]+)/,
64 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
65 rmsie = /(msie) ([\w.]+)/,
66 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
68 // Keep a UserAgent string for use with jQuery.browser
69 userAgent = navigator.userAgent,
71 // For matching the engine and version of the browser
74 // The deferred used on DOM ready
77 // The ready event handler
80 // Save a reference to some core methods
81 toString = Object.prototype.toString,
82 hasOwn = Object.prototype.hasOwnProperty,
83 push = Array.prototype.push,
84 slice = Array.prototype.slice,
85 trim = String.prototype.trim,
86 indexOf = Array.prototype.indexOf,
88 // [[Class]] -> type pairs
91 jQuery.fn = jQuery.prototype = {
93 init: function( selector, context, rootjQuery ) {
94 var match, elem, ret, doc;
96 // Handle $(""), $(null), or $(undefined)
101 // Handle $(DOMElement)
102 if ( selector.nodeType ) {
103 this.context = this[0] = selector;
108 // The body element only exists once, optimize finding it
109 if ( selector === "body" && !context && document.body ) {
110 this.context = document;
111 this[0] = document.body;
112 this.selector = selector;
117 // Handle HTML strings
118 if ( typeof selector === "string" ) {
119 // Are we dealing with HTML string or an ID?
120 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
121 // Assume that strings that start and end with <> are HTML and skip the regex check
122 match = [ null, selector, null ];
125 match = quickExpr.exec( selector );
128 // Verify a match, and that no context was specified for #id
129 if ( match && (match[1] || !context) ) {
131 // HANDLE: $(html) -> $(array)
133 context = context instanceof jQuery ? context[0] : context;
134 doc = (context ? context.ownerDocument || context : document);
136 // If a single string is passed in and it's a single tag
137 // just do a createElement and skip the rest
138 ret = rsingleTag.exec( selector );
141 if ( jQuery.isPlainObject( context ) ) {
142 selector = [ document.createElement( ret[1] ) ];
143 jQuery.fn.attr.call( selector, context, true );
146 selector = [ doc.createElement( ret[1] ) ];
150 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
154 return jQuery.merge( this, selector );
158 elem = document.getElementById( match[2] );
160 // Check parentNode to catch when Blackberry 4.6 returns
161 // nodes that are no longer in the document #6963
162 if ( elem && elem.parentNode ) {
163 // Handle the case where IE and Opera return items
164 // by name instead of ID
165 if ( elem.id !== match[2] ) {
166 return rootjQuery.find( selector );
169 // Otherwise, we inject the element directly into the jQuery object
174 this.context = document;
175 this.selector = selector;
179 // HANDLE: $(expr, $(...))
180 } else if ( !context || context.jquery ) {
181 return (context || rootjQuery).find( selector );
183 // HANDLE: $(expr, context)
184 // (which is just equivalent to: $(context).find(expr)
186 return this.constructor( context ).find( selector );
189 // HANDLE: $(function)
190 // Shortcut for document ready
191 } else if ( jQuery.isFunction( selector ) ) {
192 return rootjQuery.ready( selector );
195 if (selector.selector !== undefined) {
196 this.selector = selector.selector;
197 this.context = selector.context;
200 return jQuery.makeArray( selector, this );
203 // Start with an empty selector
206 // The current version of jQuery being used
209 // The default length of a jQuery object is 0
212 // The number of elements contained in the matched element set
217 toArray: function() {
218 return slice.call( this, 0 );
221 // Get the Nth element in the matched element set OR
222 // Get the whole matched element set as a clean array
223 get: function( num ) {
226 // Return a 'clean' array
229 // Return just the object
230 ( num < 0 ? this[ this.length + num ] : this[ num ] );
233 // Take an array of elements and push it onto the stack
234 // (returning the new matched element set)
235 pushStack: function( elems, name, selector ) {
236 // Build a new jQuery matched element set
237 var ret = this.constructor();
239 if ( jQuery.isArray( elems ) ) {
240 push.apply( ret, elems );
243 jQuery.merge( ret, elems );
246 // Add the old object onto the stack (as a reference)
247 ret.prevObject = this;
249 ret.context = this.context;
251 if ( name === "find" ) {
252 ret.selector = this.selector + (this.selector ? " " : "") + selector;
254 ret.selector = this.selector + "." + name + "(" + selector + ")";
257 // Return the newly-formed element set
261 // Execute a callback for every element in the matched set.
262 // (You can seed the arguments with an array of args, but this is
263 // only used internally.)
264 each: function( callback, args ) {
265 return jQuery.each( this, callback, args );
268 ready: function( fn ) {
269 // Attach the listeners
273 readyList.done( fn );
281 this.slice( i, +i + 1 );
289 return this.eq( -1 );
293 return this.pushStack( slice.apply( this, arguments ),
294 "slice", slice.call(arguments).join(",") );
297 map: function( callback ) {
298 return this.pushStack( jQuery.map(this, function( elem, i ) {
299 return callback.call( elem, i, elem );
304 return this.prevObject || this.constructor(null);
307 // For internal use only.
308 // Behaves like an Array's method, not like a jQuery method.
314 // Give the init function the jQuery prototype for later instantiation
315 jQuery.fn.init.prototype = jQuery.fn;
317 jQuery.extend = jQuery.fn.extend = function() {
318 var options, name, src, copy, copyIsArray, clone,
319 target = arguments[0] || {},
321 length = arguments.length,
324 // Handle a deep copy situation
325 if ( typeof target === "boolean" ) {
327 target = arguments[1] || {};
328 // skip the boolean and the target
332 // Handle case when target is a string or something (possible in deep copy)
333 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
337 // extend jQuery itself if only one argument is passed
338 if ( length === i ) {
343 for ( ; i < length; i++ ) {
344 // Only deal with non-null/undefined values
345 if ( (options = arguments[ i ]) != null ) {
346 // Extend the base object
347 for ( name in options ) {
348 src = target[ name ];
349 copy = options[ name ];
351 // Prevent never-ending loop
352 if ( target === copy ) {
356 // Recurse if we're merging plain objects or arrays
357 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
360 clone = src && jQuery.isArray(src) ? src : [];
363 clone = src && jQuery.isPlainObject(src) ? src : {};
366 // Never move original objects, clone them
367 target[ name ] = jQuery.extend( deep, clone, copy );
369 // Don't bring in undefined values
370 } else if ( copy !== undefined ) {
371 target[ name ] = copy;
377 // Return the modified object
382 noConflict: function( deep ) {
383 if ( window.$ === jQuery ) {
387 if ( deep && window.jQuery === jQuery ) {
388 window.jQuery = _jQuery;
394 // Is the DOM ready to be used? Set to true once it occurs.
397 // A counter to track how many items to wait for before
398 // the ready event fires. See #6781
401 // Hold (or release) the ready event
402 holdReady: function( hold ) {
406 jQuery.ready( true );
410 // Handle when the DOM is ready
411 ready: function( wait ) {
412 // Either a released hold or an DOMready/load event and not yet ready
413 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
414 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
415 if ( !document.body ) {
416 return setTimeout( jQuery.ready, 1 );
419 // Remember that the DOM is ready
420 jQuery.isReady = true;
422 // If a normal DOM Ready event fired, decrement, and wait if need be
423 if ( wait !== true && --jQuery.readyWait > 0 ) {
427 // If there are functions bound, to execute
428 readyList.resolveWith( document, [ jQuery ] );
430 // Trigger any bound ready events
431 if ( jQuery.fn.trigger ) {
432 jQuery( document ).trigger( "ready" ).unbind( "ready" );
437 bindReady: function() {
442 readyList = jQuery._Deferred();
444 // Catch cases where $(document).ready() is called after the
445 // browser event has already occurred.
446 if ( document.readyState === "complete" ) {
447 // Handle it asynchronously to allow scripts the opportunity to delay ready
448 return setTimeout( jQuery.ready, 1 );
451 // Mozilla, Opera and webkit nightlies currently support this event
452 if ( document.addEventListener ) {
453 // Use the handy event callback
454 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
456 // A fallback to window.onload, that will always work
457 window.addEventListener( "load", jQuery.ready, false );
459 // If IE event model is used
460 } else if ( document.attachEvent ) {
461 // ensure firing before onload,
462 // maybe late but safe also for iframes
463 document.attachEvent( "onreadystatechange", DOMContentLoaded );
465 // A fallback to window.onload, that will always work
466 window.attachEvent( "onload", jQuery.ready );
468 // If IE and not a frame
469 // continually check to see if the document is ready
470 var toplevel = false;
473 toplevel = window.frameElement == null;
476 if ( document.documentElement.doScroll && toplevel ) {
482 // See test/unit/core.js for details concerning isFunction.
483 // Since version 1.3, DOM methods and functions like alert
484 // aren't supported. They return false on IE (#2968).
485 isFunction: function( obj ) {
486 return jQuery.type(obj) === "function";
489 isArray: Array.isArray || function( obj ) {
490 return jQuery.type(obj) === "array";
493 // A crude way of determining if an object is a window
494 isWindow: function( obj ) {
495 return obj && typeof obj === "object" && "setInterval" in obj;
498 isNaN: function( obj ) {
499 return obj == null || !rdigit.test( obj ) || isNaN( obj );
502 type: function( obj ) {
505 class2type[ toString.call(obj) ] || "object";
508 isPlainObject: function( obj ) {
509 // Must be an Object.
510 // Because of IE, we also have to check the presence of the constructor property.
511 // Make sure that DOM nodes and window objects don't pass through, as well
512 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
516 // Not own constructor property must be Object
517 if ( obj.constructor &&
518 !hasOwn.call(obj, "constructor") &&
519 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
523 // Own properties are enumerated firstly, so to speed up,
524 // if last one is own, then all properties are own.
527 for ( key in obj ) {}
529 return key === undefined || hasOwn.call( obj, key );
532 isEmptyObject: function( obj ) {
533 for ( var name in obj ) {
539 error: function( msg ) {
543 parseJSON: function( data ) {
544 if ( typeof data !== "string" || !data ) {
548 // Make sure leading/trailing whitespace is removed (IE can't handle it)
549 data = jQuery.trim( data );
551 // Attempt to parse using the native JSON parser first
552 if ( window.JSON && window.JSON.parse ) {
553 return window.JSON.parse( data );
556 // Make sure the incoming data is actual JSON
557 // Logic borrowed from http://json.org/json2.js
558 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
559 .replace( rvalidtokens, "]" )
560 .replace( rvalidbraces, "")) ) {
562 return (new Function( "return " + data ))();
565 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 // Evaluates a script in a global context
593 // Workarounds based on findings by Jim Driscoll
594 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
595 globalEval: function( data ) {
596 if ( data && rnotwhite.test( data ) ) {
597 // We use execScript on Internet Explorer
598 // We use an anonymous function so that context is window
599 // rather than jQuery in Firefox
600 ( window.execScript || function( data ) {
601 window[ "eval" ].call( window, data );
606 nodeName: function( elem, name ) {
607 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
610 // args is for internal usage only
611 each: function( object, callback, args ) {
613 length = object.length,
614 isObj = length === undefined || jQuery.isFunction( object );
618 for ( name in object ) {
619 if ( callback.apply( object[ name ], args ) === false ) {
624 for ( ; i < length; ) {
625 if ( callback.apply( object[ i++ ], args ) === false ) {
631 // A special, fast, case for the most common use of each
634 for ( name in object ) {
635 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
640 for ( ; i < length; ) {
641 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
651 // Use native String.trim function wherever possible
654 return text == null ?
659 // Otherwise use our own trimming functionality
661 return text == null ?
663 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
666 // results is for internal usage only
667 makeArray: function( array, results ) {
668 var ret = results || [];
670 if ( array != null ) {
671 // The window, strings (and functions) also have 'length'
672 // The extra typeof function check is to prevent crashes
673 // in Safari 2 (See: #3039)
674 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
675 var type = jQuery.type( array );
677 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
678 push.call( ret, array );
680 jQuery.merge( ret, array );
687 inArray: function( elem, array ) {
690 return indexOf.call( array, elem );
693 for ( var i = 0, length = array.length; i < length; i++ ) {
694 if ( array[ i ] === elem ) {
702 merge: function( first, second ) {
703 var i = first.length,
706 if ( typeof second.length === "number" ) {
707 for ( var l = second.length; j < l; j++ ) {
708 first[ i++ ] = second[ j ];
712 while ( second[j] !== undefined ) {
713 first[ i++ ] = second[ j++ ];
722 grep: function( elems, callback, inv ) {
723 var ret = [], retVal;
726 // Go through the array, only saving the items
727 // that pass the validator function
728 for ( var i = 0, length = elems.length; i < length; i++ ) {
729 retVal = !!callback( elems[ i ], i );
730 if ( inv !== retVal ) {
731 ret.push( elems[ i ] );
738 // arg is for internal usage only
739 map: function( elems, callback, arg ) {
740 var value, key, ret = [],
742 length = elems.length,
743 // jquery objects are treated as arrays
744 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
746 // Go through the array, translating each of the items to their
748 for ( ; i < length; i++ ) {
749 value = callback( elems[ i ], i, arg );
751 if ( value != null ) {
752 ret[ ret.length ] = value;
756 // Go through every key on the object,
758 for ( key in elems ) {
759 value = callback( elems[ key ], key, arg );
761 if ( value != null ) {
762 ret[ ret.length ] = value;
767 // Flatten any nested arrays
768 return ret.concat.apply( [], ret );
771 // A global GUID counter for objects
774 // Bind a function to a context, optionally partially applying any
776 proxy: function( fn, context ) {
777 if ( typeof context === "string" ) {
778 var tmp = fn[ context ];
783 // Quick check to determine if target is callable, in the spec
784 // this throws a TypeError, but we will just return undefined.
785 if ( !jQuery.isFunction( fn ) ) {
790 var args = slice.call( arguments, 2 ),
792 return fn.apply( context, args.concat( slice.call( arguments ) ) );
795 // Set the guid of unique handler to the same of original handler, so it can be removed
796 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
801 // Mutifunctional method to get and set values to a collection
802 // The value/s can be optionally by executed if its a function
803 access: function( elems, key, value, exec, fn, pass ) {
804 var length = elems.length;
806 // Setting many attributes
807 if ( typeof key === "object" ) {
808 for ( var k in key ) {
809 jQuery.access( elems, k, key[k], exec, fn, value );
814 // Setting one attribute
815 if ( value !== undefined ) {
816 // Optionally, function values get executed if exec is true
817 exec = !pass && exec && jQuery.isFunction(value);
819 for ( var i = 0; i < length; i++ ) {
820 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
826 // Getting an attribute
827 return length ? fn( elems[0], key ) : undefined;
831 return (new Date()).getTime();
834 // Use of jQuery.browser is frowned upon.
835 // More details: http://docs.jquery.com/Utilities/jQuery.browser
836 uaMatch: function( ua ) {
837 ua = ua.toLowerCase();
839 var match = rwebkit.exec( ua ) ||
842 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
845 return { browser: match[1] || "", version: match[2] || "0" };
849 function jQuerySub( selector, context ) {
850 return new jQuerySub.fn.init( selector, context );
852 jQuery.extend( true, jQuerySub, this );
853 jQuerySub.superclass = this;
854 jQuerySub.fn = jQuerySub.prototype = this();
855 jQuerySub.fn.constructor = jQuerySub;
856 jQuerySub.sub = this.sub;
857 jQuerySub.fn.init = function init( selector, context ) {
858 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
859 context = jQuerySub( context );
862 return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
864 jQuerySub.fn.init.prototype = jQuerySub.fn;
865 var rootjQuerySub = jQuerySub(document);
872 // Populate the class2type map
873 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
874 class2type[ "[object " + name + "]" ] = name.toLowerCase();
877 browserMatch = jQuery.uaMatch( userAgent );
878 if ( browserMatch.browser ) {
879 jQuery.browser[ browserMatch.browser ] = true;
880 jQuery.browser.version = browserMatch.version;
883 // Deprecated, use jQuery.browser.webkit instead
884 if ( jQuery.browser.webkit ) {
885 jQuery.browser.safari = true;
888 // IE doesn't match non-breaking spaces with \s
889 if ( rnotwhite.test( "\xA0" ) ) {
890 trimLeft = /^[\s\xA0]+/;
891 trimRight = /[\s\xA0]+$/;
894 // All jQuery objects should point back to these
895 rootjQuery = jQuery(document);
897 // Cleanup functions for the document ready method
898 if ( document.addEventListener ) {
899 DOMContentLoaded = function() {
900 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
904 } else if ( document.attachEvent ) {
905 DOMContentLoaded = function() {
906 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
907 if ( document.readyState === "complete" ) {
908 document.detachEvent( "onreadystatechange", DOMContentLoaded );
914 // The DOM ready check for Internet Explorer
915 function doScrollCheck() {
916 if ( jQuery.isReady ) {
921 // If IE is used, use the trick by Diego Perini
922 // http://javascript.nwbox.com/IEContentLoaded/
923 document.documentElement.doScroll("left");
925 setTimeout( doScrollCheck, 1 );
929 // and execute any waiting functions
933 // Expose jQuery to the global object
939 var // Promise methods
940 promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
941 // Static reference to slice
942 sliceDeferred = [].slice;
945 // Create a simple deferred (one callbacks list)
946 _Deferred: function() {
947 var // callbacks list
949 // stored [ context , args ]
951 // to avoid firing when already doing so
953 // flag to know if the deferred has been cancelled
955 // the deferred itself
958 // done( f1, f2, ...)
961 var args = arguments,
971 for ( i = 0, length = args.length; i < length; i++ ) {
973 type = jQuery.type( elem );
974 if ( type === "array" ) {
975 deferred.done.apply( deferred, elem );
976 } else if ( type === "function" ) {
977 callbacks.push( elem );
981 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
987 // resolve with given context and args
988 resolveWith: function( context, args ) {
989 if ( !cancelled && !fired && !firing ) {
990 // make sure args are available (#8421)
994 while( callbacks[ 0 ] ) {
995 callbacks.shift().apply( context, args );
999 fired = [ context, args ];
1006 // resolve with this as context and given arguments
1007 resolve: function() {
1008 deferred.resolveWith( this, arguments );
1012 // Has this deferred been resolved?
1013 isResolved: function() {
1014 return !!( firing || fired );
1018 cancel: function() {
1028 // Full fledged deferred (two callbacks list)
1029 Deferred: function( func ) {
1030 var deferred = jQuery._Deferred(),
1031 failDeferred = jQuery._Deferred(),
1033 // Add errorDeferred methods, then and promise
1034 jQuery.extend( deferred, {
1035 then: function( doneCallbacks, failCallbacks ) {
1036 deferred.done( doneCallbacks ).fail( failCallbacks );
1039 always: function() {
1040 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1042 fail: failDeferred.done,
1043 rejectWith: failDeferred.resolveWith,
1044 reject: failDeferred.resolve,
1045 isRejected: failDeferred.isResolved,
1046 pipe: function( fnDone, fnFail ) {
1047 return jQuery.Deferred(function( newDefer ) {
1049 done: [ fnDone, "resolve" ],
1050 fail: [ fnFail, "reject" ]
1051 }, function( handler, data ) {
1055 if ( jQuery.isFunction( fn ) ) {
1056 deferred[ handler ](function() {
1057 returned = fn.apply( this, arguments );
1058 if ( returned && jQuery.isFunction( returned.promise ) ) {
1059 returned.promise().then( newDefer.resolve, newDefer.reject );
1061 newDefer[ action ]( returned );
1065 deferred[ handler ]( newDefer[ action ] );
1070 // Get a promise for this deferred
1071 // If obj is provided, the promise aspect is added to the object
1072 promise: function( obj ) {
1073 if ( obj == null ) {
1079 var i = promiseMethods.length;
1081 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1086 // Make sure only one callback list will be used
1087 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1089 delete deferred.cancel;
1090 // Call given func if any
1092 func.call( deferred, deferred );
1098 when: function( firstParam ) {
1099 var args = arguments,
1101 length = args.length,
1103 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1106 function resolveFunc( i ) {
1107 return function( value ) {
1108 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1109 if ( !( --count ) ) {
1110 // Strange bug in FF4:
1111 // Values changed onto the arguments object sometimes end up as undefined values
1112 // outside the $.when method. Cloning the object into a fresh array solves the issue
1113 deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1118 for( ; i < length; i++ ) {
1119 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1120 args[ i ].promise().then( resolveFunc(i), deferred.reject );
1126 deferred.resolveWith( deferred, args );
1128 } else if ( deferred !== firstParam ) {
1129 deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1131 return deferred.promise();
1137 jQuery.support = (function() {
1139 var div = document.createElement( "div" ),
1140 documentElement = document.documentElement,
1157 // Preliminary tests
1158 div.setAttribute("className", "t");
1159 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1161 all = div.getElementsByTagName( "*" );
1162 a = div.getElementsByTagName( "a" )[ 0 ];
1164 // Can't get basic test support
1165 if ( !all || !all.length || !a ) {
1169 // First batch of supports tests
1170 select = document.createElement( "select" );
1171 opt = select.appendChild( document.createElement("option") );
1172 input = div.getElementsByTagName( "input" )[ 0 ];
1175 // IE strips leading whitespace when .innerHTML is used
1176 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1178 // Make sure that tbody elements aren't automatically inserted
1179 // IE will insert them into empty tables
1180 tbody: !div.getElementsByTagName( "tbody" ).length,
1182 // Make sure that link elements get serialized correctly by innerHTML
1183 // This requires a wrapper element in IE
1184 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1186 // Get the style information from getAttribute
1187 // (IE uses .cssText instead)
1188 style: /top/.test( a.getAttribute("style") ),
1190 // Make sure that URLs aren't manipulated
1191 // (IE normalizes it by default)
1192 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1194 // Make sure that element opacity exists
1195 // (IE uses filter instead)
1196 // Use a regex to work around a WebKit issue. See #5145
1197 opacity: /^0.55$/.test( a.style.opacity ),
1199 // Verify style float existence
1200 // (IE uses styleFloat instead of cssFloat)
1201 cssFloat: !!a.style.cssFloat,
1203 // Make sure that if no value is specified for a checkbox
1204 // that it defaults to "on".
1205 // (WebKit defaults to "" instead)
1206 checkOn: ( input.value === "on" ),
1208 // Make sure that a selected-by-default option has a working selected property.
1209 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1210 optSelected: opt.selected,
1212 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1213 getSetAttribute: div.className !== "t",
1215 // Will be defined later
1216 submitBubbles: true,
1217 changeBubbles: true,
1218 focusinBubbles: false,
1219 deleteExpando: true,
1221 inlineBlockNeedsLayout: false,
1222 shrinkWrapBlocks: false,
1223 reliableMarginRight: true
1226 // Make sure checked status is properly cloned
1227 input.checked = true;
1228 support.noCloneChecked = input.cloneNode( true ).checked;
1230 // Make sure that the options inside disabled selects aren't marked as disabled
1231 // (WebKit marks them as disabled)
1232 select.disabled = true;
1233 support.optDisabled = !opt.disabled;
1235 // Test to see if it's possible to delete an expando from an element
1236 // Fails in Internet Explorer
1240 support.deleteExpando = false;
1243 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1244 div.attachEvent( "onclick", function click() {
1245 // Cloning a node shouldn't copy over any
1246 // bound event handlers (IE does this)
1247 support.noCloneEvent = false;
1248 div.detachEvent( "onclick", click );
1250 div.cloneNode( true ).fireEvent( "onclick" );
1253 // Check if a radio maintains it's value
1254 // after being appended to the DOM
1255 input = document.createElement("input");
1257 input.setAttribute("type", "radio");
1258 support.radioValue = input.value === "t";
1260 input.setAttribute("checked", "checked");
1261 div.appendChild( input );
1262 fragment = document.createDocumentFragment();
1263 fragment.appendChild( div.firstChild );
1265 // WebKit doesn't clone checked state correctly in fragments
1266 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1270 // Figure out if the W3C box model works as expected
1271 div.style.width = div.style.paddingLeft = "1px";
1273 // We use our own, invisible, body
1274 body = document.createElement( "body" );
1276 visibility: "hidden",
1281 // Set background to avoid IE crashes when removing (#9028)
1284 for ( i in bodyStyle ) {
1285 body.style[ i ] = bodyStyle[ i ];
1287 body.appendChild( div );
1288 documentElement.insertBefore( body, documentElement.firstChild );
1290 // Check if a disconnected checkbox will retain its checked
1291 // value of true after appended to the DOM (IE6/7)
1292 support.appendChecked = input.checked;
1294 support.boxModel = div.offsetWidth === 2;
1296 if ( "zoom" in div.style ) {
1297 // Check if natively block-level elements act like inline-block
1298 // elements when setting their display to 'inline' and giving
1300 // (IE < 8 does this)
1301 div.style.display = "inline";
1303 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1305 // Check if elements with layout shrink-wrap their children
1307 div.style.display = "";
1308 div.innerHTML = "<div style='width:4px;'></div>";
1309 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1312 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1313 tds = div.getElementsByTagName( "td" );
1315 // Check if table cells still have offsetWidth/Height when they are set
1316 // to display:none and there are still other visible table cells in a
1317 // table row; if so, offsetWidth/Height are not reliable for use when
1318 // determining if an element has been hidden directly using
1319 // display:none (it is still safe to use offsets if a parent element is
1320 // hidden; don safety goggles and see bug #4512 for more information).
1321 // (only IE 8 fails this test)
1322 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1324 tds[ 0 ].style.display = "";
1325 tds[ 1 ].style.display = "none";
1327 // Check if empty table cells still have offsetWidth/Height
1328 // (IE < 8 fail this test)
1329 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1332 // Check if div with explicit width and no margin-right incorrectly
1333 // gets computed margin-right based on width of container. For more
1334 // info see bug #3333
1335 // Fails in WebKit before Feb 2011 nightlies
1336 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1337 if ( document.defaultView && document.defaultView.getComputedStyle ) {
1338 marginDiv = document.createElement( "div" );
1339 marginDiv.style.width = "0";
1340 marginDiv.style.marginRight = "0";
1341 div.appendChild( marginDiv );
1342 support.reliableMarginRight =
1343 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1346 // Remove the body element we added
1347 body.innerHTML = "";
1348 documentElement.removeChild( body );
1350 // Technique from Juriy Zaytsev
1351 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1352 // We only care about the case where non-standard event systems
1353 // are used, namely in IE. Short-circuiting here helps us to
1354 // avoid an eval call (in setAttribute) which can cause CSP
1355 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1356 if ( div.attachEvent ) {
1362 eventName = "on" + i;
1363 isSupported = ( eventName in div );
1364 if ( !isSupported ) {
1365 div.setAttribute( eventName, "return;" );
1366 isSupported = ( typeof div[ eventName ] === "function" );
1368 support[ i + "Bubbles" ] = isSupported;
1375 // Keep track of boxModel
1376 jQuery.boxModel = jQuery.support.boxModel;
1381 var rbrace = /^(?:\{.*\}|\[.*\])$/,
1382 rmultiDash = /([a-z])([A-Z])/g;
1387 // Please use with caution
1390 // Unique for each copy of jQuery on the page
1391 // Non-digits removed to match rinlinejQuery
1392 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1394 // The following elements throw uncatchable exceptions if you
1395 // attempt to add expando properties to them.
1398 // Ban all objects except for Flash (which handle expandos)
1399 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1403 hasData: function( elem ) {
1404 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1406 return !!elem && !isEmptyDataObject( elem );
1409 data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1410 if ( !jQuery.acceptData( elem ) ) {
1414 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1416 // We have to handle DOM nodes and JS objects differently because IE6-7
1417 // can't GC object references properly across the DOM-JS boundary
1418 isNode = elem.nodeType,
1420 // Only DOM nodes need the global jQuery cache; JS object data is
1421 // attached directly to the object so GC can occur automatically
1422 cache = isNode ? jQuery.cache : elem,
1424 // Only defining an ID for JS objects if its cache already exists allows
1425 // the code to shortcut on the same path as a DOM node with no cache
1426 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1428 // Avoid doing any more work than we need to when trying to get data on an
1429 // object that has no data at all
1430 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1435 // Only DOM nodes need a new unique ID for each element since their data
1436 // ends up in the global cache
1438 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1440 id = jQuery.expando;
1444 if ( !cache[ id ] ) {
1447 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1448 // metadata on plain JS objects when the object is serialized using
1451 cache[ id ].toJSON = jQuery.noop;
1455 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1456 // shallow copied over onto the existing cache
1457 if ( typeof name === "object" || typeof name === "function" ) {
1459 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1461 cache[ id ] = jQuery.extend(cache[ id ], name);
1465 thisCache = cache[ id ];
1467 // Internal jQuery data is stored in a separate object inside the object's data
1468 // cache in order to avoid key collisions between internal data and user-defined
1471 if ( !thisCache[ internalKey ] ) {
1472 thisCache[ internalKey ] = {};
1475 thisCache = thisCache[ internalKey ];
1478 if ( data !== undefined ) {
1479 thisCache[ jQuery.camelCase( name ) ] = data;
1482 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1483 // not attempt to inspect the internal events object using jQuery.data, as this
1484 // internal data object is undocumented and subject to change.
1485 if ( name === "events" && !thisCache[name] ) {
1486 return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1489 return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;
1492 removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1493 if ( !jQuery.acceptData( elem ) ) {
1497 var internalKey = jQuery.expando, isNode = elem.nodeType,
1499 // See jQuery.data for more information
1500 cache = isNode ? jQuery.cache : elem,
1502 // See jQuery.data for more information
1503 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1505 // If there is already no cache entry for this object, there is no
1506 // purpose in continuing
1507 if ( !cache[ id ] ) {
1512 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1515 delete thisCache[ name ];
1517 // If there is no data left in the cache, we want to continue
1518 // and let the cache object itself get destroyed
1519 if ( !isEmptyDataObject(thisCache) ) {
1525 // See jQuery.data for more information
1527 delete cache[ id ][ internalKey ];
1529 // Don't destroy the parent cache unless the internal data object
1530 // had been the only thing left in it
1531 if ( !isEmptyDataObject(cache[ id ]) ) {
1536 var internalCache = cache[ id ][ internalKey ];
1538 // Browsers that fail expando deletion also refuse to delete expandos on
1539 // the window, but it will allow it on all other JS objects; other browsers
1541 if ( jQuery.support.deleteExpando || cache != window ) {
1547 // We destroyed the entire user cache at once because it's faster than
1548 // iterating through each key, but we need to continue to persist internal
1549 // data if it existed
1550 if ( internalCache ) {
1552 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1553 // metadata on plain JS objects when the object is serialized using
1556 cache[ id ].toJSON = jQuery.noop;
1559 cache[ id ][ internalKey ] = internalCache;
1561 // Otherwise, we need to eliminate the expando on the node to avoid
1562 // false lookups in the cache for entries that no longer exist
1563 } else if ( isNode ) {
1564 // IE does not allow us to delete expando properties from nodes,
1565 // nor does it have a removeAttribute function on Document nodes;
1566 // we must handle all of these cases
1567 if ( jQuery.support.deleteExpando ) {
1568 delete elem[ jQuery.expando ];
1569 } else if ( elem.removeAttribute ) {
1570 elem.removeAttribute( jQuery.expando );
1572 elem[ jQuery.expando ] = null;
1577 // For internal use only.
1578 _data: function( elem, name, data ) {
1579 return jQuery.data( elem, name, data, true );
1582 // A method for determining if a DOM node can handle the data expando
1583 acceptData: function( elem ) {
1584 if ( elem.nodeName ) {
1585 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1588 return !(match === true || elem.getAttribute("classid") !== match);
1597 data: function( key, value ) {
1600 if ( typeof key === "undefined" ) {
1601 if ( this.length ) {
1602 data = jQuery.data( this[0] );
1604 if ( this[0].nodeType === 1 ) {
1605 var attr = this[0].attributes, name;
1606 for ( var i = 0, l = attr.length; i < l; i++ ) {
1607 name = attr[i].name;
1609 if ( name.indexOf( "data-" ) === 0 ) {
1610 name = jQuery.camelCase( name.substring(5) );
1612 dataAttr( this[0], name, data[ name ] );
1620 } else if ( typeof key === "object" ) {
1621 return this.each(function() {
1622 jQuery.data( this, key );
1626 var parts = key.split(".");
1627 parts[1] = parts[1] ? "." + parts[1] : "";
1629 if ( value === undefined ) {
1630 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1632 // Try to fetch any internally stored data first
1633 if ( data === undefined && this.length ) {
1634 data = jQuery.data( this[0], key );
1635 data = dataAttr( this[0], key, data );
1638 return data === undefined && parts[1] ?
1639 this.data( parts[0] ) :
1643 return this.each(function() {
1644 var $this = jQuery( this ),
1645 args = [ parts[0], value ];
1647 $this.triggerHandler( "setData" + parts[1] + "!", args );
1648 jQuery.data( this, key, value );
1649 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1654 removeData: function( key ) {
1655 return this.each(function() {
1656 jQuery.removeData( this, key );
1661 function dataAttr( elem, key, data ) {
1662 // If nothing was found internally, try to fetch any
1663 // data from the HTML5 data-* attribute
1664 if ( data === undefined && elem.nodeType === 1 ) {
1665 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1667 data = elem.getAttribute( name );
1669 if ( typeof data === "string" ) {
1671 data = data === "true" ? true :
1672 data === "false" ? false :
1673 data === "null" ? null :
1674 !jQuery.isNaN( data ) ? parseFloat( data ) :
1675 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1679 // Make sure we set the data so it isn't changed later
1680 jQuery.data( elem, key, data );
1690 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1691 // property to be considered empty objects; this property always exists in
1692 // order to make sure JSON.stringify does not expose internal metadata
1693 function isEmptyDataObject( obj ) {
1694 for ( var name in obj ) {
1695 if ( name !== "toJSON" ) {
1706 function handleQueueMarkDefer( elem, type, src ) {
1707 var deferDataKey = type + "defer",
1708 queueDataKey = type + "queue",
1709 markDataKey = type + "mark",
1710 defer = jQuery.data( elem, deferDataKey, undefined, true );
1712 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1713 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1714 // Give room for hard-coded callbacks to fire first
1715 // and eventually mark/queue something else on the element
1716 setTimeout( function() {
1717 if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1718 !jQuery.data( elem, markDataKey, undefined, true ) ) {
1719 jQuery.removeData( elem, deferDataKey, true );
1728 _mark: function( elem, type ) {
1730 type = (type || "fx") + "mark";
1731 jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1735 _unmark: function( force, elem, type ) {
1736 if ( force !== true ) {
1742 type = type || "fx";
1743 var key = type + "mark",
1744 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1746 jQuery.data( elem, key, count, true );
1748 jQuery.removeData( elem, key, true );
1749 handleQueueMarkDefer( elem, type, "mark" );
1754 queue: function( elem, type, data ) {
1756 type = (type || "fx") + "queue";
1757 var q = jQuery.data( elem, type, undefined, true );
1758 // Speed up dequeue by getting out quickly if this is just a lookup
1760 if ( !q || jQuery.isArray(data) ) {
1761 q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1770 dequeue: function( elem, type ) {
1771 type = type || "fx";
1773 var queue = jQuery.queue( elem, type ),
1777 // If the fx queue is dequeued, always remove the progress sentinel
1778 if ( fn === "inprogress" ) {
1783 // Add a progress sentinel to prevent the fx queue from being
1784 // automatically dequeued
1785 if ( type === "fx" ) {
1786 queue.unshift("inprogress");
1789 fn.call(elem, function() {
1790 jQuery.dequeue(elem, type);
1794 if ( !queue.length ) {
1795 jQuery.removeData( elem, type + "queue", true );
1796 handleQueueMarkDefer( elem, type, "queue" );
1802 queue: function( type, data ) {
1803 if ( typeof type !== "string" ) {
1808 if ( data === undefined ) {
1809 return jQuery.queue( this[0], type );
1811 return this.each(function() {
1812 var queue = jQuery.queue( this, type, data );
1814 if ( type === "fx" && queue[0] !== "inprogress" ) {
1815 jQuery.dequeue( this, type );
1819 dequeue: function( type ) {
1820 return this.each(function() {
1821 jQuery.dequeue( this, type );
1824 // Based off of the plugin by Clint Helfers, with permission.
1825 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1826 delay: function( time, type ) {
1827 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1828 type = type || "fx";
1830 return this.queue( type, function() {
1832 setTimeout(function() {
1833 jQuery.dequeue( elem, type );
1837 clearQueue: function( type ) {
1838 return this.queue( type || "fx", [] );
1840 // Get a promise resolved when queues of a certain type
1841 // are emptied (fx is the type by default)
1842 promise: function( type, object ) {
1843 if ( typeof type !== "string" ) {
1847 type = type || "fx";
1848 var defer = jQuery.Deferred(),
1850 i = elements.length,
1852 deferDataKey = type + "defer",
1853 queueDataKey = type + "queue",
1854 markDataKey = type + "mark",
1856 function resolve() {
1857 if ( !( --count ) ) {
1858 defer.resolveWith( elements, [ elements ] );
1862 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1863 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1864 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1865 jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1867 tmp.done( resolve );
1871 return defer.promise();
1878 var rclass = /[\n\t\r]/g,
1881 rtype = /^(?:button|input)$/i,
1882 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1883 rclickable = /^a(?:rea)?$/i,
1884 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1885 rinvalidChar = /\:/,
1889 attr: function( name, value ) {
1890 return jQuery.access( this, name, value, true, jQuery.attr );
1893 removeAttr: function( name ) {
1894 return this.each(function() {
1895 jQuery.removeAttr( this, name );
1899 prop: function( name, value ) {
1900 return jQuery.access( this, name, value, true, jQuery.prop );
1903 removeProp: function( name ) {
1904 name = jQuery.propFix[ name ] || name;
1905 return this.each(function() {
1906 // try/catch handles cases where IE balks (such as removing a property on window)
1908 this[ name ] = undefined;
1909 delete this[ name ];
1914 addClass: function( value ) {
1915 if ( jQuery.isFunction( value ) ) {
1916 return this.each(function(i) {
1917 var self = jQuery(this);
1918 self.addClass( value.call(this, i, self.attr("class") || "") );
1922 if ( value && typeof value === "string" ) {
1923 var classNames = (value || "").split( rspace );
1925 for ( var i = 0, l = this.length; i < l; i++ ) {
1928 if ( elem.nodeType === 1 ) {
1929 if ( !elem.className ) {
1930 elem.className = value;
1933 var className = " " + elem.className + " ",
1934 setClass = elem.className;
1936 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1937 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1938 setClass += " " + classNames[c];
1941 elem.className = jQuery.trim( setClass );
1950 removeClass: function( value ) {
1951 if ( jQuery.isFunction(value) ) {
1952 return this.each(function(i) {
1953 var self = jQuery(this);
1954 self.removeClass( value.call(this, i, self.attr("class")) );
1958 if ( (value && typeof value === "string") || value === undefined ) {
1959 var classNames = (value || "").split( rspace );
1961 for ( var i = 0, l = this.length; i < l; i++ ) {
1964 if ( elem.nodeType === 1 && elem.className ) {
1966 var className = (" " + elem.className + " ").replace(rclass, " ");
1967 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1968 className = className.replace(" " + classNames[c] + " ", " ");
1970 elem.className = jQuery.trim( className );
1973 elem.className = "";
1982 toggleClass: function( value, stateVal ) {
1983 var type = typeof value,
1984 isBool = typeof stateVal === "boolean";
1986 if ( jQuery.isFunction( value ) ) {
1987 return this.each(function(i) {
1988 var self = jQuery(this);
1989 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1993 return this.each(function() {
1994 if ( type === "string" ) {
1995 // toggle individual class names
1998 self = jQuery( this ),
2000 classNames = value.split( rspace );
2002 while ( (className = classNames[ i++ ]) ) {
2003 // check each className given, space seperated list
2004 state = isBool ? state : !self.hasClass( className );
2005 self[ state ? "addClass" : "removeClass" ]( className );
2008 } else if ( type === "undefined" || type === "boolean" ) {
2009 if ( this.className ) {
2010 // store className if set
2011 jQuery._data( this, "__className__", this.className );
2014 // toggle whole className
2015 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2020 hasClass: function( selector ) {
2021 var className = " " + selector + " ";
2022 for ( var i = 0, l = this.length; i < l; i++ ) {
2023 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2031 val: function( value ) {
2035 if ( !arguments.length ) {
2037 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2039 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2043 return (elem.value || "").replace(rreturn, "");
2049 var isFunction = jQuery.isFunction( value );
2051 return this.each(function( i ) {
2052 var self = jQuery(this), val;
2054 if ( this.nodeType !== 1 ) {
2059 val = value.call( this, i, self.val() );
2064 // Treat null/undefined as ""; convert numbers to string
2065 if ( val == null ) {
2067 } else if ( typeof val === "number" ) {
2069 } else if ( jQuery.isArray( val ) ) {
2070 val = jQuery.map(val, function ( value ) {
2071 return value == null ? "" : value + "";
2075 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2077 // If set returns undefined, fall back to normal setting
2078 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2088 get: function( elem ) {
2089 // attributes.value is undefined in Blackberry 4.7 but
2090 // uses .value. See #6932
2091 var val = elem.attributes.value;
2092 return !val || val.specified ? elem.value : elem.text;
2096 get: function( elem ) {
2098 index = elem.selectedIndex,
2100 options = elem.options,
2101 one = elem.type === "select-one";
2103 // Nothing was selected
2108 // Loop through all the selected options
2109 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2110 var option = options[ i ];
2112 // Don't return options that are disabled or in a disabled optgroup
2113 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2114 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2116 // Get the specific value for the option
2117 value = jQuery( option ).val();
2119 // We don't need an array for one selects
2124 // Multi-Selects return an array
2125 values.push( value );
2129 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2130 if ( one && !values.length && options.length ) {
2131 return jQuery( options[ index ] ).val();
2137 set: function( elem, value ) {
2138 var values = jQuery.makeArray( value );
2140 jQuery(elem).find("option").each(function() {
2141 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2144 if ( !values.length ) {
2145 elem.selectedIndex = -1;
2164 // Always normalize to ensure hook usage
2165 tabindex: "tabIndex"
2168 attr: function( elem, name, value, pass ) {
2169 var nType = elem.nodeType;
2171 // don't get/set attributes on text, comment and attribute nodes
2172 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2176 if ( pass && name in jQuery.attrFn ) {
2177 return jQuery( elem )[ name ]( value );
2180 // Fallback to prop when attributes are not supported
2181 if ( !("getAttribute" in elem) ) {
2182 return jQuery.prop( elem, name, value );
2186 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2188 // Normalize the name if needed
2189 name = notxml && jQuery.attrFix[ name ] || name;
2191 hooks = jQuery.attrHooks[ name ];
2194 // Use boolHook for boolean attributes
2195 if ( rboolean.test( name ) &&
2196 (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
2200 // Use formHook for forms and if the name contains certain characters
2201 } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
2206 if ( value !== undefined ) {
2208 if ( value === null ) {
2209 jQuery.removeAttr( elem, name );
2212 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2216 elem.setAttribute( name, "" + value );
2220 } else if ( hooks && "get" in hooks && notxml ) {
2221 return hooks.get( elem, name );
2225 ret = elem.getAttribute( name );
2227 // Non-existent attributes return null, we normalize to undefined
2228 return ret === null ?
2234 removeAttr: function( elem, name ) {
2236 if ( elem.nodeType === 1 ) {
2237 name = jQuery.attrFix[ name ] || name;
2239 if ( jQuery.support.getSetAttribute ) {
2240 // Use removeAttribute in browsers that support it
2241 elem.removeAttribute( name );
2243 jQuery.attr( elem, name, "" );
2244 elem.removeAttributeNode( elem.getAttributeNode( name ) );
2247 // Set corresponding property to false for boolean attributes
2248 if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2249 elem[ propName ] = false;
2256 set: function( elem, value ) {
2257 // We can't allow the type property to be changed (since it causes problems in IE)
2258 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2259 jQuery.error( "type property can't be changed" );
2260 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2261 // Setting the type on a radio button after the value resets the value in IE6-9
2262 // Reset value to it's default in case type is set after value
2263 // This is for element creation
2264 var val = elem.value;
2265 elem.setAttribute( "type", value );
2274 get: function( elem ) {
2275 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2276 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2277 var attributeNode = elem.getAttributeNode("tabIndex");
2279 return attributeNode && attributeNode.specified ?
2280 parseInt( attributeNode.value, 10 ) :
2281 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2289 tabindex: "tabIndex",
2290 readonly: "readOnly",
2292 "class": "className",
2293 maxlength: "maxLength",
2294 cellspacing: "cellSpacing",
2295 cellpadding: "cellPadding",
2299 frameborder: "frameBorder",
2300 contenteditable: "contentEditable"
2303 prop: function( elem, name, value ) {
2304 var nType = elem.nodeType;
2306 // don't get/set properties on text, comment and attribute nodes
2307 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2312 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2314 // Try to normalize/fix the name
2315 name = notxml && jQuery.propFix[ name ] || name;
2317 hooks = jQuery.propHooks[ name ];
2319 if ( value !== undefined ) {
2320 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2324 return (elem[ name ] = value);
2328 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2332 return elem[ name ];
2340 // Hook for boolean attributes
2342 get: function( elem, name ) {
2343 // Align boolean attributes with corresponding properties
2344 return elem[ jQuery.propFix[ name ] || name ] ?
2345 name.toLowerCase() :
2348 set: function( elem, value, name ) {
2350 if ( value === false ) {
2351 // Remove boolean attributes when set to false
2352 jQuery.removeAttr( elem, name );
2354 // value is true since we know at this point it's type boolean and not false
2355 // Set boolean attributes to the same name and set the DOM property
2356 propName = jQuery.propFix[ name ] || name;
2357 if ( propName in elem ) {
2358 // Only set the IDL specifically if it already exists on the element
2359 elem[ propName ] = value;
2362 elem.setAttribute( name, name.toLowerCase() );
2368 // Use the value property for back compat
2369 // Use the formHook for button elements in IE6/7 (#1954)
2370 jQuery.attrHooks.value = {
2371 get: function( elem, name ) {
2372 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2373 return formHook.get( elem, name );
2377 set: function( elem, value, name ) {
2378 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2379 return formHook.set( elem, value, name );
2381 // Does not return so that setAttribute is also used
2386 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2387 if ( !jQuery.support.getSetAttribute ) {
2389 // propFix is more comprehensive and contains all fixes
2390 jQuery.attrFix = jQuery.propFix;
2392 // Use this for any attribute on a form in IE6/7
2393 formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
2394 get: function( elem, name ) {
2396 ret = elem.getAttributeNode( name );
2397 // Return undefined if nodeValue is empty string
2398 return ret && ret.nodeValue !== "" ?
2402 set: function( elem, value, name ) {
2403 // Check form objects in IE (multiple bugs related)
2404 // Only use nodeValue if the attribute node exists on the form
2405 var ret = elem.getAttributeNode( name );
2407 ret.nodeValue = value;
2413 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2414 // This is for removals
2415 jQuery.each([ "width", "height" ], function( i, name ) {
2416 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2417 set: function( elem, value ) {
2418 if ( value === "" ) {
2419 elem.setAttribute( name, "auto" );
2428 // Some attributes require a special call on IE
2429 if ( !jQuery.support.hrefNormalized ) {
2430 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2431 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2432 get: function( elem ) {
2433 var ret = elem.getAttribute( name, 2 );
2434 return ret === null ? undefined : ret;
2440 if ( !jQuery.support.style ) {
2441 jQuery.attrHooks.style = {
2442 get: function( elem ) {
2443 // Return undefined in the case of empty string
2444 // Normalize to lowercase since IE uppercases css property names
2445 return elem.style.cssText.toLowerCase() || undefined;
2447 set: function( elem, value ) {
2448 return (elem.style.cssText = "" + value);
2453 // Safari mis-reports the default selected property of an option
2454 // Accessing the parent's selectedIndex property fixes it
2455 if ( !jQuery.support.optSelected ) {
2456 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2457 get: function( elem ) {
2458 var parent = elem.parentNode;
2461 parent.selectedIndex;
2463 // Make sure that it also works with optgroups, see #5701
2464 if ( parent.parentNode ) {
2465 parent.parentNode.selectedIndex;
2472 // Radios and checkboxes getter/setter
2473 if ( !jQuery.support.checkOn ) {
2474 jQuery.each([ "radio", "checkbox" ], function() {
2475 jQuery.valHooks[ this ] = {
2476 get: function( elem ) {
2477 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2478 return elem.getAttribute("value") === null ? "on" : elem.value;
2483 jQuery.each([ "radio", "checkbox" ], function() {
2484 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2485 set: function( elem, value ) {
2486 if ( jQuery.isArray( value ) ) {
2487 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2496 var hasOwn = Object.prototype.hasOwnProperty,
2497 rnamespaces = /\.(.*)$/,
2498 rformElems = /^(?:textarea|input|select)$/i,
2501 rescape = /[^\w\s.|`]/g,
2502 fcleanup = function( nm ) {
2503 return nm.replace(rescape, "\\$&");
2507 * A number of helper functions used for managing events.
2508 * Many of the ideas behind this code originated from
2509 * Dean Edwards' addEvent library.
2513 // Bind an event to an element
2514 // Original by Dean Edwards
2515 add: function( elem, types, handler, data ) {
2516 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2520 if ( handler === false ) {
2521 handler = returnFalse;
2522 } else if ( !handler ) {
2523 // Fixes bug #7229. Fix recommended by jdalton
2527 var handleObjIn, handleObj;
2529 if ( handler.handler ) {
2530 handleObjIn = handler;
2531 handler = handleObjIn.handler;
2534 // Make sure that the function being executed has a unique ID
2535 if ( !handler.guid ) {
2536 handler.guid = jQuery.guid++;
2539 // Init the element's event structure
2540 var elemData = jQuery._data( elem );
2542 // If no elemData is found then we must be trying to bind to one of the
2543 // banned noData elements
2548 var events = elemData.events,
2549 eventHandle = elemData.handle;
2552 elemData.events = events = {};
2555 if ( !eventHandle ) {
2556 elemData.handle = eventHandle = function( e ) {
2557 // Discard the second event of a jQuery.event.trigger() and
2558 // when an event is called after a page has unloaded
2559 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2560 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2565 // Add elem as a property of the handle function
2566 // This is to prevent a memory leak with non-native events in IE.
2567 eventHandle.elem = elem;
2569 // Handle multiple events separated by a space
2570 // jQuery(...).bind("mouseover mouseout", fn);
2571 types = types.split(" ");
2573 var type, i = 0, namespaces;
2575 while ( (type = types[ i++ ]) ) {
2576 handleObj = handleObjIn ?
2577 jQuery.extend({}, handleObjIn) :
2578 { handler: handler, data: data };
2580 // Namespaced event handlers
2581 if ( type.indexOf(".") > -1 ) {
2582 namespaces = type.split(".");
2583 type = namespaces.shift();
2584 handleObj.namespace = namespaces.slice(0).sort().join(".");
2588 handleObj.namespace = "";
2591 handleObj.type = type;
2592 if ( !handleObj.guid ) {
2593 handleObj.guid = handler.guid;
2596 // Get the current list of functions bound to this event
2597 var handlers = events[ type ],
2598 special = jQuery.event.special[ type ] || {};
2600 // Init the event handler queue
2602 handlers = events[ type ] = [];
2604 // Check for a special event handler
2605 // Only use addEventListener/attachEvent if the special
2606 // events handler returns false
2607 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2608 // Bind the global event handler to the element
2609 if ( elem.addEventListener ) {
2610 elem.addEventListener( type, eventHandle, false );
2612 } else if ( elem.attachEvent ) {
2613 elem.attachEvent( "on" + type, eventHandle );
2618 if ( special.add ) {
2619 special.add.call( elem, handleObj );
2621 if ( !handleObj.handler.guid ) {
2622 handleObj.handler.guid = handler.guid;
2626 // Add the function to the element's handler list
2627 handlers.push( handleObj );
2629 // Keep track of which events have been used, for event optimization
2630 jQuery.event.global[ type ] = true;
2633 // Nullify elem to prevent memory leaks in IE
2639 // Detach an event or set of events from an element
2640 remove: function( elem, types, handler, pos ) {
2641 // don't do events on text and comment nodes
2642 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2646 if ( handler === false ) {
2647 handler = returnFalse;
2650 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2651 elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2652 events = elemData && elemData.events;
2654 if ( !elemData || !events ) {
2658 // types is actually an event object here
2659 if ( types && types.type ) {
2660 handler = types.handler;
2664 // Unbind all events for the element
2665 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2666 types = types || "";
2668 for ( type in events ) {
2669 jQuery.event.remove( elem, type + types );
2675 // Handle multiple events separated by a space
2676 // jQuery(...).unbind("mouseover mouseout", fn);
2677 types = types.split(" ");
2679 while ( (type = types[ i++ ]) ) {
2682 all = type.indexOf(".") < 0;
2686 // Namespaced event handlers
2687 namespaces = type.split(".");
2688 type = namespaces.shift();
2690 namespace = new RegExp("(^|\\.)" +
2691 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2694 eventType = events[ type ];
2701 for ( j = 0; j < eventType.length; j++ ) {
2702 handleObj = eventType[ j ];
2704 if ( all || namespace.test( handleObj.namespace ) ) {
2705 jQuery.event.remove( elem, origType, handleObj.handler, j );
2706 eventType.splice( j--, 1 );
2713 special = jQuery.event.special[ type ] || {};
2715 for ( j = pos || 0; j < eventType.length; j++ ) {
2716 handleObj = eventType[ j ];
2718 if ( handler.guid === handleObj.guid ) {
2719 // remove the given handler for the given type
2720 if ( all || namespace.test( handleObj.namespace ) ) {
2721 if ( pos == null ) {
2722 eventType.splice( j--, 1 );
2725 if ( special.remove ) {
2726 special.remove.call( elem, handleObj );
2730 if ( pos != null ) {
2736 // remove generic event handler if no more handlers exist
2737 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2738 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2739 jQuery.removeEvent( elem, type, elemData.handle );
2743 delete events[ type ];
2747 // Remove the expando if it's no longer used
2748 if ( jQuery.isEmptyObject( events ) ) {
2749 var handle = elemData.handle;
2754 delete elemData.events;
2755 delete elemData.handle;
2757 if ( jQuery.isEmptyObject( elemData ) ) {
2758 jQuery.removeData( elem, undefined, true );
2763 // Events that are safe to short-circuit if no handlers are attached.
2764 // Native DOM events should not be added, they may have inline handlers.
2771 trigger: function( event, data, elem, onlyHandlers ) {
2772 // Event object or event type
2773 var type = event.type || event,
2777 if ( type.indexOf("!") >= 0 ) {
2778 // Exclusive events trigger only for the exact event (no namespaces)
2779 type = type.slice(0, -1);
2783 if ( type.indexOf(".") >= 0 ) {
2784 // Namespaced trigger; create a regexp to match event type in handle()
2785 namespaces = type.split(".");
2786 type = namespaces.shift();
2790 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2791 // No jQuery handlers for this event type, and it can't have inline handlers
2795 // Caller can pass in an Event, Object, or just an event type string
2796 event = typeof event === "object" ?
2797 // jQuery.Event object
2798 event[ jQuery.expando ] ? event :
2800 new jQuery.Event( type, event ) :
2801 // Just the event type (string)
2802 new jQuery.Event( type );
2805 event.exclusive = exclusive;
2806 event.namespace = namespaces.join(".");
2807 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2809 // triggerHandler() and global events don't bubble or run the default action
2810 if ( onlyHandlers || !elem ) {
2811 event.preventDefault();
2812 event.stopPropagation();
2815 // Handle a global trigger
2817 // TODO: Stop taunting the data cache; remove global events and always attach to document
2818 jQuery.each( jQuery.cache, function() {
2819 // internalKey variable is just used to make it easier to find
2820 // and potentially change this stuff later; currently it just
2821 // points to jQuery.expando
2822 var internalKey = jQuery.expando,
2823 internalCache = this[ internalKey ];
2824 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2825 jQuery.event.trigger( event, data, internalCache.handle.elem );
2831 // Don't do events on text and comment nodes
2832 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2836 // Clean up the event in case it is being reused
2837 event.result = undefined;
2838 event.target = elem;
2840 // Clone any incoming data and prepend the event, creating the handler arg list
2841 data = data ? jQuery.makeArray( data ) : [];
2842 data.unshift( event );
2845 // IE doesn't like method names with a colon (#3533, #8272)
2846 ontype = type.indexOf(":") < 0 ? "on" + type : "";
2848 // Fire event on the current element, then bubble up the DOM tree
2850 var handle = jQuery._data( cur, "handle" );
2852 event.currentTarget = cur;
2854 handle.apply( cur, data );
2857 // Trigger an inline bound script
2858 if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2859 event.result = false;
2860 event.preventDefault();
2863 // Bubble up to document, then to window
2864 cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2865 } while ( cur && !event.isPropagationStopped() );
2867 // If nobody prevented the default action, do it now
2868 if ( !event.isDefaultPrevented() ) {
2870 special = jQuery.event.special[ type ] || {};
2872 if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2873 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2875 // Call a native DOM method on the target with the same name name as the event.
2876 // Can't use an .isFunction)() check here because IE6/7 fails that test.
2877 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2879 if ( ontype && elem[ type ] ) {
2880 // Don't re-trigger an onFOO event when we call its FOO() method
2881 old = elem[ ontype ];
2884 elem[ ontype ] = null;
2887 jQuery.event.triggered = type;
2890 } catch ( ieError ) {}
2893 elem[ ontype ] = old;
2896 jQuery.event.triggered = undefined;
2900 return event.result;
2903 handle: function( event ) {
2904 event = jQuery.event.fix( event || window.event );
2905 // Snapshot the handlers list since a called handler may add/remove events.
2906 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2907 run_all = !event.exclusive && !event.namespace,
2908 args = Array.prototype.slice.call( arguments, 0 );
2910 // Use the fix-ed Event rather than the (read-only) native event
2912 event.currentTarget = this;
2914 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2915 var handleObj = handlers[ j ];
2917 // Triggered event must 1) be non-exclusive and have no namespace, or
2918 // 2) have namespace(s) a subset or equal to those in the bound event.
2919 if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2920 // Pass in a reference to the handler function itself
2921 // So that we can later remove it
2922 event.handler = handleObj.handler;
2923 event.data = handleObj.data;
2924 event.handleObj = handleObj;
2926 var ret = handleObj.handler.apply( this, args );
2928 if ( ret !== undefined ) {
2930 if ( ret === false ) {
2931 event.preventDefault();
2932 event.stopPropagation();
2936 if ( event.isImmediatePropagationStopped() ) {
2941 return event.result;
2944 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(" "),
2946 fix: function( event ) {
2947 if ( event[ jQuery.expando ] ) {
2951 // store a copy of the original event object
2952 // and "clone" to set read-only properties
2953 var originalEvent = event;
2954 event = jQuery.Event( originalEvent );
2956 for ( var i = this.props.length, prop; i; ) {
2957 prop = this.props[ --i ];
2958 event[ prop ] = originalEvent[ prop ];
2961 // Fix target property, if necessary
2962 if ( !event.target ) {
2963 // Fixes #1925 where srcElement might not be defined either
2964 event.target = event.srcElement || document;
2967 // check if target is a textnode (safari)
2968 if ( event.target.nodeType === 3 ) {
2969 event.target = event.target.parentNode;
2972 // Add relatedTarget, if necessary
2973 if ( !event.relatedTarget && event.fromElement ) {
2974 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2977 // Calculate pageX/Y if missing and clientX/Y available
2978 if ( event.pageX == null && event.clientX != null ) {
2979 var eventDocument = event.target.ownerDocument || document,
2980 doc = eventDocument.documentElement,
2981 body = eventDocument.body;
2983 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2984 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
2987 // Add which for key events
2988 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2989 event.which = event.charCode != null ? event.charCode : event.keyCode;
2992 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2993 if ( !event.metaKey && event.ctrlKey ) {
2994 event.metaKey = event.ctrlKey;
2997 // Add which for click: 1 === left; 2 === middle; 3 === right
2998 // Note: button is not normalized, so don't use it
2999 if ( !event.which && event.button !== undefined ) {
3000 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3006 // Deprecated, use jQuery.guid instead
3009 // Deprecated, use jQuery.proxy instead
3010 proxy: jQuery.proxy,
3014 // Make sure the ready event is setup
3015 setup: jQuery.bindReady,
3016 teardown: jQuery.noop
3020 add: function( handleObj ) {
3021 jQuery.event.add( this,
3022 liveConvert( handleObj.origType, handleObj.selector ),
3023 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3026 remove: function( handleObj ) {
3027 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3032 setup: function( data, namespaces, eventHandle ) {
3033 // We only want to do this special case on windows
3034 if ( jQuery.isWindow( this ) ) {
3035 this.onbeforeunload = eventHandle;
3039 teardown: function( namespaces, eventHandle ) {
3040 if ( this.onbeforeunload === eventHandle ) {
3041 this.onbeforeunload = null;
3048 jQuery.removeEvent = document.removeEventListener ?
3049 function( elem, type, handle ) {
3050 if ( elem.removeEventListener ) {
3051 elem.removeEventListener( type, handle, false );
3054 function( elem, type, handle ) {
3055 if ( elem.detachEvent ) {
3056 elem.detachEvent( "on" + type, handle );
3060 jQuery.Event = function( src, props ) {
3061 // Allow instantiation without the 'new' keyword
3062 if ( !this.preventDefault ) {
3063 return new jQuery.Event( src, props );
3067 if ( src && src.type ) {
3068 this.originalEvent = src;
3069 this.type = src.type;
3071 // Events bubbling up the document may have been marked as prevented
3072 // by a handler lower down the tree; reflect the correct value.
3073 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3074 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3081 // Put explicitly provided properties onto the event object
3083 jQuery.extend( this, props );
3086 // timeStamp is buggy for some events on Firefox(#3843)
3087 // So we won't rely on the native value
3088 this.timeStamp = jQuery.now();
3091 this[ jQuery.expando ] = true;
3094 function returnFalse() {
3097 function returnTrue() {
3101 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3102 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3103 jQuery.Event.prototype = {
3104 preventDefault: function() {
3105 this.isDefaultPrevented = returnTrue;
3107 var e = this.originalEvent;
3112 // if preventDefault exists run it on the original event
3113 if ( e.preventDefault ) {
3116 // otherwise set the returnValue property of the original event to false (IE)
3118 e.returnValue = false;
3121 stopPropagation: function() {
3122 this.isPropagationStopped = returnTrue;
3124 var e = this.originalEvent;
3128 // if stopPropagation exists run it on the original event
3129 if ( e.stopPropagation ) {
3130 e.stopPropagation();
3132 // otherwise set the cancelBubble property of the original event to true (IE)
3133 e.cancelBubble = true;
3135 stopImmediatePropagation: function() {
3136 this.isImmediatePropagationStopped = returnTrue;
3137 this.stopPropagation();
3139 isDefaultPrevented: returnFalse,
3140 isPropagationStopped: returnFalse,
3141 isImmediatePropagationStopped: returnFalse
3144 // Checks if an event happened on an element within another element
3145 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3146 var withinElement = function( event ) {
3147 // Check if mouse(over|out) are still within the same parent element
3148 var parent = event.relatedTarget;
3150 // set the correct event type
3151 event.type = event.data;
3153 // Firefox sometimes assigns relatedTarget a XUL element
3154 // which we cannot access the parentNode property of
3157 // Chrome does something similar, the parentNode property
3158 // can be accessed but is null.
3159 if ( parent && parent !== document && !parent.parentNode ) {
3163 // Traverse up the tree
3164 while ( parent && parent !== this ) {
3165 parent = parent.parentNode;
3168 if ( parent !== this ) {
3169 // handle event if we actually just moused on to a non sub-element
3170 jQuery.event.handle.apply( this, arguments );
3173 // assuming we've left the element since we most likely mousedover a xul element
3177 // In case of event delegation, we only need to rename the event.type,
3178 // liveHandler will take care of the rest.
3179 delegate = function( event ) {
3180 event.type = event.data;
3181 jQuery.event.handle.apply( this, arguments );
3184 // Create mouseenter and mouseleave events
3186 mouseenter: "mouseover",
3187 mouseleave: "mouseout"
3188 }, function( orig, fix ) {
3189 jQuery.event.special[ orig ] = {
3190 setup: function( data ) {
3191 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3193 teardown: function( data ) {
3194 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3199 // submit delegation
3200 if ( !jQuery.support.submitBubbles ) {
3202 jQuery.event.special.submit = {
3203 setup: function( data, namespaces ) {
3204 if ( !jQuery.nodeName( this, "form" ) ) {
3205 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3206 var elem = e.target,
3209 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3210 trigger( "submit", this, arguments );
3214 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3215 var elem = e.target,
3218 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3219 trigger( "submit", this, arguments );
3228 teardown: function( namespaces ) {
3229 jQuery.event.remove( this, ".specialSubmit" );
3235 // change delegation, happens here so we have bind.
3236 if ( !jQuery.support.changeBubbles ) {
3240 getVal = function( elem ) {
3241 var type = elem.type, val = elem.value;
3243 if ( type === "radio" || type === "checkbox" ) {
3246 } else if ( type === "select-multiple" ) {
3247 val = elem.selectedIndex > -1 ?
3248 jQuery.map( elem.options, function( elem ) {
3249 return elem.selected;
3253 } else if ( jQuery.nodeName( elem, "select" ) ) {
3254 val = elem.selectedIndex;
3260 testChange = function testChange( e ) {
3261 var elem = e.target, data, val;
3263 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3267 data = jQuery._data( elem, "_change_data" );
3270 // the current data will be also retrieved by beforeactivate
3271 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3272 jQuery._data( elem, "_change_data", val );
3275 if ( data === undefined || val === data ) {
3279 if ( data != null || val ) {
3281 e.liveFired = undefined;
3282 jQuery.event.trigger( e, arguments[1], elem );
3286 jQuery.event.special.change = {
3288 focusout: testChange,
3290 beforedeactivate: testChange,
3292 click: function( e ) {
3293 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3295 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3296 testChange.call( this, e );
3300 // Change has to be called before submit
3301 // Keydown will be called before keypress, which is used in submit-event delegation
3302 keydown: function( e ) {
3303 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3305 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3306 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3307 type === "select-multiple" ) {
3308 testChange.call( this, e );
3312 // Beforeactivate happens also before the previous element is blurred
3313 // with this event you can't trigger a change event, but you can store
3315 beforeactivate: function( e ) {
3316 var elem = e.target;
3317 jQuery._data( elem, "_change_data", getVal(elem) );
3321 setup: function( data, namespaces ) {
3322 if ( this.type === "file" ) {
3326 for ( var type in changeFilters ) {
3327 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3330 return rformElems.test( this.nodeName );
3333 teardown: function( namespaces ) {
3334 jQuery.event.remove( this, ".specialChange" );
3336 return rformElems.test( this.nodeName );
3340 changeFilters = jQuery.event.special.change.filters;
3342 // Handle when the input is .focus()'d
3343 changeFilters.focus = changeFilters.beforeactivate;
3346 function trigger( type, elem, args ) {
3347 // Piggyback on a donor event to simulate a different one.
3348 // Fake originalEvent to avoid donor's stopPropagation, but if the
3349 // simulated event prevents default then we do the same on the donor.
3350 // Don't pass args or remember liveFired; they apply to the donor event.
3351 var event = jQuery.extend( {}, args[ 0 ] );
3353 event.originalEvent = {};
3354 event.liveFired = undefined;
3355 jQuery.event.handle.call( elem, event );
3356 if ( event.isDefaultPrevented() ) {
3357 args[ 0 ].preventDefault();
3361 // Create "bubbling" focus and blur events
3362 if ( !jQuery.support.focusinBubbles ) {
3363 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3365 // Attach a single capturing handler while someone wants focusin/focusout
3368 jQuery.event.special[ fix ] = {
3370 if ( attaches++ === 0 ) {
3371 document.addEventListener( orig, handler, true );
3374 teardown: function() {
3375 if ( --attaches === 0 ) {
3376 document.removeEventListener( orig, handler, true );
3381 function handler( donor ) {
3382 // Donor event is always a native one; fix it and switch its type.
3383 // Let focusin/out handler cancel the donor focus/blur event.
3384 var e = jQuery.event.fix( donor );
3386 e.originalEvent = {};
3387 jQuery.event.trigger( e, null, e.target );
3388 if ( e.isDefaultPrevented() ) {
3389 donor.preventDefault();
3395 jQuery.each(["bind", "one"], function( i, name ) {
3396 jQuery.fn[ name ] = function( type, data, fn ) {
3399 // Handle object literals
3400 if ( typeof type === "object" ) {
3401 for ( var key in type ) {
3402 this[ name ](key, data, type[key], fn);
3407 if ( arguments.length === 2 || data === false ) {
3412 if ( name === "one" ) {
3413 handler = function( event ) {
3414 jQuery( this ).unbind( event, handler );
3415 return fn.apply( this, arguments );
3417 handler.guid = fn.guid || jQuery.guid++;
3422 if ( type === "unload" && name !== "one" ) {
3423 this.one( type, data, fn );
3426 for ( var i = 0, l = this.length; i < l; i++ ) {
3427 jQuery.event.add( this[i], type, handler, data );
3436 unbind: function( type, fn ) {
3437 // Handle object literals
3438 if ( typeof type === "object" && !type.preventDefault ) {
3439 for ( var key in type ) {
3440 this.unbind(key, type[key]);
3444 for ( var i = 0, l = this.length; i < l; i++ ) {
3445 jQuery.event.remove( this[i], type, fn );
3452 delegate: function( selector, types, data, fn ) {
3453 return this.live( types, data, fn, selector );
3456 undelegate: function( selector, types, fn ) {
3457 if ( arguments.length === 0 ) {
3458 return this.unbind( "live" );
3461 return this.die( types, null, fn, selector );
3465 trigger: function( type, data ) {
3466 return this.each(function() {
3467 jQuery.event.trigger( type, data, this );
3471 triggerHandler: function( type, data ) {
3473 return jQuery.event.trigger( type, data, this[0], true );
3477 toggle: function( fn ) {
3478 // Save reference to arguments for access in closure
3479 var args = arguments,
3480 guid = fn.guid || jQuery.guid++,
3482 toggler = function( event ) {
3483 // Figure out which function to execute
3484 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3485 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3487 // Make sure that clicks stop
3488 event.preventDefault();
3490 // and execute the function
3491 return args[ lastToggle ].apply( this, arguments ) || false;
3494 // link all the functions, so any of them can unbind this click handler
3495 toggler.guid = guid;
3496 while ( i < args.length ) {
3497 args[ i++ ].guid = guid;
3500 return this.click( toggler );
3503 hover: function( fnOver, fnOut ) {
3504 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3511 mouseenter: "mouseover",
3512 mouseleave: "mouseout"
3515 jQuery.each(["live", "die"], function( i, name ) {
3516 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3517 var type, i = 0, match, namespaces, preType,
3518 selector = origSelector || this.selector,
3519 context = origSelector ? this : jQuery( this.context );
3521 if ( typeof types === "object" && !types.preventDefault ) {
3522 for ( var key in types ) {
3523 context[ name ]( key, data, types[key], selector );
3529 if ( name === "die" && !types &&
3530 origSelector && origSelector.charAt(0) === "." ) {
3532 context.unbind( origSelector );
3537 if ( data === false || jQuery.isFunction( data ) ) {
3538 fn = data || returnFalse;
3542 types = (types || "").split(" ");
3544 while ( (type = types[ i++ ]) != null ) {
3545 match = rnamespaces.exec( type );
3549 namespaces = match[0];
3550 type = type.replace( rnamespaces, "" );
3553 if ( type === "hover" ) {
3554 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3560 if ( liveMap[ type ] ) {
3561 types.push( liveMap[ type ] + namespaces );
3562 type = type + namespaces;
3565 type = (liveMap[ type ] || type) + namespaces;
3568 if ( name === "live" ) {
3569 // bind live handler
3570 for ( var j = 0, l = context.length; j < l; j++ ) {
3571 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3572 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3576 // unbind live handler
3577 context.unbind( "live." + liveConvert( type, selector ), fn );
3585 function liveHandler( event ) {
3586 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3589 events = jQuery._data( this, "events" );
3591 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3592 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3596 if ( event.namespace ) {
3597 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3600 event.liveFired = this;
3602 var live = events.live.slice(0);
3604 for ( j = 0; j < live.length; j++ ) {
3605 handleObj = live[j];
3607 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3608 selectors.push( handleObj.selector );
3611 live.splice( j--, 1 );
3615 match = jQuery( event.target ).closest( selectors, event.currentTarget );
3617 for ( i = 0, l = match.length; i < l; i++ ) {
3620 for ( j = 0; j < live.length; j++ ) {
3621 handleObj = live[j];
3623 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3627 // Those two events require additional checking
3628 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3629 event.type = handleObj.preType;
3630 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3632 // Make sure not to accidentally match a child element with the same selector
3633 if ( related && jQuery.contains( elem, related ) ) {
3638 if ( !related || related !== elem ) {
3639 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3645 for ( i = 0, l = elems.length; i < l; i++ ) {
3648 if ( maxLevel && match.level > maxLevel ) {
3652 event.currentTarget = match.elem;
3653 event.data = match.handleObj.data;
3654 event.handleObj = match.handleObj;
3656 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3658 if ( ret === false || event.isPropagationStopped() ) {
3659 maxLevel = match.level;
3661 if ( ret === false ) {
3664 if ( event.isImmediatePropagationStopped() ) {
3673 function liveConvert( type, selector ) {
3674 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3677 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3678 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3679 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3681 // Handle event binding
3682 jQuery.fn[ name ] = function( data, fn ) {
3688 return arguments.length > 0 ?
3689 this.bind( name, data, fn ) :
3690 this.trigger( name );
3693 if ( jQuery.attrFn ) {
3694 jQuery.attrFn[ name ] = true;
3701 * Sizzle CSS Selector Engine
3702 * Copyright 2011, The Dojo Foundation
3703 * Released under the MIT, BSD, and GPL Licenses.
3704 * More information: http://sizzlejs.com/
3708 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3710 toString = Object.prototype.toString,
3711 hasDuplicate = false,
3712 baseHasDuplicate = true,
3716 // Here we check if the JavaScript engine is using some sort of
3717 // optimization where it does not always call our comparision
3718 // function. If that is the case, discard the hasDuplicate value.
3719 // Thus far that includes Google Chrome.
3720 [0, 0].sort(function() {
3721 baseHasDuplicate = false;
3725 var Sizzle = function( selector, context, results, seed ) {
3726 results = results || [];
3727 context = context || document;
3729 var origContext = context;
3731 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3735 if ( !selector || typeof selector !== "string" ) {
3739 var m, set, checkSet, extra, ret, cur, pop, i,
3741 contextXML = Sizzle.isXML( context ),
3745 // Reset the position of the chunker regexp (start from head)
3748 m = chunker.exec( soFar );
3762 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3764 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3765 set = posProcess( parts[0] + parts[1], context );
3768 set = Expr.relative[ parts[0] ] ?
3770 Sizzle( parts.shift(), context );
3772 while ( parts.length ) {
3773 selector = parts.shift();
3775 if ( Expr.relative[ selector ] ) {
3776 selector += parts.shift();
3779 set = posProcess( selector, set );
3784 // Take a shortcut and set the context if the root selector is an ID
3785 // (but not if it'll be faster if the inner selector is an ID)
3786 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3787 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3789 ret = Sizzle.find( parts.shift(), context, contextXML );
3790 context = ret.expr ?
3791 Sizzle.filter( ret.expr, ret.set )[0] :
3797 { expr: parts.pop(), set: makeArray(seed) } :
3798 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3801 Sizzle.filter( ret.expr, ret.set ) :
3804 if ( parts.length > 0 ) {
3805 checkSet = makeArray( set );
3811 while ( parts.length ) {
3815 if ( !Expr.relative[ cur ] ) {
3821 if ( pop == null ) {
3825 Expr.relative[ cur ]( checkSet, pop, contextXML );
3829 checkSet = parts = [];
3838 Sizzle.error( cur || selector );
3841 if ( toString.call(checkSet) === "[object Array]" ) {
3843 results.push.apply( results, checkSet );
3845 } else if ( context && context.nodeType === 1 ) {
3846 for ( i = 0; checkSet[i] != null; i++ ) {
3847 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3848 results.push( set[i] );
3853 for ( i = 0; checkSet[i] != null; i++ ) {
3854 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3855 results.push( set[i] );
3861 makeArray( checkSet, results );
3865 Sizzle( extra, origContext, results, seed );
3866 Sizzle.uniqueSort( results );
3872 Sizzle.uniqueSort = function( results ) {
3874 hasDuplicate = baseHasDuplicate;
3875 results.sort( sortOrder );
3877 if ( hasDuplicate ) {
3878 for ( var i = 1; i < results.length; i++ ) {
3879 if ( results[i] === results[ i - 1 ] ) {
3880 results.splice( i--, 1 );
3889 Sizzle.matches = function( expr, set ) {
3890 return Sizzle( expr, null, null, set );
3893 Sizzle.matchesSelector = function( node, expr ) {
3894 return Sizzle( expr, null, null, [node] ).length > 0;
3897 Sizzle.find = function( expr, context, isXML ) {
3904 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3906 type = Expr.order[i];
3908 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3909 var left = match[1];
3910 match.splice( 1, 1 );
3912 if ( left.substr( left.length - 1 ) !== "\\" ) {
3913 match[1] = (match[1] || "").replace( rBackslash, "" );
3914 set = Expr.find[ type ]( match, context, isXML );
3916 if ( set != null ) {
3917 expr = expr.replace( Expr.match[ type ], "" );
3925 set = typeof context.getElementsByTagName !== "undefined" ?
3926 context.getElementsByTagName( "*" ) :
3930 return { set: set, expr: expr };
3933 Sizzle.filter = function( expr, set, inplace, not ) {
3934 var match, anyFound,
3938 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3940 while ( expr && set.length ) {
3941 for ( var type in Expr.filter ) {
3942 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3944 filter = Expr.filter[ type ],
3951 if ( left.substr( left.length - 1 ) === "\\" ) {
3955 if ( curLoop === result ) {
3959 if ( Expr.preFilter[ type ] ) {
3960 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3963 anyFound = found = true;
3965 } else if ( match === true ) {
3971 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3973 found = filter( item, match, i, curLoop );
3974 var pass = not ^ !!found;
3976 if ( inplace && found != null ) {
3984 } else if ( pass ) {
3985 result.push( item );
3992 if ( found !== undefined ) {
3997 expr = expr.replace( Expr.match[ type ], "" );
4008 // Improper expression
4009 if ( expr === old ) {
4010 if ( anyFound == null ) {
4011 Sizzle.error( expr );
4024 Sizzle.error = function( msg ) {
4025 throw "Syntax error, unrecognized expression: " + msg;
4028 var Expr = Sizzle.selectors = {
4029 order: [ "ID", "NAME", "TAG" ],
4032 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4033 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4034 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4035 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4036 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4037 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4038 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4039 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4045 "class": "className",
4050 href: function( elem ) {
4051 return elem.getAttribute( "href" );
4053 type: function( elem ) {
4054 return elem.getAttribute( "type" );
4059 "+": function(checkSet, part){
4060 var isPartStr = typeof part === "string",
4061 isTag = isPartStr && !rNonWord.test( part ),
4062 isPartStrNotTag = isPartStr && !isTag;
4065 part = part.toLowerCase();
4068 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4069 if ( (elem = checkSet[i]) ) {
4070 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4072 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4078 if ( isPartStrNotTag ) {
4079 Sizzle.filter( part, checkSet, true );
4083 ">": function( checkSet, part ) {
4085 isPartStr = typeof part === "string",
4087 l = checkSet.length;
4089 if ( isPartStr && !rNonWord.test( part ) ) {
4090 part = part.toLowerCase();
4092 for ( ; i < l; i++ ) {
4096 var parent = elem.parentNode;
4097 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4102 for ( ; i < l; i++ ) {
4106 checkSet[i] = isPartStr ?
4108 elem.parentNode === part;
4113 Sizzle.filter( part, checkSet, true );
4118 "": function(checkSet, part, isXML){
4123 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4124 part = part.toLowerCase();
4126 checkFn = dirNodeCheck;
4129 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4132 "~": function( checkSet, part, isXML ) {
4137 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4138 part = part.toLowerCase();
4140 checkFn = dirNodeCheck;
4143 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4148 ID: function( match, context, isXML ) {
4149 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4150 var m = context.getElementById(match[1]);
4151 // Check parentNode to catch when Blackberry 4.6 returns
4152 // nodes that are no longer in the document #6963
4153 return m && m.parentNode ? [m] : [];
4157 NAME: function( match, context ) {
4158 if ( typeof context.getElementsByName !== "undefined" ) {
4160 results = context.getElementsByName( match[1] );
4162 for ( var i = 0, l = results.length; i < l; i++ ) {
4163 if ( results[i].getAttribute("name") === match[1] ) {
4164 ret.push( results[i] );
4168 return ret.length === 0 ? null : ret;
4172 TAG: function( match, context ) {
4173 if ( typeof context.getElementsByTagName !== "undefined" ) {
4174 return context.getElementsByTagName( match[1] );
4179 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4180 match = " " + match[1].replace( rBackslash, "" ) + " ";
4186 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4188 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4190 result.push( elem );
4193 } else if ( inplace ) {
4202 ID: function( match ) {
4203 return match[1].replace( rBackslash, "" );
4206 TAG: function( match, curLoop ) {
4207 return match[1].replace( rBackslash, "" ).toLowerCase();
4210 CHILD: function( match ) {
4211 if ( match[1] === "nth" ) {
4213 Sizzle.error( match[0] );
4216 match[2] = match[2].replace(/^\+|\s*/g, '');
4218 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4219 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4220 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4221 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4223 // calculate the numbers (first)n+(last) including if they are negative
4224 match[2] = (test[1] + (test[2] || 1)) - 0;
4225 match[3] = test[3] - 0;
4227 else if ( match[2] ) {
4228 Sizzle.error( match[0] );
4231 // TODO: Move to normal caching system
4237 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4238 var name = match[1] = match[1].replace( rBackslash, "" );
4240 if ( !isXML && Expr.attrMap[name] ) {
4241 match[1] = Expr.attrMap[name];
4244 // Handle if an un-quoted value was used
4245 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4247 if ( match[2] === "~=" ) {
4248 match[4] = " " + match[4] + " ";
4254 PSEUDO: function( match, curLoop, inplace, result, not ) {
4255 if ( match[1] === "not" ) {
4256 // If we're dealing with a complex expression, or a simple one
4257 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4258 match[3] = Sizzle(match[3], null, null, curLoop);
4261 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4264 result.push.apply( result, ret );
4270 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4277 POS: function( match ) {
4278 match.unshift( true );
4285 enabled: function( elem ) {
4286 return elem.disabled === false && elem.type !== "hidden";
4289 disabled: function( elem ) {
4290 return elem.disabled === true;
4293 checked: function( elem ) {
4294 return elem.checked === true;
4297 selected: function( elem ) {
4298 // Accessing this property makes selected-by-default
4299 // options in Safari work properly
4300 if ( elem.parentNode ) {
4301 elem.parentNode.selectedIndex;
4304 return elem.selected === true;
4307 parent: function( elem ) {
4308 return !!elem.firstChild;
4311 empty: function( elem ) {
4312 return !elem.firstChild;
4315 has: function( elem, i, match ) {
4316 return !!Sizzle( match[3], elem ).length;
4319 header: function( elem ) {
4320 return (/h\d/i).test( elem.nodeName );
4323 text: function( elem ) {
4324 var attr = elem.getAttribute( "type" ), type = elem.type;
4325 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4326 // use getAttribute instead to test this case
4327 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4330 radio: function( elem ) {
4331 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4334 checkbox: function( elem ) {
4335 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4338 file: function( elem ) {
4339 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4342 password: function( elem ) {
4343 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4346 submit: function( elem ) {
4347 var name = elem.nodeName.toLowerCase();
4348 return (name === "input" || name === "button") && "submit" === elem.type;
4351 image: function( elem ) {
4352 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4355 reset: function( elem ) {
4356 var name = elem.nodeName.toLowerCase();
4357 return (name === "input" || name === "button") && "reset" === elem.type;
4360 button: function( elem ) {
4361 var name = elem.nodeName.toLowerCase();
4362 return name === "input" && "button" === elem.type || name === "button";
4365 input: function( elem ) {
4366 return (/input|select|textarea|button/i).test( elem.nodeName );
4369 focus: function( elem ) {
4370 return elem === elem.ownerDocument.activeElement;
4374 first: function( elem, i ) {
4378 last: function( elem, i, match, array ) {
4379 return i === array.length - 1;
4382 even: function( elem, i ) {
4386 odd: function( elem, i ) {
4390 lt: function( elem, i, match ) {
4391 return i < match[3] - 0;
4394 gt: function( elem, i, match ) {
4395 return i > match[3] - 0;
4398 nth: function( elem, i, match ) {
4399 return match[3] - 0 === i;
4402 eq: function( elem, i, match ) {
4403 return match[3] - 0 === i;
4407 PSEUDO: function( elem, match, i, array ) {
4408 var name = match[1],
4409 filter = Expr.filters[ name ];
4412 return filter( elem, i, match, array );
4414 } else if ( name === "contains" ) {
4415 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4417 } else if ( name === "not" ) {
4420 for ( var j = 0, l = not.length; j < l; j++ ) {
4421 if ( not[j] === elem ) {
4429 Sizzle.error( name );
4433 CHILD: function( elem, match ) {
4434 var type = match[1],
4440 while ( (node = node.previousSibling) ) {
4441 if ( node.nodeType === 1 ) {
4446 if ( type === "first" ) {
4453 while ( (node = node.nextSibling) ) {
4454 if ( node.nodeType === 1 ) {
4462 var first = match[2],
4465 if ( first === 1 && last === 0 ) {
4469 var doneName = match[0],
4470 parent = elem.parentNode;
4472 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4475 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4476 if ( node.nodeType === 1 ) {
4477 node.nodeIndex = ++count;
4481 parent.sizcache = doneName;
4484 var diff = elem.nodeIndex - last;
4486 if ( first === 0 ) {
4490 return ( diff % first === 0 && diff / first >= 0 );
4495 ID: function( elem, match ) {
4496 return elem.nodeType === 1 && elem.getAttribute("id") === match;
4499 TAG: function( elem, match ) {
4500 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4503 CLASS: function( elem, match ) {
4504 return (" " + (elem.className || elem.getAttribute("class")) + " ")
4505 .indexOf( match ) > -1;
4508 ATTR: function( elem, match ) {
4509 var name = match[1],
4510 result = Expr.attrHandle[ name ] ?
4511 Expr.attrHandle[ name ]( elem ) :
4512 elem[ name ] != null ?
4514 elem.getAttribute( name ),
4515 value = result + "",
4519 return result == null ?
4524 value.indexOf(check) >= 0 :
4526 (" " + value + " ").indexOf(check) >= 0 :
4528 value && result !== false :
4532 value.indexOf(check) === 0 :
4534 value.substr(value.length - check.length) === check :
4536 value === check || value.substr(0, check.length + 1) === check + "-" :
4540 POS: function( elem, match, i, array ) {
4541 var name = match[2],
4542 filter = Expr.setFilters[ name ];
4545 return filter( elem, i, match, array );
4551 var origPOS = Expr.match.POS,
4552 fescape = function(all, num){
4553 return "\\" + (num - 0 + 1);
4556 for ( var type in Expr.match ) {
4557 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4558 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4561 var makeArray = function( array, results ) {
4562 array = Array.prototype.slice.call( array, 0 );
4565 results.push.apply( results, array );
4572 // Perform a simple check to determine if the browser is capable of
4573 // converting a NodeList to an array using builtin methods.
4574 // Also verifies that the returned array holds DOM nodes
4575 // (which is not the case in the Blackberry browser)
4577 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4579 // Provide a fallback method if it does not work
4581 makeArray = function( array, results ) {
4583 ret = results || [];
4585 if ( toString.call(array) === "[object Array]" ) {
4586 Array.prototype.push.apply( ret, array );
4589 if ( typeof array.length === "number" ) {
4590 for ( var l = array.length; i < l; i++ ) {
4591 ret.push( array[i] );
4595 for ( ; array[i]; i++ ) {
4596 ret.push( array[i] );
4605 var sortOrder, siblingCheck;
4607 if ( document.documentElement.compareDocumentPosition ) {
4608 sortOrder = function( a, b ) {
4610 hasDuplicate = true;
4614 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4615 return a.compareDocumentPosition ? -1 : 1;
4618 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4622 sortOrder = function( a, b ) {
4623 // The nodes are identical, we can exit early
4625 hasDuplicate = true;
4628 // Fallback to using sourceIndex (in IE) if it's available on both nodes
4629 } else if ( a.sourceIndex && b.sourceIndex ) {
4630 return a.sourceIndex - b.sourceIndex;
4640 // If the nodes are siblings (or identical) we can do a quick check
4641 if ( aup === bup ) {
4642 return siblingCheck( a, b );
4644 // If no parents were found then the nodes are disconnected
4645 } else if ( !aup ) {
4648 } else if ( !bup ) {
4652 // Otherwise they're somewhere else in the tree so we need
4653 // to build up a full list of the parentNodes for comparison
4656 cur = cur.parentNode;
4663 cur = cur.parentNode;
4669 // Start walking down the tree looking for a discrepancy
4670 for ( var i = 0; i < al && i < bl; i++ ) {
4671 if ( ap[i] !== bp[i] ) {
4672 return siblingCheck( ap[i], bp[i] );
4676 // We ended someplace up the tree so do a sibling check
4678 siblingCheck( a, bp[i], -1 ) :
4679 siblingCheck( ap[i], b, 1 );
4682 siblingCheck = function( a, b, ret ) {
4687 var cur = a.nextSibling;
4694 cur = cur.nextSibling;
4701 // Utility function for retreiving the text value of an array of DOM nodes
4702 Sizzle.getText = function( elems ) {
4705 for ( var i = 0; elems[i]; i++ ) {
4708 // Get the text from text nodes and CDATA nodes
4709 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4710 ret += elem.nodeValue;
4712 // Traverse everything else, except comment nodes
4713 } else if ( elem.nodeType !== 8 ) {
4714 ret += Sizzle.getText( elem.childNodes );
4721 // Check to see if the browser returns elements by name when
4722 // querying by getElementById (and provide a workaround)
4724 // We're going to inject a fake input element with a specified name
4725 var form = document.createElement("div"),
4726 id = "script" + (new Date()).getTime(),
4727 root = document.documentElement;
4729 form.innerHTML = "<a name='" + id + "'/>";
4731 // Inject it into the root element, check its status, and remove it quickly
4732 root.insertBefore( form, root.firstChild );
4734 // The workaround has to do additional checks after a getElementById
4735 // Which slows things down for other browsers (hence the branching)
4736 if ( document.getElementById( id ) ) {
4737 Expr.find.ID = function( match, context, isXML ) {
4738 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4739 var m = context.getElementById(match[1]);
4742 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4749 Expr.filter.ID = function( elem, match ) {
4750 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4752 return elem.nodeType === 1 && node && node.nodeValue === match;
4756 root.removeChild( form );
4758 // release memory in IE
4763 // Check to see if the browser returns only elements
4764 // when doing getElementsByTagName("*")
4766 // Create a fake element
4767 var div = document.createElement("div");
4768 div.appendChild( document.createComment("") );
4770 // Make sure no comments are found
4771 if ( div.getElementsByTagName("*").length > 0 ) {
4772 Expr.find.TAG = function( match, context ) {
4773 var results = context.getElementsByTagName( match[1] );
4775 // Filter out possible comments
4776 if ( match[1] === "*" ) {
4779 for ( var i = 0; results[i]; i++ ) {
4780 if ( results[i].nodeType === 1 ) {
4781 tmp.push( results[i] );
4792 // Check to see if an attribute returns normalized href attributes
4793 div.innerHTML = "<a href='#'></a>";
4795 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4796 div.firstChild.getAttribute("href") !== "#" ) {
4798 Expr.attrHandle.href = function( elem ) {
4799 return elem.getAttribute( "href", 2 );
4803 // release memory in IE
4807 if ( document.querySelectorAll ) {
4809 var oldSizzle = Sizzle,
4810 div = document.createElement("div"),
4813 div.innerHTML = "<p class='TEST'></p>";
4815 // Safari can't handle uppercase or unicode characters when
4817 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4821 Sizzle = function( query, context, extra, seed ) {
4822 context = context || document;
4824 // Only use querySelectorAll on non-XML documents
4825 // (ID selectors don't work in non-HTML documents)
4826 if ( !seed && !Sizzle.isXML(context) ) {
4827 // See if we find a selector to speed up
4828 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4830 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4831 // Speed-up: Sizzle("TAG")
4833 return makeArray( context.getElementsByTagName( query ), extra );
4835 // Speed-up: Sizzle(".CLASS")
4836 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4837 return makeArray( context.getElementsByClassName( match[2] ), extra );
4841 if ( context.nodeType === 9 ) {
4842 // Speed-up: Sizzle("body")
4843 // The body element only exists once, optimize finding it
4844 if ( query === "body" && context.body ) {
4845 return makeArray( [ context.body ], extra );
4847 // Speed-up: Sizzle("#ID")
4848 } else if ( match && match[3] ) {
4849 var elem = context.getElementById( match[3] );
4851 // Check parentNode to catch when Blackberry 4.6 returns
4852 // nodes that are no longer in the document #6963
4853 if ( elem && elem.parentNode ) {
4854 // Handle the case where IE and Opera return items
4855 // by name instead of ID
4856 if ( elem.id === match[3] ) {
4857 return makeArray( [ elem ], extra );
4861 return makeArray( [], extra );
4866 return makeArray( context.querySelectorAll(query), extra );
4867 } catch(qsaError) {}
4869 // qSA works strangely on Element-rooted queries
4870 // We can work around this by specifying an extra ID on the root
4871 // and working up from there (Thanks to Andrew Dupont for the technique)
4872 // IE 8 doesn't work on object elements
4873 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4874 var oldContext = context,
4875 old = context.getAttribute( "id" ),
4877 hasParent = context.parentNode,
4878 relativeHierarchySelector = /^\s*[+~]/.test( query );
4881 context.setAttribute( "id", nid );
4883 nid = nid.replace( /'/g, "\\$&" );
4885 if ( relativeHierarchySelector && hasParent ) {
4886 context = context.parentNode;
4890 if ( !relativeHierarchySelector || hasParent ) {
4891 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4894 } catch(pseudoError) {
4897 oldContext.removeAttribute( "id" );
4903 return oldSizzle(query, context, extra, seed);
4906 for ( var prop in oldSizzle ) {
4907 Sizzle[ prop ] = oldSizzle[ prop ];
4910 // release memory in IE
4916 var html = document.documentElement,
4917 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
4920 // Check to see if it's possible to do matchesSelector
4921 // on a disconnected node (IE 9 fails this)
4922 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
4923 pseudoWorks = false;
4926 // This should fail with an exception
4927 // Gecko does not error, returns false instead
4928 matches.call( document.documentElement, "[test!='']:sizzle" );
4930 } catch( pseudoError ) {
4934 Sizzle.matchesSelector = function( node, expr ) {
4935 // Make sure that attribute selectors are quoted
4936 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4938 if ( !Sizzle.isXML( node ) ) {
4940 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4941 var ret = matches.call( node, expr );
4943 // IE 9's matchesSelector returns false on disconnected nodes
4944 if ( ret || !disconnectedMatch ||
4945 // As well, disconnected nodes are said to be in a document
4946 // fragment in IE 9, so check for that
4947 node.document && node.document.nodeType !== 11 ) {
4954 return Sizzle(expr, null, null, [node]).length > 0;
4960 var div = document.createElement("div");
4962 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4964 // Opera can't find a second classname (in 9.6)
4965 // Also, make sure that getElementsByClassName actually exists
4966 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4970 // Safari caches class attributes, doesn't catch changes (in 3.2)
4971 div.lastChild.className = "e";
4973 if ( div.getElementsByClassName("e").length === 1 ) {
4977 Expr.order.splice(1, 0, "CLASS");
4978 Expr.find.CLASS = function( match, context, isXML ) {
4979 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4980 return context.getElementsByClassName(match[1]);
4984 // release memory in IE
4988 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4989 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4990 var elem = checkSet[i];
4998 if ( elem.sizcache === doneName ) {
4999 match = checkSet[elem.sizset];
5003 if ( elem.nodeType === 1 && !isXML ){
5004 elem.sizcache = doneName;
5008 if ( elem.nodeName.toLowerCase() === cur ) {
5016 checkSet[i] = match;
5021 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5022 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5023 var elem = checkSet[i];
5031 if ( elem.sizcache === doneName ) {
5032 match = checkSet[elem.sizset];
5036 if ( elem.nodeType === 1 ) {
5038 elem.sizcache = doneName;
5042 if ( typeof cur !== "string" ) {
5043 if ( elem === cur ) {
5048 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5057 checkSet[i] = match;
5062 if ( document.documentElement.contains ) {
5063 Sizzle.contains = function( a, b ) {
5064 return a !== b && (a.contains ? a.contains(b) : true);
5067 } else if ( document.documentElement.compareDocumentPosition ) {
5068 Sizzle.contains = function( a, b ) {
5069 return !!(a.compareDocumentPosition(b) & 16);
5073 Sizzle.contains = function() {
5078 Sizzle.isXML = function( elem ) {
5079 // documentElement is verified for cases where it doesn't yet exist
5080 // (such as loading iframes in IE - #4833)
5081 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5083 return documentElement ? documentElement.nodeName !== "HTML" : false;
5086 var posProcess = function( selector, context ) {
5090 root = context.nodeType ? [context] : context;
5092 // Position selectors must be done after the filter
5093 // And so must :not(positional) so we move all PSEUDOs to the end
5094 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5096 selector = selector.replace( Expr.match.PSEUDO, "" );
5099 selector = Expr.relative[selector] ? selector + "*" : selector;
5101 for ( var i = 0, l = root.length; i < l; i++ ) {
5102 Sizzle( selector, root[i], tmpSet );
5105 return Sizzle.filter( later, tmpSet );
5109 jQuery.find = Sizzle;
5110 jQuery.expr = Sizzle.selectors;
5111 jQuery.expr[":"] = jQuery.expr.filters;
5112 jQuery.unique = Sizzle.uniqueSort;
5113 jQuery.text = Sizzle.getText;
5114 jQuery.isXMLDoc = Sizzle.isXML;
5115 jQuery.contains = Sizzle.contains;
5121 var runtil = /Until$/,
5122 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5123 // Note: This RegExp should be improved, or likely pulled from Sizzle
5124 rmultiselector = /,/,
5125 isSimple = /^.[^:#\[\.,]*$/,
5126 slice = Array.prototype.slice,
5127 POS = jQuery.expr.match.POS,
5128 // methods guaranteed to produce a unique set when starting from a unique set
5129 guaranteedUnique = {
5137 find: function( selector ) {
5141 if ( typeof selector !== "string" ) {
5142 return jQuery( selector ).filter(function() {
5143 for ( i = 0, l = self.length; i < l; i++ ) {
5144 if ( jQuery.contains( self[ i ], this ) ) {
5151 var ret = this.pushStack( "", "find", selector ),
5154 for ( i = 0, l = this.length; i < l; i++ ) {
5155 length = ret.length;
5156 jQuery.find( selector, this[i], ret );
5159 // Make sure that the results are unique
5160 for ( n = length; n < ret.length; n++ ) {
5161 for ( r = 0; r < length; r++ ) {
5162 if ( ret[r] === ret[n] ) {
5174 has: function( target ) {
5175 var targets = jQuery( target );
5176 return this.filter(function() {
5177 for ( var i = 0, l = targets.length; i < l; i++ ) {
5178 if ( jQuery.contains( this, targets[i] ) ) {
5185 not: function( selector ) {
5186 return this.pushStack( winnow(this, selector, false), "not", selector);
5189 filter: function( selector ) {
5190 return this.pushStack( winnow(this, selector, true), "filter", selector );
5193 is: function( selector ) {
5194 return !!selector && ( typeof selector === "string" ?
5195 jQuery.filter( selector, this ).length > 0 :
5196 this.filter( selector ).length > 0 );
5199 closest: function( selectors, context ) {
5200 var ret = [], i, l, cur = this[0];
5203 if ( jQuery.isArray( selectors ) ) {
5204 var match, selector,
5208 if ( cur && selectors.length ) {
5209 for ( i = 0, l = selectors.length; i < l; i++ ) {
5210 selector = selectors[i];
5212 if ( !matches[ selector ] ) {
5213 matches[ selector ] = POS.test( selector ) ?
5214 jQuery( selector, context || this.context ) :
5219 while ( cur && cur.ownerDocument && cur !== context ) {
5220 for ( selector in matches ) {
5221 match = matches[ selector ];
5223 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5224 ret.push({ selector: selector, elem: cur, level: level });
5228 cur = cur.parentNode;
5237 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5238 jQuery( selectors, context || this.context ) :
5241 for ( i = 0, l = this.length; i < l; i++ ) {
5245 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5250 cur = cur.parentNode;
5251 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5258 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5260 return this.pushStack( ret, "closest", selectors );
5263 // Determine the position of an element within
5264 // the matched set of elements
5265 index: function( elem ) {
5266 if ( !elem || typeof elem === "string" ) {
5267 return jQuery.inArray( this[0],
5268 // If it receives a string, the selector is used
5269 // If it receives nothing, the siblings are used
5270 elem ? jQuery( elem ) : this.parent().children() );
5272 // Locate the position of the desired element
5273 return jQuery.inArray(
5274 // If it receives a jQuery object, the first element is used
5275 elem.jquery ? elem[0] : elem, this );
5278 add: function( selector, context ) {
5279 var set = typeof selector === "string" ?
5280 jQuery( selector, context ) :
5281 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5282 all = jQuery.merge( this.get(), set );
5284 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5286 jQuery.unique( all ) );
5289 andSelf: function() {
5290 return this.add( this.prevObject );
5294 // A painfully simple check to see if an element is disconnected
5295 // from a document (should be improved, where feasible).
5296 function isDisconnected( node ) {
5297 return !node || !node.parentNode || node.parentNode.nodeType === 11;
5301 parent: function( elem ) {
5302 var parent = elem.parentNode;
5303 return parent && parent.nodeType !== 11 ? parent : null;
5305 parents: function( elem ) {
5306 return jQuery.dir( elem, "parentNode" );
5308 parentsUntil: function( elem, i, until ) {
5309 return jQuery.dir( elem, "parentNode", until );
5311 next: function( elem ) {
5312 return jQuery.nth( elem, 2, "nextSibling" );
5314 prev: function( elem ) {
5315 return jQuery.nth( elem, 2, "previousSibling" );
5317 nextAll: function( elem ) {
5318 return jQuery.dir( elem, "nextSibling" );
5320 prevAll: function( elem ) {
5321 return jQuery.dir( elem, "previousSibling" );
5323 nextUntil: function( elem, i, until ) {
5324 return jQuery.dir( elem, "nextSibling", until );
5326 prevUntil: function( elem, i, until ) {
5327 return jQuery.dir( elem, "previousSibling", until );
5329 siblings: function( elem ) {
5330 return jQuery.sibling( elem.parentNode.firstChild, elem );
5332 children: function( elem ) {
5333 return jQuery.sibling( elem.firstChild );
5335 contents: function( elem ) {
5336 return jQuery.nodeName( elem, "iframe" ) ?
5337 elem.contentDocument || elem.contentWindow.document :
5338 jQuery.makeArray( elem.childNodes );
5340 }, function( name, fn ) {
5341 jQuery.fn[ name ] = function( until, selector ) {
5342 var ret = jQuery.map( this, fn, until ),
5343 // The variable 'args' was introduced in
5344 // https://github.com/jquery/jquery/commit/52a0238
5345 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5346 // http://code.google.com/p/v8/issues/detail?id=1050
5347 args = slice.call(arguments);
5349 if ( !runtil.test( name ) ) {
5353 if ( selector && typeof selector === "string" ) {
5354 ret = jQuery.filter( selector, ret );
5357 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5359 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5360 ret = ret.reverse();
5363 return this.pushStack( ret, name, args.join(",") );
5368 filter: function( expr, elems, not ) {
5370 expr = ":not(" + expr + ")";
5373 return elems.length === 1 ?
5374 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5375 jQuery.find.matches(expr, elems);
5378 dir: function( elem, dir, until ) {
5382 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5383 if ( cur.nodeType === 1 ) {
5384 matched.push( cur );
5391 nth: function( cur, result, dir, elem ) {
5392 result = result || 1;
5395 for ( ; cur; cur = cur[dir] ) {
5396 if ( cur.nodeType === 1 && ++num === result ) {
5404 sibling: function( n, elem ) {
5407 for ( ; n; n = n.nextSibling ) {
5408 if ( n.nodeType === 1 && n !== elem ) {
5417 // Implement the identical functionality for filter and not
5418 function winnow( elements, qualifier, keep ) {
5420 // Can't pass null or undefined to indexOf in Firefox 4
5421 // Set to 0 to skip string check
5422 qualifier = qualifier || 0;
5424 if ( jQuery.isFunction( qualifier ) ) {
5425 return jQuery.grep(elements, function( elem, i ) {
5426 var retVal = !!qualifier.call( elem, i, elem );
5427 return retVal === keep;
5430 } else if ( qualifier.nodeType ) {
5431 return jQuery.grep(elements, function( elem, i ) {
5432 return (elem === qualifier) === keep;
5435 } else if ( typeof qualifier === "string" ) {
5436 var filtered = jQuery.grep(elements, function( elem ) {
5437 return elem.nodeType === 1;
5440 if ( isSimple.test( qualifier ) ) {
5441 return jQuery.filter(qualifier, filtered, !keep);
5443 qualifier = jQuery.filter( qualifier, filtered );
5447 return jQuery.grep(elements, function( elem, i ) {
5448 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5455 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5456 rleadingWhitespace = /^\s+/,
5457 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5458 rtagName = /<([\w:]+)/,
5460 rhtml = /<|&#?\w+;/,
5461 rnocache = /<(?:script|object|embed|option|style)/i,
5462 // checked="checked" or checked
5463 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5464 rscriptType = /\/(java|ecma)script/i,
5465 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5467 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5468 legend: [ 1, "<fieldset>", "</fieldset>" ],
5469 thead: [ 1, "<table>", "</table>" ],
5470 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5471 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5472 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5473 area: [ 1, "<map>", "</map>" ],
5474 _default: [ 0, "", "" ]
5477 wrapMap.optgroup = wrapMap.option;
5478 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5479 wrapMap.th = wrapMap.td;
5481 // IE can't serialize <link> and <script> tags normally
5482 if ( !jQuery.support.htmlSerialize ) {
5483 wrapMap._default = [ 1, "div<div>", "</div>" ];
5487 text: function( text ) {
5488 if ( jQuery.isFunction(text) ) {
5489 return this.each(function(i) {
5490 var self = jQuery( this );
5492 self.text( text.call(this, i, self.text()) );
5496 if ( typeof text !== "object" && text !== undefined ) {
5497 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5500 return jQuery.text( this );
5503 wrapAll: function( html ) {
5504 if ( jQuery.isFunction( html ) ) {
5505 return this.each(function(i) {
5506 jQuery(this).wrapAll( html.call(this, i) );
5511 // The elements to wrap the target around
5512 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5514 if ( this[0].parentNode ) {
5515 wrap.insertBefore( this[0] );
5518 wrap.map(function() {
5521 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5522 elem = elem.firstChild;
5532 wrapInner: function( html ) {
5533 if ( jQuery.isFunction( html ) ) {
5534 return this.each(function(i) {
5535 jQuery(this).wrapInner( html.call(this, i) );
5539 return this.each(function() {
5540 var self = jQuery( this ),
5541 contents = self.contents();
5543 if ( contents.length ) {
5544 contents.wrapAll( html );
5547 self.append( html );
5552 wrap: function( html ) {
5553 return this.each(function() {
5554 jQuery( this ).wrapAll( html );
5558 unwrap: function() {
5559 return this.parent().each(function() {
5560 if ( !jQuery.nodeName( this, "body" ) ) {
5561 jQuery( this ).replaceWith( this.childNodes );
5566 append: function() {
5567 return this.domManip(arguments, true, function( elem ) {
5568 if ( this.nodeType === 1 ) {
5569 this.appendChild( elem );
5574 prepend: function() {
5575 return this.domManip(arguments, true, function( elem ) {
5576 if ( this.nodeType === 1 ) {
5577 this.insertBefore( elem, this.firstChild );
5582 before: function() {
5583 if ( this[0] && this[0].parentNode ) {
5584 return this.domManip(arguments, false, function( elem ) {
5585 this.parentNode.insertBefore( elem, this );
5587 } else if ( arguments.length ) {
5588 var set = jQuery(arguments[0]);
5589 set.push.apply( set, this.toArray() );
5590 return this.pushStack( set, "before", arguments );
5595 if ( this[0] && this[0].parentNode ) {
5596 return this.domManip(arguments, false, function( elem ) {
5597 this.parentNode.insertBefore( elem, this.nextSibling );
5599 } else if ( arguments.length ) {
5600 var set = this.pushStack( this, "after", arguments );
5601 set.push.apply( set, jQuery(arguments[0]).toArray() );
5606 // keepData is for internal use only--do not document
5607 remove: function( selector, keepData ) {
5608 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5609 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5610 if ( !keepData && elem.nodeType === 1 ) {
5611 jQuery.cleanData( elem.getElementsByTagName("*") );
5612 jQuery.cleanData( [ elem ] );
5615 if ( elem.parentNode ) {
5616 elem.parentNode.removeChild( elem );
5625 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5626 // Remove element nodes and prevent memory leaks
5627 if ( elem.nodeType === 1 ) {
5628 jQuery.cleanData( elem.getElementsByTagName("*") );
5631 // Remove any remaining nodes
5632 while ( elem.firstChild ) {
5633 elem.removeChild( elem.firstChild );
5640 clone: function( dataAndEvents, deepDataAndEvents ) {
5641 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5642 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5644 return this.map( function () {
5645 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5649 html: function( value ) {
5650 if ( value === undefined ) {
5651 return this[0] && this[0].nodeType === 1 ?
5652 this[0].innerHTML.replace(rinlinejQuery, "") :
5655 // See if we can take a shortcut and just use innerHTML
5656 } else if ( typeof value === "string" && !rnocache.test( value ) &&
5657 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5658 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5660 value = value.replace(rxhtmlTag, "<$1></$2>");
5663 for ( var i = 0, l = this.length; i < l; i++ ) {
5664 // Remove element nodes and prevent memory leaks
5665 if ( this[i].nodeType === 1 ) {
5666 jQuery.cleanData( this[i].getElementsByTagName("*") );
5667 this[i].innerHTML = value;
5671 // If using innerHTML throws an exception, use the fallback method
5673 this.empty().append( value );
5676 } else if ( jQuery.isFunction( value ) ) {
5677 this.each(function(i){
5678 var self = jQuery( this );
5680 self.html( value.call(this, i, self.html()) );
5684 this.empty().append( value );
5690 replaceWith: function( value ) {
5691 if ( this[0] && this[0].parentNode ) {
5692 // Make sure that the elements are removed from the DOM before they are inserted
5693 // this can help fix replacing a parent with child elements
5694 if ( jQuery.isFunction( value ) ) {
5695 return this.each(function(i) {
5696 var self = jQuery(this), old = self.html();
5697 self.replaceWith( value.call( this, i, old ) );
5701 if ( typeof value !== "string" ) {
5702 value = jQuery( value ).detach();
5705 return this.each(function() {
5706 var next = this.nextSibling,
5707 parent = this.parentNode;
5709 jQuery( this ).remove();
5712 jQuery(next).before( value );
5714 jQuery(parent).append( value );
5718 return this.length ?
5719 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5724 detach: function( selector ) {
5725 return this.remove( selector, true );
5728 domManip: function( args, table, callback ) {
5729 var results, first, fragment, parent,
5733 // We can't cloneNode fragments that contain checked, in WebKit
5734 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5735 return this.each(function() {
5736 jQuery(this).domManip( args, table, callback, true );
5740 if ( jQuery.isFunction(value) ) {
5741 return this.each(function(i) {
5742 var self = jQuery(this);
5743 args[0] = value.call(this, i, table ? self.html() : undefined);
5744 self.domManip( args, table, callback );
5749 parent = value && value.parentNode;
5751 // If we're in a fragment, just use that instead of building a new one
5752 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5753 results = { fragment: parent };
5756 results = jQuery.buildFragment( args, this, scripts );
5759 fragment = results.fragment;
5761 if ( fragment.childNodes.length === 1 ) {
5762 first = fragment = fragment.firstChild;
5764 first = fragment.firstChild;
5768 table = table && jQuery.nodeName( first, "tr" );
5770 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5773 root(this[i], first) :
5775 // Make sure that we do not leak memory by inadvertently discarding
5776 // the original fragment (which might have attached data) instead of
5777 // using it; in addition, use the original fragment object for the last
5778 // item instead of first because it can end up being emptied incorrectly
5779 // in certain situations (Bug #8070).
5780 // Fragments from the fragment cache must always be cloned and never used
5782 results.cacheable || (l > 1 && i < lastIndex) ?
5783 jQuery.clone( fragment, true, true ) :
5789 if ( scripts.length ) {
5790 jQuery.each( scripts, evalScript );
5798 function root( elem, cur ) {
5799 return jQuery.nodeName(elem, "table") ?
5800 (elem.getElementsByTagName("tbody")[0] ||
5801 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5805 function cloneCopyEvent( src, dest ) {
5807 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5811 var internalKey = jQuery.expando,
5812 oldData = jQuery.data( src ),
5813 curData = jQuery.data( dest, oldData );
5815 // Switch to use the internal data object, if it exists, for the next
5816 // stage of data copying
5817 if ( (oldData = oldData[ internalKey ]) ) {
5818 var events = oldData.events;
5819 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5822 delete curData.handle;
5823 curData.events = {};
5825 for ( var type in events ) {
5826 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5827 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5834 function cloneFixAttributes( src, dest ) {
5837 // We do not need to do anything for non-Elements
5838 if ( dest.nodeType !== 1 ) {
5842 // clearAttributes removes the attributes, which we don't want,
5843 // but also removes the attachEvent events, which we *do* want
5844 if ( dest.clearAttributes ) {
5845 dest.clearAttributes();
5848 // mergeAttributes, in contrast, only merges back on the
5849 // original attributes, not the events
5850 if ( dest.mergeAttributes ) {
5851 dest.mergeAttributes( src );
5854 nodeName = dest.nodeName.toLowerCase();
5856 // IE6-8 fail to clone children inside object elements that use
5857 // the proprietary classid attribute value (rather than the type
5858 // attribute) to identify the type of content to display
5859 if ( nodeName === "object" ) {
5860 dest.outerHTML = src.outerHTML;
5862 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5863 // IE6-8 fails to persist the checked state of a cloned checkbox
5864 // or radio button. Worse, IE6-7 fail to give the cloned element
5865 // a checked appearance if the defaultChecked value isn't also set
5866 if ( src.checked ) {
5867 dest.defaultChecked = dest.checked = src.checked;
5870 // IE6-7 get confused and end up setting the value of a cloned
5871 // checkbox/radio button to an empty string instead of "on"
5872 if ( dest.value !== src.value ) {
5873 dest.value = src.value;
5876 // IE6-8 fails to return the selected option to the default selected
5877 // state when cloning options
5878 } else if ( nodeName === "option" ) {
5879 dest.selected = src.defaultSelected;
5881 // IE6-8 fails to set the defaultValue to the correct value when
5882 // cloning other types of input fields
5883 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5884 dest.defaultValue = src.defaultValue;
5887 // Event data gets referenced instead of copied if the expando
5889 dest.removeAttribute( jQuery.expando );
5892 jQuery.buildFragment = function( args, nodes, scripts ) {
5893 var fragment, cacheable, cacheresults,
5894 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5896 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5897 // Cloning options loses the selected state, so don't cache them
5898 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5899 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5900 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5901 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5905 cacheresults = jQuery.fragments[ args[0] ];
5906 if ( cacheresults && cacheresults !== 1 ) {
5907 fragment = cacheresults;
5912 fragment = doc.createDocumentFragment();
5913 jQuery.clean( args, doc, fragment, scripts );
5917 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5920 return { fragment: fragment, cacheable: cacheable };
5923 jQuery.fragments = {};
5927 prependTo: "prepend",
5928 insertBefore: "before",
5929 insertAfter: "after",
5930 replaceAll: "replaceWith"
5931 }, function( name, original ) {
5932 jQuery.fn[ name ] = function( selector ) {
5934 insert = jQuery( selector ),
5935 parent = this.length === 1 && this[0].parentNode;
5937 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5938 insert[ original ]( this[0] );
5942 for ( var i = 0, l = insert.length; i < l; i++ ) {
5943 var elems = (i > 0 ? this.clone(true) : this).get();
5944 jQuery( insert[i] )[ original ]( elems );
5945 ret = ret.concat( elems );
5948 return this.pushStack( ret, name, insert.selector );
5953 function getAll( elem ) {
5954 if ( "getElementsByTagName" in elem ) {
5955 return elem.getElementsByTagName( "*" );
5957 } else if ( "querySelectorAll" in elem ) {
5958 return elem.querySelectorAll( "*" );
5965 // Used in clean, fixes the defaultChecked property
5966 function fixDefaultChecked( elem ) {
5967 if ( elem.type === "checkbox" || elem.type === "radio" ) {
5968 elem.defaultChecked = elem.checked;
5971 // Finds all inputs and passes them to fixDefaultChecked
5972 function findInputs( elem ) {
5973 if ( jQuery.nodeName( elem, "input" ) ) {
5974 fixDefaultChecked( elem );
5975 } else if ( elem.getElementsByTagName ) {
5976 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
5981 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5982 var clone = elem.cloneNode(true),
5987 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
5988 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
5989 // IE copies events bound via attachEvent when using cloneNode.
5990 // Calling detachEvent on the clone will also remove the events
5991 // from the original. In order to get around this, we use some
5992 // proprietary methods to clear the events. Thanks to MooTools
5993 // guys for this hotness.
5995 cloneFixAttributes( elem, clone );
5997 // Using Sizzle here is crazy slow, so we use getElementsByTagName
5999 srcElements = getAll( elem );
6000 destElements = getAll( clone );
6002 // Weird iteration because IE will replace the length property
6003 // with an element if you are cloning the body and one of the
6004 // elements on the page has a name or id of "length"
6005 for ( i = 0; srcElements[i]; ++i ) {
6006 cloneFixAttributes( srcElements[i], destElements[i] );
6010 // Copy the events from the original to the clone
6011 if ( dataAndEvents ) {
6012 cloneCopyEvent( elem, clone );
6014 if ( deepDataAndEvents ) {
6015 srcElements = getAll( elem );
6016 destElements = getAll( clone );
6018 for ( i = 0; srcElements[i]; ++i ) {
6019 cloneCopyEvent( srcElements[i], destElements[i] );
6024 // Return the cloned set
6028 clean: function( elems, context, fragment, scripts ) {
6029 var checkScriptType;
6031 context = context || document;
6033 // !context.createElement fails in IE with an error but returns typeof 'object'
6034 if ( typeof context.createElement === "undefined" ) {
6035 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6040 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6041 if ( typeof elem === "number" ) {
6049 // Convert html string into DOM nodes
6050 if ( typeof elem === "string" ) {
6051 if ( !rhtml.test( elem ) ) {
6052 elem = context.createTextNode( elem );
6054 // Fix "XHTML"-style tags in all browsers
6055 elem = elem.replace(rxhtmlTag, "<$1></$2>");
6057 // Trim whitespace, otherwise indexOf won't work as expected
6058 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6059 wrap = wrapMap[ tag ] || wrapMap._default,
6061 div = context.createElement("div");
6063 // Go to html and back, then peel off extra wrappers
6064 div.innerHTML = wrap[1] + elem + wrap[2];
6066 // Move to the right depth
6068 div = div.lastChild;
6071 // Remove IE's autoinserted <tbody> from table fragments
6072 if ( !jQuery.support.tbody ) {
6074 // String was a <table>, *may* have spurious <tbody>
6075 var hasBody = rtbody.test(elem),
6076 tbody = tag === "table" && !hasBody ?
6077 div.firstChild && div.firstChild.childNodes :
6079 // String was a bare <thead> or <tfoot>
6080 wrap[1] === "<table>" && !hasBody ?
6084 for ( j = tbody.length - 1; j >= 0 ; --j ) {
6085 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6086 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6091 // IE completely kills leading whitespace when innerHTML is used
6092 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6093 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6096 elem = div.childNodes;
6100 // Resets defaultChecked for any radios and checkboxes
6101 // about to be appended to the DOM in IE 6/7 (#8060)
6103 if ( !jQuery.support.appendChecked ) {
6104 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6105 for ( j = 0; j < len; j++ ) {
6106 findInputs( elem[j] );
6113 if ( elem.nodeType ) {
6116 ret = jQuery.merge( ret, elem );
6121 checkScriptType = function( elem ) {
6122 return !elem.type || rscriptType.test( elem.type );
6124 for ( i = 0; ret[i]; i++ ) {
6125 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6126 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6129 if ( ret[i].nodeType === 1 ) {
6130 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6132 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6134 fragment.appendChild( ret[i] );
6142 cleanData: function( elems ) {
6143 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6144 deleteExpando = jQuery.support.deleteExpando;
6146 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6147 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6151 id = elem[ jQuery.expando ];
6154 data = cache[ id ] && cache[ id ][ internalKey ];
6156 if ( data && data.events ) {
6157 for ( var type in data.events ) {
6158 if ( special[ type ] ) {
6159 jQuery.event.remove( elem, type );
6161 // This is a shortcut to avoid jQuery.event.remove's overhead
6163 jQuery.removeEvent( elem, type, data.handle );
6167 // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6168 if ( data.handle ) {
6169 data.handle.elem = null;
6173 if ( deleteExpando ) {
6174 delete elem[ jQuery.expando ];
6176 } else if ( elem.removeAttribute ) {
6177 elem.removeAttribute( jQuery.expando );
6186 function evalScript( i, elem ) {
6194 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6197 if ( elem.parentNode ) {
6198 elem.parentNode.removeChild( elem );
6205 var ralpha = /alpha\([^)]*\)/i,
6206 ropacity = /opacity=([^)]*)/,
6207 rdashAlpha = /-([a-z])/ig,
6208 // fixed for IE9, see #8346
6209 rupper = /([A-Z]|^ms)/g,
6210 rnumpx = /^-?\d+(?:px)?$/i,
6212 rrelNum = /^[+\-]=/,
6213 rrelNumFilter = /[^+\-\.\de]+/g,
6215 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6216 cssWidth = [ "Left", "Right" ],
6217 cssHeight = [ "Top", "Bottom" ],
6223 fcamelCase = function( all, letter ) {
6224 return letter.toUpperCase();
6227 jQuery.fn.css = function( name, value ) {
6228 // Setting 'undefined' is a no-op
6229 if ( arguments.length === 2 && value === undefined ) {
6233 return jQuery.access( this, name, value, true, function( elem, name, value ) {
6234 return value !== undefined ?
6235 jQuery.style( elem, name, value ) :
6236 jQuery.css( elem, name );
6241 // Add in style property hooks for overriding the default
6242 // behavior of getting and setting a style property
6245 get: function( elem, computed ) {
6247 // We should always get a number back from opacity
6248 var ret = curCSS( elem, "opacity", "opacity" );
6249 return ret === "" ? "1" : ret;
6252 return elem.style.opacity;
6258 // Exclude the following css properties to add px
6269 // Add in properties whose names you wish to fix before
6270 // setting or getting the value
6272 // normalize float css property
6273 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6276 // Get and set the style property on a DOM Node
6277 style: function( elem, name, value, extra ) {
6278 // Don't set styles on text and comment nodes
6279 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6283 // Make sure that we're working with the right name
6284 var ret, type, origName = jQuery.camelCase( name ),
6285 style = elem.style, hooks = jQuery.cssHooks[ origName ];
6287 name = jQuery.cssProps[ origName ] || origName;
6289 // Check if we're setting a value
6290 if ( value !== undefined ) {
6291 type = typeof value;
6293 // Make sure that NaN and null values aren't set. See: #7116
6294 if ( type === "number" && isNaN( value ) || value == null ) {
6298 // convert relative number strings (+= or -=) to relative numbers. #7345
6299 if ( type === "string" && rrelNum.test( value ) ) {
6300 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6303 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6304 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6308 // If a hook was provided, use that value, otherwise just set the specified value
6309 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6310 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6313 style[ name ] = value;
6318 // If a hook was provided get the non-computed value from there
6319 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6323 // Otherwise just get the value from the style object
6324 return style[ name ];
6328 css: function( elem, name, extra ) {
6331 // Make sure that we're working with the right name
6332 name = jQuery.camelCase( name );
6333 hooks = jQuery.cssHooks[ name ];
6334 name = jQuery.cssProps[ name ] || name;
6336 // cssFloat needs a special treatment
6337 if ( name === "cssFloat" ) {
6341 // If a hook was provided get the computed value from there
6342 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6345 // Otherwise, if a way to get the computed value exists, use that
6346 } else if ( curCSS ) {
6347 return curCSS( elem, name );
6351 // A method for quickly swapping in/out CSS properties to get correct calculations
6352 swap: function( elem, options, callback ) {
6355 // Remember the old values, and insert the new ones
6356 for ( var name in options ) {
6357 old[ name ] = elem.style[ name ];
6358 elem.style[ name ] = options[ name ];
6361 callback.call( elem );
6363 // Revert the old values
6364 for ( name in options ) {
6365 elem.style[ name ] = old[ name ];
6369 camelCase: function( string ) {
6370 return string.replace( rdashAlpha, fcamelCase );
6374 // DEPRECATED, Use jQuery.css() instead
6375 jQuery.curCSS = jQuery.css;
6377 jQuery.each(["height", "width"], function( i, name ) {
6378 jQuery.cssHooks[ name ] = {
6379 get: function( elem, computed, extra ) {
6383 if ( elem.offsetWidth !== 0 ) {
6384 val = getWH( elem, name, extra );
6387 jQuery.swap( elem, cssShow, function() {
6388 val = getWH( elem, name, extra );
6393 val = curCSS( elem, name, name );
6395 if ( val === "0px" && currentStyle ) {
6396 val = currentStyle( elem, name, name );
6399 if ( val != null ) {
6400 // Should return "auto" instead of 0, use 0 for
6401 // temporary backwards-compat
6402 return val === "" || val === "auto" ? "0px" : val;
6406 if ( val < 0 || val == null ) {
6407 val = elem.style[ name ];
6409 // Should return "auto" instead of 0, use 0 for
6410 // temporary backwards-compat
6411 return val === "" || val === "auto" ? "0px" : val;
6414 return typeof val === "string" ? val : val + "px";
6418 set: function( elem, value ) {
6419 if ( rnumpx.test( value ) ) {
6420 // ignore negative width and height values #1599
6421 value = parseFloat(value);
6424 return value + "px";
6434 if ( !jQuery.support.opacity ) {
6435 jQuery.cssHooks.opacity = {
6436 get: function( elem, computed ) {
6437 // IE uses filters for opacity
6438 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6439 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6440 computed ? "1" : "";
6443 set: function( elem, value ) {
6444 var style = elem.style,
6445 currentStyle = elem.currentStyle;
6447 // IE has trouble with opacity if it does not have layout
6448 // Force it by setting the zoom level
6451 // Set the alpha filter to set the opacity
6452 var opacity = jQuery.isNaN( value ) ?
6454 "alpha(opacity=" + value * 100 + ")",
6455 filter = currentStyle && currentStyle.filter || style.filter || "";
6457 style.filter = ralpha.test( filter ) ?
6458 filter.replace( ralpha, opacity ) :
6459 filter + " " + opacity;
6465 // This hook cannot be added until DOM ready because the support test
6466 // for it is not run until after DOM ready
6467 if ( !jQuery.support.reliableMarginRight ) {
6468 jQuery.cssHooks.marginRight = {
6469 get: function( elem, computed ) {
6470 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6471 // Work around by temporarily setting element display to inline-block
6473 jQuery.swap( elem, { "display": "inline-block" }, function() {
6475 ret = curCSS( elem, "margin-right", "marginRight" );
6477 ret = elem.style.marginRight;
6486 if ( document.defaultView && document.defaultView.getComputedStyle ) {
6487 getComputedStyle = function( elem, name ) {
6488 var ret, defaultView, computedStyle;
6490 name = name.replace( rupper, "-$1" ).toLowerCase();
6492 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6496 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6497 ret = computedStyle.getPropertyValue( name );
6498 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6499 ret = jQuery.style( elem, name );
6507 if ( document.documentElement.currentStyle ) {
6508 currentStyle = function( elem, name ) {
6510 ret = elem.currentStyle && elem.currentStyle[ name ],
6511 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6514 // From the awesome hack by Dean Edwards
6515 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6517 // If we're not dealing with a regular pixel number
6518 // but a number that has a weird ending, we need to convert it to pixels
6519 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6520 // Remember the original values
6523 // Put in the new values to get a computed value out
6525 elem.runtimeStyle.left = elem.currentStyle.left;
6527 style.left = name === "fontSize" ? "1em" : (ret || 0);
6528 ret = style.pixelLeft + "px";
6530 // Revert the changed values
6533 elem.runtimeStyle.left = rsLeft;
6537 return ret === "" ? "auto" : ret;
6541 curCSS = getComputedStyle || currentStyle;
6543 function getWH( elem, name, extra ) {
6544 var which = name === "width" ? cssWidth : cssHeight,
6545 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
6547 if ( extra === "border" ) {
6551 jQuery.each( which, function() {
6553 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
6556 if ( extra === "margin" ) {
6557 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
6560 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
6567 if ( jQuery.expr && jQuery.expr.filters ) {
6568 jQuery.expr.filters.hidden = function( elem ) {
6569 var width = elem.offsetWidth,
6570 height = elem.offsetHeight;
6572 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6575 jQuery.expr.filters.visible = function( elem ) {
6576 return !jQuery.expr.filters.hidden( elem );
6587 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6588 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6589 // #7653, #8125, #8152: local protocol detection
6590 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
6591 rnoContent = /^(?:GET|HEAD)$/,
6592 rprotocol = /^\/\//,
6594 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6595 rselectTextarea = /^(?:select|textarea)/i,
6596 rspacesAjax = /\s+/,
6597 rts = /([?&])_=[^&]*/,
6598 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6600 // Keep a copy of the old load method
6601 _load = jQuery.fn.load,
6604 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6605 * 2) These are called:
6606 * - BEFORE asking for a transport
6607 * - AFTER param serialization (s.data is a string if s.processData is true)
6608 * 3) key is the dataType
6609 * 4) the catchall symbol "*" can be used
6610 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6614 /* Transports bindings
6615 * 1) key is the dataType
6616 * 2) the catchall symbol "*" can be used
6617 * 3) selection will start with transport dataType and THEN go to "*" if needed
6621 // Document location
6624 // Document location segments
6627 // #8138, IE may throw an exception when accessing
6628 // a field from window.location if document.domain has been set
6630 ajaxLocation = location.href;
6632 // Use the href attribute of an A element
6633 // since IE will modify it given document.location
6634 ajaxLocation = document.createElement( "a" );
6635 ajaxLocation.href = "";
6636 ajaxLocation = ajaxLocation.href;
6639 // Segment location into parts
6640 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6642 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6643 function addToPrefiltersOrTransports( structure ) {
6645 // dataTypeExpression is optional and defaults to "*"
6646 return function( dataTypeExpression, func ) {
6648 if ( typeof dataTypeExpression !== "string" ) {
6649 func = dataTypeExpression;
6650 dataTypeExpression = "*";
6653 if ( jQuery.isFunction( func ) ) {
6654 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6656 length = dataTypes.length,
6661 // For each dataType in the dataTypeExpression
6662 for(; i < length; i++ ) {
6663 dataType = dataTypes[ i ];
6664 // We control if we're asked to add before
6665 // any existing element
6666 placeBefore = /^\+/.test( dataType );
6667 if ( placeBefore ) {
6668 dataType = dataType.substr( 1 ) || "*";
6670 list = structure[ dataType ] = structure[ dataType ] || [];
6671 // then we add to the structure accordingly
6672 list[ placeBefore ? "unshift" : "push" ]( func );
6678 // Base inspection function for prefilters and transports
6679 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6680 dataType /* internal */, inspected /* internal */ ) {
6682 dataType = dataType || options.dataTypes[ 0 ];
6683 inspected = inspected || {};
6685 inspected[ dataType ] = true;
6687 var list = structure[ dataType ],
6689 length = list ? list.length : 0,
6690 executeOnly = ( structure === prefilters ),
6693 for(; i < length && ( executeOnly || !selection ); i++ ) {
6694 selection = list[ i ]( options, originalOptions, jqXHR );
6695 // If we got redirected to another dataType
6696 // we try there if executing only and not done already
6697 if ( typeof selection === "string" ) {
6698 if ( !executeOnly || inspected[ selection ] ) {
6699 selection = undefined;
6701 options.dataTypes.unshift( selection );
6702 selection = inspectPrefiltersOrTransports(
6703 structure, options, originalOptions, jqXHR, selection, inspected );
6707 // If we're only executing or nothing was selected
6708 // we try the catchall dataType if not done already
6709 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6710 selection = inspectPrefiltersOrTransports(
6711 structure, options, originalOptions, jqXHR, "*", inspected );
6713 // unnecessary when only executing (prefilters)
6714 // but it'll be ignored by the caller in that case
6719 load: function( url, params, callback ) {
6720 if ( typeof url !== "string" && _load ) {
6721 return _load.apply( this, arguments );
6723 // Don't do a request if no elements are being requested
6724 } else if ( !this.length ) {
6728 var off = url.indexOf( " " );
6730 var selector = url.slice( off, url.length );
6731 url = url.slice( 0, off );
6734 // Default to a GET request
6737 // If the second parameter was provided
6739 // If it's a function
6740 if ( jQuery.isFunction( params ) ) {
6741 // We assume that it's the callback
6745 // Otherwise, build a param string
6746 } else if ( typeof params === "object" ) {
6747 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6754 // Request the remote document
6760 // Complete callback (responseText is used internally)
6761 complete: function( jqXHR, status, responseText ) {
6762 // Store the response as specified by the jqXHR object
6763 responseText = jqXHR.responseText;
6764 // If successful, inject the HTML into all the matched elements
6765 if ( jqXHR.isResolved() ) {
6766 // #4825: Get the actual response in case
6767 // a dataFilter is present in ajaxSettings
6768 jqXHR.done(function( r ) {
6771 // See if a selector was specified
6772 self.html( selector ?
6773 // Create a dummy div to hold the results
6775 // inject the contents of the document in, removing the scripts
6776 // to avoid any 'Permission Denied' errors in IE
6777 .append(responseText.replace(rscript, ""))
6779 // Locate the specified elements
6782 // If not, just inject the full result
6787 self.each( callback, [ responseText, status, jqXHR ] );
6795 serialize: function() {
6796 return jQuery.param( this.serializeArray() );
6799 serializeArray: function() {
6800 return this.map(function(){
6801 return this.elements ? jQuery.makeArray( this.elements ) : this;
6804 return this.name && !this.disabled &&
6805 ( this.checked || rselectTextarea.test( this.nodeName ) ||
6806 rinput.test( this.type ) );
6808 .map(function( i, elem ){
6809 var val = jQuery( this ).val();
6811 return val == null ?
6813 jQuery.isArray( val ) ?
6814 jQuery.map( val, function( val, i ){
6815 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6817 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6822 // Attach a bunch of functions for handling common AJAX events
6823 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6824 jQuery.fn[ o ] = function( f ){
6825 return this.bind( o, f );
6829 jQuery.each( [ "get", "post" ], function( i, method ) {
6830 jQuery[ method ] = function( url, data, callback, type ) {
6831 // shift arguments if data argument was omitted
6832 if ( jQuery.isFunction( data ) ) {
6833 type = type || callback;
6838 return jQuery.ajax({
6850 getScript: function( url, callback ) {
6851 return jQuery.get( url, undefined, callback, "script" );
6854 getJSON: function( url, data, callback ) {
6855 return jQuery.get( url, data, callback, "json" );
6858 // Creates a full fledged settings object into target
6859 // with both ajaxSettings and settings fields.
6860 // If target is omitted, writes into ajaxSettings.
6861 ajaxSetup: function ( target, settings ) {
6863 // Only one parameter, we extend ajaxSettings
6865 target = jQuery.extend( true, jQuery.ajaxSettings, settings );
6867 // target was provided, we extend into it
6868 jQuery.extend( true, target, jQuery.ajaxSettings, settings );
6870 // Flatten fields we don't want deep extended
6871 for( var field in { context: 1, url: 1 } ) {
6872 if ( field in settings ) {
6873 target[ field ] = settings[ field ];
6874 } else if( field in jQuery.ajaxSettings ) {
6875 target[ field ] = jQuery.ajaxSettings[ field ];
6883 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
6886 contentType: "application/x-www-form-urlencoded",
6901 xml: "application/xml, text/xml",
6904 json: "application/json, text/javascript",
6916 text: "responseText"
6919 // List of data converters
6920 // 1) key format is "source_type destination_type" (a single space in-between)
6921 // 2) the catchall symbol "*" can be used for source_type
6924 // Convert anything to text
6925 "* text": window.String,
6927 // Text to html (true = no transformation)
6930 // Evaluate text as a json expression
6931 "text json": jQuery.parseJSON,
6933 // Parse text as xml
6934 "text xml": jQuery.parseXML
6938 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6939 ajaxTransport: addToPrefiltersOrTransports( transports ),
6942 ajax: function( url, options ) {
6944 // If url is an object, simulate pre-1.5 signature
6945 if ( typeof url === "object" ) {
6950 // Force options to be an object
6951 options = options || {};
6953 var // Create the final options object
6954 s = jQuery.ajaxSetup( {}, options ),
6955 // Callbacks context
6956 callbackContext = s.context || s,
6957 // Context for global events
6958 // It's the callbackContext if one was provided in the options
6959 // and if it's a DOM node or a jQuery collection
6960 globalEventContext = callbackContext !== s &&
6961 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
6962 jQuery( callbackContext ) : jQuery.event,
6964 deferred = jQuery.Deferred(),
6965 completeDeferred = jQuery._Deferred(),
6966 // Status-dependent callbacks
6967 statusCode = s.statusCode || {},
6970 // Headers (they are sent all at once)
6971 requestHeaders = {},
6972 requestHeadersNames = {},
6974 responseHeadersString,
6980 // Cross-domain detection vars
6984 // To know if global events are to be dispatched
6993 // Caches the header
6994 setRequestHeader: function( name, value ) {
6996 var lname = name.toLowerCase();
6997 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
6998 requestHeaders[ name ] = value;
7004 getAllResponseHeaders: function() {
7005 return state === 2 ? responseHeadersString : null;
7008 // Builds headers hashtable if needed
7009 getResponseHeader: function( key ) {
7011 if ( state === 2 ) {
7012 if ( !responseHeaders ) {
7013 responseHeaders = {};
7014 while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7015 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7018 match = responseHeaders[ key.toLowerCase() ];
7020 return match === undefined ? null : match;
7023 // Overrides response content-type header
7024 overrideMimeType: function( type ) {
7031 // Cancel the request
7032 abort: function( statusText ) {
7033 statusText = statusText || "abort";
7035 transport.abort( statusText );
7037 done( 0, statusText );
7042 // Callback for when everything is done
7043 // It is defined here because jslint complains if it is declared
7044 // at the end of the function (which would be more logical and readable)
7045 function done( status, statusText, responses, headers ) {
7048 if ( state === 2 ) {
7052 // State is "done" now
7055 // Clear timeout if it exists
7056 if ( timeoutTimer ) {
7057 clearTimeout( timeoutTimer );
7060 // Dereference transport for early garbage collection
7061 // (no matter how long the jqXHR object will be used)
7062 transport = undefined;
7064 // Cache response headers
7065 responseHeadersString = headers || "";
7068 jqXHR.readyState = status ? 4 : 0;
7073 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7077 // If successful, handle type chaining
7078 if ( status >= 200 && status < 300 || status === 304 ) {
7080 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7081 if ( s.ifModified ) {
7083 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7084 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7086 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7087 jQuery.etag[ ifModifiedKey ] = etag;
7092 if ( status === 304 ) {
7094 statusText = "notmodified";
7101 success = ajaxConvert( s, response );
7102 statusText = "success";
7105 // We have a parsererror
7106 statusText = "parsererror";
7111 // We extract error from statusText
7112 // then normalize statusText and status for non-aborts
7114 if( !statusText || status ) {
7115 statusText = "error";
7122 // Set data for the fake xhr object
7123 jqXHR.status = status;
7124 jqXHR.statusText = statusText;
7128 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7130 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7133 // Status-dependent callbacks
7134 jqXHR.statusCode( statusCode );
7135 statusCode = undefined;
7137 if ( fireGlobals ) {
7138 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7139 [ jqXHR, s, isSuccess ? success : error ] );
7143 completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7145 if ( fireGlobals ) {
7146 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7147 // Handle the global AJAX counter
7148 if ( !( --jQuery.active ) ) {
7149 jQuery.event.trigger( "ajaxStop" );
7155 deferred.promise( jqXHR );
7156 jqXHR.success = jqXHR.done;
7157 jqXHR.error = jqXHR.fail;
7158 jqXHR.complete = completeDeferred.done;
7160 // Status-dependent callbacks
7161 jqXHR.statusCode = function( map ) {
7166 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7169 tmp = map[ jqXHR.status ];
7170 jqXHR.then( tmp, tmp );
7176 // Remove hash character (#7531: and string promotion)
7177 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7178 // We also use the url parameter if available
7179 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7181 // Extract dataTypes list
7182 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7184 // Determine if a cross-domain request is in order
7185 if ( s.crossDomain == null ) {
7186 parts = rurl.exec( s.url.toLowerCase() );
7187 s.crossDomain = !!( parts &&
7188 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7189 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7190 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7194 // Convert data if not already a string
7195 if ( s.data && s.processData && typeof s.data !== "string" ) {
7196 s.data = jQuery.param( s.data, s.traditional );
7200 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7202 // If request was aborted inside a prefiler, stop there
7203 if ( state === 2 ) {
7207 // We can fire global events as of now if asked to
7208 fireGlobals = s.global;
7210 // Uppercase the type
7211 s.type = s.type.toUpperCase();
7213 // Determine if request has content
7214 s.hasContent = !rnoContent.test( s.type );
7216 // Watch for a new set of requests
7217 if ( fireGlobals && jQuery.active++ === 0 ) {
7218 jQuery.event.trigger( "ajaxStart" );
7221 // More options handling for requests with no content
7222 if ( !s.hasContent ) {
7224 // If data is available, append data to url
7226 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7229 // Get ifModifiedKey before adding the anti-cache parameter
7230 ifModifiedKey = s.url;
7232 // Add anti-cache in url if needed
7233 if ( s.cache === false ) {
7235 var ts = jQuery.now(),
7236 // try replacing _= if it is there
7237 ret = s.url.replace( rts, "$1_=" + ts );
7239 // if nothing was replaced, add timestamp to the end
7240 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7244 // Set the correct header, if data is being sent
7245 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7246 jqXHR.setRequestHeader( "Content-Type", s.contentType );
7249 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7250 if ( s.ifModified ) {
7251 ifModifiedKey = ifModifiedKey || s.url;
7252 if ( jQuery.lastModified[ ifModifiedKey ] ) {
7253 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7255 if ( jQuery.etag[ ifModifiedKey ] ) {
7256 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7260 // Set the Accepts header for the server, depending on the dataType
7261 jqXHR.setRequestHeader(
7263 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7264 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7268 // Check for headers option
7269 for ( i in s.headers ) {
7270 jqXHR.setRequestHeader( i, s.headers[ i ] );
7273 // Allow custom headers/mimetypes and early abort
7274 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7275 // Abort if not done already
7281 // Install callbacks on deferreds
7282 for ( i in { success: 1, error: 1, complete: 1 } ) {
7283 jqXHR[ i ]( s[ i ] );
7287 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7289 // If no transport, we auto-abort
7291 done( -1, "No Transport" );
7293 jqXHR.readyState = 1;
7294 // Send global event
7295 if ( fireGlobals ) {
7296 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7299 if ( s.async && s.timeout > 0 ) {
7300 timeoutTimer = setTimeout( function(){
7301 jqXHR.abort( "timeout" );
7307 transport.send( requestHeaders, done );
7309 // Propagate exception as error if not done
7312 // Simply rethrow otherwise
7322 // Serialize an array of form elements or a set of
7323 // key/values into a query string
7324 param: function( a, traditional ) {
7326 add = function( key, value ) {
7327 // If value is a function, invoke it and return its value
7328 value = jQuery.isFunction( value ) ? value() : value;
7329 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7332 // Set traditional to true for jQuery <= 1.3.2 behavior.
7333 if ( traditional === undefined ) {
7334 traditional = jQuery.ajaxSettings.traditional;
7337 // If an array was passed in, assume that it is an array of form elements.
7338 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7339 // Serialize the form elements
7340 jQuery.each( a, function() {
7341 add( this.name, this.value );
7345 // If traditional, encode the "old" way (the way 1.3.2 or older
7346 // did it), otherwise encode params recursively.
7347 for ( var prefix in a ) {
7348 buildParams( prefix, a[ prefix ], traditional, add );
7352 // Return the resulting serialization
7353 return s.join( "&" ).replace( r20, "+" );
7357 function buildParams( prefix, obj, traditional, add ) {
7358 if ( jQuery.isArray( obj ) ) {
7359 // Serialize array item.
7360 jQuery.each( obj, function( i, v ) {
7361 if ( traditional || rbracket.test( prefix ) ) {
7362 // Treat each array item as a scalar.
7366 // If array item is non-scalar (array or object), encode its
7367 // numeric index to resolve deserialization ambiguity issues.
7368 // Note that rack (as of 1.0.0) can't currently deserialize
7369 // nested arrays properly, and attempting to do so may cause
7370 // a server error. Possible fixes are to modify rack's
7371 // deserialization algorithm or to provide an option or flag
7372 // to force array serialization to be shallow.
7373 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7377 } else if ( !traditional && obj != null && typeof obj === "object" ) {
7378 // Serialize object item.
7379 for ( var name in obj ) {
7380 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7384 // Serialize scalar item.
7389 // This is still on the jQuery object... for now
7390 // Want to move this to jQuery.ajax some day
7393 // Counter for holding the number of active queries
7396 // Last-Modified header cache for next request
7402 /* Handles responses to an ajax request:
7403 * - sets all responseXXX fields accordingly
7404 * - finds the right dataType (mediates between content-type and expected dataType)
7405 * - returns the corresponding response
7407 function ajaxHandleResponses( s, jqXHR, responses ) {
7409 var contents = s.contents,
7410 dataTypes = s.dataTypes,
7411 responseFields = s.responseFields,
7417 // Fill responseXXX fields
7418 for( type in responseFields ) {
7419 if ( type in responses ) {
7420 jqXHR[ responseFields[type] ] = responses[ type ];
7424 // Remove auto dataType and get content-type in the process
7425 while( dataTypes[ 0 ] === "*" ) {
7427 if ( ct === undefined ) {
7428 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7432 // Check if we're dealing with a known content-type
7434 for ( type in contents ) {
7435 if ( contents[ type ] && contents[ type ].test( ct ) ) {
7436 dataTypes.unshift( type );
7442 // Check to see if we have a response for the expected dataType
7443 if ( dataTypes[ 0 ] in responses ) {
7444 finalDataType = dataTypes[ 0 ];
7446 // Try convertible dataTypes
7447 for ( type in responses ) {
7448 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7449 finalDataType = type;
7452 if ( !firstDataType ) {
7453 firstDataType = type;
7456 // Or just use first one
7457 finalDataType = finalDataType || firstDataType;
7460 // If we found a dataType
7461 // We add the dataType to the list if needed
7462 // and return the corresponding response
7463 if ( finalDataType ) {
7464 if ( finalDataType !== dataTypes[ 0 ] ) {
7465 dataTypes.unshift( finalDataType );
7467 return responses[ finalDataType ];
7471 // Chain conversions given the request and the original response
7472 function ajaxConvert( s, response ) {
7474 // Apply the dataFilter if provided
7475 if ( s.dataFilter ) {
7476 response = s.dataFilter( response, s.dataType );
7479 var dataTypes = s.dataTypes,
7483 length = dataTypes.length,
7485 // Current and previous dataTypes
7486 current = dataTypes[ 0 ],
7488 // Conversion expression
7490 // Conversion function
7492 // Conversion functions (transitive conversion)
7496 // For each dataType in the chain
7497 for( i = 1; i < length; i++ ) {
7499 // Create converters map
7500 // with lowercased keys
7502 for( key in s.converters ) {
7503 if( typeof key === "string" ) {
7504 converters[ key.toLowerCase() ] = s.converters[ key ];
7509 // Get the dataTypes
7511 current = dataTypes[ i ];
7513 // If current is auto dataType, update it to prev
7514 if( current === "*" ) {
7516 // If no auto and dataTypes are actually different
7517 } else if ( prev !== "*" && prev !== current ) {
7519 // Get the converter
7520 conversion = prev + " " + current;
7521 conv = converters[ conversion ] || converters[ "* " + current ];
7523 // If there is no direct converter, search transitively
7526 for( conv1 in converters ) {
7527 tmp = conv1.split( " " );
7528 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7529 conv2 = converters[ tmp[1] + " " + current ];
7531 conv1 = converters[ conv1 ];
7532 if ( conv1 === true ) {
7534 } else if ( conv2 === true ) {
7542 // If we found no converter, dispatch an error
7543 if ( !( conv || conv2 ) ) {
7544 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7546 // If found converter is not an equivalence
7547 if ( conv !== true ) {
7548 // Convert with 1 or 2 converters accordingly
7549 response = conv ? conv( response ) : conv2( conv1(response) );
7559 var jsc = jQuery.now(),
7560 jsre = /(\=)\?(&|$)|\?\?/i;
7562 // Default jsonp settings
7565 jsonpCallback: function() {
7566 return jQuery.expando + "_" + ( jsc++ );
7570 // Detect, normalize options and install callbacks for jsonp requests
7571 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7573 var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7574 ( typeof s.data === "string" );
7576 if ( s.dataTypes[ 0 ] === "jsonp" ||
7577 s.jsonp !== false && ( jsre.test( s.url ) ||
7578 inspectData && jsre.test( s.data ) ) ) {
7580 var responseContainer,
7581 jsonpCallback = s.jsonpCallback =
7582 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7583 previous = window[ jsonpCallback ],
7586 replace = "$1" + jsonpCallback + "$2";
7588 if ( s.jsonp !== false ) {
7589 url = url.replace( jsre, replace );
7590 if ( s.url === url ) {
7591 if ( inspectData ) {
7592 data = data.replace( jsre, replace );
7594 if ( s.data === data ) {
7595 // Add callback manually
7596 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7605 window[ jsonpCallback ] = function( response ) {
7606 responseContainer = [ response ];
7609 // Clean-up function
7610 jqXHR.always(function() {
7611 // Set callback back to previous value
7612 window[ jsonpCallback ] = previous;
7613 // Call if it was a function and we have a response
7614 if ( responseContainer && jQuery.isFunction( previous ) ) {
7615 window[ jsonpCallback ]( responseContainer[ 0 ] );
7619 // Use data converter to retrieve json after script execution
7620 s.converters["script json"] = function() {
7621 if ( !responseContainer ) {
7622 jQuery.error( jsonpCallback + " was not called" );
7624 return responseContainer[ 0 ];
7627 // force json dataType
7628 s.dataTypes[ 0 ] = "json";
7630 // Delegate to script
7638 // Install script dataType
7641 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7644 script: /javascript|ecmascript/
7647 "text script": function( text ) {
7648 jQuery.globalEval( text );
7654 // Handle cache's special case and global
7655 jQuery.ajaxPrefilter( "script", function( s ) {
7656 if ( s.cache === undefined ) {
7659 if ( s.crossDomain ) {
7665 // Bind script tag hack transport
7666 jQuery.ajaxTransport( "script", function(s) {
7668 // This transport only deals with cross domain requests
7669 if ( s.crossDomain ) {
7672 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7676 send: function( _, callback ) {
7678 script = document.createElement( "script" );
7680 script.async = "async";
7682 if ( s.scriptCharset ) {
7683 script.charset = s.scriptCharset;
7688 // Attach handlers for all browsers
7689 script.onload = script.onreadystatechange = function( _, isAbort ) {
7691 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7693 // Handle memory leak in IE
7694 script.onload = script.onreadystatechange = null;
7696 // Remove the script
7697 if ( head && script.parentNode ) {
7698 head.removeChild( script );
7701 // Dereference the script
7704 // Callback if not abort
7706 callback( 200, "success" );
7710 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
7711 // This arises when a base node is used (#2709 and #4378).
7712 head.insertBefore( script, head.firstChild );
7717 script.onload( 0, 1 );
7727 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7728 xhrOnUnloadAbort = window.ActiveXObject ? function() {
7729 // Abort all pending requests
7730 for ( var key in xhrCallbacks ) {
7731 xhrCallbacks[ key ]( 0, 1 );
7737 // Functions to create xhrs
7738 function createStandardXHR() {
7740 return new window.XMLHttpRequest();
7744 function createActiveXHR() {
7746 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7750 // Create the request object
7751 // (This is still attached to ajaxSettings for backward compatibility)
7752 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7753 /* Microsoft failed to properly
7754 * implement the XMLHttpRequest in IE7 (can't request local files),
7755 * so we use the ActiveXObject when it is available
7756 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7757 * we need a fallback.
7760 return !this.isLocal && createStandardXHR() || createActiveXHR();
7762 // For all other browsers, use the standard XMLHttpRequest object
7765 // Determine support properties
7767 jQuery.extend( jQuery.support, {
7769 cors: !!xhr && ( "withCredentials" in xhr )
7771 })( jQuery.ajaxSettings.xhr() );
7773 // Create transport if the browser can provide an xhr
7774 if ( jQuery.support.ajax ) {
7776 jQuery.ajaxTransport(function( s ) {
7777 // Cross domain only allowed if supported through XMLHttpRequest
7778 if ( !s.crossDomain || jQuery.support.cors ) {
7783 send: function( headers, complete ) {
7791 // Passing null username, generates a login popup on Opera (#2865)
7793 xhr.open( s.type, s.url, s.async, s.username, s.password );
7795 xhr.open( s.type, s.url, s.async );
7798 // Apply custom fields if provided
7799 if ( s.xhrFields ) {
7800 for ( i in s.xhrFields ) {
7801 xhr[ i ] = s.xhrFields[ i ];
7805 // Override mime type if needed
7806 if ( s.mimeType && xhr.overrideMimeType ) {
7807 xhr.overrideMimeType( s.mimeType );
7810 // X-Requested-With header
7811 // For cross-domain requests, seeing as conditions for a preflight are
7812 // akin to a jigsaw puzzle, we simply never set it to be sure.
7813 // (it can always be set on a per-request basis or even using ajaxSetup)
7814 // For same-domain requests, won't change header if already provided.
7815 if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7816 headers[ "X-Requested-With" ] = "XMLHttpRequest";
7819 // Need an extra try/catch for cross domain requests in Firefox 3
7821 for ( i in headers ) {
7822 xhr.setRequestHeader( i, headers[ i ] );
7826 // Do send the request
7827 // This may raise an exception which is actually
7828 // handled in jQuery.ajax (so no try/catch here)
7829 xhr.send( ( s.hasContent && s.data ) || null );
7832 callback = function( _, isAbort ) {
7840 // Firefox throws exceptions when accessing properties
7841 // of an xhr when a network error occured
7842 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7845 // Was never called and is aborted or complete
7846 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7849 callback = undefined;
7851 // Do not keep as active anymore
7853 xhr.onreadystatechange = jQuery.noop;
7854 if ( xhrOnUnloadAbort ) {
7855 delete xhrCallbacks[ handle ];
7861 // Abort it manually if needed
7862 if ( xhr.readyState !== 4 ) {
7866 status = xhr.status;
7867 responseHeaders = xhr.getAllResponseHeaders();
7869 xml = xhr.responseXML;
7871 // Construct response list
7872 if ( xml && xml.documentElement /* #4958 */ ) {
7873 responses.xml = xml;
7875 responses.text = xhr.responseText;
7877 // Firefox throws an exception when accessing
7878 // statusText for faulty cross-domain requests
7880 statusText = xhr.statusText;
7882 // We normalize with Webkit giving an empty statusText
7886 // Filter status for non standard behaviors
7888 // If the request is local and we have data: assume a success
7889 // (success with no data won't get notified, that's the best we
7890 // can do given current implementations)
7891 if ( !status && s.isLocal && !s.crossDomain ) {
7892 status = responses.text ? 200 : 404;
7893 // IE - #1450: sometimes returns 1223 when it should be 204
7894 } else if ( status === 1223 ) {
7899 } catch( firefoxAccessException ) {
7901 complete( -1, firefoxAccessException );
7905 // Call complete if needed
7907 complete( status, statusText, responses, responseHeaders );
7911 // if we're in sync mode or it's in cache
7912 // and has been retrieved directly (IE6 & IE7)
7913 // we need to manually fire the callback
7914 if ( !s.async || xhr.readyState === 4 ) {
7918 if ( xhrOnUnloadAbort ) {
7919 // Create the active xhrs callbacks list if needed
7920 // and attach the unload handler
7921 if ( !xhrCallbacks ) {
7923 jQuery( window ).unload( xhrOnUnloadAbort );
7925 // Add to list of active xhrs callbacks
7926 xhrCallbacks[ handle ] = callback;
7928 xhr.onreadystatechange = callback;
7945 var elemdisplay = {},
7947 rfxtypes = /^(?:toggle|show|hide)$/,
7948 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
7951 // height animations
7952 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
7954 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
7955 // opacity animations
7959 requestAnimationFrame = window.webkitRequestAnimationFrame ||
7960 window.mozRequestAnimationFrame ||
7961 window.oRequestAnimationFrame;
7964 show: function( speed, easing, callback ) {
7967 if ( speed || speed === 0 ) {
7968 return this.animate( genFx("show", 3), speed, easing, callback);
7971 for ( var i = 0, j = this.length; i < j; i++ ) {
7975 display = elem.style.display;
7977 // Reset the inline display of this element to learn if it is
7978 // being hidden by cascaded rules or not
7979 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
7980 display = elem.style.display = "";
7983 // Set elements which have been overridden with display: none
7984 // in a stylesheet to whatever the default browser style is
7985 // for such an element
7986 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
7987 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
7992 // Set the display of most of the elements in a second loop
7993 // to avoid the constant reflow
7994 for ( i = 0; i < j; i++ ) {
7998 display = elem.style.display;
8000 if ( display === "" || display === "none" ) {
8001 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8010 hide: function( speed, easing, callback ) {
8011 if ( speed || speed === 0 ) {
8012 return this.animate( genFx("hide", 3), speed, easing, callback);
8015 for ( var i = 0, j = this.length; i < j; i++ ) {
8016 if ( this[i].style ) {
8017 var display = jQuery.css( this[i], "display" );
8019 if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8020 jQuery._data( this[i], "olddisplay", display );
8025 // Set the display of the elements in a second loop
8026 // to avoid the constant reflow
8027 for ( i = 0; i < j; i++ ) {
8028 if ( this[i].style ) {
8029 this[i].style.display = "none";
8037 // Save the old toggle function
8038 _toggle: jQuery.fn.toggle,
8040 toggle: function( fn, fn2, callback ) {
8041 var bool = typeof fn === "boolean";
8043 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8044 this._toggle.apply( this, arguments );
8046 } else if ( fn == null || bool ) {
8047 this.each(function() {
8048 var state = bool ? fn : jQuery(this).is(":hidden");
8049 jQuery(this)[ state ? "show" : "hide" ]();
8053 this.animate(genFx("toggle", 3), fn, fn2, callback);
8059 fadeTo: function( speed, to, easing, callback ) {
8060 return this.filter(":hidden").css("opacity", 0).show().end()
8061 .animate({opacity: to}, speed, easing, callback);
8064 animate: function( prop, speed, easing, callback ) {
8065 var optall = jQuery.speed(speed, easing, callback);
8067 if ( jQuery.isEmptyObject( prop ) ) {
8068 return this.each( optall.complete, [ false ] );
8071 // Do not change referenced properties as per-property easing will be lost
8072 prop = jQuery.extend( {}, prop );
8074 return this[ optall.queue === false ? "each" : "queue" ](function() {
8075 // XXX 'this' does not always have a nodeName when running the
8078 if ( optall.queue === false ) {
8079 jQuery._mark( this );
8082 var opt = jQuery.extend( {}, optall ),
8083 isElement = this.nodeType === 1,
8084 hidden = isElement && jQuery(this).is(":hidden"),
8087 parts, start, end, unit;
8089 // will store per property easing and be used to determine when an animation is complete
8090 opt.animatedProperties = {};
8094 // property name normalization
8095 name = jQuery.camelCase( p );
8097 prop[ name ] = prop[ p ];
8103 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8104 if ( jQuery.isArray( val ) ) {
8105 opt.animatedProperties[ name ] = val[ 1 ];
8106 val = prop[ name ] = val[ 0 ];
8108 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8111 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8112 return opt.complete.call( this );
8115 if ( isElement && ( name === "height" || name === "width" ) ) {
8116 // Make sure that nothing sneaks out
8117 // Record all 3 overflow attributes because IE does not
8118 // change the overflow attribute when overflowX and
8119 // overflowY are set to the same value
8120 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8122 // Set display property to inline-block for height/width
8123 // animations on inline elements that are having width/height
8125 if ( jQuery.css( this, "display" ) === "inline" &&
8126 jQuery.css( this, "float" ) === "none" ) {
8127 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8128 this.style.display = "inline-block";
8131 display = defaultDisplay( this.nodeName );
8133 // inline-level elements accept inline-block;
8134 // block-level elements need to be inline with layout
8135 if ( display === "inline" ) {
8136 this.style.display = "inline-block";
8139 this.style.display = "inline";
8140 this.style.zoom = 1;
8147 if ( opt.overflow != null ) {
8148 this.style.overflow = "hidden";
8152 e = new jQuery.fx( this, opt, p );
8155 if ( rfxtypes.test(val) ) {
8156 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8159 parts = rfxnum.exec( val );
8163 end = parseFloat( parts[2] );
8164 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8166 // We need to compute starting value
8167 if ( unit !== "px" ) {
8168 jQuery.style( this, p, (end || 1) + unit);
8169 start = ((end || 1) / e.cur()) * start;
8170 jQuery.style( this, p, start + unit);
8173 // If a +=/-= token was provided, we're doing a relative animation
8175 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8178 e.custom( start, end, unit );
8181 e.custom( start, val, "" );
8186 // For JS strict compliance
8191 stop: function( clearQueue, gotoEnd ) {
8196 this.each(function() {
8197 var timers = jQuery.timers,
8199 // clear marker counters if we know they won't be
8201 jQuery._unmark( true, this );
8204 if ( timers[i].elem === this ) {
8206 // force the next step to be the last
8210 timers.splice(i, 1);
8215 // start the next in the queue if the last step wasn't forced
8225 // Animations created synchronously will run synchronously
8226 function createFxNow() {
8227 setTimeout( clearFxNow, 0 );
8228 return ( fxNow = jQuery.now() );
8231 function clearFxNow() {
8235 // Generate parameters to create a standard animation
8236 function genFx( type, num ) {
8239 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8246 // Generate shortcuts for custom animations
8248 slideDown: genFx("show", 1),
8249 slideUp: genFx("hide", 1),
8250 slideToggle: genFx("toggle", 1),
8251 fadeIn: { opacity: "show" },
8252 fadeOut: { opacity: "hide" },
8253 fadeToggle: { opacity: "toggle" }
8254 }, function( name, props ) {
8255 jQuery.fn[ name ] = function( speed, easing, callback ) {
8256 return this.animate( props, speed, easing, callback );
8261 speed: function( speed, easing, fn ) {
8262 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8263 complete: fn || !fn && easing ||
8264 jQuery.isFunction( speed ) && speed,
8266 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8269 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8270 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8273 opt.old = opt.complete;
8274 opt.complete = function( noUnmark ) {
8275 if ( opt.queue !== false ) {
8276 jQuery.dequeue( this );
8277 } else if ( noUnmark !== false ) {
8278 jQuery._unmark( this );
8281 if ( jQuery.isFunction( opt.old ) ) {
8282 opt.old.call( this );
8290 linear: function( p, n, firstNum, diff ) {
8291 return firstNum + diff * p;
8293 swing: function( p, n, firstNum, diff ) {
8294 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8300 fx: function( elem, options, prop ) {
8301 this.options = options;
8305 options.orig = options.orig || {};
8310 jQuery.fx.prototype = {
8311 // Simple function for setting a style value
8312 update: function() {
8313 if ( this.options.step ) {
8314 this.options.step.call( this.elem, this.now, this );
8317 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8320 // Get the current size
8322 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8323 return this.elem[ this.prop ];
8327 r = jQuery.css( this.elem, this.prop );
8328 // Empty strings, null, undefined and "auto" are converted to 0,
8329 // complex values such as "rotate(1rad)" are returned as is,
8330 // simple values such as "10px" are parsed to Float.
8331 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8334 // Start an animation from one number to another
8335 custom: function( from, to, unit ) {
8340 this.startTime = fxNow || createFxNow();
8343 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8344 this.now = this.start;
8345 this.pos = this.state = 0;
8347 function t( gotoEnd ) {
8348 return self.step(gotoEnd);
8353 if ( t() && jQuery.timers.push(t) && !timerId ) {
8354 // Use requestAnimationFrame instead of setInterval if available
8355 if ( requestAnimationFrame ) {
8358 // When timerId gets set to null at any point, this stops
8360 requestAnimationFrame( raf );
8364 requestAnimationFrame( raf );
8366 timerId = setInterval( fx.tick, fx.interval );
8371 // Simple 'show' function
8373 // Remember where we started, so that we can go back to it later
8374 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8375 this.options.show = true;
8377 // Begin the animation
8378 // Make sure that we start at a small width/height to avoid any
8380 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8382 // Start by showing the element
8383 jQuery( this.elem ).show();
8386 // Simple 'hide' function
8388 // Remember where we started, so that we can go back to it later
8389 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8390 this.options.hide = true;
8392 // Begin the animation
8393 this.custom(this.cur(), 0);
8396 // Each step of an animation
8397 step: function( gotoEnd ) {
8398 var t = fxNow || createFxNow(),
8401 options = this.options,
8404 if ( gotoEnd || t >= options.duration + this.startTime ) {
8405 this.now = this.end;
8406 this.pos = this.state = 1;
8409 options.animatedProperties[ this.prop ] = true;
8411 for ( i in options.animatedProperties ) {
8412 if ( options.animatedProperties[i] !== true ) {
8418 // Reset the overflow
8419 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8421 jQuery.each( [ "", "X", "Y" ], function (index, value) {
8422 elem.style[ "overflow" + value ] = options.overflow[index];
8426 // Hide the element if the "hide" operation was done
8427 if ( options.hide ) {
8428 jQuery(elem).hide();
8431 // Reset the properties, if the item has been hidden or shown
8432 if ( options.hide || options.show ) {
8433 for ( var p in options.animatedProperties ) {
8434 jQuery.style( elem, p, options.orig[p] );
8438 // Execute the complete function
8439 options.complete.call( elem );
8445 // classical easing cannot be used with an Infinity duration
8446 if ( options.duration == Infinity ) {
8449 n = t - this.startTime;
8450 this.state = n / options.duration;
8452 // Perform the easing function, defaults to swing
8453 this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8454 this.now = this.start + ((this.end - this.start) * this.pos);
8456 // Perform the next step of the animation
8464 jQuery.extend( jQuery.fx, {
8466 for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8467 if ( !timers[i]() ) {
8468 timers.splice(i--, 1);
8472 if ( !timers.length ) {
8480 clearInterval( timerId );
8492 opacity: function( fx ) {
8493 jQuery.style( fx.elem, "opacity", fx.now );
8496 _default: function( fx ) {
8497 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8498 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8500 fx.elem[ fx.prop ] = fx.now;
8506 if ( jQuery.expr && jQuery.expr.filters ) {
8507 jQuery.expr.filters.animated = function( elem ) {
8508 return jQuery.grep(jQuery.timers, function( fn ) {
8509 return elem === fn.elem;
8514 // Try to restore the default display value of an element
8515 function defaultDisplay( nodeName ) {
8517 if ( !elemdisplay[ nodeName ] ) {
8519 var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
8520 display = elem.css( "display" );
8524 // If the simple way fails,
8525 // get element's real default display by attaching it to a temp iframe
8526 if ( display === "none" || display === "" ) {
8527 // No iframe to use yet, so create it
8529 iframe = document.createElement( "iframe" );
8530 iframe.frameBorder = iframe.width = iframe.height = 0;
8533 document.body.appendChild( iframe );
8535 // Create a cacheable copy of the iframe document on first call.
8536 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
8537 // document to it, Webkit & Firefox won't allow reusing the iframe document
8538 if ( !iframeDoc || !iframe.createElement ) {
8539 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8540 iframeDoc.write( "<!doctype><html><body></body></html>" );
8543 elem = iframeDoc.createElement( nodeName );
8545 iframeDoc.body.appendChild( elem );
8547 display = jQuery.css( elem, "display" );
8549 document.body.removeChild( iframe );
8552 // Store the correct default display
8553 elemdisplay[ nodeName ] = display;
8556 return elemdisplay[ nodeName ];
8562 var rtable = /^t(?:able|d|h)$/i,
8563 rroot = /^(?:body|html)$/i;
8565 if ( "getBoundingClientRect" in document.documentElement ) {
8566 jQuery.fn.offset = function( options ) {
8567 var elem = this[0], box;
8570 return this.each(function( i ) {
8571 jQuery.offset.setOffset( this, options, i );
8575 if ( !elem || !elem.ownerDocument ) {
8579 if ( elem === elem.ownerDocument.body ) {
8580 return jQuery.offset.bodyOffset( elem );
8584 box = elem.getBoundingClientRect();
8587 var doc = elem.ownerDocument,
8588 docElem = doc.documentElement;
8590 // Make sure we're not dealing with a disconnected DOM node
8591 if ( !box || !jQuery.contains( docElem, elem ) ) {
8592 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8595 var body = doc.body,
8596 win = getWindow(doc),
8597 clientTop = docElem.clientTop || body.clientTop || 0,
8598 clientLeft = docElem.clientLeft || body.clientLeft || 0,
8599 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
8600 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8601 top = box.top + scrollTop - clientTop,
8602 left = box.left + scrollLeft - clientLeft;
8604 return { top: top, left: left };
8608 jQuery.fn.offset = function( options ) {
8612 return this.each(function( i ) {
8613 jQuery.offset.setOffset( this, options, i );
8617 if ( !elem || !elem.ownerDocument ) {
8621 if ( elem === elem.ownerDocument.body ) {
8622 return jQuery.offset.bodyOffset( elem );
8625 jQuery.offset.initialize();
8628 offsetParent = elem.offsetParent,
8629 prevOffsetParent = elem,
8630 doc = elem.ownerDocument,
8631 docElem = doc.documentElement,
8633 defaultView = doc.defaultView,
8634 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8635 top = elem.offsetTop,
8636 left = elem.offsetLeft;
8638 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8639 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8643 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8644 top -= elem.scrollTop;
8645 left -= elem.scrollLeft;
8647 if ( elem === offsetParent ) {
8648 top += elem.offsetTop;
8649 left += elem.offsetLeft;
8651 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8652 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8653 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8656 prevOffsetParent = offsetParent;
8657 offsetParent = elem.offsetParent;
8660 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8661 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8662 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8665 prevComputedStyle = computedStyle;
8668 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8669 top += body.offsetTop;
8670 left += body.offsetLeft;
8673 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8674 top += Math.max( docElem.scrollTop, body.scrollTop );
8675 left += Math.max( docElem.scrollLeft, body.scrollLeft );
8678 return { top: top, left: left };
8683 initialize: function() {
8684 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8685 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>";
8687 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8689 container.innerHTML = html;
8690 body.insertBefore( container, body.firstChild );
8691 innerDiv = container.firstChild;
8692 checkDiv = innerDiv.firstChild;
8693 td = innerDiv.nextSibling.firstChild.firstChild;
8695 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8696 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8698 checkDiv.style.position = "fixed";
8699 checkDiv.style.top = "20px";
8701 // safari subtracts parent border width here which is 5px
8702 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8703 checkDiv.style.position = checkDiv.style.top = "";
8705 innerDiv.style.overflow = "hidden";
8706 innerDiv.style.position = "relative";
8708 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8710 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8712 body.removeChild( container );
8713 jQuery.offset.initialize = jQuery.noop;
8716 bodyOffset: function( body ) {
8717 var top = body.offsetTop,
8718 left = body.offsetLeft;
8720 jQuery.offset.initialize();
8722 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8723 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8724 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8727 return { top: top, left: left };
8730 setOffset: function( elem, options, i ) {
8731 var position = jQuery.css( elem, "position" );
8733 // set position first, in-case top/left are set even on static elem
8734 if ( position === "static" ) {
8735 elem.style.position = "relative";
8738 var curElem = jQuery( elem ),
8739 curOffset = curElem.offset(),
8740 curCSSTop = jQuery.css( elem, "top" ),
8741 curCSSLeft = jQuery.css( elem, "left" ),
8742 calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8743 props = {}, curPosition = {}, curTop, curLeft;
8745 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8746 if ( calculatePosition ) {
8747 curPosition = curElem.position();
8748 curTop = curPosition.top;
8749 curLeft = curPosition.left;
8751 curTop = parseFloat( curCSSTop ) || 0;
8752 curLeft = parseFloat( curCSSLeft ) || 0;
8755 if ( jQuery.isFunction( options ) ) {
8756 options = options.call( elem, i, curOffset );
8759 if (options.top != null) {
8760 props.top = (options.top - curOffset.top) + curTop;
8762 if (options.left != null) {
8763 props.left = (options.left - curOffset.left) + curLeft;
8766 if ( "using" in options ) {
8767 options.using.call( elem, props );
8769 curElem.css( props );
8776 position: function() {
8783 // Get *real* offsetParent
8784 offsetParent = this.offsetParent(),
8786 // Get correct offsets
8787 offset = this.offset(),
8788 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8790 // Subtract element margins
8791 // note: when an element has margin: auto the offsetLeft and marginLeft
8792 // are the same in Safari causing offset.left to incorrectly be 0
8793 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8794 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8796 // Add offsetParent borders
8797 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8798 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8800 // Subtract the two offsets
8802 top: offset.top - parentOffset.top,
8803 left: offset.left - parentOffset.left
8807 offsetParent: function() {
8808 return this.map(function() {
8809 var offsetParent = this.offsetParent || document.body;
8810 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8811 offsetParent = offsetParent.offsetParent;
8813 return offsetParent;
8819 // Create scrollLeft and scrollTop methods
8820 jQuery.each( ["Left", "Top"], function( i, name ) {
8821 var method = "scroll" + name;
8823 jQuery.fn[ method ] = function( val ) {
8826 if ( val === undefined ) {
8833 win = getWindow( elem );
8835 // Return the scroll offset
8836 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8837 jQuery.support.boxModel && win.document.documentElement[ method ] ||
8838 win.document.body[ method ] :
8842 // Set the scroll offset
8843 return this.each(function() {
8844 win = getWindow( this );
8848 !i ? val : jQuery( win ).scrollLeft(),
8849 i ? val : jQuery( win ).scrollTop()
8853 this[ method ] = val;
8859 function getWindow( elem ) {
8860 return jQuery.isWindow( elem ) ?
8862 elem.nodeType === 9 ?
8863 elem.defaultView || elem.parentWindow :
8870 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
8871 jQuery.each([ "Height", "Width" ], function( i, name ) {
8873 var type = name.toLowerCase();
8875 // innerHeight and innerWidth
8876 jQuery.fn["inner" + name] = function() {
8878 parseFloat( jQuery.css( this[0], type, "padding" ) ) :
8882 // outerHeight and outerWidth
8883 jQuery.fn["outer" + name] = function( margin ) {
8885 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
8889 jQuery.fn[ type ] = function( size ) {
8890 // Get window width or height
8893 return size == null ? null : this;
8896 if ( jQuery.isFunction( size ) ) {
8897 return this.each(function( i ) {
8898 var self = jQuery( this );
8899 self[ type ]( size.call( this, i, self[ type ]() ) );
8903 if ( jQuery.isWindow( elem ) ) {
8904 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
8905 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
8906 var docElemProp = elem.document.documentElement[ "client" + name ];
8907 return elem.document.compatMode === "CSS1Compat" && docElemProp ||
8908 elem.document.body[ "client" + name ] || docElemProp;
8910 // Get document width or height
8911 } else if ( elem.nodeType === 9 ) {
8912 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
8914 elem.documentElement["client" + name],
8915 elem.body["scroll" + name], elem.documentElement["scroll" + name],
8916 elem.body["offset" + name], elem.documentElement["offset" + name]
8919 // Get or set width or height on the element
8920 } else if ( size === undefined ) {
8921 var orig = jQuery.css( elem, type ),
8922 ret = parseFloat( orig );
8924 return jQuery.isNaN( ret ) ? orig : ret;
8926 // Set the width or height on the element (default to pixels if value is unitless)
8928 return this.css( type, typeof size === "string" ? size : size + "px" );
8935 window.jQuery = window.$ = jQuery;