2 * jQuery JavaScript Library v1.6
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: Mon May 2 13:50:00 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 ( 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" ),
1156 // Preliminary tests
1157 div.setAttribute("className", "t");
1158 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1160 all = div.getElementsByTagName( "*" );
1161 a = div.getElementsByTagName( "a" )[ 0 ];
1163 // Can't get basic test support
1164 if ( !all || !all.length || !a ) {
1168 // First batch of supports tests
1169 select = document.createElement( "select" );
1170 opt = select.appendChild( document.createElement("option") );
1171 input = div.getElementsByTagName( "input" )[ 0 ];
1174 // IE strips leading whitespace when .innerHTML is used
1175 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1177 // Make sure that tbody elements aren't automatically inserted
1178 // IE will insert them into empty tables
1179 tbody: !div.getElementsByTagName( "tbody" ).length,
1181 // Make sure that link elements get serialized correctly by innerHTML
1182 // This requires a wrapper element in IE
1183 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1185 // Get the style information from getAttribute
1186 // (IE uses .cssText instead)
1187 style: /top/.test( a.getAttribute("style") ),
1189 // Make sure that URLs aren't manipulated
1190 // (IE normalizes it by default)
1191 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1193 // Make sure that element opacity exists
1194 // (IE uses filter instead)
1195 // Use a regex to work around a WebKit issue. See #5145
1196 opacity: /^0.55$/.test( a.style.opacity ),
1198 // Verify style float existence
1199 // (IE uses styleFloat instead of cssFloat)
1200 cssFloat: !!a.style.cssFloat,
1202 // Make sure that if no value is specified for a checkbox
1203 // that it defaults to "on".
1204 // (WebKit defaults to "" instead)
1205 checkOn: ( input.value === "on" ),
1207 // Make sure that a selected-by-default option has a working selected property.
1208 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1209 optSelected: opt.selected,
1211 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1212 getSetAttribute: div.className !== "t",
1214 // Will be defined later
1215 submitBubbles: true,
1216 changeBubbles: true,
1217 focusinBubbles: false,
1218 deleteExpando: true,
1220 inlineBlockNeedsLayout: false,
1221 shrinkWrapBlocks: false,
1222 reliableMarginRight: true
1225 // Make sure checked status is properly cloned
1226 input.checked = true;
1227 support.noCloneChecked = input.cloneNode( true ).checked;
1229 // Make sure that the options inside disabled selects aren't marked as disabled
1230 // (WebKit marks them as disabled)
1231 select.disabled = true;
1232 support.optDisabled = !opt.disabled;
1234 // Test to see if it's possible to delete an expando from an element
1235 // Fails in Internet Explorer
1239 support.deleteExpando = false;
1242 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1243 div.attachEvent( "onclick", function click() {
1244 // Cloning a node shouldn't copy over any
1245 // bound event handlers (IE does this)
1246 support.noCloneEvent = false;
1247 div.detachEvent( "onclick", click );
1249 div.cloneNode( true ).fireEvent( "onclick" );
1252 // Check if a radio maintains it's value
1253 // after being appended to the DOM
1254 input = document.createElement("input");
1256 input.setAttribute("type", "radio");
1257 support.radioValue = input.value === "t";
1259 input.setAttribute("checked", "checked");
1260 div.appendChild( input );
1261 fragment = document.createDocumentFragment();
1262 fragment.appendChild( div.firstChild );
1264 // WebKit doesn't clone checked state correctly in fragments
1265 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1269 // Figure out if the W3C box model works as expected
1270 div.style.width = div.style.paddingLeft = "1px";
1272 // We use our own, invisible, body
1273 body = document.createElement( "body" );
1275 visibility: "hidden",
1280 // Set background to avoid IE crashes when removing (#9028)
1283 for ( i in bodyStyle ) {
1284 body.style[ i ] = bodyStyle[ i ];
1286 body.appendChild( div );
1287 document.documentElement.appendChild( body );
1289 // Check if a disconnected checkbox will retain its checked
1290 // value of true after appended to the DOM (IE6/7)
1291 support.appendChecked = input.checked;
1293 support.boxModel = div.offsetWidth === 2;
1295 if ( "zoom" in div.style ) {
1296 // Check if natively block-level elements act like inline-block
1297 // elements when setting their display to 'inline' and giving
1299 // (IE < 8 does this)
1300 div.style.display = "inline";
1302 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1304 // Check if elements with layout shrink-wrap their children
1306 div.style.display = "";
1307 div.innerHTML = "<div style='width:4px;'></div>";
1308 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1311 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1312 tds = div.getElementsByTagName( "td" );
1314 // Check if table cells still have offsetWidth/Height when they are set
1315 // to display:none and there are still other visible table cells in a
1316 // table row; if so, offsetWidth/Height are not reliable for use when
1317 // determining if an element has been hidden directly using
1318 // display:none (it is still safe to use offsets if a parent element is
1319 // hidden; don safety goggles and see bug #4512 for more information).
1320 // (only IE 8 fails this test)
1321 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1323 tds[ 0 ].style.display = "";
1324 tds[ 1 ].style.display = "none";
1326 // Check if empty table cells still have offsetWidth/Height
1327 // (IE < 8 fail this test)
1328 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1331 // Check if div with explicit width and no margin-right incorrectly
1332 // gets computed margin-right based on width of container. For more
1333 // info see bug #3333
1334 // Fails in WebKit before Feb 2011 nightlies
1335 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1336 if ( document.defaultView && document.defaultView.getComputedStyle ) {
1337 marginDiv = document.createElement( "div" );
1338 marginDiv.style.width = "0";
1339 marginDiv.style.marginRight = "0";
1340 div.appendChild( marginDiv );
1341 support.reliableMarginRight =
1342 ( parseInt( document.defaultView.getComputedStyle( marginDiv, null ).marginRight, 10 ) || 0 ) === 0;
1345 // Remove the body element we added
1346 body.innerHTML = "";
1347 document.documentElement.removeChild( body );
1349 // Technique from Juriy Zaytsev
1350 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1351 // We only care about the case where non-standard event systems
1352 // are used, namely in IE. Short-circuiting here helps us to
1353 // avoid an eval call (in setAttribute) which can cause CSP
1354 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1355 if ( div.attachEvent ) {
1361 eventName = "on" + i;
1362 isSupported = ( eventName in div );
1363 if ( !isSupported ) {
1364 div.setAttribute( eventName, "return;" );
1365 isSupported = ( typeof div[ eventName ] === "function" );
1367 support[ i + "Bubbles" ] = isSupported;
1374 // Keep track of boxModel
1375 jQuery.boxModel = jQuery.support.boxModel;
1380 var rbrace = /^(?:\{.*\}|\[.*\])$/,
1381 rmultiDash = /([a-z])([A-Z])/g;
1386 // Please use with caution
1389 // Unique for each copy of jQuery on the page
1390 // Non-digits removed to match rinlinejQuery
1391 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1393 // The following elements throw uncatchable exceptions if you
1394 // attempt to add expando properties to them.
1397 // Ban all objects except for Flash (which handle expandos)
1398 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1402 hasData: function( elem ) {
1403 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1405 return !!elem && !isEmptyDataObject( elem );
1408 data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1409 if ( !jQuery.acceptData( elem ) ) {
1413 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1415 // We have to handle DOM nodes and JS objects differently because IE6-7
1416 // can't GC object references properly across the DOM-JS boundary
1417 isNode = elem.nodeType,
1419 // Only DOM nodes need the global jQuery cache; JS object data is
1420 // attached directly to the object so GC can occur automatically
1421 cache = isNode ? jQuery.cache : elem,
1423 // Only defining an ID for JS objects if its cache already exists allows
1424 // the code to shortcut on the same path as a DOM node with no cache
1425 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1427 // Avoid doing any more work than we need to when trying to get data on an
1428 // object that has no data at all
1429 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1434 // Only DOM nodes need a new unique ID for each element since their data
1435 // ends up in the global cache
1437 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1439 id = jQuery.expando;
1443 if ( !cache[ id ] ) {
1446 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1447 // metadata on plain JS objects when the object is serialized using
1450 cache[ id ].toJSON = jQuery.noop;
1454 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1455 // shallow copied over onto the existing cache
1456 if ( typeof name === "object" || typeof name === "function" ) {
1458 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1460 cache[ id ] = jQuery.extend(cache[ id ], name);
1464 thisCache = cache[ id ];
1466 // Internal jQuery data is stored in a separate object inside the object's data
1467 // cache in order to avoid key collisions between internal data and user-defined
1470 if ( !thisCache[ internalKey ] ) {
1471 thisCache[ internalKey ] = {};
1474 thisCache = thisCache[ internalKey ];
1477 if ( data !== undefined ) {
1478 thisCache[ name ] = data;
1481 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1482 // not attempt to inspect the internal events object using jQuery.data, as this
1483 // internal data object is undocumented and subject to change.
1484 if ( name === "events" && !thisCache[name] ) {
1485 return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1488 return getByName ? thisCache[ name ] : thisCache;
1491 removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1492 if ( !jQuery.acceptData( elem ) ) {
1496 var internalKey = jQuery.expando, isNode = elem.nodeType,
1498 // See jQuery.data for more information
1499 cache = isNode ? jQuery.cache : elem,
1501 // See jQuery.data for more information
1502 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1504 // If there is already no cache entry for this object, there is no
1505 // purpose in continuing
1506 if ( !cache[ id ] ) {
1511 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1514 delete thisCache[ name ];
1516 // If there is no data left in the cache, we want to continue
1517 // and let the cache object itself get destroyed
1518 if ( !isEmptyDataObject(thisCache) ) {
1524 // See jQuery.data for more information
1526 delete cache[ id ][ internalKey ];
1528 // Don't destroy the parent cache unless the internal data object
1529 // had been the only thing left in it
1530 if ( !isEmptyDataObject(cache[ id ]) ) {
1535 var internalCache = cache[ id ][ internalKey ];
1537 // Browsers that fail expando deletion also refuse to delete expandos on
1538 // the window, but it will allow it on all other JS objects; other browsers
1540 if ( jQuery.support.deleteExpando || cache != window ) {
1546 // We destroyed the entire user cache at once because it's faster than
1547 // iterating through each key, but we need to continue to persist internal
1548 // data if it existed
1549 if ( internalCache ) {
1551 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1552 // metadata on plain JS objects when the object is serialized using
1555 cache[ id ].toJSON = jQuery.noop;
1558 cache[ id ][ internalKey ] = internalCache;
1560 // Otherwise, we need to eliminate the expando on the node to avoid
1561 // false lookups in the cache for entries that no longer exist
1562 } else if ( isNode ) {
1563 // IE does not allow us to delete expando properties from nodes,
1564 // nor does it have a removeAttribute function on Document nodes;
1565 // we must handle all of these cases
1566 if ( jQuery.support.deleteExpando ) {
1567 delete elem[ jQuery.expando ];
1568 } else if ( elem.removeAttribute ) {
1569 elem.removeAttribute( jQuery.expando );
1571 elem[ jQuery.expando ] = null;
1576 // For internal use only.
1577 _data: function( elem, name, data ) {
1578 return jQuery.data( elem, name, data, true );
1581 // A method for determining if a DOM node can handle the data expando
1582 acceptData: function( elem ) {
1583 if ( elem.nodeName ) {
1584 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1587 return !(match === true || elem.getAttribute("classid") !== match);
1596 data: function( key, value ) {
1599 if ( typeof key === "undefined" ) {
1600 if ( this.length ) {
1601 data = jQuery.data( this[0] );
1603 if ( this[0].nodeType === 1 ) {
1604 var attr = this[0].attributes, name;
1605 for ( var i = 0, l = attr.length; i < l; i++ ) {
1606 name = attr[i].name;
1608 if ( name.indexOf( "data-" ) === 0 ) {
1609 name = jQuery.camelCase( name.substring(5) );
1611 dataAttr( this[0], name, data[ name ] );
1619 } else if ( typeof key === "object" ) {
1620 return this.each(function() {
1621 jQuery.data( this, key );
1625 var parts = key.split(".");
1626 parts[1] = parts[1] ? "." + parts[1] : "";
1628 if ( value === undefined ) {
1629 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1631 // Try to fetch any internally stored data first
1632 if ( data === undefined && this.length ) {
1633 data = jQuery.data( this[0], key );
1634 data = dataAttr( this[0], key, data );
1637 return data === undefined && parts[1] ?
1638 this.data( parts[0] ) :
1642 return this.each(function() {
1643 var $this = jQuery( this ),
1644 args = [ parts[0], value ];
1646 $this.triggerHandler( "setData" + parts[1] + "!", args );
1647 jQuery.data( this, key, value );
1648 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1653 removeData: function( key ) {
1654 return this.each(function() {
1655 jQuery.removeData( this, key );
1660 function dataAttr( elem, key, data ) {
1661 // If nothing was found internally, try to fetch any
1662 // data from the HTML5 data-* attribute
1663 if ( data === undefined && elem.nodeType === 1 ) {
1664 name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1666 data = elem.getAttribute( name );
1668 if ( typeof data === "string" ) {
1670 data = data === "true" ? true :
1671 data === "false" ? false :
1672 data === "null" ? null :
1673 !jQuery.isNaN( data ) ? parseFloat( data ) :
1674 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1678 // Make sure we set the data so it isn't changed later
1679 jQuery.data( elem, key, data );
1689 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1690 // property to be considered empty objects; this property always exists in
1691 // order to make sure JSON.stringify does not expose internal metadata
1692 function isEmptyDataObject( obj ) {
1693 for ( var name in obj ) {
1694 if ( name !== "toJSON" ) {
1705 function handleQueueMarkDefer( elem, type, src ) {
1706 var deferDataKey = type + "defer",
1707 queueDataKey = type + "queue",
1708 markDataKey = type + "mark",
1709 defer = jQuery.data( elem, deferDataKey, undefined, true );
1711 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1712 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1713 // Give room for hard-coded callbacks to fire first
1714 // and eventually mark/queue something else on the element
1715 setTimeout( function() {
1716 if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1717 !jQuery.data( elem, markDataKey, undefined, true ) ) {
1718 jQuery.removeData( elem, deferDataKey, true );
1727 _mark: function( elem, type ) {
1729 type = (type || "fx") + "mark";
1730 jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1734 _unmark: function( force, elem, type ) {
1735 if ( force !== true ) {
1741 type = type || "fx";
1742 var key = type + "mark",
1743 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1745 jQuery.data( elem, key, count, true );
1747 jQuery.removeData( elem, key, true );
1748 handleQueueMarkDefer( elem, type, "mark" );
1753 queue: function( elem, type, data ) {
1755 type = (type || "fx") + "queue";
1756 var q = jQuery.data( elem, type, undefined, true );
1757 // Speed up dequeue by getting out quickly if this is just a lookup
1759 if ( !q || jQuery.isArray(data) ) {
1760 q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1769 dequeue: function( elem, type ) {
1770 type = type || "fx";
1772 var queue = jQuery.queue( elem, type ),
1776 // If the fx queue is dequeued, always remove the progress sentinel
1777 if ( fn === "inprogress" ) {
1782 // Add a progress sentinel to prevent the fx queue from being
1783 // automatically dequeued
1784 if ( type === "fx" ) {
1785 queue.unshift("inprogress");
1788 fn.call(elem, function() {
1789 jQuery.dequeue(elem, type);
1793 if ( !queue.length ) {
1794 jQuery.removeData( elem, type + "queue", true );
1795 handleQueueMarkDefer( elem, type, "queue" );
1801 queue: function( type, data ) {
1802 if ( typeof type !== "string" ) {
1807 if ( data === undefined ) {
1808 return jQuery.queue( this[0], type );
1810 return this.each(function() {
1811 var queue = jQuery.queue( this, type, data );
1813 if ( type === "fx" && queue[0] !== "inprogress" ) {
1814 jQuery.dequeue( this, type );
1818 dequeue: function( type ) {
1819 return this.each(function() {
1820 jQuery.dequeue( this, type );
1823 // Based off of the plugin by Clint Helfers, with permission.
1824 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1825 delay: function( time, type ) {
1826 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1827 type = type || "fx";
1829 return this.queue( type, function() {
1831 setTimeout(function() {
1832 jQuery.dequeue( elem, type );
1836 clearQueue: function( type ) {
1837 return this.queue( type || "fx", [] );
1839 // Get a promise resolved when queues of a certain type
1840 // are emptied (fx is the type by default)
1841 promise: function( type, object ) {
1842 if ( typeof type !== "string" ) {
1846 type = type || "fx";
1847 var defer = jQuery.Deferred(),
1849 i = elements.length,
1851 deferDataKey = type + "defer",
1852 queueDataKey = type + "queue",
1853 markDataKey = type + "mark";
1854 function resolve() {
1855 if ( !( --count ) ) {
1856 defer.resolveWith( elements, [ elements ] );
1860 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1861 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1862 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1863 jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1865 tmp.done( resolve );
1869 return defer.promise();
1876 var rclass = /[\n\t\r]/g,
1879 rtype = /^(?:button|input)$/i,
1880 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1881 rclickable = /^a(?:rea)?$/i,
1882 rspecial = /^(?:data-|aria-)/,
1883 rinvalidChar = /\:/,
1887 attr: function( name, value ) {
1888 return jQuery.access( this, name, value, true, jQuery.attr );
1891 removeAttr: function( name ) {
1892 return this.each(function() {
1893 jQuery.removeAttr( this, name );
1897 prop: function( name, value ) {
1898 return jQuery.access( this, name, value, true, jQuery.prop );
1901 removeProp: function( name ) {
1902 return this.each(function() {
1903 // try/catch handles cases where IE balks (such as removing a property on window)
1905 this[ name ] = undefined;
1906 delete this[ name ];
1911 addClass: function( value ) {
1912 if ( jQuery.isFunction( value ) ) {
1913 return this.each(function(i) {
1914 var self = jQuery(this);
1915 self.addClass( value.call(this, i, self.attr("class") || "") );
1919 if ( value && typeof value === "string" ) {
1920 var classNames = (value || "").split( rspace );
1922 for ( var i = 0, l = this.length; i < l; i++ ) {
1925 if ( elem.nodeType === 1 ) {
1926 if ( !elem.className ) {
1927 elem.className = value;
1930 var className = " " + elem.className + " ",
1931 setClass = elem.className;
1933 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1934 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1935 setClass += " " + classNames[c];
1938 elem.className = jQuery.trim( setClass );
1947 removeClass: function( value ) {
1948 if ( jQuery.isFunction(value) ) {
1949 return this.each(function(i) {
1950 var self = jQuery(this);
1951 self.removeClass( value.call(this, i, self.attr("class")) );
1955 if ( (value && typeof value === "string") || value === undefined ) {
1956 var classNames = (value || "").split( rspace );
1958 for ( var i = 0, l = this.length; i < l; i++ ) {
1961 if ( elem.nodeType === 1 && elem.className ) {
1963 var className = (" " + elem.className + " ").replace(rclass, " ");
1964 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1965 className = className.replace(" " + classNames[c] + " ", " ");
1967 elem.className = jQuery.trim( className );
1970 elem.className = "";
1979 toggleClass: function( value, stateVal ) {
1980 var type = typeof value,
1981 isBool = typeof stateVal === "boolean";
1983 if ( jQuery.isFunction( value ) ) {
1984 return this.each(function(i) {
1985 var self = jQuery(this);
1986 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1990 return this.each(function() {
1991 if ( type === "string" ) {
1992 // toggle individual class names
1995 self = jQuery( this ),
1997 classNames = value.split( rspace );
1999 while ( (className = classNames[ i++ ]) ) {
2000 // check each className given, space seperated list
2001 state = isBool ? state : !self.hasClass( className );
2002 self[ state ? "addClass" : "removeClass" ]( className );
2005 } else if ( type === "undefined" || type === "boolean" ) {
2006 if ( this.className ) {
2007 // store className if set
2008 jQuery._data( this, "__className__", this.className );
2011 // toggle whole className
2012 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2017 hasClass: function( selector ) {
2018 var className = " " + selector + " ";
2019 for ( var i = 0, l = this.length; i < l; i++ ) {
2020 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2028 val: function( value ) {
2032 if ( !arguments.length ) {
2034 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2036 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2040 return (elem.value || "").replace(rreturn, "");
2046 var isFunction = jQuery.isFunction( value );
2048 return this.each(function( i ) {
2049 var self = jQuery(this), val;
2051 if ( this.nodeType !== 1 ) {
2056 val = value.call( this, i, self.val() );
2061 // Treat null/undefined as ""; convert numbers to string
2062 if ( val == null ) {
2064 } else if ( typeof val === "number" ) {
2066 } else if ( jQuery.isArray( val ) ) {
2067 val = jQuery.map(val, function ( value ) {
2068 return value == null ? "" : value + "";
2072 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2074 // If set returns undefined, fall back to normal setting
2075 if ( !hooks || ("set" in hooks && hooks.set( this, val, "value" ) === undefined) ) {
2085 get: function( elem ) {
2086 // attributes.value is undefined in Blackberry 4.7 but
2087 // uses .value. See #6932
2088 var val = elem.attributes.value;
2089 return !val || val.specified ? elem.value : elem.text;
2093 get: function( elem ) {
2094 var index = elem.selectedIndex,
2096 options = elem.options,
2097 one = elem.type === "select-one";
2099 // Nothing was selected
2104 // Loop through all the selected options
2105 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2106 var option = options[ i ];
2108 // Don't return options that are disabled or in a disabled optgroup
2109 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2110 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2112 // Get the specific value for the option
2113 value = jQuery( option ).val();
2115 // We don't need an array for one selects
2120 // Multi-Selects return an array
2121 values.push( value );
2125 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2126 if ( one && !values.length && options.length ) {
2127 return jQuery( options[ index ] ).val();
2133 set: function( elem, value ) {
2134 var values = jQuery.makeArray( value );
2136 jQuery(elem).find("option").each(function() {
2137 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2140 if ( !values.length ) {
2141 elem.selectedIndex = -1;
2160 // Always normalize to ensure hook usage
2161 tabindex: "tabIndex",
2162 readonly: "readOnly"
2165 attr: function( elem, name, value, pass ) {
2166 var nType = elem.nodeType;
2168 // don't get/set attributes on text, comment and attribute nodes
2169 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2173 if ( pass && name in jQuery.attrFn ) {
2174 return jQuery( elem )[ name ]( value );
2178 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2180 // Normalize the name if needed
2181 name = notxml && jQuery.attrFix[ name ] || name;
2183 // Get the appropriate hook, or the formHook
2184 // if getSetAttribute is not supported and we have form objects in IE6/7
2185 hooks = jQuery.attrHooks[ name ] ||
2186 ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ?
2190 if ( value !== undefined ) {
2192 if ( value === null || (value === false && !rspecial.test( name )) ) {
2193 jQuery.removeAttr( elem, name );
2196 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2201 // Set boolean attributes to the same name
2202 if ( value === true && !rspecial.test( name ) ) {
2206 elem.setAttribute( name, "" + value );
2212 if ( hooks && "get" in hooks && notxml ) {
2213 return hooks.get( elem, name );
2217 ret = elem.getAttribute( name );
2219 // Non-existent attributes return null, we normalize to undefined
2220 return ret === null ?
2227 removeAttr: function( elem, name ) {
2228 if ( elem.nodeType === 1 ) {
2229 name = jQuery.attrFix[ name ] || name;
2231 if ( jQuery.support.getSetAttribute ) {
2232 // Use removeAttribute in browsers that support it
2233 elem.removeAttribute( name );
2235 jQuery.attr( elem, name, "" );
2236 elem.removeAttributeNode( elem.getAttributeNode( name ) );
2243 set: function( elem, value ) {
2244 // We can't allow the type property to be changed (since it causes problems in IE)
2245 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2246 jQuery.error( "type property can't be changed" );
2247 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2248 // Setting the type on a radio button after the value resets the value in IE6-9
2249 // Reset value to it's default in case type is set after value
2250 // This is for element creation
2251 var val = elem.getAttribute("value");
2252 elem.setAttribute( "type", value );
2261 get: function( elem ) {
2262 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2263 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2264 var attributeNode = elem.getAttributeNode("tabIndex");
2266 return attributeNode && attributeNode.specified ?
2267 parseInt( attributeNode.value, 10 ) :
2268 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2277 prop: function( elem, name, value ) {
2278 var nType = elem.nodeType;
2280 // don't get/set properties on text, comment and attribute nodes
2281 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2286 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2288 // Try to normalize/fix the name
2289 name = notxml && jQuery.propFix[ name ] || name;
2291 hooks = jQuery.propHooks[ name ];
2293 if ( value !== undefined ) {
2294 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2298 return (elem[ name ] = value);
2302 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2306 return elem[ name ];
2314 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2315 if ( !jQuery.support.getSetAttribute ) {
2316 jQuery.attrFix = jQuery.extend( jQuery.attrFix, {
2318 "class": "className",
2319 maxlength: "maxLength",
2320 cellspacing: "cellSpacing",
2321 cellpadding: "cellPadding",
2325 frameborder: "frameBorder"
2328 // Use this for any attribute on a form in IE6/7
2329 formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = {
2330 get: function( elem, name ) {
2332 if ( name === "value" && !jQuery.nodeName( elem, "button" ) ) {
2333 return elem.getAttribute( name );
2335 ret = elem.getAttributeNode( name );
2336 // Return undefined if not specified instead of empty string
2337 return ret && ret.specified ?
2341 set: function( elem, value, name ) {
2342 // Check form objects in IE (multiple bugs related)
2343 // Only use nodeValue if the attribute node exists on the form
2344 var ret = elem.getAttributeNode( name );
2346 ret.nodeValue = value;
2352 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2353 // This is for removals
2354 jQuery.each([ "width", "height" ], function( i, name ) {
2355 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2356 set: function( elem, value ) {
2357 if ( value === "" ) {
2358 elem.setAttribute( name, "auto" );
2367 // Some attributes require a special call on IE
2368 if ( !jQuery.support.hrefNormalized ) {
2369 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2370 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2371 get: function( elem ) {
2372 var ret = elem.getAttribute( name, 2 );
2373 return ret === null ? undefined : ret;
2379 if ( !jQuery.support.style ) {
2380 jQuery.attrHooks.style = {
2381 get: function( elem ) {
2382 // Return undefined in the case of empty string
2383 // Normalize to lowercase since IE uppercases css property names
2384 return elem.style.cssText.toLowerCase() || undefined;
2386 set: function( elem, value ) {
2387 return (elem.style.cssText = "" + value);
2392 // Safari mis-reports the default selected property of an option
2393 // Accessing the parent's selectedIndex property fixes it
2394 if ( !jQuery.support.optSelected ) {
2395 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2396 get: function( elem ) {
2397 var parent = elem.parentNode;
2400 parent.selectedIndex;
2402 // Make sure that it also works with optgroups, see #5701
2403 if ( parent.parentNode ) {
2404 parent.parentNode.selectedIndex;
2411 // Radios and checkboxes getter/setter
2412 if ( !jQuery.support.checkOn ) {
2413 jQuery.each([ "radio", "checkbox" ], function() {
2414 jQuery.valHooks[ this ] = {
2415 get: function( elem ) {
2416 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2417 return elem.getAttribute("value") === null ? "on" : elem.value;
2422 jQuery.each([ "radio", "checkbox" ], function() {
2423 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2424 set: function( elem, value ) {
2425 if ( jQuery.isArray( value ) ) {
2426 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2435 var hasOwn = Object.prototype.hasOwnProperty,
2436 rnamespaces = /\.(.*)$/,
2437 rformElems = /^(?:textarea|input|select)$/i,
2440 rescape = /[^\w\s.|`]/g,
2441 fcleanup = function( nm ) {
2442 return nm.replace(rescape, "\\$&");
2446 * A number of helper functions used for managing events.
2447 * Many of the ideas behind this code originated from
2448 * Dean Edwards' addEvent library.
2452 // Bind an event to an element
2453 // Original by Dean Edwards
2454 add: function( elem, types, handler, data ) {
2455 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2459 if ( handler === false ) {
2460 handler = returnFalse;
2461 } else if ( !handler ) {
2462 // Fixes bug #7229. Fix recommended by jdalton
2466 var handleObjIn, handleObj;
2468 if ( handler.handler ) {
2469 handleObjIn = handler;
2470 handler = handleObjIn.handler;
2473 // Make sure that the function being executed has a unique ID
2474 if ( !handler.guid ) {
2475 handler.guid = jQuery.guid++;
2478 // Init the element's event structure
2479 var elemData = jQuery._data( elem );
2481 // If no elemData is found then we must be trying to bind to one of the
2482 // banned noData elements
2487 var events = elemData.events,
2488 eventHandle = elemData.handle;
2491 elemData.events = events = {};
2494 if ( !eventHandle ) {
2495 elemData.handle = eventHandle = function( e ) {
2496 // Discard the second event of a jQuery.event.trigger() and
2497 // when an event is called after a page has unloaded
2498 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2499 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2504 // Add elem as a property of the handle function
2505 // This is to prevent a memory leak with non-native events in IE.
2506 eventHandle.elem = elem;
2508 // Handle multiple events separated by a space
2509 // jQuery(...).bind("mouseover mouseout", fn);
2510 types = types.split(" ");
2512 var type, i = 0, namespaces;
2514 while ( (type = types[ i++ ]) ) {
2515 handleObj = handleObjIn ?
2516 jQuery.extend({}, handleObjIn) :
2517 { handler: handler, data: data };
2519 // Namespaced event handlers
2520 if ( type.indexOf(".") > -1 ) {
2521 namespaces = type.split(".");
2522 type = namespaces.shift();
2523 handleObj.namespace = namespaces.slice(0).sort().join(".");
2527 handleObj.namespace = "";
2530 handleObj.type = type;
2531 if ( !handleObj.guid ) {
2532 handleObj.guid = handler.guid;
2535 // Get the current list of functions bound to this event
2536 var handlers = events[ type ],
2537 special = jQuery.event.special[ type ] || {};
2539 // Init the event handler queue
2541 handlers = events[ type ] = [];
2543 // Check for a special event handler
2544 // Only use addEventListener/attachEvent if the special
2545 // events handler returns false
2546 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2547 // Bind the global event handler to the element
2548 if ( elem.addEventListener ) {
2549 elem.addEventListener( type, eventHandle, false );
2551 } else if ( elem.attachEvent ) {
2552 elem.attachEvent( "on" + type, eventHandle );
2557 if ( special.add ) {
2558 special.add.call( elem, handleObj );
2560 if ( !handleObj.handler.guid ) {
2561 handleObj.handler.guid = handler.guid;
2565 // Add the function to the element's handler list
2566 handlers.push( handleObj );
2568 // Keep track of which events have been used, for event optimization
2569 jQuery.event.global[ type ] = true;
2572 // Nullify elem to prevent memory leaks in IE
2578 // Detach an event or set of events from an element
2579 remove: function( elem, types, handler, pos ) {
2580 // don't do events on text and comment nodes
2581 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2585 if ( handler === false ) {
2586 handler = returnFalse;
2589 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2590 elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2591 events = elemData && elemData.events;
2593 if ( !elemData || !events ) {
2597 // types is actually an event object here
2598 if ( types && types.type ) {
2599 handler = types.handler;
2603 // Unbind all events for the element
2604 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2605 types = types || "";
2607 for ( type in events ) {
2608 jQuery.event.remove( elem, type + types );
2614 // Handle multiple events separated by a space
2615 // jQuery(...).unbind("mouseover mouseout", fn);
2616 types = types.split(" ");
2618 while ( (type = types[ i++ ]) ) {
2621 all = type.indexOf(".") < 0;
2625 // Namespaced event handlers
2626 namespaces = type.split(".");
2627 type = namespaces.shift();
2629 namespace = new RegExp("(^|\\.)" +
2630 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2633 eventType = events[ type ];
2640 for ( j = 0; j < eventType.length; j++ ) {
2641 handleObj = eventType[ j ];
2643 if ( all || namespace.test( handleObj.namespace ) ) {
2644 jQuery.event.remove( elem, origType, handleObj.handler, j );
2645 eventType.splice( j--, 1 );
2652 special = jQuery.event.special[ type ] || {};
2654 for ( j = pos || 0; j < eventType.length; j++ ) {
2655 handleObj = eventType[ j ];
2657 if ( handler.guid === handleObj.guid ) {
2658 // remove the given handler for the given type
2659 if ( all || namespace.test( handleObj.namespace ) ) {
2660 if ( pos == null ) {
2661 eventType.splice( j--, 1 );
2664 if ( special.remove ) {
2665 special.remove.call( elem, handleObj );
2669 if ( pos != null ) {
2675 // remove generic event handler if no more handlers exist
2676 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2677 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2678 jQuery.removeEvent( elem, type, elemData.handle );
2682 delete events[ type ];
2686 // Remove the expando if it's no longer used
2687 if ( jQuery.isEmptyObject( events ) ) {
2688 var handle = elemData.handle;
2693 delete elemData.events;
2694 delete elemData.handle;
2696 if ( jQuery.isEmptyObject( elemData ) ) {
2697 jQuery.removeData( elem, undefined, true );
2702 // Events that are safe to short-circuit if no handlers are attached.
2703 // Native DOM events should not be added, they may have inline handlers.
2710 trigger: function( event, data, elem, onlyHandlers ) {
2711 // Event object or event type
2712 var type = event.type || event,
2716 if ( type.indexOf("!") >= 0 ) {
2717 // Exclusive events trigger only for the exact event (no namespaces)
2718 type = type.slice(0, -1);
2722 if ( type.indexOf(".") >= 0 ) {
2723 // Namespaced trigger; create a regexp to match event type in handle()
2724 namespaces = type.split(".");
2725 type = namespaces.shift();
2729 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2730 // No jQuery handlers for this event type, and it can't have inline handlers
2734 // Caller can pass in an Event, Object, or just an event type string
2735 event = typeof event === "object" ?
2736 // jQuery.Event object
2737 event[ jQuery.expando ] ? event :
2739 new jQuery.Event( type, event ) :
2740 // Just the event type (string)
2741 new jQuery.Event( type );
2744 event.exclusive = exclusive;
2745 event.namespace = namespaces.join(".");
2746 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2748 // triggerHandler() and global events don't bubble or run the default action
2749 if ( onlyHandlers || !elem ) {
2750 event.preventDefault();
2751 event.stopPropagation();
2754 // Handle a global trigger
2756 // TODO: Stop taunting the data cache; remove global events and always attach to document
2757 jQuery.each( jQuery.cache, function() {
2758 // internalKey variable is just used to make it easier to find
2759 // and potentially change this stuff later; currently it just
2760 // points to jQuery.expando
2761 var internalKey = jQuery.expando,
2762 internalCache = this[ internalKey ];
2763 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2764 jQuery.event.trigger( event, data, internalCache.handle.elem );
2770 // Don't do events on text and comment nodes
2771 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2775 // Clean up the event in case it is being reused
2776 event.result = undefined;
2777 event.target = elem;
2779 // Clone any incoming data and prepend the event, creating the handler arg list
2780 data = data ? jQuery.makeArray( data ) : [];
2781 data.unshift( event );
2784 // IE doesn't like method names with a colon (#3533, #8272)
2785 ontype = type.indexOf(":") < 0 ? "on" + type : "";
2787 // Fire event on the current element, then bubble up the DOM tree
2789 var handle = jQuery._data( cur, "handle" );
2791 event.currentTarget = cur;
2793 handle.apply( cur, data );
2796 // Trigger an inline bound script
2797 if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2798 event.result = false;
2799 event.preventDefault();
2802 // Bubble up to document, then to window
2803 cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2804 } while ( cur && !event.isPropagationStopped() );
2806 // If nobody prevented the default action, do it now
2807 if ( !event.isDefaultPrevented() ) {
2809 special = jQuery.event.special[ type ] || {};
2811 if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2812 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2814 // Call a native DOM method on the target with the same name name as the event.
2815 // Can't use an .isFunction)() check here because IE6/7 fails that test.
2816 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2818 if ( ontype && elem[ type ] ) {
2819 // Don't re-trigger an onFOO event when we call its FOO() method
2820 old = elem[ ontype ];
2823 elem[ ontype ] = null;
2826 jQuery.event.triggered = type;
2829 } catch ( ieError ) {}
2832 elem[ ontype ] = old;
2835 jQuery.event.triggered = undefined;
2839 return event.result;
2842 handle: function( event ) {
2843 event = jQuery.event.fix( event || window.event );
2844 // Snapshot the handlers list since a called handler may add/remove events.
2845 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2846 run_all = !event.exclusive && !event.namespace,
2847 args = Array.prototype.slice.call( arguments, 0 );
2849 // Use the fix-ed Event rather than the (read-only) native event
2851 event.currentTarget = this;
2853 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2854 var handleObj = handlers[ j ];
2856 // Triggered event must 1) be non-exclusive and have no namespace, or
2857 // 2) have namespace(s) a subset or equal to those in the bound event.
2858 if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2859 // Pass in a reference to the handler function itself
2860 // So that we can later remove it
2861 event.handler = handleObj.handler;
2862 event.data = handleObj.data;
2863 event.handleObj = handleObj;
2865 var ret = handleObj.handler.apply( this, args );
2867 if ( ret !== undefined ) {
2869 if ( ret === false ) {
2870 event.preventDefault();
2871 event.stopPropagation();
2875 if ( event.isImmediatePropagationStopped() ) {
2880 return event.result;
2883 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(" "),
2885 fix: function( event ) {
2886 if ( event[ jQuery.expando ] ) {
2890 // store a copy of the original event object
2891 // and "clone" to set read-only properties
2892 var originalEvent = event;
2893 event = jQuery.Event( originalEvent );
2895 for ( var i = this.props.length, prop; i; ) {
2896 prop = this.props[ --i ];
2897 event[ prop ] = originalEvent[ prop ];
2900 // Fix target property, if necessary
2901 if ( !event.target ) {
2902 // Fixes #1925 where srcElement might not be defined either
2903 event.target = event.srcElement || document;
2906 // check if target is a textnode (safari)
2907 if ( event.target.nodeType === 3 ) {
2908 event.target = event.target.parentNode;
2911 // Add relatedTarget, if necessary
2912 if ( !event.relatedTarget && event.fromElement ) {
2913 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2916 // Calculate pageX/Y if missing and clientX/Y available
2917 if ( event.pageX == null && event.clientX != null ) {
2918 var eventDocument = event.target.ownerDocument || document,
2919 doc = eventDocument.documentElement,
2920 body = eventDocument.body;
2922 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2923 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
2926 // Add which for key events
2927 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2928 event.which = event.charCode != null ? event.charCode : event.keyCode;
2931 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2932 if ( !event.metaKey && event.ctrlKey ) {
2933 event.metaKey = event.ctrlKey;
2936 // Add which for click: 1 === left; 2 === middle; 3 === right
2937 // Note: button is not normalized, so don't use it
2938 if ( !event.which && event.button !== undefined ) {
2939 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2945 // Deprecated, use jQuery.guid instead
2948 // Deprecated, use jQuery.proxy instead
2949 proxy: jQuery.proxy,
2953 // Make sure the ready event is setup
2954 setup: jQuery.bindReady,
2955 teardown: jQuery.noop
2959 add: function( handleObj ) {
2960 jQuery.event.add( this,
2961 liveConvert( handleObj.origType, handleObj.selector ),
2962 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
2965 remove: function( handleObj ) {
2966 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
2971 setup: function( data, namespaces, eventHandle ) {
2972 // We only want to do this special case on windows
2973 if ( jQuery.isWindow( this ) ) {
2974 this.onbeforeunload = eventHandle;
2978 teardown: function( namespaces, eventHandle ) {
2979 if ( this.onbeforeunload === eventHandle ) {
2980 this.onbeforeunload = null;
2987 jQuery.removeEvent = document.removeEventListener ?
2988 function( elem, type, handle ) {
2989 if ( elem.removeEventListener ) {
2990 elem.removeEventListener( type, handle, false );
2993 function( elem, type, handle ) {
2994 if ( elem.detachEvent ) {
2995 elem.detachEvent( "on" + type, handle );
2999 jQuery.Event = function( src, props ) {
3000 // Allow instantiation without the 'new' keyword
3001 if ( !this.preventDefault ) {
3002 return new jQuery.Event( src, props );
3006 if ( src && src.type ) {
3007 this.originalEvent = src;
3008 this.type = src.type;
3010 // Events bubbling up the document may have been marked as prevented
3011 // by a handler lower down the tree; reflect the correct value.
3012 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3013 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3020 // Put explicitly provided properties onto the event object
3022 jQuery.extend( this, props );
3025 // timeStamp is buggy for some events on Firefox(#3843)
3026 // So we won't rely on the native value
3027 this.timeStamp = jQuery.now();
3030 this[ jQuery.expando ] = true;
3033 function returnFalse() {
3036 function returnTrue() {
3040 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3041 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3042 jQuery.Event.prototype = {
3043 preventDefault: function() {
3044 this.isDefaultPrevented = returnTrue;
3046 var e = this.originalEvent;
3051 // if preventDefault exists run it on the original event
3052 if ( e.preventDefault ) {
3055 // otherwise set the returnValue property of the original event to false (IE)
3057 e.returnValue = false;
3060 stopPropagation: function() {
3061 this.isPropagationStopped = returnTrue;
3063 var e = this.originalEvent;
3067 // if stopPropagation exists run it on the original event
3068 if ( e.stopPropagation ) {
3069 e.stopPropagation();
3071 // otherwise set the cancelBubble property of the original event to true (IE)
3072 e.cancelBubble = true;
3074 stopImmediatePropagation: function() {
3075 this.isImmediatePropagationStopped = returnTrue;
3076 this.stopPropagation();
3078 isDefaultPrevented: returnFalse,
3079 isPropagationStopped: returnFalse,
3080 isImmediatePropagationStopped: returnFalse
3083 // Checks if an event happened on an element within another element
3084 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3085 var withinElement = function( event ) {
3086 // Check if mouse(over|out) are still within the same parent element
3087 var parent = event.relatedTarget;
3089 // Firefox sometimes assigns relatedTarget a XUL element
3090 // which we cannot access the parentNode property of
3093 // Chrome does something similar, the parentNode property
3094 // can be accessed but is null.
3095 if ( parent && parent !== document && !parent.parentNode ) {
3098 // Traverse up the tree
3099 while ( parent && parent !== this ) {
3100 parent = parent.parentNode;
3103 if ( parent !== this ) {
3104 // set the correct event type
3105 event.type = event.data;
3107 // handle event if we actually just moused on to a non sub-element
3108 jQuery.event.handle.apply( this, arguments );
3111 // assuming we've left the element since we most likely mousedover a xul element
3115 // In case of event delegation, we only need to rename the event.type,
3116 // liveHandler will take care of the rest.
3117 delegate = function( event ) {
3118 event.type = event.data;
3119 jQuery.event.handle.apply( this, arguments );
3122 // Create mouseenter and mouseleave events
3124 mouseenter: "mouseover",
3125 mouseleave: "mouseout"
3126 }, function( orig, fix ) {
3127 jQuery.event.special[ orig ] = {
3128 setup: function( data ) {
3129 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3131 teardown: function( data ) {
3132 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3137 // submit delegation
3138 if ( !jQuery.support.submitBubbles ) {
3140 jQuery.event.special.submit = {
3141 setup: function( data, namespaces ) {
3142 if ( !jQuery.nodeName( this, "form" ) ) {
3143 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3144 var elem = e.target,
3147 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3148 trigger( "submit", this, arguments );
3152 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3153 var elem = e.target,
3156 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3157 trigger( "submit", this, arguments );
3166 teardown: function( namespaces ) {
3167 jQuery.event.remove( this, ".specialSubmit" );
3173 // change delegation, happens here so we have bind.
3174 if ( !jQuery.support.changeBubbles ) {
3178 getVal = function( elem ) {
3179 var type = elem.type, val = elem.value;
3181 if ( type === "radio" || type === "checkbox" ) {
3184 } else if ( type === "select-multiple" ) {
3185 val = elem.selectedIndex > -1 ?
3186 jQuery.map( elem.options, function( elem ) {
3187 return elem.selected;
3191 } else if ( jQuery.nodeName( elem, "select" ) ) {
3192 val = elem.selectedIndex;
3198 testChange = function testChange( e ) {
3199 var elem = e.target, data, val;
3201 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3205 data = jQuery._data( elem, "_change_data" );
3208 // the current data will be also retrieved by beforeactivate
3209 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3210 jQuery._data( elem, "_change_data", val );
3213 if ( data === undefined || val === data ) {
3217 if ( data != null || val ) {
3219 e.liveFired = undefined;
3220 jQuery.event.trigger( e, arguments[1], elem );
3224 jQuery.event.special.change = {
3226 focusout: testChange,
3228 beforedeactivate: testChange,
3230 click: function( e ) {
3231 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3233 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3234 testChange.call( this, e );
3238 // Change has to be called before submit
3239 // Keydown will be called before keypress, which is used in submit-event delegation
3240 keydown: function( e ) {
3241 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3243 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3244 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3245 type === "select-multiple" ) {
3246 testChange.call( this, e );
3250 // Beforeactivate happens also before the previous element is blurred
3251 // with this event you can't trigger a change event, but you can store
3253 beforeactivate: function( e ) {
3254 var elem = e.target;
3255 jQuery._data( elem, "_change_data", getVal(elem) );
3259 setup: function( data, namespaces ) {
3260 if ( this.type === "file" ) {
3264 for ( var type in changeFilters ) {
3265 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3268 return rformElems.test( this.nodeName );
3271 teardown: function( namespaces ) {
3272 jQuery.event.remove( this, ".specialChange" );
3274 return rformElems.test( this.nodeName );
3278 changeFilters = jQuery.event.special.change.filters;
3280 // Handle when the input is .focus()'d
3281 changeFilters.focus = changeFilters.beforeactivate;
3284 function trigger( type, elem, args ) {
3285 // Piggyback on a donor event to simulate a different one.
3286 // Fake originalEvent to avoid donor's stopPropagation, but if the
3287 // simulated event prevents default then we do the same on the donor.
3288 // Don't pass args or remember liveFired; they apply to the donor event.
3289 var event = jQuery.extend( {}, args[ 0 ] );
3291 event.originalEvent = {};
3292 event.liveFired = undefined;
3293 jQuery.event.handle.call( elem, event );
3294 if ( event.isDefaultPrevented() ) {
3295 args[ 0 ].preventDefault();
3299 // Create "bubbling" focus and blur events
3300 if ( !jQuery.support.focusinBubbles ) {
3301 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3303 // Attach a single capturing handler while someone wants focusin/focusout
3306 jQuery.event.special[ fix ] = {
3308 if ( attaches++ === 0 ) {
3309 document.addEventListener( orig, handler, true );
3312 teardown: function() {
3313 if ( --attaches === 0 ) {
3314 document.removeEventListener( orig, handler, true );
3319 function handler( donor ) {
3320 // Donor event is always a native one; fix it and switch its type.
3321 // Let focusin/out handler cancel the donor focus/blur event.
3322 var e = jQuery.event.fix( donor );
3324 e.originalEvent = {};
3325 jQuery.event.trigger( e, null, e.target );
3326 if ( e.isDefaultPrevented() ) {
3327 donor.preventDefault();
3333 jQuery.each(["bind", "one"], function( i, name ) {
3334 jQuery.fn[ name ] = function( type, data, fn ) {
3337 // Handle object literals
3338 if ( typeof type === "object" ) {
3339 for ( var key in type ) {
3340 this[ name ](key, data, type[key], fn);
3345 if ( arguments.length === 2 || data === false ) {
3350 if ( name === "one" ) {
3351 handler = function( event ) {
3352 jQuery( this ).unbind( event, handler );
3353 return fn.apply( this, arguments );
3355 handler.guid = fn.guid || jQuery.guid++;
3360 if ( type === "unload" && name !== "one" ) {
3361 this.one( type, data, fn );
3364 for ( var i = 0, l = this.length; i < l; i++ ) {
3365 jQuery.event.add( this[i], type, handler, data );
3374 unbind: function( type, fn ) {
3375 // Handle object literals
3376 if ( typeof type === "object" && !type.preventDefault ) {
3377 for ( var key in type ) {
3378 this.unbind(key, type[key]);
3382 for ( var i = 0, l = this.length; i < l; i++ ) {
3383 jQuery.event.remove( this[i], type, fn );
3390 delegate: function( selector, types, data, fn ) {
3391 return this.live( types, data, fn, selector );
3394 undelegate: function( selector, types, fn ) {
3395 if ( arguments.length === 0 ) {
3396 return this.unbind( "live" );
3399 return this.die( types, null, fn, selector );
3403 trigger: function( type, data ) {
3404 return this.each(function() {
3405 jQuery.event.trigger( type, data, this );
3409 triggerHandler: function( type, data ) {
3411 return jQuery.event.trigger( type, data, this[0], true );
3415 toggle: function( fn ) {
3416 // Save reference to arguments for access in closure
3417 var args = arguments,
3418 guid = fn.guid || jQuery.guid++,
3420 toggler = function( event ) {
3421 // Figure out which function to execute
3422 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3423 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3425 // Make sure that clicks stop
3426 event.preventDefault();
3428 // and execute the function
3429 return args[ lastToggle ].apply( this, arguments ) || false;
3432 // link all the functions, so any of them can unbind this click handler
3433 toggler.guid = guid;
3434 while ( i < args.length ) {
3435 args[ i++ ].guid = guid;
3438 return this.click( toggler );
3441 hover: function( fnOver, fnOut ) {
3442 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3449 mouseenter: "mouseover",
3450 mouseleave: "mouseout"
3453 jQuery.each(["live", "die"], function( i, name ) {
3454 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3455 var type, i = 0, match, namespaces, preType,
3456 selector = origSelector || this.selector,
3457 context = origSelector ? this : jQuery( this.context );
3459 if ( typeof types === "object" && !types.preventDefault ) {
3460 for ( var key in types ) {
3461 context[ name ]( key, data, types[key], selector );
3467 if ( name === "die" && !types &&
3468 origSelector && origSelector.charAt(0) === "." ) {
3470 context.unbind( origSelector );
3475 if ( data === false || jQuery.isFunction( data ) ) {
3476 fn = data || returnFalse;
3480 types = (types || "").split(" ");
3482 while ( (type = types[ i++ ]) != null ) {
3483 match = rnamespaces.exec( type );
3487 namespaces = match[0];
3488 type = type.replace( rnamespaces, "" );
3491 if ( type === "hover" ) {
3492 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3498 if ( liveMap[ type ] ) {
3499 types.push( liveMap[ type ] + namespaces );
3500 type = type + namespaces;
3503 type = (liveMap[ type ] || type) + namespaces;
3506 if ( name === "live" ) {
3507 // bind live handler
3508 for ( var j = 0, l = context.length; j < l; j++ ) {
3509 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3510 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3514 // unbind live handler
3515 context.unbind( "live." + liveConvert( type, selector ), fn );
3523 function liveHandler( event ) {
3524 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3527 events = jQuery._data( this, "events" );
3529 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3530 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3534 if ( event.namespace ) {
3535 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3538 event.liveFired = this;
3540 var live = events.live.slice(0);
3542 for ( j = 0; j < live.length; j++ ) {
3543 handleObj = live[j];
3545 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3546 selectors.push( handleObj.selector );
3549 live.splice( j--, 1 );
3553 match = jQuery( event.target ).closest( selectors, event.currentTarget );
3555 for ( i = 0, l = match.length; i < l; i++ ) {
3558 for ( j = 0; j < live.length; j++ ) {
3559 handleObj = live[j];
3561 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3565 // Those two events require additional checking
3566 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3567 event.type = handleObj.preType;
3568 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3570 // Make sure not to accidentally match a child element with the same selector
3571 if ( related && jQuery.contains( elem, related ) ) {
3576 if ( !related || related !== elem ) {
3577 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3583 for ( i = 0, l = elems.length; i < l; i++ ) {
3586 if ( maxLevel && match.level > maxLevel ) {
3590 event.currentTarget = match.elem;
3591 event.data = match.handleObj.data;
3592 event.handleObj = match.handleObj;
3594 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3596 if ( ret === false || event.isPropagationStopped() ) {
3597 maxLevel = match.level;
3599 if ( ret === false ) {
3602 if ( event.isImmediatePropagationStopped() ) {
3611 function liveConvert( type, selector ) {
3612 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3615 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3616 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3617 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3619 // Handle event binding
3620 jQuery.fn[ name ] = function( data, fn ) {
3626 return arguments.length > 0 ?
3627 this.bind( name, data, fn ) :
3628 this.trigger( name );
3631 if ( jQuery.attrFn ) {
3632 jQuery.attrFn[ name ] = true;
3639 * Sizzle CSS Selector Engine
3640 * Copyright 2011, The Dojo Foundation
3641 * Released under the MIT, BSD, and GPL Licenses.
3642 * More information: http://sizzlejs.com/
3646 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3648 toString = Object.prototype.toString,
3649 hasDuplicate = false,
3650 baseHasDuplicate = true,
3654 // Here we check if the JavaScript engine is using some sort of
3655 // optimization where it does not always call our comparision
3656 // function. If that is the case, discard the hasDuplicate value.
3657 // Thus far that includes Google Chrome.
3658 [0, 0].sort(function() {
3659 baseHasDuplicate = false;
3663 var Sizzle = function( selector, context, results, seed ) {
3664 results = results || [];
3665 context = context || document;
3667 var origContext = context;
3669 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3673 if ( !selector || typeof selector !== "string" ) {
3677 var m, set, checkSet, extra, ret, cur, pop, i,
3679 contextXML = Sizzle.isXML( context ),
3683 // Reset the position of the chunker regexp (start from head)
3686 m = chunker.exec( soFar );
3700 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3702 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3703 set = posProcess( parts[0] + parts[1], context );
3706 set = Expr.relative[ parts[0] ] ?
3708 Sizzle( parts.shift(), context );
3710 while ( parts.length ) {
3711 selector = parts.shift();
3713 if ( Expr.relative[ selector ] ) {
3714 selector += parts.shift();
3717 set = posProcess( selector, set );
3722 // Take a shortcut and set the context if the root selector is an ID
3723 // (but not if it'll be faster if the inner selector is an ID)
3724 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3725 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3727 ret = Sizzle.find( parts.shift(), context, contextXML );
3728 context = ret.expr ?
3729 Sizzle.filter( ret.expr, ret.set )[0] :
3735 { expr: parts.pop(), set: makeArray(seed) } :
3736 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3739 Sizzle.filter( ret.expr, ret.set ) :
3742 if ( parts.length > 0 ) {
3743 checkSet = makeArray( set );
3749 while ( parts.length ) {
3753 if ( !Expr.relative[ cur ] ) {
3759 if ( pop == null ) {
3763 Expr.relative[ cur ]( checkSet, pop, contextXML );
3767 checkSet = parts = [];
3776 Sizzle.error( cur || selector );
3779 if ( toString.call(checkSet) === "[object Array]" ) {
3781 results.push.apply( results, checkSet );
3783 } else if ( context && context.nodeType === 1 ) {
3784 for ( i = 0; checkSet[i] != null; i++ ) {
3785 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3786 results.push( set[i] );
3791 for ( i = 0; checkSet[i] != null; i++ ) {
3792 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3793 results.push( set[i] );
3799 makeArray( checkSet, results );
3803 Sizzle( extra, origContext, results, seed );
3804 Sizzle.uniqueSort( results );
3810 Sizzle.uniqueSort = function( results ) {
3812 hasDuplicate = baseHasDuplicate;
3813 results.sort( sortOrder );
3815 if ( hasDuplicate ) {
3816 for ( var i = 1; i < results.length; i++ ) {
3817 if ( results[i] === results[ i - 1 ] ) {
3818 results.splice( i--, 1 );
3827 Sizzle.matches = function( expr, set ) {
3828 return Sizzle( expr, null, null, set );
3831 Sizzle.matchesSelector = function( node, expr ) {
3832 return Sizzle( expr, null, null, [node] ).length > 0;
3835 Sizzle.find = function( expr, context, isXML ) {
3842 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3844 type = Expr.order[i];
3846 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3847 var left = match[1];
3848 match.splice( 1, 1 );
3850 if ( left.substr( left.length - 1 ) !== "\\" ) {
3851 match[1] = (match[1] || "").replace( rBackslash, "" );
3852 set = Expr.find[ type ]( match, context, isXML );
3854 if ( set != null ) {
3855 expr = expr.replace( Expr.match[ type ], "" );
3863 set = typeof context.getElementsByTagName !== "undefined" ?
3864 context.getElementsByTagName( "*" ) :
3868 return { set: set, expr: expr };
3871 Sizzle.filter = function( expr, set, inplace, not ) {
3872 var match, anyFound,
3876 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3878 while ( expr && set.length ) {
3879 for ( var type in Expr.filter ) {
3880 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3882 filter = Expr.filter[ type ],
3889 if ( left.substr( left.length - 1 ) === "\\" ) {
3893 if ( curLoop === result ) {
3897 if ( Expr.preFilter[ type ] ) {
3898 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3901 anyFound = found = true;
3903 } else if ( match === true ) {
3909 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3911 found = filter( item, match, i, curLoop );
3912 var pass = not ^ !!found;
3914 if ( inplace && found != null ) {
3922 } else if ( pass ) {
3923 result.push( item );
3930 if ( found !== undefined ) {
3935 expr = expr.replace( Expr.match[ type ], "" );
3946 // Improper expression
3947 if ( expr === old ) {
3948 if ( anyFound == null ) {
3949 Sizzle.error( expr );
3962 Sizzle.error = function( msg ) {
3963 throw "Syntax error, unrecognized expression: " + msg;
3966 var Expr = Sizzle.selectors = {
3967 order: [ "ID", "NAME", "TAG" ],
3970 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3971 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3972 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3973 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
3974 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3975 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
3976 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3977 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3983 "class": "className",
3988 href: function( elem ) {
3989 return elem.getAttribute( "href" );
3991 type: function( elem ) {
3992 return elem.getAttribute( "type" );
3997 "+": function(checkSet, part){
3998 var isPartStr = typeof part === "string",
3999 isTag = isPartStr && !rNonWord.test( part ),
4000 isPartStrNotTag = isPartStr && !isTag;
4003 part = part.toLowerCase();
4006 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4007 if ( (elem = checkSet[i]) ) {
4008 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4010 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4016 if ( isPartStrNotTag ) {
4017 Sizzle.filter( part, checkSet, true );
4021 ">": function( checkSet, part ) {
4023 isPartStr = typeof part === "string",
4025 l = checkSet.length;
4027 if ( isPartStr && !rNonWord.test( part ) ) {
4028 part = part.toLowerCase();
4030 for ( ; i < l; i++ ) {
4034 var parent = elem.parentNode;
4035 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4040 for ( ; i < l; i++ ) {
4044 checkSet[i] = isPartStr ?
4046 elem.parentNode === part;
4051 Sizzle.filter( part, checkSet, true );
4056 "": function(checkSet, part, isXML){
4061 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4062 part = part.toLowerCase();
4064 checkFn = dirNodeCheck;
4067 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4070 "~": function( checkSet, part, isXML ) {
4075 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4076 part = part.toLowerCase();
4078 checkFn = dirNodeCheck;
4081 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4086 ID: function( match, context, isXML ) {
4087 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4088 var m = context.getElementById(match[1]);
4089 // Check parentNode to catch when Blackberry 4.6 returns
4090 // nodes that are no longer in the document #6963
4091 return m && m.parentNode ? [m] : [];
4095 NAME: function( match, context ) {
4096 if ( typeof context.getElementsByName !== "undefined" ) {
4098 results = context.getElementsByName( match[1] );
4100 for ( var i = 0, l = results.length; i < l; i++ ) {
4101 if ( results[i].getAttribute("name") === match[1] ) {
4102 ret.push( results[i] );
4106 return ret.length === 0 ? null : ret;
4110 TAG: function( match, context ) {
4111 if ( typeof context.getElementsByTagName !== "undefined" ) {
4112 return context.getElementsByTagName( match[1] );
4117 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4118 match = " " + match[1].replace( rBackslash, "" ) + " ";
4124 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4126 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4128 result.push( elem );
4131 } else if ( inplace ) {
4140 ID: function( match ) {
4141 return match[1].replace( rBackslash, "" );
4144 TAG: function( match, curLoop ) {
4145 return match[1].replace( rBackslash, "" ).toLowerCase();
4148 CHILD: function( match ) {
4149 if ( match[1] === "nth" ) {
4151 Sizzle.error( match[0] );
4154 match[2] = match[2].replace(/^\+|\s*/g, '');
4156 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4157 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4158 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4159 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4161 // calculate the numbers (first)n+(last) including if they are negative
4162 match[2] = (test[1] + (test[2] || 1)) - 0;
4163 match[3] = test[3] - 0;
4165 else if ( match[2] ) {
4166 Sizzle.error( match[0] );
4169 // TODO: Move to normal caching system
4175 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4176 var name = match[1] = match[1].replace( rBackslash, "" );
4178 if ( !isXML && Expr.attrMap[name] ) {
4179 match[1] = Expr.attrMap[name];
4182 // Handle if an un-quoted value was used
4183 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4185 if ( match[2] === "~=" ) {
4186 match[4] = " " + match[4] + " ";
4192 PSEUDO: function( match, curLoop, inplace, result, not ) {
4193 if ( match[1] === "not" ) {
4194 // If we're dealing with a complex expression, or a simple one
4195 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4196 match[3] = Sizzle(match[3], null, null, curLoop);
4199 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4202 result.push.apply( result, ret );
4208 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4215 POS: function( match ) {
4216 match.unshift( true );
4223 enabled: function( elem ) {
4224 return elem.disabled === false && elem.type !== "hidden";
4227 disabled: function( elem ) {
4228 return elem.disabled === true;
4231 checked: function( elem ) {
4232 return elem.checked === true;
4235 selected: function( elem ) {
4236 // Accessing this property makes selected-by-default
4237 // options in Safari work properly
4238 if ( elem.parentNode ) {
4239 elem.parentNode.selectedIndex;
4242 return elem.selected === true;
4245 parent: function( elem ) {
4246 return !!elem.firstChild;
4249 empty: function( elem ) {
4250 return !elem.firstChild;
4253 has: function( elem, i, match ) {
4254 return !!Sizzle( match[3], elem ).length;
4257 header: function( elem ) {
4258 return (/h\d/i).test( elem.nodeName );
4261 text: function( elem ) {
4262 var attr = elem.getAttribute( "type" ), type = elem.type;
4263 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4264 // use getAttribute instead to test this case
4265 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4268 radio: function( elem ) {
4269 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4272 checkbox: function( elem ) {
4273 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4276 file: function( elem ) {
4277 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4280 password: function( elem ) {
4281 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4284 submit: function( elem ) {
4285 var name = elem.nodeName.toLowerCase();
4286 return (name === "input" || name === "button") && "submit" === elem.type;
4289 image: function( elem ) {
4290 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4293 reset: function( elem ) {
4294 return elem.nodeName.toLowerCase() === "input" && "reset" === elem.type;
4297 button: function( elem ) {
4298 var name = elem.nodeName.toLowerCase();
4299 return name === "input" && "button" === elem.type || name === "button";
4302 input: function( elem ) {
4303 return (/input|select|textarea|button/i).test( elem.nodeName );
4306 focus: function( elem ) {
4307 return elem === elem.ownerDocument.activeElement;
4311 first: function( elem, i ) {
4315 last: function( elem, i, match, array ) {
4316 return i === array.length - 1;
4319 even: function( elem, i ) {
4323 odd: function( elem, i ) {
4327 lt: function( elem, i, match ) {
4328 return i < match[3] - 0;
4331 gt: function( elem, i, match ) {
4332 return i > match[3] - 0;
4335 nth: function( elem, i, match ) {
4336 return match[3] - 0 === i;
4339 eq: function( elem, i, match ) {
4340 return match[3] - 0 === i;
4344 PSEUDO: function( elem, match, i, array ) {
4345 var name = match[1],
4346 filter = Expr.filters[ name ];
4349 return filter( elem, i, match, array );
4351 } else if ( name === "contains" ) {
4352 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4354 } else if ( name === "not" ) {
4357 for ( var j = 0, l = not.length; j < l; j++ ) {
4358 if ( not[j] === elem ) {
4366 Sizzle.error( name );
4370 CHILD: function( elem, match ) {
4371 var type = match[1],
4377 while ( (node = node.previousSibling) ) {
4378 if ( node.nodeType === 1 ) {
4383 if ( type === "first" ) {
4390 while ( (node = node.nextSibling) ) {
4391 if ( node.nodeType === 1 ) {
4399 var first = match[2],
4402 if ( first === 1 && last === 0 ) {
4406 var doneName = match[0],
4407 parent = elem.parentNode;
4409 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4412 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4413 if ( node.nodeType === 1 ) {
4414 node.nodeIndex = ++count;
4418 parent.sizcache = doneName;
4421 var diff = elem.nodeIndex - last;
4423 if ( first === 0 ) {
4427 return ( diff % first === 0 && diff / first >= 0 );
4432 ID: function( elem, match ) {
4433 return elem.nodeType === 1 && elem.getAttribute("id") === match;
4436 TAG: function( elem, match ) {
4437 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4440 CLASS: function( elem, match ) {
4441 return (" " + (elem.className || elem.getAttribute("class")) + " ")
4442 .indexOf( match ) > -1;
4445 ATTR: function( elem, match ) {
4446 var name = match[1],
4447 result = Expr.attrHandle[ name ] ?
4448 Expr.attrHandle[ name ]( elem ) :
4449 elem[ name ] != null ?
4451 elem.getAttribute( name ),
4452 value = result + "",
4456 return result == null ?
4461 value.indexOf(check) >= 0 :
4463 (" " + value + " ").indexOf(check) >= 0 :
4465 value && result !== false :
4469 value.indexOf(check) === 0 :
4471 value.substr(value.length - check.length) === check :
4473 value === check || value.substr(0, check.length + 1) === check + "-" :
4477 POS: function( elem, match, i, array ) {
4478 var name = match[2],
4479 filter = Expr.setFilters[ name ];
4482 return filter( elem, i, match, array );
4488 var origPOS = Expr.match.POS,
4489 fescape = function(all, num){
4490 return "\\" + (num - 0 + 1);
4493 for ( var type in Expr.match ) {
4494 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4495 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4498 var makeArray = function( array, results ) {
4499 array = Array.prototype.slice.call( array, 0 );
4502 results.push.apply( results, array );
4509 // Perform a simple check to determine if the browser is capable of
4510 // converting a NodeList to an array using builtin methods.
4511 // Also verifies that the returned array holds DOM nodes
4512 // (which is not the case in the Blackberry browser)
4514 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4516 // Provide a fallback method if it does not work
4518 makeArray = function( array, results ) {
4520 ret = results || [];
4522 if ( toString.call(array) === "[object Array]" ) {
4523 Array.prototype.push.apply( ret, array );
4526 if ( typeof array.length === "number" ) {
4527 for ( var l = array.length; i < l; i++ ) {
4528 ret.push( array[i] );
4532 for ( ; array[i]; i++ ) {
4533 ret.push( array[i] );
4542 var sortOrder, siblingCheck;
4544 if ( document.documentElement.compareDocumentPosition ) {
4545 sortOrder = function( a, b ) {
4547 hasDuplicate = true;
4551 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4552 return a.compareDocumentPosition ? -1 : 1;
4555 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4559 sortOrder = function( a, b ) {
4567 // The nodes are identical, we can exit early
4569 hasDuplicate = true;
4572 // If the nodes are siblings (or identical) we can do a quick check
4573 } else if ( aup === bup ) {
4574 return siblingCheck( a, b );
4576 // If no parents were found then the nodes are disconnected
4577 } else if ( !aup ) {
4580 } else if ( !bup ) {
4584 // Otherwise they're somewhere else in the tree so we need
4585 // to build up a full list of the parentNodes for comparison
4588 cur = cur.parentNode;
4595 cur = cur.parentNode;
4601 // Start walking down the tree looking for a discrepancy
4602 for ( var i = 0; i < al && i < bl; i++ ) {
4603 if ( ap[i] !== bp[i] ) {
4604 return siblingCheck( ap[i], bp[i] );
4608 // We ended someplace up the tree so do a sibling check
4610 siblingCheck( a, bp[i], -1 ) :
4611 siblingCheck( ap[i], b, 1 );
4614 siblingCheck = function( a, b, ret ) {
4619 var cur = a.nextSibling;
4626 cur = cur.nextSibling;
4633 // Utility function for retreiving the text value of an array of DOM nodes
4634 Sizzle.getText = function( elems ) {
4637 for ( var i = 0; elems[i]; i++ ) {
4640 // Get the text from text nodes and CDATA nodes
4641 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4642 ret += elem.nodeValue;
4644 // Traverse everything else, except comment nodes
4645 } else if ( elem.nodeType !== 8 ) {
4646 ret += Sizzle.getText( elem.childNodes );
4653 // Check to see if the browser returns elements by name when
4654 // querying by getElementById (and provide a workaround)
4656 // We're going to inject a fake input element with a specified name
4657 var form = document.createElement("div"),
4658 id = "script" + (new Date()).getTime(),
4659 root = document.documentElement;
4661 form.innerHTML = "<a name='" + id + "'/>";
4663 // Inject it into the root element, check its status, and remove it quickly
4664 root.insertBefore( form, root.firstChild );
4666 // The workaround has to do additional checks after a getElementById
4667 // Which slows things down for other browsers (hence the branching)
4668 if ( document.getElementById( id ) ) {
4669 Expr.find.ID = function( match, context, isXML ) {
4670 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4671 var m = context.getElementById(match[1]);
4674 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4681 Expr.filter.ID = function( elem, match ) {
4682 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4684 return elem.nodeType === 1 && node && node.nodeValue === match;
4688 root.removeChild( form );
4690 // release memory in IE
4695 // Check to see if the browser returns only elements
4696 // when doing getElementsByTagName("*")
4698 // Create a fake element
4699 var div = document.createElement("div");
4700 div.appendChild( document.createComment("") );
4702 // Make sure no comments are found
4703 if ( div.getElementsByTagName("*").length > 0 ) {
4704 Expr.find.TAG = function( match, context ) {
4705 var results = context.getElementsByTagName( match[1] );
4707 // Filter out possible comments
4708 if ( match[1] === "*" ) {
4711 for ( var i = 0; results[i]; i++ ) {
4712 if ( results[i].nodeType === 1 ) {
4713 tmp.push( results[i] );
4724 // Check to see if an attribute returns normalized href attributes
4725 div.innerHTML = "<a href='#'></a>";
4727 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4728 div.firstChild.getAttribute("href") !== "#" ) {
4730 Expr.attrHandle.href = function( elem ) {
4731 return elem.getAttribute( "href", 2 );
4735 // release memory in IE
4739 if ( document.querySelectorAll ) {
4741 var oldSizzle = Sizzle,
4742 div = document.createElement("div"),
4745 div.innerHTML = "<p class='TEST'></p>";
4747 // Safari can't handle uppercase or unicode characters when
4749 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4753 Sizzle = function( query, context, extra, seed ) {
4754 context = context || document;
4756 // Only use querySelectorAll on non-XML documents
4757 // (ID selectors don't work in non-HTML documents)
4758 if ( !seed && !Sizzle.isXML(context) ) {
4759 // See if we find a selector to speed up
4760 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4762 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4763 // Speed-up: Sizzle("TAG")
4765 return makeArray( context.getElementsByTagName( query ), extra );
4767 // Speed-up: Sizzle(".CLASS")
4768 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4769 return makeArray( context.getElementsByClassName( match[2] ), extra );
4773 if ( context.nodeType === 9 ) {
4774 // Speed-up: Sizzle("body")
4775 // The body element only exists once, optimize finding it
4776 if ( query === "body" && context.body ) {
4777 return makeArray( [ context.body ], extra );
4779 // Speed-up: Sizzle("#ID")
4780 } else if ( match && match[3] ) {
4781 var elem = context.getElementById( match[3] );
4783 // Check parentNode to catch when Blackberry 4.6 returns
4784 // nodes that are no longer in the document #6963
4785 if ( elem && elem.parentNode ) {
4786 // Handle the case where IE and Opera return items
4787 // by name instead of ID
4788 if ( elem.id === match[3] ) {
4789 return makeArray( [ elem ], extra );
4793 return makeArray( [], extra );
4798 return makeArray( context.querySelectorAll(query), extra );
4799 } catch(qsaError) {}
4801 // qSA works strangely on Element-rooted queries
4802 // We can work around this by specifying an extra ID on the root
4803 // and working up from there (Thanks to Andrew Dupont for the technique)
4804 // IE 8 doesn't work on object elements
4805 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4806 var oldContext = context,
4807 old = context.getAttribute( "id" ),
4809 hasParent = context.parentNode,
4810 relativeHierarchySelector = /^\s*[+~]/.test( query );
4813 context.setAttribute( "id", nid );
4815 nid = nid.replace( /'/g, "\\$&" );
4817 if ( relativeHierarchySelector && hasParent ) {
4818 context = context.parentNode;
4822 if ( !relativeHierarchySelector || hasParent ) {
4823 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4826 } catch(pseudoError) {
4829 oldContext.removeAttribute( "id" );
4835 return oldSizzle(query, context, extra, seed);
4838 for ( var prop in oldSizzle ) {
4839 Sizzle[ prop ] = oldSizzle[ prop ];
4842 // release memory in IE
4848 var html = document.documentElement,
4849 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
4852 // Check to see if it's possible to do matchesSelector
4853 // on a disconnected node (IE 9 fails this)
4854 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
4855 pseudoWorks = false;
4858 // This should fail with an exception
4859 // Gecko does not error, returns false instead
4860 matches.call( document.documentElement, "[test!='']:sizzle" );
4862 } catch( pseudoError ) {
4866 Sizzle.matchesSelector = function( node, expr ) {
4867 // Make sure that attribute selectors are quoted
4868 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4870 if ( !Sizzle.isXML( node ) ) {
4872 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4873 var ret = matches.call( node, expr );
4875 // IE 9's matchesSelector returns false on disconnected nodes
4876 if ( ret || !disconnectedMatch ||
4877 // As well, disconnected nodes are said to be in a document
4878 // fragment in IE 9, so check for that
4879 node.document && node.document.nodeType !== 11 ) {
4886 return Sizzle(expr, null, null, [node]).length > 0;
4892 var div = document.createElement("div");
4894 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4896 // Opera can't find a second classname (in 9.6)
4897 // Also, make sure that getElementsByClassName actually exists
4898 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4902 // Safari caches class attributes, doesn't catch changes (in 3.2)
4903 div.lastChild.className = "e";
4905 if ( div.getElementsByClassName("e").length === 1 ) {
4909 Expr.order.splice(1, 0, "CLASS");
4910 Expr.find.CLASS = function( match, context, isXML ) {
4911 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4912 return context.getElementsByClassName(match[1]);
4916 // release memory in IE
4920 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4921 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4922 var elem = checkSet[i];
4930 if ( elem.sizcache === doneName ) {
4931 match = checkSet[elem.sizset];
4935 if ( elem.nodeType === 1 && !isXML ){
4936 elem.sizcache = doneName;
4940 if ( elem.nodeName.toLowerCase() === cur ) {
4948 checkSet[i] = match;
4953 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4954 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4955 var elem = checkSet[i];
4963 if ( elem.sizcache === doneName ) {
4964 match = checkSet[elem.sizset];
4968 if ( elem.nodeType === 1 ) {
4970 elem.sizcache = doneName;
4974 if ( typeof cur !== "string" ) {
4975 if ( elem === cur ) {
4980 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4989 checkSet[i] = match;
4994 if ( document.documentElement.contains ) {
4995 Sizzle.contains = function( a, b ) {
4996 return a !== b && (a.contains ? a.contains(b) : true);
4999 } else if ( document.documentElement.compareDocumentPosition ) {
5000 Sizzle.contains = function( a, b ) {
5001 return !!(a.compareDocumentPosition(b) & 16);
5005 Sizzle.contains = function() {
5010 Sizzle.isXML = function( elem ) {
5011 // documentElement is verified for cases where it doesn't yet exist
5012 // (such as loading iframes in IE - #4833)
5013 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5015 return documentElement ? documentElement.nodeName !== "HTML" : false;
5018 var posProcess = function( selector, context ) {
5022 root = context.nodeType ? [context] : context;
5024 // Position selectors must be done after the filter
5025 // And so must :not(positional) so we move all PSEUDOs to the end
5026 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5028 selector = selector.replace( Expr.match.PSEUDO, "" );
5031 selector = Expr.relative[selector] ? selector + "*" : selector;
5033 for ( var i = 0, l = root.length; i < l; i++ ) {
5034 Sizzle( selector, root[i], tmpSet );
5037 return Sizzle.filter( later, tmpSet );
5041 jQuery.find = Sizzle;
5042 jQuery.expr = Sizzle.selectors;
5043 jQuery.expr[":"] = jQuery.expr.filters;
5044 jQuery.unique = Sizzle.uniqueSort;
5045 jQuery.text = Sizzle.getText;
5046 jQuery.isXMLDoc = Sizzle.isXML;
5047 jQuery.contains = Sizzle.contains;
5053 var runtil = /Until$/,
5054 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5055 // Note: This RegExp should be improved, or likely pulled from Sizzle
5056 rmultiselector = /,/,
5057 isSimple = /^.[^:#\[\.,]*$/,
5058 slice = Array.prototype.slice,
5059 POS = jQuery.expr.match.POS,
5060 // methods guaranteed to produce a unique set when starting from a unique set
5061 guaranteedUnique = {
5069 find: function( selector ) {
5073 if ( typeof selector !== "string" ) {
5074 return jQuery( selector ).filter(function() {
5075 for ( i = 0, l = self.length; i < l; i++ ) {
5076 if ( jQuery.contains( self[ i ], this ) ) {
5083 var ret = this.pushStack( "", "find", selector ),
5086 for ( i = 0, l = this.length; i < l; i++ ) {
5087 length = ret.length;
5088 jQuery.find( selector, this[i], ret );
5091 // Make sure that the results are unique
5092 for ( n = length; n < ret.length; n++ ) {
5093 for ( r = 0; r < length; r++ ) {
5094 if ( ret[r] === ret[n] ) {
5106 has: function( target ) {
5107 var targets = jQuery( target );
5108 return this.filter(function() {
5109 for ( var i = 0, l = targets.length; i < l; i++ ) {
5110 if ( jQuery.contains( this, targets[i] ) ) {
5117 not: function( selector ) {
5118 return this.pushStack( winnow(this, selector, false), "not", selector);
5121 filter: function( selector ) {
5122 return this.pushStack( winnow(this, selector, true), "filter", selector );
5125 is: function( selector ) {
5126 return !!selector && ( typeof selector === "string" ?
5127 jQuery.filter( selector, this ).length > 0 :
5128 this.filter( selector ).length > 0 );
5131 closest: function( selectors, context ) {
5132 var ret = [], i, l, cur = this[0];
5135 if ( jQuery.isArray( selectors ) ) {
5136 var match, selector,
5140 if ( cur && selectors.length ) {
5141 for ( i = 0, l = selectors.length; i < l; i++ ) {
5142 selector = selectors[i];
5144 if ( !matches[ selector ] ) {
5145 matches[ selector ] = POS.test( selector ) ?
5146 jQuery( selector, context || this.context ) :
5151 while ( cur && cur.ownerDocument && cur !== context ) {
5152 for ( selector in matches ) {
5153 match = matches[ selector ];
5155 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5156 ret.push({ selector: selector, elem: cur, level: level });
5160 cur = cur.parentNode;
5169 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5170 jQuery( selectors, context || this.context ) :
5173 for ( i = 0, l = this.length; i < l; i++ ) {
5177 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5182 cur = cur.parentNode;
5183 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5190 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5192 return this.pushStack( ret, "closest", selectors );
5195 // Determine the position of an element within
5196 // the matched set of elements
5197 index: function( elem ) {
5198 if ( !elem || typeof elem === "string" ) {
5199 return jQuery.inArray( this[0],
5200 // If it receives a string, the selector is used
5201 // If it receives nothing, the siblings are used
5202 elem ? jQuery( elem ) : this.parent().children() );
5204 // Locate the position of the desired element
5205 return jQuery.inArray(
5206 // If it receives a jQuery object, the first element is used
5207 elem.jquery ? elem[0] : elem, this );
5210 add: function( selector, context ) {
5211 var set = typeof selector === "string" ?
5212 jQuery( selector, context ) :
5213 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5214 all = jQuery.merge( this.get(), set );
5216 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5218 jQuery.unique( all ) );
5221 andSelf: function() {
5222 return this.add( this.prevObject );
5226 // A painfully simple check to see if an element is disconnected
5227 // from a document (should be improved, where feasible).
5228 function isDisconnected( node ) {
5229 return !node || !node.parentNode || node.parentNode.nodeType === 11;
5233 parent: function( elem ) {
5234 var parent = elem.parentNode;
5235 return parent && parent.nodeType !== 11 ? parent : null;
5237 parents: function( elem ) {
5238 return jQuery.dir( elem, "parentNode" );
5240 parentsUntil: function( elem, i, until ) {
5241 return jQuery.dir( elem, "parentNode", until );
5243 next: function( elem ) {
5244 return jQuery.nth( elem, 2, "nextSibling" );
5246 prev: function( elem ) {
5247 return jQuery.nth( elem, 2, "previousSibling" );
5249 nextAll: function( elem ) {
5250 return jQuery.dir( elem, "nextSibling" );
5252 prevAll: function( elem ) {
5253 return jQuery.dir( elem, "previousSibling" );
5255 nextUntil: function( elem, i, until ) {
5256 return jQuery.dir( elem, "nextSibling", until );
5258 prevUntil: function( elem, i, until ) {
5259 return jQuery.dir( elem, "previousSibling", until );
5261 siblings: function( elem ) {
5262 return jQuery.sibling( elem.parentNode.firstChild, elem );
5264 children: function( elem ) {
5265 return jQuery.sibling( elem.firstChild );
5267 contents: function( elem ) {
5268 return jQuery.nodeName( elem, "iframe" ) ?
5269 elem.contentDocument || elem.contentWindow.document :
5270 jQuery.makeArray( elem.childNodes );
5272 }, function( name, fn ) {
5273 jQuery.fn[ name ] = function( until, selector ) {
5274 var ret = jQuery.map( this, fn, until ),
5275 // The variable 'args' was introduced in
5276 // https://github.com/jquery/jquery/commit/52a0238
5277 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5278 // http://code.google.com/p/v8/issues/detail?id=1050
5279 args = slice.call(arguments);
5281 if ( !runtil.test( name ) ) {
5285 if ( selector && typeof selector === "string" ) {
5286 ret = jQuery.filter( selector, ret );
5289 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5291 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5292 ret = ret.reverse();
5295 return this.pushStack( ret, name, args.join(",") );
5300 filter: function( expr, elems, not ) {
5302 expr = ":not(" + expr + ")";
5305 return elems.length === 1 ?
5306 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5307 jQuery.find.matches(expr, elems);
5310 dir: function( elem, dir, until ) {
5314 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5315 if ( cur.nodeType === 1 ) {
5316 matched.push( cur );
5323 nth: function( cur, result, dir, elem ) {
5324 result = result || 1;
5327 for ( ; cur; cur = cur[dir] ) {
5328 if ( cur.nodeType === 1 && ++num === result ) {
5336 sibling: function( n, elem ) {
5339 for ( ; n; n = n.nextSibling ) {
5340 if ( n.nodeType === 1 && n !== elem ) {
5349 // Implement the identical functionality for filter and not
5350 function winnow( elements, qualifier, keep ) {
5352 // Can't pass null or undefined to indexOf in Firefox 4
5353 // Set to 0 to skip string check
5354 qualifier = qualifier || 0;
5356 if ( jQuery.isFunction( qualifier ) ) {
5357 return jQuery.grep(elements, function( elem, i ) {
5358 var retVal = !!qualifier.call( elem, i, elem );
5359 return retVal === keep;
5362 } else if ( qualifier.nodeType ) {
5363 return jQuery.grep(elements, function( elem, i ) {
5364 return (elem === qualifier) === keep;
5367 } else if ( typeof qualifier === "string" ) {
5368 var filtered = jQuery.grep(elements, function( elem ) {
5369 return elem.nodeType === 1;
5372 if ( isSimple.test( qualifier ) ) {
5373 return jQuery.filter(qualifier, filtered, !keep);
5375 qualifier = jQuery.filter( qualifier, filtered );
5379 return jQuery.grep(elements, function( elem, i ) {
5380 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5387 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5388 rleadingWhitespace = /^\s+/,
5389 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5390 rtagName = /<([\w:]+)/,
5392 rhtml = /<|&#?\w+;/,
5393 rnocache = /<(?:script|object|embed|option|style)/i,
5394 // checked="checked" or checked
5395 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5396 rscriptType = /\/(java|ecma)script/i,
5398 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5399 legend: [ 1, "<fieldset>", "</fieldset>" ],
5400 thead: [ 1, "<table>", "</table>" ],
5401 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5402 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5403 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5404 area: [ 1, "<map>", "</map>" ],
5405 _default: [ 0, "", "" ]
5408 wrapMap.optgroup = wrapMap.option;
5409 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5410 wrapMap.th = wrapMap.td;
5412 // IE can't serialize <link> and <script> tags normally
5413 if ( !jQuery.support.htmlSerialize ) {
5414 wrapMap._default = [ 1, "div<div>", "</div>" ];
5418 text: function( text ) {
5419 if ( jQuery.isFunction(text) ) {
5420 return this.each(function(i) {
5421 var self = jQuery( this );
5423 self.text( text.call(this, i, self.text()) );
5427 if ( typeof text !== "object" && text !== undefined ) {
5428 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5431 return jQuery.text( this );
5434 wrapAll: function( html ) {
5435 if ( jQuery.isFunction( html ) ) {
5436 return this.each(function(i) {
5437 jQuery(this).wrapAll( html.call(this, i) );
5442 // The elements to wrap the target around
5443 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5445 if ( this[0].parentNode ) {
5446 wrap.insertBefore( this[0] );
5449 wrap.map(function() {
5452 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5453 elem = elem.firstChild;
5463 wrapInner: function( html ) {
5464 if ( jQuery.isFunction( html ) ) {
5465 return this.each(function(i) {
5466 jQuery(this).wrapInner( html.call(this, i) );
5470 return this.each(function() {
5471 var self = jQuery( this ),
5472 contents = self.contents();
5474 if ( contents.length ) {
5475 contents.wrapAll( html );
5478 self.append( html );
5483 wrap: function( html ) {
5484 return this.each(function() {
5485 jQuery( this ).wrapAll( html );
5489 unwrap: function() {
5490 return this.parent().each(function() {
5491 if ( !jQuery.nodeName( this, "body" ) ) {
5492 jQuery( this ).replaceWith( this.childNodes );
5497 append: function() {
5498 return this.domManip(arguments, true, function( elem ) {
5499 if ( this.nodeType === 1 ) {
5500 this.appendChild( elem );
5505 prepend: function() {
5506 return this.domManip(arguments, true, function( elem ) {
5507 if ( this.nodeType === 1 ) {
5508 this.insertBefore( elem, this.firstChild );
5513 before: function() {
5514 if ( this[0] && this[0].parentNode ) {
5515 return this.domManip(arguments, false, function( elem ) {
5516 this.parentNode.insertBefore( elem, this );
5518 } else if ( arguments.length ) {
5519 var set = jQuery(arguments[0]);
5520 set.push.apply( set, this.toArray() );
5521 return this.pushStack( set, "before", arguments );
5526 if ( this[0] && this[0].parentNode ) {
5527 return this.domManip(arguments, false, function( elem ) {
5528 this.parentNode.insertBefore( elem, this.nextSibling );
5530 } else if ( arguments.length ) {
5531 var set = this.pushStack( this, "after", arguments );
5532 set.push.apply( set, jQuery(arguments[0]).toArray() );
5537 // keepData is for internal use only--do not document
5538 remove: function( selector, keepData ) {
5539 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5540 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5541 if ( !keepData && elem.nodeType === 1 ) {
5542 jQuery.cleanData( elem.getElementsByTagName("*") );
5543 jQuery.cleanData( [ elem ] );
5546 if ( elem.parentNode ) {
5547 elem.parentNode.removeChild( elem );
5556 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5557 // Remove element nodes and prevent memory leaks
5558 if ( elem.nodeType === 1 ) {
5559 jQuery.cleanData( elem.getElementsByTagName("*") );
5562 // Remove any remaining nodes
5563 while ( elem.firstChild ) {
5564 elem.removeChild( elem.firstChild );
5571 clone: function( dataAndEvents, deepDataAndEvents ) {
5572 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5573 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5575 return this.map( function () {
5576 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5580 html: function( value ) {
5581 if ( value === undefined ) {
5582 return this[0] && this[0].nodeType === 1 ?
5583 this[0].innerHTML.replace(rinlinejQuery, "") :
5586 // See if we can take a shortcut and just use innerHTML
5587 } else if ( typeof value === "string" && !rnocache.test( value ) &&
5588 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5589 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5591 value = value.replace(rxhtmlTag, "<$1></$2>");
5594 for ( var i = 0, l = this.length; i < l; i++ ) {
5595 // Remove element nodes and prevent memory leaks
5596 if ( this[i].nodeType === 1 ) {
5597 jQuery.cleanData( this[i].getElementsByTagName("*") );
5598 this[i].innerHTML = value;
5602 // If using innerHTML throws an exception, use the fallback method
5604 this.empty().append( value );
5607 } else if ( jQuery.isFunction( value ) ) {
5608 this.each(function(i){
5609 var self = jQuery( this );
5611 self.html( value.call(this, i, self.html()) );
5615 this.empty().append( value );
5621 replaceWith: function( value ) {
5622 if ( this[0] && this[0].parentNode ) {
5623 // Make sure that the elements are removed from the DOM before they are inserted
5624 // this can help fix replacing a parent with child elements
5625 if ( jQuery.isFunction( value ) ) {
5626 return this.each(function(i) {
5627 var self = jQuery(this), old = self.html();
5628 self.replaceWith( value.call( this, i, old ) );
5632 if ( typeof value !== "string" ) {
5633 value = jQuery( value ).detach();
5636 return this.each(function() {
5637 var next = this.nextSibling,
5638 parent = this.parentNode;
5640 jQuery( this ).remove();
5643 jQuery(next).before( value );
5645 jQuery(parent).append( value );
5649 return this.length ?
5650 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5655 detach: function( selector ) {
5656 return this.remove( selector, true );
5659 domManip: function( args, table, callback ) {
5660 var results, first, fragment, parent,
5664 // We can't cloneNode fragments that contain checked, in WebKit
5665 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5666 return this.each(function() {
5667 jQuery(this).domManip( args, table, callback, true );
5671 if ( jQuery.isFunction(value) ) {
5672 return this.each(function(i) {
5673 var self = jQuery(this);
5674 args[0] = value.call(this, i, table ? self.html() : undefined);
5675 self.domManip( args, table, callback );
5680 parent = value && value.parentNode;
5682 // If we're in a fragment, just use that instead of building a new one
5683 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5684 results = { fragment: parent };
5687 results = jQuery.buildFragment( args, this, scripts );
5690 fragment = results.fragment;
5692 if ( fragment.childNodes.length === 1 ) {
5693 first = fragment = fragment.firstChild;
5695 first = fragment.firstChild;
5699 table = table && jQuery.nodeName( first, "tr" );
5701 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5704 root(this[i], first) :
5706 // Make sure that we do not leak memory by inadvertently discarding
5707 // the original fragment (which might have attached data) instead of
5708 // using it; in addition, use the original fragment object for the last
5709 // item instead of first because it can end up being emptied incorrectly
5710 // in certain situations (Bug #8070).
5711 // Fragments from the fragment cache must always be cloned and never used
5713 results.cacheable || (l > 1 && i < lastIndex) ?
5714 jQuery.clone( fragment, true, true ) :
5720 if ( scripts.length ) {
5721 jQuery.each( scripts, evalScript );
5729 function root( elem, cur ) {
5730 return jQuery.nodeName(elem, "table") ?
5731 (elem.getElementsByTagName("tbody")[0] ||
5732 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5736 function cloneCopyEvent( src, dest ) {
5738 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5742 var internalKey = jQuery.expando,
5743 oldData = jQuery.data( src ),
5744 curData = jQuery.data( dest, oldData );
5746 // Switch to use the internal data object, if it exists, for the next
5747 // stage of data copying
5748 if ( (oldData = oldData[ internalKey ]) ) {
5749 var events = oldData.events;
5750 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5753 delete curData.handle;
5754 curData.events = {};
5756 for ( var type in events ) {
5757 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5758 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5765 function cloneFixAttributes( src, dest ) {
5768 // We do not need to do anything for non-Elements
5769 if ( dest.nodeType !== 1 ) {
5773 // clearAttributes removes the attributes, which we don't want,
5774 // but also removes the attachEvent events, which we *do* want
5775 if ( dest.clearAttributes ) {
5776 dest.clearAttributes();
5779 // mergeAttributes, in contrast, only merges back on the
5780 // original attributes, not the events
5781 if ( dest.mergeAttributes ) {
5782 dest.mergeAttributes( src );
5785 nodeName = dest.nodeName.toLowerCase();
5787 // IE6-8 fail to clone children inside object elements that use
5788 // the proprietary classid attribute value (rather than the type
5789 // attribute) to identify the type of content to display
5790 if ( nodeName === "object" ) {
5791 dest.outerHTML = src.outerHTML;
5793 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5794 // IE6-8 fails to persist the checked state of a cloned checkbox
5795 // or radio button. Worse, IE6-7 fail to give the cloned element
5796 // a checked appearance if the defaultChecked value isn't also set
5797 if ( src.checked ) {
5798 dest.defaultChecked = dest.checked = src.checked;
5801 // IE6-7 get confused and end up setting the value of a cloned
5802 // checkbox/radio button to an empty string instead of "on"
5803 if ( dest.value !== src.value ) {
5804 dest.value = src.value;
5807 // IE6-8 fails to return the selected option to the default selected
5808 // state when cloning options
5809 } else if ( nodeName === "option" ) {
5810 dest.selected = src.defaultSelected;
5812 // IE6-8 fails to set the defaultValue to the correct value when
5813 // cloning other types of input fields
5814 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5815 dest.defaultValue = src.defaultValue;
5818 // Event data gets referenced instead of copied if the expando
5820 dest.removeAttribute( jQuery.expando );
5823 jQuery.buildFragment = function( args, nodes, scripts ) {
5824 var fragment, cacheable, cacheresults,
5825 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5827 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5828 // Cloning options loses the selected state, so don't cache them
5829 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5830 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5831 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5832 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5836 cacheresults = jQuery.fragments[ args[0] ];
5837 if ( cacheresults && cacheresults !== 1 ) {
5838 fragment = cacheresults;
5843 fragment = doc.createDocumentFragment();
5844 jQuery.clean( args, doc, fragment, scripts );
5848 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5851 return { fragment: fragment, cacheable: cacheable };
5854 jQuery.fragments = {};
5858 prependTo: "prepend",
5859 insertBefore: "before",
5860 insertAfter: "after",
5861 replaceAll: "replaceWith"
5862 }, function( name, original ) {
5863 jQuery.fn[ name ] = function( selector ) {
5865 insert = jQuery( selector ),
5866 parent = this.length === 1 && this[0].parentNode;
5868 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5869 insert[ original ]( this[0] );
5873 for ( var i = 0, l = insert.length; i < l; i++ ) {
5874 var elems = (i > 0 ? this.clone(true) : this).get();
5875 jQuery( insert[i] )[ original ]( elems );
5876 ret = ret.concat( elems );
5879 return this.pushStack( ret, name, insert.selector );
5884 function getAll( elem ) {
5885 if ( "getElementsByTagName" in elem ) {
5886 return elem.getElementsByTagName( "*" );
5888 } else if ( "querySelectorAll" in elem ) {
5889 return elem.querySelectorAll( "*" );
5896 // Used in clean, fixes the defaultChecked property
5897 function fixDefaultChecked( elem ) {
5898 if ( elem.type === "checkbox" || elem.type === "radio" ) {
5899 elem.defaultChecked = elem.checked;
5902 // Finds all inputs and passes them to fixDefaultChecked
5903 function findInputs( elem ) {
5904 if ( jQuery.nodeName( elem, "input" ) ) {
5905 fixDefaultChecked( elem );
5906 } else if ( elem.getElementsByTagName ) {
5907 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
5912 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5913 var clone = elem.cloneNode(true),
5918 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
5919 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
5920 // IE copies events bound via attachEvent when using cloneNode.
5921 // Calling detachEvent on the clone will also remove the events
5922 // from the original. In order to get around this, we use some
5923 // proprietary methods to clear the events. Thanks to MooTools
5924 // guys for this hotness.
5926 cloneFixAttributes( elem, clone );
5928 // Using Sizzle here is crazy slow, so we use getElementsByTagName
5930 srcElements = getAll( elem );
5931 destElements = getAll( clone );
5933 // Weird iteration because IE will replace the length property
5934 // with an element if you are cloning the body and one of the
5935 // elements on the page has a name or id of "length"
5936 for ( i = 0; srcElements[i]; ++i ) {
5937 cloneFixAttributes( srcElements[i], destElements[i] );
5941 // Copy the events from the original to the clone
5942 if ( dataAndEvents ) {
5943 cloneCopyEvent( elem, clone );
5945 if ( deepDataAndEvents ) {
5946 srcElements = getAll( elem );
5947 destElements = getAll( clone );
5949 for ( i = 0; srcElements[i]; ++i ) {
5950 cloneCopyEvent( srcElements[i], destElements[i] );
5955 // Return the cloned set
5959 clean: function( elems, context, fragment, scripts ) {
5960 var checkScriptType;
5962 context = context || document;
5964 // !context.createElement fails in IE with an error but returns typeof 'object'
5965 if ( typeof context.createElement === "undefined" ) {
5966 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
5971 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5972 if ( typeof elem === "number" ) {
5980 // Convert html string into DOM nodes
5981 if ( typeof elem === "string" ) {
5982 if ( !rhtml.test( elem ) ) {
5983 elem = context.createTextNode( elem );
5985 // Fix "XHTML"-style tags in all browsers
5986 elem = elem.replace(rxhtmlTag, "<$1></$2>");
5988 // Trim whitespace, otherwise indexOf won't work as expected
5989 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
5990 wrap = wrapMap[ tag ] || wrapMap._default,
5992 div = context.createElement("div");
5994 // Go to html and back, then peel off extra wrappers
5995 div.innerHTML = wrap[1] + elem + wrap[2];
5997 // Move to the right depth
5999 div = div.lastChild;
6002 // Remove IE's autoinserted <tbody> from table fragments
6003 if ( !jQuery.support.tbody ) {
6005 // String was a <table>, *may* have spurious <tbody>
6006 var hasBody = rtbody.test(elem),
6007 tbody = tag === "table" && !hasBody ?
6008 div.firstChild && div.firstChild.childNodes :
6010 // String was a bare <thead> or <tfoot>
6011 wrap[1] === "<table>" && !hasBody ?
6015 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
6016 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6017 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6022 // IE completely kills leading whitespace when innerHTML is used
6023 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6024 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6027 elem = div.childNodes;
6031 // Resets defaultChecked for any radios and checkboxes
6032 // about to be appended to the DOM in IE 6/7 (#8060)
6034 if ( !jQuery.support.appendChecked ) {
6035 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6036 for ( i = 0; i < len; i++ ) {
6037 findInputs( elem[i] );
6044 if ( elem.nodeType ) {
6047 ret = jQuery.merge( ret, elem );
6052 checkScriptType = function( elem ) {
6053 return !elem.type || rscriptType.test( elem.type );
6055 for ( i = 0; ret[i]; i++ ) {
6056 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6057 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6060 if ( ret[i].nodeType === 1 ) {
6061 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6063 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6065 fragment.appendChild( ret[i] );
6073 cleanData: function( elems ) {
6074 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6075 deleteExpando = jQuery.support.deleteExpando;
6077 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6078 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6082 id = elem[ jQuery.expando ];
6085 data = cache[ id ] && cache[ id ][ internalKey ];
6087 if ( data && data.events ) {
6088 for ( var type in data.events ) {
6089 if ( special[ type ] ) {
6090 jQuery.event.remove( elem, type );
6092 // This is a shortcut to avoid jQuery.event.remove's overhead
6094 jQuery.removeEvent( elem, type, data.handle );
6098 // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6099 if ( data.handle ) {
6100 data.handle.elem = null;
6104 if ( deleteExpando ) {
6105 delete elem[ jQuery.expando ];
6107 } else if ( elem.removeAttribute ) {
6108 elem.removeAttribute( jQuery.expando );
6117 function evalScript( i, elem ) {
6125 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
6128 if ( elem.parentNode ) {
6129 elem.parentNode.removeChild( elem );
6136 var ralpha = /alpha\([^)]*\)/i,
6137 ropacity = /opacity=([^)]*)/,
6138 rdashAlpha = /-([a-z])/ig,
6139 // fixed for IE9, see #8346
6140 rupper = /([A-Z]|^ms)/g,
6141 rnumpx = /^-?\d+(?:px)?$/i,
6143 rrelNum = /^[+\-]=/,
6144 rrelNumFilter = /[^+\-\.\de]+/g,
6146 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6147 cssWidth = [ "Left", "Right" ],
6148 cssHeight = [ "Top", "Bottom" ],
6154 fcamelCase = function( all, letter ) {
6155 return letter.toUpperCase();
6158 jQuery.fn.css = function( name, value ) {
6159 // Setting 'undefined' is a no-op
6160 if ( arguments.length === 2 && value === undefined ) {
6164 return jQuery.access( this, name, value, true, function( elem, name, value ) {
6165 return value !== undefined ?
6166 jQuery.style( elem, name, value ) :
6167 jQuery.css( elem, name );
6172 // Add in style property hooks for overriding the default
6173 // behavior of getting and setting a style property
6176 get: function( elem, computed ) {
6178 // We should always get a number back from opacity
6179 var ret = curCSS( elem, "opacity", "opacity" );
6180 return ret === "" ? "1" : ret;
6183 return elem.style.opacity;
6189 // Exclude the following css properties to add px
6200 // Add in properties whose names you wish to fix before
6201 // setting or getting the value
6203 // normalize float css property
6204 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6207 // Get and set the style property on a DOM Node
6208 style: function( elem, name, value, extra ) {
6209 // Don't set styles on text and comment nodes
6210 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6214 // Make sure that we're working with the right name
6215 var ret, type, origName = jQuery.camelCase( name ),
6216 style = elem.style, hooks = jQuery.cssHooks[ origName ];
6218 name = jQuery.cssProps[ origName ] || origName;
6220 // Check if we're setting a value
6221 if ( value !== undefined ) {
6222 type = typeof value;
6224 // Make sure that NaN and null values aren't set. See: #7116
6225 if ( type === "number" && isNaN( value ) || value == null ) {
6229 // convert relative number strings (+= or -=) to relative numbers. #7345
6230 if ( type === "string" && rrelNum.test( value ) ) {
6231 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6234 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6235 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6239 // If a hook was provided, use that value, otherwise just set the specified value
6240 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6241 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6244 style[ name ] = value;
6249 // If a hook was provided get the non-computed value from there
6250 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6254 // Otherwise just get the value from the style object
6255 return style[ name ];
6259 css: function( elem, name, extra ) {
6262 // Make sure that we're working with the right name
6263 name = jQuery.camelCase( name );
6264 hooks = jQuery.cssHooks[ name ];
6265 name = jQuery.cssProps[ name ] || name;
6267 // cssFloat needs a special treatment
6268 if ( name === "cssFloat" ) {
6272 // If a hook was provided get the computed value from there
6273 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6276 // Otherwise, if a way to get the computed value exists, use that
6277 } else if ( curCSS ) {
6278 return curCSS( elem, name );
6282 // A method for quickly swapping in/out CSS properties to get correct calculations
6283 swap: function( elem, options, callback ) {
6286 // Remember the old values, and insert the new ones
6287 for ( var name in options ) {
6288 old[ name ] = elem.style[ name ];
6289 elem.style[ name ] = options[ name ];
6292 callback.call( elem );
6294 // Revert the old values
6295 for ( name in options ) {
6296 elem.style[ name ] = old[ name ];
6300 camelCase: function( string ) {
6301 return string.replace( rdashAlpha, fcamelCase );
6305 // DEPRECATED, Use jQuery.css() instead
6306 jQuery.curCSS = jQuery.css;
6308 jQuery.each(["height", "width"], function( i, name ) {
6309 jQuery.cssHooks[ name ] = {
6310 get: function( elem, computed, extra ) {
6314 if ( elem.offsetWidth !== 0 ) {
6315 val = getWH( elem, name, extra );
6318 jQuery.swap( elem, cssShow, function() {
6319 val = getWH( elem, name, extra );
6324 val = curCSS( elem, name, name );
6326 if ( val === "0px" && currentStyle ) {
6327 val = currentStyle( elem, name, name );
6330 if ( val != null ) {
6331 // Should return "auto" instead of 0, use 0 for
6332 // temporary backwards-compat
6333 return val === "" || val === "auto" ? "0px" : val;
6337 if ( val < 0 || val == null ) {
6338 val = elem.style[ name ];
6340 // Should return "auto" instead of 0, use 0 for
6341 // temporary backwards-compat
6342 return val === "" || val === "auto" ? "0px" : val;
6345 return typeof val === "string" ? val : val + "px";
6349 set: function( elem, value ) {
6350 if ( rnumpx.test( value ) ) {
6351 // ignore negative width and height values #1599
6352 value = parseFloat(value);
6355 return value + "px";
6365 if ( !jQuery.support.opacity ) {
6366 jQuery.cssHooks.opacity = {
6367 get: function( elem, computed ) {
6368 // IE uses filters for opacity
6369 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6370 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6371 computed ? "1" : "";
6374 set: function( elem, value ) {
6375 var style = elem.style,
6376 currentStyle = elem.currentStyle;
6378 // IE has trouble with opacity if it does not have layout
6379 // Force it by setting the zoom level
6382 // Set the alpha filter to set the opacity
6383 var opacity = jQuery.isNaN( value ) ?
6385 "alpha(opacity=" + value * 100 + ")",
6386 filter = currentStyle && currentStyle.filter || style.filter || "";
6388 style.filter = ralpha.test( filter ) ?
6389 filter.replace( ralpha, opacity ) :
6390 filter + " " + opacity;
6396 // This hook cannot be added until DOM ready because the support test
6397 // for it is not run until after DOM ready
6398 if ( !jQuery.support.reliableMarginRight ) {
6399 jQuery.cssHooks.marginRight = {
6400 get: function( elem, computed ) {
6401 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6402 // Work around by temporarily setting element display to inline-block
6404 jQuery.swap( elem, { "display": "inline-block" }, function() {
6406 ret = curCSS( elem, "margin-right", "marginRight" );
6408 ret = elem.style.marginRight;
6417 if ( document.defaultView && document.defaultView.getComputedStyle ) {
6418 getComputedStyle = function( elem, name ) {
6419 var ret, defaultView, computedStyle;
6421 name = name.replace( rupper, "-$1" ).toLowerCase();
6423 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6427 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6428 ret = computedStyle.getPropertyValue( name );
6429 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6430 ret = jQuery.style( elem, name );
6438 if ( document.documentElement.currentStyle ) {
6439 currentStyle = function( elem, name ) {
6441 ret = elem.currentStyle && elem.currentStyle[ name ],
6442 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6445 // From the awesome hack by Dean Edwards
6446 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6448 // If we're not dealing with a regular pixel number
6449 // but a number that has a weird ending, we need to convert it to pixels
6450 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6451 // Remember the original values
6454 // Put in the new values to get a computed value out
6456 elem.runtimeStyle.left = elem.currentStyle.left;
6458 style.left = name === "fontSize" ? "1em" : (ret || 0);
6459 ret = style.pixelLeft + "px";
6461 // Revert the changed values
6464 elem.runtimeStyle.left = rsLeft;
6468 return ret === "" ? "auto" : ret;
6472 curCSS = getComputedStyle || currentStyle;
6474 function getWH( elem, name, extra ) {
6475 var which = name === "width" ? cssWidth : cssHeight,
6476 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
6478 if ( extra === "border" ) {
6482 jQuery.each( which, function() {
6484 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
6487 if ( extra === "margin" ) {
6488 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
6491 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
6498 if ( jQuery.expr && jQuery.expr.filters ) {
6499 jQuery.expr.filters.hidden = function( elem ) {
6500 var width = elem.offsetWidth,
6501 height = elem.offsetHeight;
6503 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6506 jQuery.expr.filters.visible = function( elem ) {
6507 return !jQuery.expr.filters.hidden( elem );
6518 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6519 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6520 // #7653, #8125, #8152: local protocol detection
6521 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
6522 rnoContent = /^(?:GET|HEAD)$/,
6523 rprotocol = /^\/\//,
6525 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6526 rselectTextarea = /^(?:select|textarea)/i,
6527 rspacesAjax = /\s+/,
6528 rts = /([?&])_=[^&]*/,
6529 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6531 // Keep a copy of the old load method
6532 _load = jQuery.fn.load,
6535 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6536 * 2) These are called:
6537 * - BEFORE asking for a transport
6538 * - AFTER param serialization (s.data is a string if s.processData is true)
6539 * 3) key is the dataType
6540 * 4) the catchall symbol "*" can be used
6541 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6545 /* Transports bindings
6546 * 1) key is the dataType
6547 * 2) the catchall symbol "*" can be used
6548 * 3) selection will start with transport dataType and THEN go to "*" if needed
6552 // Document location
6555 // Document location segments
6558 // #8138, IE may throw an exception when accessing
6559 // a field from window.location if document.domain has been set
6561 ajaxLocation = location.href;
6563 // Use the href attribute of an A element
6564 // since IE will modify it given document.location
6565 ajaxLocation = document.createElement( "a" );
6566 ajaxLocation.href = "";
6567 ajaxLocation = ajaxLocation.href;
6570 // Segment location into parts
6571 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6573 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6574 function addToPrefiltersOrTransports( structure ) {
6576 // dataTypeExpression is optional and defaults to "*"
6577 return function( dataTypeExpression, func ) {
6579 if ( typeof dataTypeExpression !== "string" ) {
6580 func = dataTypeExpression;
6581 dataTypeExpression = "*";
6584 if ( jQuery.isFunction( func ) ) {
6585 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6587 length = dataTypes.length,
6592 // For each dataType in the dataTypeExpression
6593 for(; i < length; i++ ) {
6594 dataType = dataTypes[ i ];
6595 // We control if we're asked to add before
6596 // any existing element
6597 placeBefore = /^\+/.test( dataType );
6598 if ( placeBefore ) {
6599 dataType = dataType.substr( 1 ) || "*";
6601 list = structure[ dataType ] = structure[ dataType ] || [];
6602 // then we add to the structure accordingly
6603 list[ placeBefore ? "unshift" : "push" ]( func );
6609 // Base inspection function for prefilters and transports
6610 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6611 dataType /* internal */, inspected /* internal */ ) {
6613 dataType = dataType || options.dataTypes[ 0 ];
6614 inspected = inspected || {};
6616 inspected[ dataType ] = true;
6618 var list = structure[ dataType ],
6620 length = list ? list.length : 0,
6621 executeOnly = ( structure === prefilters ),
6624 for(; i < length && ( executeOnly || !selection ); i++ ) {
6625 selection = list[ i ]( options, originalOptions, jqXHR );
6626 // If we got redirected to another dataType
6627 // we try there if executing only and not done already
6628 if ( typeof selection === "string" ) {
6629 if ( !executeOnly || inspected[ selection ] ) {
6630 selection = undefined;
6632 options.dataTypes.unshift( selection );
6633 selection = inspectPrefiltersOrTransports(
6634 structure, options, originalOptions, jqXHR, selection, inspected );
6638 // If we're only executing or nothing was selected
6639 // we try the catchall dataType if not done already
6640 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6641 selection = inspectPrefiltersOrTransports(
6642 structure, options, originalOptions, jqXHR, "*", inspected );
6644 // unnecessary when only executing (prefilters)
6645 // but it'll be ignored by the caller in that case
6650 load: function( url, params, callback ) {
6651 if ( typeof url !== "string" && _load ) {
6652 return _load.apply( this, arguments );
6654 // Don't do a request if no elements are being requested
6655 } else if ( !this.length ) {
6659 var off = url.indexOf( " " );
6661 var selector = url.slice( off, url.length );
6662 url = url.slice( 0, off );
6665 // Default to a GET request
6668 // If the second parameter was provided
6670 // If it's a function
6671 if ( jQuery.isFunction( params ) ) {
6672 // We assume that it's the callback
6676 // Otherwise, build a param string
6677 } else if ( typeof params === "object" ) {
6678 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6685 // Request the remote document
6691 // Complete callback (responseText is used internally)
6692 complete: function( jqXHR, status, responseText ) {
6693 // Store the response as specified by the jqXHR object
6694 responseText = jqXHR.responseText;
6695 // If successful, inject the HTML into all the matched elements
6696 if ( jqXHR.isResolved() ) {
6697 // #4825: Get the actual response in case
6698 // a dataFilter is present in ajaxSettings
6699 jqXHR.done(function( r ) {
6702 // See if a selector was specified
6703 self.html( selector ?
6704 // Create a dummy div to hold the results
6706 // inject the contents of the document in, removing the scripts
6707 // to avoid any 'Permission Denied' errors in IE
6708 .append(responseText.replace(rscript, ""))
6710 // Locate the specified elements
6713 // If not, just inject the full result
6718 self.each( callback, [ responseText, status, jqXHR ] );
6726 serialize: function() {
6727 return jQuery.param( this.serializeArray() );
6730 serializeArray: function() {
6731 return this.map(function(){
6732 return this.elements ? jQuery.makeArray( this.elements ) : this;
6735 return this.name && !this.disabled &&
6736 ( this.checked || rselectTextarea.test( this.nodeName ) ||
6737 rinput.test( this.type ) );
6739 .map(function( i, elem ){
6740 var val = jQuery( this ).val();
6742 return val == null ?
6744 jQuery.isArray( val ) ?
6745 jQuery.map( val, function( val, i ){
6746 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6748 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6753 // Attach a bunch of functions for handling common AJAX events
6754 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6755 jQuery.fn[ o ] = function( f ){
6756 return this.bind( o, f );
6760 jQuery.each( [ "get", "post" ], function( i, method ) {
6761 jQuery[ method ] = function( url, data, callback, type ) {
6762 // shift arguments if data argument was omitted
6763 if ( jQuery.isFunction( data ) ) {
6764 type = type || callback;
6769 return jQuery.ajax({
6781 getScript: function( url, callback ) {
6782 return jQuery.get( url, undefined, callback, "script" );
6785 getJSON: function( url, data, callback ) {
6786 return jQuery.get( url, data, callback, "json" );
6789 // Creates a full fledged settings object into target
6790 // with both ajaxSettings and settings fields.
6791 // If target is omitted, writes into ajaxSettings.
6792 ajaxSetup: function ( target, settings ) {
6794 // Only one parameter, we extend ajaxSettings
6796 target = jQuery.extend( true, jQuery.ajaxSettings, settings );
6798 // target was provided, we extend into it
6799 jQuery.extend( true, target, jQuery.ajaxSettings, settings );
6801 // Flatten fields we don't want deep extended
6802 for( var field in { context: 1, url: 1 } ) {
6803 if ( field in settings ) {
6804 target[ field ] = settings[ field ];
6805 } else if( field in jQuery.ajaxSettings ) {
6806 target[ field ] = jQuery.ajaxSettings[ field ];
6814 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
6817 contentType: "application/x-www-form-urlencoded",
6832 xml: "application/xml, text/xml",
6835 json: "application/json, text/javascript",
6847 text: "responseText"
6850 // List of data converters
6851 // 1) key format is "source_type destination_type" (a single space in-between)
6852 // 2) the catchall symbol "*" can be used for source_type
6855 // Convert anything to text
6856 "* text": window.String,
6858 // Text to html (true = no transformation)
6861 // Evaluate text as a json expression
6862 "text json": jQuery.parseJSON,
6864 // Parse text as xml
6865 "text xml": jQuery.parseXML
6869 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6870 ajaxTransport: addToPrefiltersOrTransports( transports ),
6873 ajax: function( url, options ) {
6875 // If url is an object, simulate pre-1.5 signature
6876 if ( typeof url === "object" ) {
6881 // Force options to be an object
6882 options = options || {};
6884 var // Create the final options object
6885 s = jQuery.ajaxSetup( {}, options ),
6886 // Callbacks context
6887 callbackContext = s.context || s,
6888 // Context for global events
6889 // It's the callbackContext if one was provided in the options
6890 // and if it's a DOM node or a jQuery collection
6891 globalEventContext = callbackContext !== s &&
6892 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
6893 jQuery( callbackContext ) : jQuery.event,
6895 deferred = jQuery.Deferred(),
6896 completeDeferred = jQuery._Deferred(),
6897 // Status-dependent callbacks
6898 statusCode = s.statusCode || {},
6901 // Headers (they are sent all at once)
6902 requestHeaders = {},
6903 requestHeadersNames = {},
6905 responseHeadersString,
6911 // Cross-domain detection vars
6915 // To know if global events are to be dispatched
6924 // Caches the header
6925 setRequestHeader: function( name, value ) {
6927 var lname = name.toLowerCase();
6928 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
6929 requestHeaders[ name ] = value;
6935 getAllResponseHeaders: function() {
6936 return state === 2 ? responseHeadersString : null;
6939 // Builds headers hashtable if needed
6940 getResponseHeader: function( key ) {
6942 if ( state === 2 ) {
6943 if ( !responseHeaders ) {
6944 responseHeaders = {};
6945 while( ( match = rheaders.exec( responseHeadersString ) ) ) {
6946 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
6949 match = responseHeaders[ key.toLowerCase() ];
6951 return match === undefined ? null : match;
6954 // Overrides response content-type header
6955 overrideMimeType: function( type ) {
6962 // Cancel the request
6963 abort: function( statusText ) {
6964 statusText = statusText || "abort";
6966 transport.abort( statusText );
6968 done( 0, statusText );
6973 // Callback for when everything is done
6974 // It is defined here because jslint complains if it is declared
6975 // at the end of the function (which would be more logical and readable)
6976 function done( status, statusText, responses, headers ) {
6979 if ( state === 2 ) {
6983 // State is "done" now
6986 // Clear timeout if it exists
6987 if ( timeoutTimer ) {
6988 clearTimeout( timeoutTimer );
6991 // Dereference transport for early garbage collection
6992 // (no matter how long the jqXHR object will be used)
6993 transport = undefined;
6995 // Cache response headers
6996 responseHeadersString = headers || "";
6999 jqXHR.readyState = status ? 4 : 0;
7004 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7008 // If successful, handle type chaining
7009 if ( status >= 200 && status < 300 || status === 304 ) {
7011 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7012 if ( s.ifModified ) {
7014 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7015 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7017 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7018 jQuery.etag[ ifModifiedKey ] = etag;
7023 if ( status === 304 ) {
7025 statusText = "notmodified";
7032 success = ajaxConvert( s, response );
7033 statusText = "success";
7036 // We have a parsererror
7037 statusText = "parsererror";
7042 // We extract error from statusText
7043 // then normalize statusText and status for non-aborts
7045 if( !statusText || status ) {
7046 statusText = "error";
7053 // Set data for the fake xhr object
7054 jqXHR.status = status;
7055 jqXHR.statusText = statusText;
7059 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7061 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7064 // Status-dependent callbacks
7065 jqXHR.statusCode( statusCode );
7066 statusCode = undefined;
7068 if ( fireGlobals ) {
7069 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7070 [ jqXHR, s, isSuccess ? success : error ] );
7074 completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7076 if ( fireGlobals ) {
7077 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7078 // Handle the global AJAX counter
7079 if ( !( --jQuery.active ) ) {
7080 jQuery.event.trigger( "ajaxStop" );
7086 deferred.promise( jqXHR );
7087 jqXHR.success = jqXHR.done;
7088 jqXHR.error = jqXHR.fail;
7089 jqXHR.complete = completeDeferred.done;
7091 // Status-dependent callbacks
7092 jqXHR.statusCode = function( map ) {
7097 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7100 tmp = map[ jqXHR.status ];
7101 jqXHR.then( tmp, tmp );
7107 // Remove hash character (#7531: and string promotion)
7108 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7109 // We also use the url parameter if available
7110 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7112 // Extract dataTypes list
7113 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7115 // Determine if a cross-domain request is in order
7116 if ( s.crossDomain == null ) {
7117 parts = rurl.exec( s.url.toLowerCase() );
7118 s.crossDomain = !!( parts &&
7119 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7120 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7121 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7125 // Convert data if not already a string
7126 if ( s.data && s.processData && typeof s.data !== "string" ) {
7127 s.data = jQuery.param( s.data, s.traditional );
7131 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7133 // If request was aborted inside a prefiler, stop there
7134 if ( state === 2 ) {
7138 // We can fire global events as of now if asked to
7139 fireGlobals = s.global;
7141 // Uppercase the type
7142 s.type = s.type.toUpperCase();
7144 // Determine if request has content
7145 s.hasContent = !rnoContent.test( s.type );
7147 // Watch for a new set of requests
7148 if ( fireGlobals && jQuery.active++ === 0 ) {
7149 jQuery.event.trigger( "ajaxStart" );
7152 // More options handling for requests with no content
7153 if ( !s.hasContent ) {
7155 // If data is available, append data to url
7157 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7160 // Get ifModifiedKey before adding the anti-cache parameter
7161 ifModifiedKey = s.url;
7163 // Add anti-cache in url if needed
7164 if ( s.cache === false ) {
7166 var ts = jQuery.now(),
7167 // try replacing _= if it is there
7168 ret = s.url.replace( rts, "$1_=" + ts );
7170 // if nothing was replaced, add timestamp to the end
7171 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7175 // Set the correct header, if data is being sent
7176 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7177 jqXHR.setRequestHeader( "Content-Type", s.contentType );
7180 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7181 if ( s.ifModified ) {
7182 ifModifiedKey = ifModifiedKey || s.url;
7183 if ( jQuery.lastModified[ ifModifiedKey ] ) {
7184 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7186 if ( jQuery.etag[ ifModifiedKey ] ) {
7187 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7191 // Set the Accepts header for the server, depending on the dataType
7192 jqXHR.setRequestHeader(
7194 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7195 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7199 // Check for headers option
7200 for ( i in s.headers ) {
7201 jqXHR.setRequestHeader( i, s.headers[ i ] );
7204 // Allow custom headers/mimetypes and early abort
7205 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7206 // Abort if not done already
7212 // Install callbacks on deferreds
7213 for ( i in { success: 1, error: 1, complete: 1 } ) {
7214 jqXHR[ i ]( s[ i ] );
7218 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7220 // If no transport, we auto-abort
7222 done( -1, "No Transport" );
7224 jqXHR.readyState = 1;
7225 // Send global event
7226 if ( fireGlobals ) {
7227 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7230 if ( s.async && s.timeout > 0 ) {
7231 timeoutTimer = setTimeout( function(){
7232 jqXHR.abort( "timeout" );
7238 transport.send( requestHeaders, done );
7240 // Propagate exception as error if not done
7243 // Simply rethrow otherwise
7253 // Serialize an array of form elements or a set of
7254 // key/values into a query string
7255 param: function( a, traditional ) {
7257 add = function( key, value ) {
7258 // If value is a function, invoke it and return its value
7259 value = jQuery.isFunction( value ) ? value() : value;
7260 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7263 // Set traditional to true for jQuery <= 1.3.2 behavior.
7264 if ( traditional === undefined ) {
7265 traditional = jQuery.ajaxSettings.traditional;
7268 // If an array was passed in, assume that it is an array of form elements.
7269 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7270 // Serialize the form elements
7271 jQuery.each( a, function() {
7272 add( this.name, this.value );
7276 // If traditional, encode the "old" way (the way 1.3.2 or older
7277 // did it), otherwise encode params recursively.
7278 for ( var prefix in a ) {
7279 buildParams( prefix, a[ prefix ], traditional, add );
7283 // Return the resulting serialization
7284 return s.join( "&" ).replace( r20, "+" );
7288 function buildParams( prefix, obj, traditional, add ) {
7289 if ( jQuery.isArray( obj ) ) {
7290 // Serialize array item.
7291 jQuery.each( obj, function( i, v ) {
7292 if ( traditional || rbracket.test( prefix ) ) {
7293 // Treat each array item as a scalar.
7297 // If array item is non-scalar (array or object), encode its
7298 // numeric index to resolve deserialization ambiguity issues.
7299 // Note that rack (as of 1.0.0) can't currently deserialize
7300 // nested arrays properly, and attempting to do so may cause
7301 // a server error. Possible fixes are to modify rack's
7302 // deserialization algorithm or to provide an option or flag
7303 // to force array serialization to be shallow.
7304 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7308 } else if ( !traditional && obj != null && typeof obj === "object" ) {
7309 // Serialize object item.
7310 for ( var name in obj ) {
7311 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7315 // Serialize scalar item.
7320 // This is still on the jQuery object... for now
7321 // Want to move this to jQuery.ajax some day
7324 // Counter for holding the number of active queries
7327 // Last-Modified header cache for next request
7333 /* Handles responses to an ajax request:
7334 * - sets all responseXXX fields accordingly
7335 * - finds the right dataType (mediates between content-type and expected dataType)
7336 * - returns the corresponding response
7338 function ajaxHandleResponses( s, jqXHR, responses ) {
7340 var contents = s.contents,
7341 dataTypes = s.dataTypes,
7342 responseFields = s.responseFields,
7348 // Fill responseXXX fields
7349 for( type in responseFields ) {
7350 if ( type in responses ) {
7351 jqXHR[ responseFields[type] ] = responses[ type ];
7355 // Remove auto dataType and get content-type in the process
7356 while( dataTypes[ 0 ] === "*" ) {
7358 if ( ct === undefined ) {
7359 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7363 // Check if we're dealing with a known content-type
7365 for ( type in contents ) {
7366 if ( contents[ type ] && contents[ type ].test( ct ) ) {
7367 dataTypes.unshift( type );
7373 // Check to see if we have a response for the expected dataType
7374 if ( dataTypes[ 0 ] in responses ) {
7375 finalDataType = dataTypes[ 0 ];
7377 // Try convertible dataTypes
7378 for ( type in responses ) {
7379 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7380 finalDataType = type;
7383 if ( !firstDataType ) {
7384 firstDataType = type;
7387 // Or just use first one
7388 finalDataType = finalDataType || firstDataType;
7391 // If we found a dataType
7392 // We add the dataType to the list if needed
7393 // and return the corresponding response
7394 if ( finalDataType ) {
7395 if ( finalDataType !== dataTypes[ 0 ] ) {
7396 dataTypes.unshift( finalDataType );
7398 return responses[ finalDataType ];
7402 // Chain conversions given the request and the original response
7403 function ajaxConvert( s, response ) {
7405 // Apply the dataFilter if provided
7406 if ( s.dataFilter ) {
7407 response = s.dataFilter( response, s.dataType );
7410 var dataTypes = s.dataTypes,
7414 length = dataTypes.length,
7416 // Current and previous dataTypes
7417 current = dataTypes[ 0 ],
7419 // Conversion expression
7421 // Conversion function
7423 // Conversion functions (transitive conversion)
7427 // For each dataType in the chain
7428 for( i = 1; i < length; i++ ) {
7430 // Create converters map
7431 // with lowercased keys
7433 for( key in s.converters ) {
7434 if( typeof key === "string" ) {
7435 converters[ key.toLowerCase() ] = s.converters[ key ];
7440 // Get the dataTypes
7442 current = dataTypes[ i ];
7444 // If current is auto dataType, update it to prev
7445 if( current === "*" ) {
7447 // If no auto and dataTypes are actually different
7448 } else if ( prev !== "*" && prev !== current ) {
7450 // Get the converter
7451 conversion = prev + " " + current;
7452 conv = converters[ conversion ] || converters[ "* " + current ];
7454 // If there is no direct converter, search transitively
7457 for( conv1 in converters ) {
7458 tmp = conv1.split( " " );
7459 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7460 conv2 = converters[ tmp[1] + " " + current ];
7462 conv1 = converters[ conv1 ];
7463 if ( conv1 === true ) {
7465 } else if ( conv2 === true ) {
7473 // If we found no converter, dispatch an error
7474 if ( !( conv || conv2 ) ) {
7475 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7477 // If found converter is not an equivalence
7478 if ( conv !== true ) {
7479 // Convert with 1 or 2 converters accordingly
7480 response = conv ? conv( response ) : conv2( conv1(response) );
7490 var jsc = jQuery.now(),
7491 jsre = /(\=)\?(&|$)|\?\?/i;
7493 // Default jsonp settings
7496 jsonpCallback: function() {
7497 return jQuery.expando + "_" + ( jsc++ );
7501 // Detect, normalize options and install callbacks for jsonp requests
7502 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7504 var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7505 ( typeof s.data === "string" );
7507 if ( s.dataTypes[ 0 ] === "jsonp" ||
7508 s.jsonp !== false && ( jsre.test( s.url ) ||
7509 inspectData && jsre.test( s.data ) ) ) {
7511 var responseContainer,
7512 jsonpCallback = s.jsonpCallback =
7513 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7514 previous = window[ jsonpCallback ],
7517 replace = "$1" + jsonpCallback + "$2";
7519 if ( s.jsonp !== false ) {
7520 url = url.replace( jsre, replace );
7521 if ( s.url === url ) {
7522 if ( inspectData ) {
7523 data = data.replace( jsre, replace );
7525 if ( s.data === data ) {
7526 // Add callback manually
7527 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7536 window[ jsonpCallback ] = function( response ) {
7537 responseContainer = [ response ];
7540 // Clean-up function
7541 jqXHR.always(function() {
7542 // Set callback back to previous value
7543 window[ jsonpCallback ] = previous;
7544 // Call if it was a function and we have a response
7545 if ( responseContainer && jQuery.isFunction( previous ) ) {
7546 window[ jsonpCallback ]( responseContainer[ 0 ] );
7550 // Use data converter to retrieve json after script execution
7551 s.converters["script json"] = function() {
7552 if ( !responseContainer ) {
7553 jQuery.error( jsonpCallback + " was not called" );
7555 return responseContainer[ 0 ];
7558 // force json dataType
7559 s.dataTypes[ 0 ] = "json";
7561 // Delegate to script
7569 // Install script dataType
7572 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7575 script: /javascript|ecmascript/
7578 "text script": function( text ) {
7579 jQuery.globalEval( text );
7585 // Handle cache's special case and global
7586 jQuery.ajaxPrefilter( "script", function( s ) {
7587 if ( s.cache === undefined ) {
7590 if ( s.crossDomain ) {
7596 // Bind script tag hack transport
7597 jQuery.ajaxTransport( "script", function(s) {
7599 // This transport only deals with cross domain requests
7600 if ( s.crossDomain ) {
7603 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7607 send: function( _, callback ) {
7609 script = document.createElement( "script" );
7611 script.async = "async";
7613 if ( s.scriptCharset ) {
7614 script.charset = s.scriptCharset;
7619 // Attach handlers for all browsers
7620 script.onload = script.onreadystatechange = function( _, isAbort ) {
7622 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7624 // Handle memory leak in IE
7625 script.onload = script.onreadystatechange = null;
7627 // Remove the script
7628 if ( head && script.parentNode ) {
7629 head.removeChild( script );
7632 // Dereference the script
7635 // Callback if not abort
7637 callback( 200, "success" );
7641 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
7642 // This arises when a base node is used (#2709 and #4378).
7643 head.insertBefore( script, head.firstChild );
7648 script.onload( 0, 1 );
7658 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7659 xhrOnUnloadAbort = window.ActiveXObject ? function() {
7660 // Abort all pending requests
7661 for ( var key in xhrCallbacks ) {
7662 xhrCallbacks[ key ]( 0, 1 );
7668 // Functions to create xhrs
7669 function createStandardXHR() {
7671 return new window.XMLHttpRequest();
7675 function createActiveXHR() {
7677 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7681 // Create the request object
7682 // (This is still attached to ajaxSettings for backward compatibility)
7683 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7684 /* Microsoft failed to properly
7685 * implement the XMLHttpRequest in IE7 (can't request local files),
7686 * so we use the ActiveXObject when it is available
7687 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7688 * we need a fallback.
7691 return !this.isLocal && createStandardXHR() || createActiveXHR();
7693 // For all other browsers, use the standard XMLHttpRequest object
7696 // Determine support properties
7698 jQuery.extend( jQuery.support, {
7700 cors: !!xhr && ( "withCredentials" in xhr )
7702 })( jQuery.ajaxSettings.xhr() );
7704 // Create transport if the browser can provide an xhr
7705 if ( jQuery.support.ajax ) {
7707 jQuery.ajaxTransport(function( s ) {
7708 // Cross domain only allowed if supported through XMLHttpRequest
7709 if ( !s.crossDomain || jQuery.support.cors ) {
7714 send: function( headers, complete ) {
7722 // Passing null username, generates a login popup on Opera (#2865)
7724 xhr.open( s.type, s.url, s.async, s.username, s.password );
7726 xhr.open( s.type, s.url, s.async );
7729 // Apply custom fields if provided
7730 if ( s.xhrFields ) {
7731 for ( i in s.xhrFields ) {
7732 xhr[ i ] = s.xhrFields[ i ];
7736 // Override mime type if needed
7737 if ( s.mimeType && xhr.overrideMimeType ) {
7738 xhr.overrideMimeType( s.mimeType );
7741 // X-Requested-With header
7742 // For cross-domain requests, seeing as conditions for a preflight are
7743 // akin to a jigsaw puzzle, we simply never set it to be sure.
7744 // (it can always be set on a per-request basis or even using ajaxSetup)
7745 // For same-domain requests, won't change header if already provided.
7746 if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7747 headers[ "X-Requested-With" ] = "XMLHttpRequest";
7750 // Need an extra try/catch for cross domain requests in Firefox 3
7752 for ( i in headers ) {
7753 xhr.setRequestHeader( i, headers[ i ] );
7757 // Do send the request
7758 // This may raise an exception which is actually
7759 // handled in jQuery.ajax (so no try/catch here)
7760 xhr.send( ( s.hasContent && s.data ) || null );
7763 callback = function( _, isAbort ) {
7771 // Firefox throws exceptions when accessing properties
7772 // of an xhr when a network error occured
7773 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7776 // Was never called and is aborted or complete
7777 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7780 callback = undefined;
7782 // Do not keep as active anymore
7784 xhr.onreadystatechange = jQuery.noop;
7785 if ( xhrOnUnloadAbort ) {
7786 delete xhrCallbacks[ handle ];
7792 // Abort it manually if needed
7793 if ( xhr.readyState !== 4 ) {
7797 status = xhr.status;
7798 responseHeaders = xhr.getAllResponseHeaders();
7800 xml = xhr.responseXML;
7802 // Construct response list
7803 if ( xml && xml.documentElement /* #4958 */ ) {
7804 responses.xml = xml;
7806 responses.text = xhr.responseText;
7808 // Firefox throws an exception when accessing
7809 // statusText for faulty cross-domain requests
7811 statusText = xhr.statusText;
7813 // We normalize with Webkit giving an empty statusText
7817 // Filter status for non standard behaviors
7819 // If the request is local and we have data: assume a success
7820 // (success with no data won't get notified, that's the best we
7821 // can do given current implementations)
7822 if ( !status && s.isLocal && !s.crossDomain ) {
7823 status = responses.text ? 200 : 404;
7824 // IE - #1450: sometimes returns 1223 when it should be 204
7825 } else if ( status === 1223 ) {
7830 } catch( firefoxAccessException ) {
7832 complete( -1, firefoxAccessException );
7836 // Call complete if needed
7838 complete( status, statusText, responses, responseHeaders );
7842 // if we're in sync mode or it's in cache
7843 // and has been retrieved directly (IE6 & IE7)
7844 // we need to manually fire the callback
7845 if ( !s.async || xhr.readyState === 4 ) {
7849 if ( xhrOnUnloadAbort ) {
7850 // Create the active xhrs callbacks list if needed
7851 // and attach the unload handler
7852 if ( !xhrCallbacks ) {
7854 jQuery( window ).unload( xhrOnUnloadAbort );
7856 // Add to list of active xhrs callbacks
7857 xhrCallbacks[ handle ] = callback;
7859 xhr.onreadystatechange = callback;
7876 var elemdisplay = {},
7878 rfxtypes = /^(?:toggle|show|hide)$/,
7879 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
7882 // height animations
7883 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
7885 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
7886 // opacity animations
7890 requestAnimationFrame = window.webkitRequestAnimationFrame ||
7891 window.mozRequestAnimationFrame ||
7892 window.oRequestAnimationFrame;
7895 show: function( speed, easing, callback ) {
7898 if ( speed || speed === 0 ) {
7899 return this.animate( genFx("show", 3), speed, easing, callback);
7902 for ( var i = 0, j = this.length; i < j; i++ ) {
7906 display = elem.style.display;
7908 // Reset the inline display of this element to learn if it is
7909 // being hidden by cascaded rules or not
7910 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
7911 display = elem.style.display = "";
7914 // Set elements which have been overridden with display: none
7915 // in a stylesheet to whatever the default browser style is
7916 // for such an element
7917 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
7918 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
7923 // Set the display of most of the elements in a second loop
7924 // to avoid the constant reflow
7925 for ( i = 0; i < j; i++ ) {
7929 display = elem.style.display;
7931 if ( display === "" || display === "none" ) {
7932 elem.style.display = jQuery._data(elem, "olddisplay") || "";
7941 hide: function( speed, easing, callback ) {
7942 if ( speed || speed === 0 ) {
7943 return this.animate( genFx("hide", 3), speed, easing, callback);
7946 for ( var i = 0, j = this.length; i < j; i++ ) {
7947 if ( this[i].style ) {
7948 var display = jQuery.css( this[i], "display" );
7950 if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
7951 jQuery._data( this[i], "olddisplay", display );
7956 // Set the display of the elements in a second loop
7957 // to avoid the constant reflow
7958 for ( i = 0; i < j; i++ ) {
7959 if ( this[i].style ) {
7960 this[i].style.display = "none";
7968 // Save the old toggle function
7969 _toggle: jQuery.fn.toggle,
7971 toggle: function( fn, fn2, callback ) {
7972 var bool = typeof fn === "boolean";
7974 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
7975 this._toggle.apply( this, arguments );
7977 } else if ( fn == null || bool ) {
7978 this.each(function() {
7979 var state = bool ? fn : jQuery(this).is(":hidden");
7980 jQuery(this)[ state ? "show" : "hide" ]();
7984 this.animate(genFx("toggle", 3), fn, fn2, callback);
7990 fadeTo: function( speed, to, easing, callback ) {
7991 return this.filter(":hidden").css("opacity", 0).show().end()
7992 .animate({opacity: to}, speed, easing, callback);
7995 animate: function( prop, speed, easing, callback ) {
7996 var optall = jQuery.speed(speed, easing, callback);
7998 if ( jQuery.isEmptyObject( prop ) ) {
7999 return this.each( optall.complete, [ false ] );
8002 return this[ optall.queue === false ? "each" : "queue" ](function() {
8003 // XXX 'this' does not always have a nodeName when running the
8006 if ( optall.queue === false ) {
8007 jQuery._mark( this );
8010 var opt = jQuery.extend({}, optall),
8011 isElement = this.nodeType === 1,
8012 hidden = isElement && jQuery(this).is(":hidden"),
8015 parts, start, end, unit;
8017 // will store per property easing and be used to determine when an animation is complete
8018 opt.animatedProperties = {};
8022 // property name normalization
8023 name = jQuery.camelCase( p );
8025 prop[ name ] = prop[ p ];
8031 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8032 return opt.complete.call(this);
8035 if ( isElement && ( name === "height" || name === "width" ) ) {
8036 // Make sure that nothing sneaks out
8037 // Record all 3 overflow attributes because IE does not
8038 // change the overflow attribute when overflowX and
8039 // overflowY are set to the same value
8040 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8042 // Set display property to inline-block for height/width
8043 // animations on inline elements that are having width/height
8045 if ( jQuery.css( this, "display" ) === "inline" &&
8046 jQuery.css( this, "float" ) === "none" ) {
8047 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8048 this.style.display = "inline-block";
8051 display = defaultDisplay(this.nodeName);
8053 // inline-level elements accept inline-block;
8054 // block-level elements need to be inline with layout
8055 if ( display === "inline" ) {
8056 this.style.display = "inline-block";
8059 this.style.display = "inline";
8060 this.style.zoom = 1;
8066 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8067 opt.animatedProperties[name] = jQuery.isArray( val ) ?
8069 opt.specialEasing && opt.specialEasing[name] || opt.easing || 'swing';
8072 if ( opt.overflow != null ) {
8073 this.style.overflow = "hidden";
8077 e = new jQuery.fx( this, opt, p );
8081 if ( rfxtypes.test(val) ) {
8082 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8085 parts = rfxnum.exec(val);
8089 end = parseFloat( parts[2] );
8090 unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" );
8092 // We need to compute starting value
8093 if ( unit !== "px" ) {
8094 jQuery.style( this, p, (end || 1) + unit);
8095 start = ((end || 1) / e.cur()) * start;
8096 jQuery.style( this, p, start + unit);
8099 // If a +=/-= token was provided, we're doing a relative animation
8101 end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
8104 e.custom( start, end, unit );
8107 e.custom( start, val, "" );
8112 // For JS strict compliance
8117 stop: function( clearQueue, gotoEnd ) {
8122 this.each(function() {
8123 var timers = jQuery.timers,
8125 // clear marker counters if we know they won't be
8127 jQuery._unmark( true, this );
8129 // go in reverse order so anything added to the queue during the loop is ignored
8131 if ( timers[i].elem === this ) {
8133 // force the next step to be the last
8137 timers.splice(i, 1);
8142 // start the next in the queue if the last step wasn't forced
8152 // Animations created synchronously will run synchronously
8153 function createFxNow() {
8154 setTimeout( clearFxNow, 0 );
8155 return ( fxNow = jQuery.now() );
8158 function clearFxNow() {
8162 // Generate parameters to create a standard animation
8163 function genFx( type, num ) {
8166 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8173 // Generate shortcuts for custom animations
8175 slideDown: genFx("show", 1),
8176 slideUp: genFx("hide", 1),
8177 slideToggle: genFx("toggle", 1),
8178 fadeIn: { opacity: "show" },
8179 fadeOut: { opacity: "hide" },
8180 fadeToggle: { opacity: "toggle" }
8181 }, function( name, props ) {
8182 jQuery.fn[ name ] = function( speed, easing, callback ) {
8183 return this.animate( props, speed, easing, callback );
8188 speed: function( speed, easing, fn ) {
8189 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8190 complete: fn || !fn && easing ||
8191 jQuery.isFunction( speed ) && speed,
8193 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8196 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8197 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8200 opt.old = opt.complete;
8201 opt.complete = function( noUnmark ) {
8202 if ( opt.queue !== false ) {
8203 jQuery.dequeue( this );
8204 } else if ( noUnmark !== false ) {
8205 jQuery._unmark( this );
8208 if ( jQuery.isFunction( opt.old ) ) {
8209 opt.old.call( this );
8217 linear: function( p, n, firstNum, diff ) {
8218 return firstNum + diff * p;
8220 swing: function( p, n, firstNum, diff ) {
8221 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8227 fx: function( elem, options, prop ) {
8228 this.options = options;
8232 options.orig = options.orig || {};
8237 jQuery.fx.prototype = {
8238 // Simple function for setting a style value
8239 update: function() {
8240 if ( this.options.step ) {
8241 this.options.step.call( this.elem, this.now, this );
8244 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8247 // Get the current size
8249 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8250 return this.elem[ this.prop ];
8254 r = jQuery.css( this.elem, this.prop );
8255 // Empty strings, null, undefined and "auto" are converted to 0,
8256 // complex values such as "rotate(1rad)" are returned as is,
8257 // simple values such as "10px" are parsed to Float.
8258 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8261 // Start an animation from one number to another
8262 custom: function( from, to, unit ) {
8267 this.startTime = fxNow || createFxNow();
8270 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8271 this.now = this.start;
8272 this.pos = this.state = 0;
8274 function t( gotoEnd ) {
8275 return self.step(gotoEnd);
8280 if ( t() && jQuery.timers.push(t) && !timerId ) {
8281 // Use requestAnimationFrame instead of setInterval if available
8282 if ( requestAnimationFrame ) {
8285 // When timerId gets set to null at any point, this stops
8287 requestAnimationFrame( raf );
8291 requestAnimationFrame( raf );
8293 timerId = setInterval( fx.tick, fx.interval );
8298 // Simple 'show' function
8300 // Remember where we started, so that we can go back to it later
8301 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8302 this.options.show = true;
8304 // Begin the animation
8305 // Make sure that we start at a small width/height to avoid any
8307 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8309 // Start by showing the element
8310 jQuery( this.elem ).show();
8313 // Simple 'hide' function
8315 // Remember where we started, so that we can go back to it later
8316 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8317 this.options.hide = true;
8319 // Begin the animation
8320 this.custom(this.cur(), 0);
8323 // Each step of an animation
8324 step: function( gotoEnd ) {
8325 var t = fxNow || createFxNow(),
8328 options = this.options,
8331 if ( gotoEnd || t >= options.duration + this.startTime ) {
8332 this.now = this.end;
8333 this.pos = this.state = 1;
8336 options.animatedProperties[ this.prop ] = true;
8338 for ( i in options.animatedProperties ) {
8339 if ( options.animatedProperties[i] !== true ) {
8345 // Reset the overflow
8346 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8348 jQuery.each( [ "", "X", "Y" ], function (index, value) {
8349 elem.style[ "overflow" + value ] = options.overflow[index];
8353 // Hide the element if the "hide" operation was done
8354 if ( options.hide ) {
8355 jQuery(elem).hide();
8358 // Reset the properties, if the item has been hidden or shown
8359 if ( options.hide || options.show ) {
8360 for ( var p in options.animatedProperties ) {
8361 jQuery.style( elem, p, options.orig[p] );
8365 // Execute the complete function
8366 options.complete.call( elem );
8372 // classical easing cannot be used with an Infinity duration
8373 if ( options.duration == Infinity ) {
8376 n = t - this.startTime;
8378 this.state = n / options.duration;
8379 // Perform the easing function, defaults to swing
8380 this.pos = jQuery.easing[options.animatedProperties[this.prop]](this.state, n, 0, 1, options.duration);
8381 this.now = this.start + ((this.end - this.start) * this.pos);
8383 // Perform the next step of the animation
8391 jQuery.extend( jQuery.fx, {
8393 var timers = jQuery.timers,
8396 if ( !timers[i]() ) {
8397 timers.splice(i, 1);
8401 if ( !timers.length ) {
8409 clearInterval( timerId );
8421 opacity: function( fx ) {
8422 jQuery.style( fx.elem, "opacity", fx.now );
8425 _default: function( fx ) {
8426 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8427 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8429 fx.elem[ fx.prop ] = fx.now;
8435 if ( jQuery.expr && jQuery.expr.filters ) {
8436 jQuery.expr.filters.animated = function( elem ) {
8437 return jQuery.grep(jQuery.timers, function( fn ) {
8438 return elem === fn.elem;
8443 // Try to restore the default display value of an element
8444 function defaultDisplay( nodeName ) {
8446 if ( !elemdisplay[ nodeName ] ) {
8448 var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
8449 display = elem.css( "display" );
8453 // If the simple way fails,
8454 // get element's real default display by attaching it to a temp iframe
8455 if ( display === "none" || display === "" ) {
8456 // No iframe to use yet, so create it
8458 iframe = document.createElement( "iframe" );
8459 iframe.frameBorder = iframe.width = iframe.height = 0;
8462 document.body.appendChild( iframe );
8464 // Create a cacheable copy of the iframe document on first call.
8465 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
8466 // document to it, Webkit & Firefox won't allow reusing the iframe document
8467 if ( !iframeDoc || !iframe.createElement ) {
8468 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8469 iframeDoc.write( "<!doctype><html><body></body></html>" );
8472 elem = iframeDoc.createElement( nodeName );
8474 iframeDoc.body.appendChild( elem );
8476 display = jQuery.css( elem, "display" );
8478 document.body.removeChild( iframe );
8481 // Store the correct default display
8482 elemdisplay[ nodeName ] = display;
8485 return elemdisplay[ nodeName ];
8491 var rtable = /^t(?:able|d|h)$/i,
8492 rroot = /^(?:body|html)$/i;
8494 if ( "getBoundingClientRect" in document.documentElement ) {
8495 jQuery.fn.offset = function( options ) {
8496 var elem = this[0], box;
8499 return this.each(function( i ) {
8500 jQuery.offset.setOffset( this, options, i );
8504 if ( !elem || !elem.ownerDocument ) {
8508 if ( elem === elem.ownerDocument.body ) {
8509 return jQuery.offset.bodyOffset( elem );
8513 box = elem.getBoundingClientRect();
8516 var doc = elem.ownerDocument,
8517 docElem = doc.documentElement;
8519 // Make sure we're not dealing with a disconnected DOM node
8520 if ( !box || !jQuery.contains( docElem, elem ) ) {
8521 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8524 var body = doc.body,
8525 win = getWindow(doc),
8526 clientTop = docElem.clientTop || body.clientTop || 0,
8527 clientLeft = docElem.clientLeft || body.clientLeft || 0,
8528 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
8529 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8530 top = box.top + scrollTop - clientTop,
8531 left = box.left + scrollLeft - clientLeft;
8533 return { top: top, left: left };
8537 jQuery.fn.offset = function( options ) {
8541 return this.each(function( i ) {
8542 jQuery.offset.setOffset( this, options, i );
8546 if ( !elem || !elem.ownerDocument ) {
8550 if ( elem === elem.ownerDocument.body ) {
8551 return jQuery.offset.bodyOffset( elem );
8554 jQuery.offset.initialize();
8557 offsetParent = elem.offsetParent,
8558 prevOffsetParent = elem,
8559 doc = elem.ownerDocument,
8560 docElem = doc.documentElement,
8562 defaultView = doc.defaultView,
8563 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8564 top = elem.offsetTop,
8565 left = elem.offsetLeft;
8567 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8568 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8572 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8573 top -= elem.scrollTop;
8574 left -= elem.scrollLeft;
8576 if ( elem === offsetParent ) {
8577 top += elem.offsetTop;
8578 left += elem.offsetLeft;
8580 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8581 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8582 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8585 prevOffsetParent = offsetParent;
8586 offsetParent = elem.offsetParent;
8589 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8590 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8591 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8594 prevComputedStyle = computedStyle;
8597 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8598 top += body.offsetTop;
8599 left += body.offsetLeft;
8602 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8603 top += Math.max( docElem.scrollTop, body.scrollTop );
8604 left += Math.max( docElem.scrollLeft, body.scrollLeft );
8607 return { top: top, left: left };
8612 initialize: function() {
8613 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8614 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>";
8616 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8618 container.innerHTML = html;
8619 body.insertBefore( container, body.firstChild );
8620 innerDiv = container.firstChild;
8621 checkDiv = innerDiv.firstChild;
8622 td = innerDiv.nextSibling.firstChild.firstChild;
8624 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8625 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8627 checkDiv.style.position = "fixed";
8628 checkDiv.style.top = "20px";
8630 // safari subtracts parent border width here which is 5px
8631 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8632 checkDiv.style.position = checkDiv.style.top = "";
8634 innerDiv.style.overflow = "hidden";
8635 innerDiv.style.position = "relative";
8637 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8639 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8641 body.removeChild( container );
8642 jQuery.offset.initialize = jQuery.noop;
8645 bodyOffset: function( body ) {
8646 var top = body.offsetTop,
8647 left = body.offsetLeft;
8649 jQuery.offset.initialize();
8651 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8652 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8653 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8656 return { top: top, left: left };
8659 setOffset: function( elem, options, i ) {
8660 var position = jQuery.css( elem, "position" );
8662 // set position first, in-case top/left are set even on static elem
8663 if ( position === "static" ) {
8664 elem.style.position = "relative";
8667 var curElem = jQuery( elem ),
8668 curOffset = curElem.offset(),
8669 curCSSTop = jQuery.css( elem, "top" ),
8670 curCSSLeft = jQuery.css( elem, "left" ),
8671 calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8672 props = {}, curPosition = {}, curTop, curLeft;
8674 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8675 if ( calculatePosition ) {
8676 curPosition = curElem.position();
8677 curTop = curPosition.top;
8678 curLeft = curPosition.left;
8680 curTop = parseFloat( curCSSTop ) || 0;
8681 curLeft = parseFloat( curCSSLeft ) || 0;
8684 if ( jQuery.isFunction( options ) ) {
8685 options = options.call( elem, i, curOffset );
8688 if (options.top != null) {
8689 props.top = (options.top - curOffset.top) + curTop;
8691 if (options.left != null) {
8692 props.left = (options.left - curOffset.left) + curLeft;
8695 if ( "using" in options ) {
8696 options.using.call( elem, props );
8698 curElem.css( props );
8705 position: function() {
8712 // Get *real* offsetParent
8713 offsetParent = this.offsetParent(),
8715 // Get correct offsets
8716 offset = this.offset(),
8717 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8719 // Subtract element margins
8720 // note: when an element has margin: auto the offsetLeft and marginLeft
8721 // are the same in Safari causing offset.left to incorrectly be 0
8722 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8723 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8725 // Add offsetParent borders
8726 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8727 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8729 // Subtract the two offsets
8731 top: offset.top - parentOffset.top,
8732 left: offset.left - parentOffset.left
8736 offsetParent: function() {
8737 return this.map(function() {
8738 var offsetParent = this.offsetParent || document.body;
8739 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8740 offsetParent = offsetParent.offsetParent;
8742 return offsetParent;
8748 // Create scrollLeft and scrollTop methods
8749 jQuery.each( ["Left", "Top"], function( i, name ) {
8750 var method = "scroll" + name;
8752 jQuery.fn[ method ] = function( val ) {
8755 if ( val === undefined ) {
8762 win = getWindow( elem );
8764 // Return the scroll offset
8765 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8766 jQuery.support.boxModel && win.document.documentElement[ method ] ||
8767 win.document.body[ method ] :
8771 // Set the scroll offset
8772 return this.each(function() {
8773 win = getWindow( this );
8777 !i ? val : jQuery( win ).scrollLeft(),
8778 i ? val : jQuery( win ).scrollTop()
8782 this[ method ] = val;
8788 function getWindow( elem ) {
8789 return jQuery.isWindow( elem ) ?
8791 elem.nodeType === 9 ?
8792 elem.defaultView || elem.parentWindow :
8799 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
8800 jQuery.each([ "Height", "Width" ], function( i, name ) {
8802 var type = name.toLowerCase();
8804 // innerHeight and innerWidth
8805 jQuery.fn["inner" + name] = function() {
8807 parseFloat( jQuery.css( this[0], type, "padding" ) ) :
8811 // outerHeight and outerWidth
8812 jQuery.fn["outer" + name] = function( margin ) {
8814 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
8818 jQuery.fn[ type ] = function( size ) {
8819 // Get window width or height
8822 return size == null ? null : this;
8825 if ( jQuery.isFunction( size ) ) {
8826 return this.each(function( i ) {
8827 var self = jQuery( this );
8828 self[ type ]( size.call( this, i, self[ type ]() ) );
8832 if ( jQuery.isWindow( elem ) ) {
8833 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
8834 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
8835 var docElemProp = elem.document.documentElement[ "client" + name ];
8836 return elem.document.compatMode === "CSS1Compat" && docElemProp ||
8837 elem.document.body[ "client" + name ] || docElemProp;
8839 // Get document width or height
8840 } else if ( elem.nodeType === 9 ) {
8841 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
8843 elem.documentElement["client" + name],
8844 elem.body["scroll" + name], elem.documentElement["scroll" + name],
8845 elem.body["offset" + name], elem.documentElement["offset" + name]
8848 // Get or set width or height on the element
8849 } else if ( size === undefined ) {
8850 var orig = jQuery.css( elem, type ),
8851 ret = parseFloat( orig );
8853 return jQuery.isNaN( ret ) ? orig : ret;
8855 // Set the width or height on the element (default to pixels if value is unitless)
8857 return this.css( type, typeof size === "string" ? size : size + "px" );
8864 window.jQuery = window.$ = jQuery;