2 * jQuery JavaScript Library v1.6.3
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: Wed Aug 31 10:35:15 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 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
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 // Matches dashed string for camelizing
69 rdashAlpha = /-([a-z]|[0-9])/ig,
72 // Used by jQuery.camelCase as callback to replace()
73 fcamelCase = function( all, letter ) {
74 return ( letter + "" ).toUpperCase();
77 // Keep a UserAgent string for use with jQuery.browser
78 userAgent = navigator.userAgent,
80 // For matching the engine and version of the browser
83 // The deferred used on DOM ready
86 // The ready event handler
89 // Save a reference to some core methods
90 toString = Object.prototype.toString,
91 hasOwn = Object.prototype.hasOwnProperty,
92 push = Array.prototype.push,
93 slice = Array.prototype.slice,
94 trim = String.prototype.trim,
95 indexOf = Array.prototype.indexOf,
97 // [[Class]] -> type pairs
100 jQuery.fn = jQuery.prototype = {
102 init: function( selector, context, rootjQuery ) {
103 var match, elem, ret, doc;
105 // Handle $(""), $(null), or $(undefined)
110 // Handle $(DOMElement)
111 if ( selector.nodeType ) {
112 this.context = this[0] = selector;
117 // The body element only exists once, optimize finding it
118 if ( selector === "body" && !context && document.body ) {
119 this.context = document;
120 this[0] = document.body;
121 this.selector = selector;
126 // Handle HTML strings
127 if ( typeof selector === "string" ) {
128 // Are we dealing with HTML string or an ID?
129 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
130 // Assume that strings that start and end with <> are HTML and skip the regex check
131 match = [ null, selector, null ];
134 match = quickExpr.exec( selector );
137 // Verify a match, and that no context was specified for #id
138 if ( match && (match[1] || !context) ) {
140 // HANDLE: $(html) -> $(array)
142 context = context instanceof jQuery ? context[0] : context;
143 doc = (context ? context.ownerDocument || context : document);
145 // If a single string is passed in and it's a single tag
146 // just do a createElement and skip the rest
147 ret = rsingleTag.exec( selector );
150 if ( jQuery.isPlainObject( context ) ) {
151 selector = [ document.createElement( ret[1] ) ];
152 jQuery.fn.attr.call( selector, context, true );
155 selector = [ doc.createElement( ret[1] ) ];
159 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
160 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
163 return jQuery.merge( this, selector );
167 elem = document.getElementById( match[2] );
169 // Check parentNode to catch when Blackberry 4.6 returns
170 // nodes that are no longer in the document #6963
171 if ( elem && elem.parentNode ) {
172 // Handle the case where IE and Opera return items
173 // by name instead of ID
174 if ( elem.id !== match[2] ) {
175 return rootjQuery.find( selector );
178 // Otherwise, we inject the element directly into the jQuery object
183 this.context = document;
184 this.selector = selector;
188 // HANDLE: $(expr, $(...))
189 } else if ( !context || context.jquery ) {
190 return (context || rootjQuery).find( selector );
192 // HANDLE: $(expr, context)
193 // (which is just equivalent to: $(context).find(expr)
195 return this.constructor( context ).find( selector );
198 // HANDLE: $(function)
199 // Shortcut for document ready
200 } else if ( jQuery.isFunction( selector ) ) {
201 return rootjQuery.ready( selector );
204 if (selector.selector !== undefined) {
205 this.selector = selector.selector;
206 this.context = selector.context;
209 return jQuery.makeArray( selector, this );
212 // Start with an empty selector
215 // The current version of jQuery being used
218 // The default length of a jQuery object is 0
221 // The number of elements contained in the matched element set
226 toArray: function() {
227 return slice.call( this, 0 );
230 // Get the Nth element in the matched element set OR
231 // Get the whole matched element set as a clean array
232 get: function( num ) {
235 // Return a 'clean' array
238 // Return just the object
239 ( num < 0 ? this[ this.length + num ] : this[ num ] );
242 // Take an array of elements and push it onto the stack
243 // (returning the new matched element set)
244 pushStack: function( elems, name, selector ) {
245 // Build a new jQuery matched element set
246 var ret = this.constructor();
248 if ( jQuery.isArray( elems ) ) {
249 push.apply( ret, elems );
252 jQuery.merge( ret, elems );
255 // Add the old object onto the stack (as a reference)
256 ret.prevObject = this;
258 ret.context = this.context;
260 if ( name === "find" ) {
261 ret.selector = this.selector + (this.selector ? " " : "") + selector;
263 ret.selector = this.selector + "." + name + "(" + selector + ")";
266 // Return the newly-formed element set
270 // Execute a callback for every element in the matched set.
271 // (You can seed the arguments with an array of args, but this is
272 // only used internally.)
273 each: function( callback, args ) {
274 return jQuery.each( this, callback, args );
277 ready: function( fn ) {
278 // Attach the listeners
282 readyList.done( fn );
290 this.slice( i, +i + 1 );
298 return this.eq( -1 );
302 return this.pushStack( slice.apply( this, arguments ),
303 "slice", slice.call(arguments).join(",") );
306 map: function( callback ) {
307 return this.pushStack( jQuery.map(this, function( elem, i ) {
308 return callback.call( elem, i, elem );
313 return this.prevObject || this.constructor(null);
316 // For internal use only.
317 // Behaves like an Array's method, not like a jQuery method.
323 // Give the init function the jQuery prototype for later instantiation
324 jQuery.fn.init.prototype = jQuery.fn;
326 jQuery.extend = jQuery.fn.extend = function() {
327 var options, name, src, copy, copyIsArray, clone,
328 target = arguments[0] || {},
330 length = arguments.length,
333 // Handle a deep copy situation
334 if ( typeof target === "boolean" ) {
336 target = arguments[1] || {};
337 // skip the boolean and the target
341 // Handle case when target is a string or something (possible in deep copy)
342 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
346 // extend jQuery itself if only one argument is passed
347 if ( length === i ) {
352 for ( ; i < length; i++ ) {
353 // Only deal with non-null/undefined values
354 if ( (options = arguments[ i ]) != null ) {
355 // Extend the base object
356 for ( name in options ) {
357 src = target[ name ];
358 copy = options[ name ];
360 // Prevent never-ending loop
361 if ( target === copy ) {
365 // Recurse if we're merging plain objects or arrays
366 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
369 clone = src && jQuery.isArray(src) ? src : [];
372 clone = src && jQuery.isPlainObject(src) ? src : {};
375 // Never move original objects, clone them
376 target[ name ] = jQuery.extend( deep, clone, copy );
378 // Don't bring in undefined values
379 } else if ( copy !== undefined ) {
380 target[ name ] = copy;
386 // Return the modified object
391 noConflict: function( deep ) {
392 if ( window.$ === jQuery ) {
396 if ( deep && window.jQuery === jQuery ) {
397 window.jQuery = _jQuery;
403 // Is the DOM ready to be used? Set to true once it occurs.
406 // A counter to track how many items to wait for before
407 // the ready event fires. See #6781
410 // Hold (or release) the ready event
411 holdReady: function( hold ) {
415 jQuery.ready( true );
419 // Handle when the DOM is ready
420 ready: function( wait ) {
421 // Either a released hold or an DOMready/load event and not yet ready
422 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
423 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
424 if ( !document.body ) {
425 return setTimeout( jQuery.ready, 1 );
428 // Remember that the DOM is ready
429 jQuery.isReady = true;
431 // If a normal DOM Ready event fired, decrement, and wait if need be
432 if ( wait !== true && --jQuery.readyWait > 0 ) {
436 // If there are functions bound, to execute
437 readyList.resolveWith( document, [ jQuery ] );
439 // Trigger any bound ready events
440 if ( jQuery.fn.trigger ) {
441 jQuery( document ).trigger( "ready" ).unbind( "ready" );
446 bindReady: function() {
451 readyList = jQuery._Deferred();
453 // Catch cases where $(document).ready() is called after the
454 // browser event has already occurred.
455 if ( document.readyState === "complete" ) {
456 // Handle it asynchronously to allow scripts the opportunity to delay ready
457 return setTimeout( jQuery.ready, 1 );
460 // Mozilla, Opera and webkit nightlies currently support this event
461 if ( document.addEventListener ) {
462 // Use the handy event callback
463 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
465 // A fallback to window.onload, that will always work
466 window.addEventListener( "load", jQuery.ready, false );
468 // If IE event model is used
469 } else if ( document.attachEvent ) {
470 // ensure firing before onload,
471 // maybe late but safe also for iframes
472 document.attachEvent( "onreadystatechange", DOMContentLoaded );
474 // A fallback to window.onload, that will always work
475 window.attachEvent( "onload", jQuery.ready );
477 // If IE and not a frame
478 // continually check to see if the document is ready
479 var toplevel = false;
482 toplevel = window.frameElement == null;
485 if ( document.documentElement.doScroll && toplevel ) {
491 // See test/unit/core.js for details concerning isFunction.
492 // Since version 1.3, DOM methods and functions like alert
493 // aren't supported. They return false on IE (#2968).
494 isFunction: function( obj ) {
495 return jQuery.type(obj) === "function";
498 isArray: Array.isArray || function( obj ) {
499 return jQuery.type(obj) === "array";
502 // A crude way of determining if an object is a window
503 isWindow: function( obj ) {
504 return obj && typeof obj === "object" && "setInterval" in obj;
507 isNaN: function( obj ) {
508 return obj == null || !rdigit.test( obj ) || isNaN( obj );
511 type: function( obj ) {
514 class2type[ toString.call(obj) ] || "object";
517 isPlainObject: function( obj ) {
518 // Must be an Object.
519 // Because of IE, we also have to check the presence of the constructor property.
520 // Make sure that DOM nodes and window objects don't pass through, as well
521 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
526 // Not own constructor property must be Object
527 if ( obj.constructor &&
528 !hasOwn.call(obj, "constructor") &&
529 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
533 // IE8,9 Will throw exceptions on certain host objects #9897
537 // Own properties are enumerated firstly, so to speed up,
538 // if last one is own, then all properties are own.
541 for ( key in obj ) {}
543 return key === undefined || hasOwn.call( obj, key );
546 isEmptyObject: function( obj ) {
547 for ( var name in obj ) {
553 error: function( msg ) {
557 parseJSON: function( data ) {
558 if ( typeof data !== "string" || !data ) {
562 // Make sure leading/trailing whitespace is removed (IE can't handle it)
563 data = jQuery.trim( data );
565 // Attempt to parse using the native JSON parser first
566 if ( window.JSON && window.JSON.parse ) {
567 return window.JSON.parse( data );
570 // Make sure the incoming data is actual JSON
571 // Logic borrowed from http://json.org/json2.js
572 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
573 .replace( rvalidtokens, "]" )
574 .replace( rvalidbraces, "")) ) {
576 return (new Function( "return " + data ))();
579 jQuery.error( "Invalid JSON: " + data );
582 // Cross-browser xml parsing
583 parseXML: function( data ) {
586 if ( window.DOMParser ) { // Standard
587 tmp = new DOMParser();
588 xml = tmp.parseFromString( data , "text/xml" );
590 xml = new ActiveXObject( "Microsoft.XMLDOM" );
597 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
598 jQuery.error( "Invalid XML: " + data );
605 // Evaluates a script in a global context
606 // Workarounds based on findings by Jim Driscoll
607 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
608 globalEval: function( data ) {
609 if ( data && rnotwhite.test( data ) ) {
610 // We use execScript on Internet Explorer
611 // We use an anonymous function so that context is window
612 // rather than jQuery in Firefox
613 ( window.execScript || function( data ) {
614 window[ "eval" ].call( window, data );
619 // Convert dashed to camelCase; used by the css and data modules
620 // Microsoft forgot to hump their vendor prefix (#9572)
621 camelCase: function( string ) {
622 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
625 nodeName: function( elem, name ) {
626 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
629 // args is for internal usage only
630 each: function( object, callback, args ) {
632 length = object.length,
633 isObj = length === undefined || jQuery.isFunction( object );
637 for ( name in object ) {
638 if ( callback.apply( object[ name ], args ) === false ) {
643 for ( ; i < length; ) {
644 if ( callback.apply( object[ i++ ], args ) === false ) {
650 // A special, fast, case for the most common use of each
653 for ( name in object ) {
654 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
659 for ( ; i < length; ) {
660 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
670 // Use native String.trim function wherever possible
673 return text == null ?
678 // Otherwise use our own trimming functionality
680 return text == null ?
682 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
685 // results is for internal usage only
686 makeArray: function( array, results ) {
687 var ret = results || [];
689 if ( array != null ) {
690 // The window, strings (and functions) also have 'length'
691 // The extra typeof function check is to prevent crashes
692 // in Safari 2 (See: #3039)
693 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
694 var type = jQuery.type( array );
696 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
697 push.call( ret, array );
699 jQuery.merge( ret, array );
706 inArray: function( elem, array ) {
712 return indexOf.call( array, elem );
715 for ( var i = 0, length = array.length; i < length; i++ ) {
716 if ( array[ i ] === elem ) {
724 merge: function( first, second ) {
725 var i = first.length,
728 if ( typeof second.length === "number" ) {
729 for ( var l = second.length; j < l; j++ ) {
730 first[ i++ ] = second[ j ];
734 while ( second[j] !== undefined ) {
735 first[ i++ ] = second[ j++ ];
744 grep: function( elems, callback, inv ) {
745 var ret = [], retVal;
748 // Go through the array, only saving the items
749 // that pass the validator function
750 for ( var i = 0, length = elems.length; i < length; i++ ) {
751 retVal = !!callback( elems[ i ], i );
752 if ( inv !== retVal ) {
753 ret.push( elems[ i ] );
760 // arg is for internal usage only
761 map: function( elems, callback, arg ) {
762 var value, key, ret = [],
764 length = elems.length,
765 // jquery objects are treated as arrays
766 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
768 // Go through the array, translating each of the items to their
770 for ( ; i < length; i++ ) {
771 value = callback( elems[ i ], i, arg );
773 if ( value != null ) {
774 ret[ ret.length ] = value;
778 // Go through every key on the object,
780 for ( key in elems ) {
781 value = callback( elems[ key ], key, arg );
783 if ( value != null ) {
784 ret[ ret.length ] = value;
789 // Flatten any nested arrays
790 return ret.concat.apply( [], ret );
793 // A global GUID counter for objects
796 // Bind a function to a context, optionally partially applying any
798 proxy: function( fn, context ) {
799 if ( typeof context === "string" ) {
800 var tmp = fn[ context ];
805 // Quick check to determine if target is callable, in the spec
806 // this throws a TypeError, but we will just return undefined.
807 if ( !jQuery.isFunction( fn ) ) {
812 var args = slice.call( arguments, 2 ),
814 return fn.apply( context, args.concat( slice.call( arguments ) ) );
817 // Set the guid of unique handler to the same of original handler, so it can be removed
818 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
823 // Mutifunctional method to get and set values to a collection
824 // The value/s can optionally be executed if it's a function
825 access: function( elems, key, value, exec, fn, pass ) {
826 var length = elems.length;
828 // Setting many attributes
829 if ( typeof key === "object" ) {
830 for ( var k in key ) {
831 jQuery.access( elems, k, key[k], exec, fn, value );
836 // Setting one attribute
837 if ( value !== undefined ) {
838 // Optionally, function values get executed if exec is true
839 exec = !pass && exec && jQuery.isFunction(value);
841 for ( var i = 0; i < length; i++ ) {
842 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
848 // Getting an attribute
849 return length ? fn( elems[0], key ) : undefined;
853 return (new Date()).getTime();
856 // Use of jQuery.browser is frowned upon.
857 // More details: http://docs.jquery.com/Utilities/jQuery.browser
858 uaMatch: function( ua ) {
859 ua = ua.toLowerCase();
861 var match = rwebkit.exec( ua ) ||
864 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
867 return { browser: match[1] || "", version: match[2] || "0" };
871 function jQuerySub( selector, context ) {
872 return new jQuerySub.fn.init( selector, context );
874 jQuery.extend( true, jQuerySub, this );
875 jQuerySub.superclass = this;
876 jQuerySub.fn = jQuerySub.prototype = this();
877 jQuerySub.fn.constructor = jQuerySub;
878 jQuerySub.sub = this.sub;
879 jQuerySub.fn.init = function init( selector, context ) {
880 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
881 context = jQuerySub( context );
884 return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
886 jQuerySub.fn.init.prototype = jQuerySub.fn;
887 var rootjQuerySub = jQuerySub(document);
894 // Populate the class2type map
895 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
896 class2type[ "[object " + name + "]" ] = name.toLowerCase();
899 browserMatch = jQuery.uaMatch( userAgent );
900 if ( browserMatch.browser ) {
901 jQuery.browser[ browserMatch.browser ] = true;
902 jQuery.browser.version = browserMatch.version;
905 // Deprecated, use jQuery.browser.webkit instead
906 if ( jQuery.browser.webkit ) {
907 jQuery.browser.safari = true;
910 // IE doesn't match non-breaking spaces with \s
911 if ( rnotwhite.test( "\xA0" ) ) {
912 trimLeft = /^[\s\xA0]+/;
913 trimRight = /[\s\xA0]+$/;
916 // All jQuery objects should point back to these
917 rootjQuery = jQuery(document);
919 // Cleanup functions for the document ready method
920 if ( document.addEventListener ) {
921 DOMContentLoaded = function() {
922 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
926 } else if ( document.attachEvent ) {
927 DOMContentLoaded = function() {
928 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
929 if ( document.readyState === "complete" ) {
930 document.detachEvent( "onreadystatechange", DOMContentLoaded );
936 // The DOM ready check for Internet Explorer
937 function doScrollCheck() {
938 if ( jQuery.isReady ) {
943 // If IE is used, use the trick by Diego Perini
944 // http://javascript.nwbox.com/IEContentLoaded/
945 document.documentElement.doScroll("left");
947 setTimeout( doScrollCheck, 1 );
951 // and execute any waiting functions
960 var // Promise methods
961 promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
962 // Static reference to slice
963 sliceDeferred = [].slice;
966 // Create a simple deferred (one callbacks list)
967 _Deferred: function() {
968 var // callbacks list
970 // stored [ context , args ]
972 // to avoid firing when already doing so
974 // flag to know if the deferred has been cancelled
976 // the deferred itself
979 // done( f1, f2, ...)
982 var args = arguments,
992 for ( i = 0, length = args.length; i < length; i++ ) {
994 type = jQuery.type( elem );
995 if ( type === "array" ) {
996 deferred.done.apply( deferred, elem );
997 } else if ( type === "function" ) {
998 callbacks.push( elem );
1002 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
1008 // resolve with given context and args
1009 resolveWith: function( context, args ) {
1010 if ( !cancelled && !fired && !firing ) {
1011 // make sure args are available (#8421)
1015 while( callbacks[ 0 ] ) {
1016 callbacks.shift().apply( context, args );
1020 fired = [ context, args ];
1027 // resolve with this as context and given arguments
1028 resolve: function() {
1029 deferred.resolveWith( this, arguments );
1033 // Has this deferred been resolved?
1034 isResolved: function() {
1035 return !!( firing || fired );
1039 cancel: function() {
1049 // Full fledged deferred (two callbacks list)
1050 Deferred: function( func ) {
1051 var deferred = jQuery._Deferred(),
1052 failDeferred = jQuery._Deferred(),
1054 // Add errorDeferred methods, then and promise
1055 jQuery.extend( deferred, {
1056 then: function( doneCallbacks, failCallbacks ) {
1057 deferred.done( doneCallbacks ).fail( failCallbacks );
1060 always: function() {
1061 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1063 fail: failDeferred.done,
1064 rejectWith: failDeferred.resolveWith,
1065 reject: failDeferred.resolve,
1066 isRejected: failDeferred.isResolved,
1067 pipe: function( fnDone, fnFail ) {
1068 return jQuery.Deferred(function( newDefer ) {
1070 done: [ fnDone, "resolve" ],
1071 fail: [ fnFail, "reject" ]
1072 }, function( handler, data ) {
1076 if ( jQuery.isFunction( fn ) ) {
1077 deferred[ handler ](function() {
1078 returned = fn.apply( this, arguments );
1079 if ( returned && jQuery.isFunction( returned.promise ) ) {
1080 returned.promise().then( newDefer.resolve, newDefer.reject );
1082 newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1086 deferred[ handler ]( newDefer[ action ] );
1091 // Get a promise for this deferred
1092 // If obj is provided, the promise aspect is added to the object
1093 promise: function( obj ) {
1094 if ( obj == null ) {
1100 var i = promiseMethods.length;
1102 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1107 // Make sure only one callback list will be used
1108 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1110 delete deferred.cancel;
1111 // Call given func if any
1113 func.call( deferred, deferred );
1119 when: function( firstParam ) {
1120 var args = arguments,
1122 length = args.length,
1124 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1127 function resolveFunc( i ) {
1128 return function( value ) {
1129 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1130 if ( !( --count ) ) {
1131 // Strange bug in FF4:
1132 // Values changed onto the arguments object sometimes end up as undefined values
1133 // outside the $.when method. Cloning the object into a fresh array solves the issue
1134 deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1139 for( ; i < length; i++ ) {
1140 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1141 args[ i ].promise().then( resolveFunc(i), deferred.reject );
1147 deferred.resolveWith( deferred, args );
1149 } else if ( deferred !== firstParam ) {
1150 deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1152 return deferred.promise();
1158 jQuery.support = (function() {
1160 var div = document.createElement( "div" ),
1161 documentElement = document.documentElement,
1180 // Preliminary tests
1181 div.setAttribute("className", "t");
1182 div.innerHTML = " <link><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type=checkbox>";
1185 all = div.getElementsByTagName( "*" );
1186 a = div.getElementsByTagName( "a" )[ 0 ];
1188 // Can't get basic test support
1189 if ( !all || !all.length || !a ) {
1193 // First batch of supports tests
1194 select = document.createElement( "select" );
1195 opt = select.appendChild( document.createElement("option") );
1196 input = div.getElementsByTagName( "input" )[ 0 ];
1199 // IE strips leading whitespace when .innerHTML is used
1200 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1202 // Make sure that tbody elements aren't automatically inserted
1203 // IE will insert them into empty tables
1204 tbody: !div.getElementsByTagName( "tbody" ).length,
1206 // Make sure that link elements get serialized correctly by innerHTML
1207 // This requires a wrapper element in IE
1208 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1210 // Get the style information from getAttribute
1211 // (IE uses .cssText instead)
1212 style: /top/.test( a.getAttribute("style") ),
1214 // Make sure that URLs aren't manipulated
1215 // (IE normalizes it by default)
1216 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1218 // Make sure that element opacity exists
1219 // (IE uses filter instead)
1220 // Use a regex to work around a WebKit issue. See #5145
1221 opacity: /^0.55$/.test( a.style.opacity ),
1223 // Verify style float existence
1224 // (IE uses styleFloat instead of cssFloat)
1225 cssFloat: !!a.style.cssFloat,
1227 // Make sure that if no value is specified for a checkbox
1228 // that it defaults to "on".
1229 // (WebKit defaults to "" instead)
1230 checkOn: ( input.value === "on" ),
1232 // Make sure that a selected-by-default option has a working selected property.
1233 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1234 optSelected: opt.selected,
1236 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1237 getSetAttribute: div.className !== "t",
1239 // Will be defined later
1240 submitBubbles: true,
1241 changeBubbles: true,
1242 focusinBubbles: false,
1243 deleteExpando: true,
1245 inlineBlockNeedsLayout: false,
1246 shrinkWrapBlocks: false,
1247 reliableMarginRight: true
1250 // Make sure checked status is properly cloned
1251 input.checked = true;
1252 support.noCloneChecked = input.cloneNode( true ).checked;
1254 // Make sure that the options inside disabled selects aren't marked as disabled
1255 // (WebKit marks them as disabled)
1256 select.disabled = true;
1257 support.optDisabled = !opt.disabled;
1259 // Test to see if it's possible to delete an expando from an element
1260 // Fails in Internet Explorer
1264 support.deleteExpando = false;
1267 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1268 div.attachEvent( "onclick", function() {
1269 // Cloning a node shouldn't copy over any
1270 // bound event handlers (IE does this)
1271 support.noCloneEvent = false;
1273 div.cloneNode( true ).fireEvent( "onclick" );
1276 // Check if a radio maintains it's value
1277 // after being appended to the DOM
1278 input = document.createElement("input");
1280 input.setAttribute("type", "radio");
1281 support.radioValue = input.value === "t";
1283 input.setAttribute("checked", "checked");
1284 div.appendChild( input );
1285 fragment = document.createDocumentFragment();
1286 fragment.appendChild( div.firstChild );
1288 // WebKit doesn't clone checked state correctly in fragments
1289 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1293 // Figure out if the W3C box model works as expected
1294 div.style.width = div.style.paddingLeft = "1px";
1296 body = document.getElementsByTagName( "body" )[ 0 ];
1297 // We use our own, invisible, body unless the body is already present
1298 // in which case we use a div (#9239)
1299 testElement = document.createElement( body ? "div" : "body" );
1300 testElementStyle = {
1301 visibility: "hidden",
1309 jQuery.extend( testElementStyle, {
1310 position: "absolute",
1315 for ( i in testElementStyle ) {
1316 testElement.style[ i ] = testElementStyle[ i ];
1318 testElement.appendChild( div );
1319 testElementParent = body || documentElement;
1320 testElementParent.insertBefore( testElement, testElementParent.firstChild );
1322 // Check if a disconnected checkbox will retain its checked
1323 // value of true after appended to the DOM (IE6/7)
1324 support.appendChecked = input.checked;
1326 support.boxModel = div.offsetWidth === 2;
1328 if ( "zoom" in div.style ) {
1329 // Check if natively block-level elements act like inline-block
1330 // elements when setting their display to 'inline' and giving
1332 // (IE < 8 does this)
1333 div.style.display = "inline";
1335 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1337 // Check if elements with layout shrink-wrap their children
1339 div.style.display = "";
1340 div.innerHTML = "<div style='width:4px;'></div>";
1341 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1344 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1345 tds = div.getElementsByTagName( "td" );
1347 // Check if table cells still have offsetWidth/Height when they are set
1348 // to display:none and there are still other visible table cells in a
1349 // table row; if so, offsetWidth/Height are not reliable for use when
1350 // determining if an element has been hidden directly using
1351 // display:none (it is still safe to use offsets if a parent element is
1352 // hidden; don safety goggles and see bug #4512 for more information).
1353 // (only IE 8 fails this test)
1354 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1356 tds[ 0 ].style.display = "";
1357 tds[ 1 ].style.display = "none";
1359 // Check if empty table cells still have offsetWidth/Height
1360 // (IE < 8 fail this test)
1361 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1364 // Check if div with explicit width and no margin-right incorrectly
1365 // gets computed margin-right based on width of container. For more
1366 // info see bug #3333
1367 // Fails in WebKit before Feb 2011 nightlies
1368 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1369 if ( document.defaultView && document.defaultView.getComputedStyle ) {
1370 marginDiv = document.createElement( "div" );
1371 marginDiv.style.width = "0";
1372 marginDiv.style.marginRight = "0";
1373 div.appendChild( marginDiv );
1374 support.reliableMarginRight =
1375 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1378 // Remove the body element we added
1379 testElement.innerHTML = "";
1380 testElementParent.removeChild( testElement );
1382 // Technique from Juriy Zaytsev
1383 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1384 // We only care about the case where non-standard event systems
1385 // are used, namely in IE. Short-circuiting here helps us to
1386 // avoid an eval call (in setAttribute) which can cause CSP
1387 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1388 if ( div.attachEvent ) {
1394 eventName = "on" + i;
1395 isSupported = ( eventName in div );
1396 if ( !isSupported ) {
1397 div.setAttribute( eventName, "return;" );
1398 isSupported = ( typeof div[ eventName ] === "function" );
1400 support[ i + "Bubbles" ] = isSupported;
1404 // Null connected elements to avoid leaks in IE
1405 testElement = fragment = select = opt = body = marginDiv = div = input = null;
1410 // Keep track of boxModel
1411 jQuery.boxModel = jQuery.support.boxModel;
1416 var rbrace = /^(?:\{.*\}|\[.*\])$/,
1417 rmultiDash = /([a-z])([A-Z])/g;
1422 // Please use with caution
1425 // Unique for each copy of jQuery on the page
1426 // Non-digits removed to match rinlinejQuery
1427 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1429 // The following elements throw uncatchable exceptions if you
1430 // attempt to add expando properties to them.
1433 // Ban all objects except for Flash (which handle expandos)
1434 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1438 hasData: function( elem ) {
1439 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1441 return !!elem && !isEmptyDataObject( elem );
1444 data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1445 if ( !jQuery.acceptData( elem ) ) {
1450 internalKey = jQuery.expando,
1451 getByName = typeof name === "string",
1453 // We have to handle DOM nodes and JS objects differently because IE6-7
1454 // can't GC object references properly across the DOM-JS boundary
1455 isNode = elem.nodeType,
1457 // Only DOM nodes need the global jQuery cache; JS object data is
1458 // attached directly to the object so GC can occur automatically
1459 cache = isNode ? jQuery.cache : elem,
1461 // Only defining an ID for JS objects if its cache already exists allows
1462 // the code to shortcut on the same path as a DOM node with no cache
1463 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1465 // Avoid doing any more work than we need to when trying to get data on an
1466 // object that has no data at all
1467 if ( (!id || (pvt && id && (cache[ id ] && !cache[ id ][ internalKey ]))) && getByName && data === undefined ) {
1472 // Only DOM nodes need a new unique ID for each element since their data
1473 // ends up in the global cache
1475 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1477 id = jQuery.expando;
1481 if ( !cache[ id ] ) {
1484 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1485 // metadata on plain JS objects when the object is serialized using
1488 cache[ id ].toJSON = jQuery.noop;
1492 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1493 // shallow copied over onto the existing cache
1494 if ( typeof name === "object" || typeof name === "function" ) {
1496 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1498 cache[ id ] = jQuery.extend(cache[ id ], name);
1502 thisCache = cache[ id ];
1504 // Internal jQuery data is stored in a separate object inside the object's data
1505 // cache in order to avoid key collisions between internal data and user-defined
1508 if ( !thisCache[ internalKey ] ) {
1509 thisCache[ internalKey ] = {};
1512 thisCache = thisCache[ internalKey ];
1515 if ( data !== undefined ) {
1516 thisCache[ jQuery.camelCase( name ) ] = data;
1519 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1520 // not attempt to inspect the internal events object using jQuery.data, as this
1521 // internal data object is undocumented and subject to change.
1522 if ( name === "events" && !thisCache[name] ) {
1523 return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1526 // Check for both converted-to-camel and non-converted data property names
1527 // If a data property was specified
1530 // First Try to find as-is property data
1531 ret = thisCache[ name ];
1533 // Test for null|undefined property data
1534 if ( ret == null ) {
1536 // Try to find the camelCased property
1537 ret = thisCache[ jQuery.camelCase( name ) ];
1546 removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1547 if ( !jQuery.acceptData( elem ) ) {
1553 // Reference to internal data cache key
1554 internalKey = jQuery.expando,
1556 isNode = elem.nodeType,
1558 // See jQuery.data for more information
1559 cache = isNode ? jQuery.cache : elem,
1561 // See jQuery.data for more information
1562 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1564 // If there is already no cache entry for this object, there is no
1565 // purpose in continuing
1566 if ( !cache[ id ] ) {
1572 thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1576 // Support interoperable removal of hyphenated or camelcased keys
1577 if ( !thisCache[ name ] ) {
1578 name = jQuery.camelCase( name );
1581 delete thisCache[ name ];
1583 // If there is no data left in the cache, we want to continue
1584 // and let the cache object itself get destroyed
1585 if ( !isEmptyDataObject(thisCache) ) {
1591 // See jQuery.data for more information
1593 delete cache[ id ][ internalKey ];
1595 // Don't destroy the parent cache unless the internal data object
1596 // had been the only thing left in it
1597 if ( !isEmptyDataObject(cache[ id ]) ) {
1602 var internalCache = cache[ id ][ internalKey ];
1604 // Browsers that fail expando deletion also refuse to delete expandos on
1605 // the window, but it will allow it on all other JS objects; other browsers
1607 // Ensure that `cache` is not a window object #10080
1608 if ( jQuery.support.deleteExpando || !cache.setInterval ) {
1614 // We destroyed the entire user cache at once because it's faster than
1615 // iterating through each key, but we need to continue to persist internal
1616 // data if it existed
1617 if ( internalCache ) {
1619 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1620 // metadata on plain JS objects when the object is serialized using
1623 cache[ id ].toJSON = jQuery.noop;
1626 cache[ id ][ internalKey ] = internalCache;
1628 // Otherwise, we need to eliminate the expando on the node to avoid
1629 // false lookups in the cache for entries that no longer exist
1630 } else if ( isNode ) {
1631 // IE does not allow us to delete expando properties from nodes,
1632 // nor does it have a removeAttribute function on Document nodes;
1633 // we must handle all of these cases
1634 if ( jQuery.support.deleteExpando ) {
1635 delete elem[ jQuery.expando ];
1636 } else if ( elem.removeAttribute ) {
1637 elem.removeAttribute( jQuery.expando );
1639 elem[ jQuery.expando ] = null;
1644 // For internal use only.
1645 _data: function( elem, name, data ) {
1646 return jQuery.data( elem, name, data, true );
1649 // A method for determining if a DOM node can handle the data expando
1650 acceptData: function( elem ) {
1651 if ( elem.nodeName ) {
1652 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1655 return !(match === true || elem.getAttribute("classid") !== match);
1664 data: function( key, value ) {
1667 if ( typeof key === "undefined" ) {
1668 if ( this.length ) {
1669 data = jQuery.data( this[0] );
1671 if ( this[0].nodeType === 1 ) {
1672 var attr = this[0].attributes, name;
1673 for ( var i = 0, l = attr.length; i < l; i++ ) {
1674 name = attr[i].name;
1676 if ( name.indexOf( "data-" ) === 0 ) {
1677 name = jQuery.camelCase( name.substring(5) );
1679 dataAttr( this[0], name, data[ name ] );
1687 } else if ( typeof key === "object" ) {
1688 return this.each(function() {
1689 jQuery.data( this, key );
1693 var parts = key.split(".");
1694 parts[1] = parts[1] ? "." + parts[1] : "";
1696 if ( value === undefined ) {
1697 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1699 // Try to fetch any internally stored data first
1700 if ( data === undefined && this.length ) {
1701 data = jQuery.data( this[0], key );
1702 data = dataAttr( this[0], key, data );
1705 return data === undefined && parts[1] ?
1706 this.data( parts[0] ) :
1710 return this.each(function() {
1711 var $this = jQuery( this ),
1712 args = [ parts[0], value ];
1714 $this.triggerHandler( "setData" + parts[1] + "!", args );
1715 jQuery.data( this, key, value );
1716 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1721 removeData: function( key ) {
1722 return this.each(function() {
1723 jQuery.removeData( this, key );
1728 function dataAttr( elem, key, data ) {
1729 // If nothing was found internally, try to fetch any
1730 // data from the HTML5 data-* attribute
1731 if ( data === undefined && elem.nodeType === 1 ) {
1732 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1734 data = elem.getAttribute( name );
1736 if ( typeof data === "string" ) {
1738 data = data === "true" ? true :
1739 data === "false" ? false :
1740 data === "null" ? null :
1741 !jQuery.isNaN( data ) ? parseFloat( data ) :
1742 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1746 // Make sure we set the data so it isn't changed later
1747 jQuery.data( elem, key, data );
1757 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1758 // property to be considered empty objects; this property always exists in
1759 // order to make sure JSON.stringify does not expose internal metadata
1760 function isEmptyDataObject( obj ) {
1761 for ( var name in obj ) {
1762 if ( name !== "toJSON" ) {
1773 function handleQueueMarkDefer( elem, type, src ) {
1774 var deferDataKey = type + "defer",
1775 queueDataKey = type + "queue",
1776 markDataKey = type + "mark",
1777 defer = jQuery.data( elem, deferDataKey, undefined, true );
1779 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1780 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1781 // Give room for hard-coded callbacks to fire first
1782 // and eventually mark/queue something else on the element
1783 setTimeout( function() {
1784 if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1785 !jQuery.data( elem, markDataKey, undefined, true ) ) {
1786 jQuery.removeData( elem, deferDataKey, true );
1795 _mark: function( elem, type ) {
1797 type = (type || "fx") + "mark";
1798 jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1802 _unmark: function( force, elem, type ) {
1803 if ( force !== true ) {
1809 type = type || "fx";
1810 var key = type + "mark",
1811 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1813 jQuery.data( elem, key, count, true );
1815 jQuery.removeData( elem, key, true );
1816 handleQueueMarkDefer( elem, type, "mark" );
1821 queue: function( elem, type, data ) {
1823 type = (type || "fx") + "queue";
1824 var q = jQuery.data( elem, type, undefined, true );
1825 // Speed up dequeue by getting out quickly if this is just a lookup
1827 if ( !q || jQuery.isArray(data) ) {
1828 q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1837 dequeue: function( elem, type ) {
1838 type = type || "fx";
1840 var queue = jQuery.queue( elem, type ),
1844 // If the fx queue is dequeued, always remove the progress sentinel
1845 if ( fn === "inprogress" ) {
1850 // Add a progress sentinel to prevent the fx queue from being
1851 // automatically dequeued
1852 if ( type === "fx" ) {
1853 queue.unshift("inprogress");
1856 fn.call(elem, function() {
1857 jQuery.dequeue(elem, type);
1861 if ( !queue.length ) {
1862 jQuery.removeData( elem, type + "queue", true );
1863 handleQueueMarkDefer( elem, type, "queue" );
1869 queue: function( type, data ) {
1870 if ( typeof type !== "string" ) {
1875 if ( data === undefined ) {
1876 return jQuery.queue( this[0], type );
1878 return this.each(function() {
1879 var queue = jQuery.queue( this, type, data );
1881 if ( type === "fx" && queue[0] !== "inprogress" ) {
1882 jQuery.dequeue( this, type );
1886 dequeue: function( type ) {
1887 return this.each(function() {
1888 jQuery.dequeue( this, type );
1891 // Based off of the plugin by Clint Helfers, with permission.
1892 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1893 delay: function( time, type ) {
1894 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1895 type = type || "fx";
1897 return this.queue( type, function() {
1899 setTimeout(function() {
1900 jQuery.dequeue( elem, type );
1904 clearQueue: function( type ) {
1905 return this.queue( type || "fx", [] );
1907 // Get a promise resolved when queues of a certain type
1908 // are emptied (fx is the type by default)
1909 promise: function( type, object ) {
1910 if ( typeof type !== "string" ) {
1914 type = type || "fx";
1915 var defer = jQuery.Deferred(),
1917 i = elements.length,
1919 deferDataKey = type + "defer",
1920 queueDataKey = type + "queue",
1921 markDataKey = type + "mark",
1923 function resolve() {
1924 if ( !( --count ) ) {
1925 defer.resolveWith( elements, [ elements ] );
1929 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1930 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1931 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1932 jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1934 tmp.done( resolve );
1938 return defer.promise();
1945 var rclass = /[\n\t\r]/g,
1948 rtype = /^(?:button|input)$/i,
1949 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1950 rclickable = /^a(?:rea)?$/i,
1951 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1955 attr: function( name, value ) {
1956 return jQuery.access( this, name, value, true, jQuery.attr );
1959 removeAttr: function( name ) {
1960 return this.each(function() {
1961 jQuery.removeAttr( this, name );
1965 prop: function( name, value ) {
1966 return jQuery.access( this, name, value, true, jQuery.prop );
1969 removeProp: function( name ) {
1970 name = jQuery.propFix[ name ] || name;
1971 return this.each(function() {
1972 // try/catch handles cases where IE balks (such as removing a property on window)
1974 this[ name ] = undefined;
1975 delete this[ name ];
1980 addClass: function( value ) {
1981 var classNames, i, l, elem,
1984 if ( jQuery.isFunction( value ) ) {
1985 return this.each(function( j ) {
1986 jQuery( this ).addClass( value.call(this, j, this.className) );
1990 if ( value && typeof value === "string" ) {
1991 classNames = value.split( rspace );
1993 for ( i = 0, l = this.length; i < l; i++ ) {
1996 if ( elem.nodeType === 1 ) {
1997 if ( !elem.className && classNames.length === 1 ) {
1998 elem.className = value;
2001 setClass = " " + elem.className + " ";
2003 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2004 if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
2005 setClass += classNames[ c ] + " ";
2008 elem.className = jQuery.trim( setClass );
2017 removeClass: function( value ) {
2018 var classNames, i, l, elem, className, c, cl;
2020 if ( jQuery.isFunction( value ) ) {
2021 return this.each(function( j ) {
2022 jQuery( this ).removeClass( value.call(this, j, this.className) );
2026 if ( (value && typeof value === "string") || value === undefined ) {
2027 classNames = (value || "").split( rspace );
2029 for ( i = 0, l = this.length; i < l; i++ ) {
2032 if ( elem.nodeType === 1 && elem.className ) {
2034 className = (" " + elem.className + " ").replace( rclass, " " );
2035 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2036 className = className.replace(" " + classNames[ c ] + " ", " ");
2038 elem.className = jQuery.trim( className );
2041 elem.className = "";
2050 toggleClass: function( value, stateVal ) {
2051 var type = typeof value,
2052 isBool = typeof stateVal === "boolean";
2054 if ( jQuery.isFunction( value ) ) {
2055 return this.each(function( i ) {
2056 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2060 return this.each(function() {
2061 if ( type === "string" ) {
2062 // toggle individual class names
2065 self = jQuery( this ),
2067 classNames = value.split( rspace );
2069 while ( (className = classNames[ i++ ]) ) {
2070 // check each className given, space seperated list
2071 state = isBool ? state : !self.hasClass( className );
2072 self[ state ? "addClass" : "removeClass" ]( className );
2075 } else if ( type === "undefined" || type === "boolean" ) {
2076 if ( this.className ) {
2077 // store className if set
2078 jQuery._data( this, "__className__", this.className );
2081 // toggle whole className
2082 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2087 hasClass: function( selector ) {
2088 var className = " " + selector + " ";
2089 for ( var i = 0, l = this.length; i < l; i++ ) {
2090 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2098 val: function( value ) {
2102 if ( !arguments.length ) {
2104 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2106 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2112 return typeof ret === "string" ?
2113 // handle most common string cases
2114 ret.replace(rreturn, "") :
2115 // handle cases where value is null/undef or number
2116 ret == null ? "" : ret;
2122 var isFunction = jQuery.isFunction( value );
2124 return this.each(function( i ) {
2125 var self = jQuery(this), val;
2127 if ( this.nodeType !== 1 ) {
2132 val = value.call( this, i, self.val() );
2137 // Treat null/undefined as ""; convert numbers to string
2138 if ( val == null ) {
2140 } else if ( typeof val === "number" ) {
2142 } else if ( jQuery.isArray( val ) ) {
2143 val = jQuery.map(val, function ( value ) {
2144 return value == null ? "" : value + "";
2148 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2150 // If set returns undefined, fall back to normal setting
2151 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2161 get: function( elem ) {
2162 // attributes.value is undefined in Blackberry 4.7 but
2163 // uses .value. See #6932
2164 var val = elem.attributes.value;
2165 return !val || val.specified ? elem.value : elem.text;
2169 get: function( elem ) {
2171 index = elem.selectedIndex,
2173 options = elem.options,
2174 one = elem.type === "select-one";
2176 // Nothing was selected
2181 // Loop through all the selected options
2182 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2183 var option = options[ i ];
2185 // Don't return options that are disabled or in a disabled optgroup
2186 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2187 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2189 // Get the specific value for the option
2190 value = jQuery( option ).val();
2192 // We don't need an array for one selects
2197 // Multi-Selects return an array
2198 values.push( value );
2202 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2203 if ( one && !values.length && options.length ) {
2204 return jQuery( options[ index ] ).val();
2210 set: function( elem, value ) {
2211 var values = jQuery.makeArray( value );
2213 jQuery(elem).find("option").each(function() {
2214 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2217 if ( !values.length ) {
2218 elem.selectedIndex = -1;
2237 // Always normalize to ensure hook usage
2238 tabindex: "tabIndex"
2241 attr: function( elem, name, value, pass ) {
2242 var nType = elem.nodeType;
2244 // don't get/set attributes on text, comment and attribute nodes
2245 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2249 if ( pass && name in jQuery.attrFn ) {
2250 return jQuery( elem )[ name ]( value );
2253 // Fallback to prop when attributes are not supported
2254 if ( !("getAttribute" in elem) ) {
2255 return jQuery.prop( elem, name, value );
2259 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2261 // Normalize the name if needed
2263 name = jQuery.attrFix[ name ] || name;
2265 hooks = jQuery.attrHooks[ name ];
2268 // Use boolHook for boolean attributes
2269 if ( rboolean.test( name ) ) {
2272 // Use nodeHook if available( IE6/7 )
2273 } else if ( nodeHook ) {
2279 if ( value !== undefined ) {
2281 if ( value === null ) {
2282 jQuery.removeAttr( elem, name );
2285 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2289 elem.setAttribute( name, "" + value );
2293 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2298 ret = elem.getAttribute( name );
2300 // Non-existent attributes return null, we normalize to undefined
2301 return ret === null ?
2307 removeAttr: function( elem, name ) {
2309 if ( elem.nodeType === 1 ) {
2310 name = jQuery.attrFix[ name ] || name;
2312 jQuery.attr( elem, name, "" );
2313 elem.removeAttribute( name );
2315 // Set corresponding property to false for boolean attributes
2316 if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2317 elem[ propName ] = false;
2324 set: function( elem, value ) {
2325 // We can't allow the type property to be changed (since it causes problems in IE)
2326 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2327 jQuery.error( "type property can't be changed" );
2328 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2329 // Setting the type on a radio button after the value resets the value in IE6-9
2330 // Reset value to it's default in case type is set after value
2331 // This is for element creation
2332 var val = elem.value;
2333 elem.setAttribute( "type", value );
2341 // Use the value property for back compat
2342 // Use the nodeHook for button elements in IE6/7 (#1954)
2344 get: function( elem, name ) {
2345 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2346 return nodeHook.get( elem, name );
2348 return name in elem ?
2352 set: function( elem, value, name ) {
2353 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2354 return nodeHook.set( elem, value, name );
2356 // Does not return so that setAttribute is also used
2363 tabindex: "tabIndex",
2364 readonly: "readOnly",
2366 "class": "className",
2367 maxlength: "maxLength",
2368 cellspacing: "cellSpacing",
2369 cellpadding: "cellPadding",
2373 frameborder: "frameBorder",
2374 contenteditable: "contentEditable"
2377 prop: function( elem, name, value ) {
2378 var nType = elem.nodeType;
2380 // don't get/set properties on text, comment and attribute nodes
2381 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2386 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2389 // Fix name and attach hooks
2390 name = jQuery.propFix[ name ] || name;
2391 hooks = jQuery.propHooks[ name ];
2394 if ( value !== undefined ) {
2395 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2399 return (elem[ name ] = value);
2403 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2407 return elem[ name ];
2414 get: function( elem ) {
2415 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2416 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2417 var attributeNode = elem.getAttributeNode("tabindex");
2419 return attributeNode && attributeNode.specified ?
2420 parseInt( attributeNode.value, 10 ) :
2421 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2429 // Add the tabindex propHook to attrHooks for back-compat
2430 jQuery.attrHooks.tabIndex = jQuery.propHooks.tabIndex;
2432 // Hook for boolean attributes
2434 get: function( elem, name ) {
2435 // Align boolean attributes with corresponding properties
2436 // Fall back to attribute presence where some booleans are not supported
2438 return jQuery.prop( elem, name ) === true || ( attrNode = elem.getAttributeNode( name ) ) && attrNode.nodeValue !== false ?
2439 name.toLowerCase() :
2442 set: function( elem, value, name ) {
2444 if ( value === false ) {
2445 // Remove boolean attributes when set to false
2446 jQuery.removeAttr( elem, name );
2448 // value is true since we know at this point it's type boolean and not false
2449 // Set boolean attributes to the same name and set the DOM property
2450 propName = jQuery.propFix[ name ] || name;
2451 if ( propName in elem ) {
2452 // Only set the IDL specifically if it already exists on the element
2453 elem[ propName ] = true;
2456 elem.setAttribute( name, name.toLowerCase() );
2462 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2463 if ( !jQuery.support.getSetAttribute ) {
2465 // Use this for any attribute in IE6/7
2466 // This fixes almost every IE6/7 issue
2467 nodeHook = jQuery.valHooks.button = {
2468 get: function( elem, name ) {
2470 ret = elem.getAttributeNode( name );
2471 // Return undefined if nodeValue is empty string
2472 return ret && ret.nodeValue !== "" ?
2476 set: function( elem, value, name ) {
2477 // Set the existing or create a new attribute node
2478 var ret = elem.getAttributeNode( name );
2480 ret = document.createAttribute( name );
2481 elem.setAttributeNode( ret );
2483 return (ret.nodeValue = value + "");
2487 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2488 // This is for removals
2489 jQuery.each([ "width", "height" ], function( i, name ) {
2490 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2491 set: function( elem, value ) {
2492 if ( value === "" ) {
2493 elem.setAttribute( name, "auto" );
2502 // Some attributes require a special call on IE
2503 if ( !jQuery.support.hrefNormalized ) {
2504 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2505 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2506 get: function( elem ) {
2507 var ret = elem.getAttribute( name, 2 );
2508 return ret === null ? undefined : ret;
2514 if ( !jQuery.support.style ) {
2515 jQuery.attrHooks.style = {
2516 get: function( elem ) {
2517 // Return undefined in the case of empty string
2518 // Normalize to lowercase since IE uppercases css property names
2519 return elem.style.cssText.toLowerCase() || undefined;
2521 set: function( elem, value ) {
2522 return (elem.style.cssText = "" + value);
2527 // Safari mis-reports the default selected property of an option
2528 // Accessing the parent's selectedIndex property fixes it
2529 if ( !jQuery.support.optSelected ) {
2530 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2531 get: function( elem ) {
2532 var parent = elem.parentNode;
2535 parent.selectedIndex;
2537 // Make sure that it also works with optgroups, see #5701
2538 if ( parent.parentNode ) {
2539 parent.parentNode.selectedIndex;
2547 // Radios and checkboxes getter/setter
2548 if ( !jQuery.support.checkOn ) {
2549 jQuery.each([ "radio", "checkbox" ], function() {
2550 jQuery.valHooks[ this ] = {
2551 get: function( elem ) {
2552 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2553 return elem.getAttribute("value") === null ? "on" : elem.value;
2558 jQuery.each([ "radio", "checkbox" ], function() {
2559 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2560 set: function( elem, value ) {
2561 if ( jQuery.isArray( value ) ) {
2562 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2571 var rnamespaces = /\.(.*)$/,
2572 rformElems = /^(?:textarea|input|select)$/i,
2575 rescape = /[^\w\s.|`]/g,
2576 fcleanup = function( nm ) {
2577 return nm.replace(rescape, "\\$&");
2581 * A number of helper functions used for managing events.
2582 * Many of the ideas behind this code originated from
2583 * Dean Edwards' addEvent library.
2587 // Bind an event to an element
2588 // Original by Dean Edwards
2589 add: function( elem, types, handler, data ) {
2590 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2594 if ( handler === false ) {
2595 handler = returnFalse;
2596 } else if ( !handler ) {
2597 // Fixes bug #7229. Fix recommended by jdalton
2601 var handleObjIn, handleObj;
2603 if ( handler.handler ) {
2604 handleObjIn = handler;
2605 handler = handleObjIn.handler;
2608 // Make sure that the function being executed has a unique ID
2609 if ( !handler.guid ) {
2610 handler.guid = jQuery.guid++;
2613 // Init the element's event structure
2614 var elemData = jQuery._data( elem );
2616 // If no elemData is found then we must be trying to bind to one of the
2617 // banned noData elements
2622 var events = elemData.events,
2623 eventHandle = elemData.handle;
2626 elemData.events = events = {};
2629 if ( !eventHandle ) {
2630 elemData.handle = eventHandle = function( e ) {
2631 // Discard the second event of a jQuery.event.trigger() and
2632 // when an event is called after a page has unloaded
2633 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2634 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2639 // Add elem as a property of the handle function
2640 // This is to prevent a memory leak with non-native events in IE.
2641 eventHandle.elem = elem;
2643 // Handle multiple events separated by a space
2644 // jQuery(...).bind("mouseover mouseout", fn);
2645 types = types.split(" ");
2647 var type, i = 0, namespaces;
2649 while ( (type = types[ i++ ]) ) {
2650 handleObj = handleObjIn ?
2651 jQuery.extend({}, handleObjIn) :
2652 { handler: handler, data: data };
2654 // Namespaced event handlers
2655 if ( type.indexOf(".") > -1 ) {
2656 namespaces = type.split(".");
2657 type = namespaces.shift();
2658 handleObj.namespace = namespaces.slice(0).sort().join(".");
2662 handleObj.namespace = "";
2665 handleObj.type = type;
2666 if ( !handleObj.guid ) {
2667 handleObj.guid = handler.guid;
2670 // Get the current list of functions bound to this event
2671 var handlers = events[ type ],
2672 special = jQuery.event.special[ type ] || {};
2674 // Init the event handler queue
2676 handlers = events[ type ] = [];
2678 // Check for a special event handler
2679 // Only use addEventListener/attachEvent if the special
2680 // events handler returns false
2681 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2682 // Bind the global event handler to the element
2683 if ( elem.addEventListener ) {
2684 elem.addEventListener( type, eventHandle, false );
2686 } else if ( elem.attachEvent ) {
2687 elem.attachEvent( "on" + type, eventHandle );
2692 if ( special.add ) {
2693 special.add.call( elem, handleObj );
2695 if ( !handleObj.handler.guid ) {
2696 handleObj.handler.guid = handler.guid;
2700 // Add the function to the element's handler list
2701 handlers.push( handleObj );
2703 // Keep track of which events have been used, for event optimization
2704 jQuery.event.global[ type ] = true;
2707 // Nullify elem to prevent memory leaks in IE
2713 // Detach an event or set of events from an element
2714 remove: function( elem, types, handler, pos ) {
2715 // don't do events on text and comment nodes
2716 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2720 if ( handler === false ) {
2721 handler = returnFalse;
2724 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2725 elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2726 events = elemData && elemData.events;
2728 if ( !elemData || !events ) {
2732 // types is actually an event object here
2733 if ( types && types.type ) {
2734 handler = types.handler;
2738 // Unbind all events for the element
2739 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2740 types = types || "";
2742 for ( type in events ) {
2743 jQuery.event.remove( elem, type + types );
2749 // Handle multiple events separated by a space
2750 // jQuery(...).unbind("mouseover mouseout", fn);
2751 types = types.split(" ");
2753 while ( (type = types[ i++ ]) ) {
2756 all = type.indexOf(".") < 0;
2760 // Namespaced event handlers
2761 namespaces = type.split(".");
2762 type = namespaces.shift();
2764 namespace = new RegExp("(^|\\.)" +
2765 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2768 eventType = events[ type ];
2775 for ( j = 0; j < eventType.length; j++ ) {
2776 handleObj = eventType[ j ];
2778 if ( all || namespace.test( handleObj.namespace ) ) {
2779 jQuery.event.remove( elem, origType, handleObj.handler, j );
2780 eventType.splice( j--, 1 );
2787 special = jQuery.event.special[ type ] || {};
2789 for ( j = pos || 0; j < eventType.length; j++ ) {
2790 handleObj = eventType[ j ];
2792 if ( handler.guid === handleObj.guid ) {
2793 // remove the given handler for the given type
2794 if ( all || namespace.test( handleObj.namespace ) ) {
2795 if ( pos == null ) {
2796 eventType.splice( j--, 1 );
2799 if ( special.remove ) {
2800 special.remove.call( elem, handleObj );
2804 if ( pos != null ) {
2810 // remove generic event handler if no more handlers exist
2811 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2812 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2813 jQuery.removeEvent( elem, type, elemData.handle );
2817 delete events[ type ];
2821 // Remove the expando if it's no longer used
2822 if ( jQuery.isEmptyObject( events ) ) {
2823 var handle = elemData.handle;
2828 delete elemData.events;
2829 delete elemData.handle;
2831 if ( jQuery.isEmptyObject( elemData ) ) {
2832 jQuery.removeData( elem, undefined, true );
2837 // Events that are safe to short-circuit if no handlers are attached.
2838 // Native DOM events should not be added, they may have inline handlers.
2845 trigger: function( event, data, elem, onlyHandlers ) {
2846 // Event object or event type
2847 var type = event.type || event,
2851 if ( type.indexOf("!") >= 0 ) {
2852 // Exclusive events trigger only for the exact event (no namespaces)
2853 type = type.slice(0, -1);
2857 if ( type.indexOf(".") >= 0 ) {
2858 // Namespaced trigger; create a regexp to match event type in handle()
2859 namespaces = type.split(".");
2860 type = namespaces.shift();
2864 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2865 // No jQuery handlers for this event type, and it can't have inline handlers
2869 // Caller can pass in an Event, Object, or just an event type string
2870 event = typeof event === "object" ?
2871 // jQuery.Event object
2872 event[ jQuery.expando ] ? event :
2874 new jQuery.Event( type, event ) :
2875 // Just the event type (string)
2876 new jQuery.Event( type );
2879 event.exclusive = exclusive;
2880 event.namespace = namespaces.join(".");
2881 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2883 // triggerHandler() and global events don't bubble or run the default action
2884 if ( onlyHandlers || !elem ) {
2885 event.preventDefault();
2886 event.stopPropagation();
2889 // Handle a global trigger
2891 // TODO: Stop taunting the data cache; remove global events and always attach to document
2892 jQuery.each( jQuery.cache, function() {
2893 // internalKey variable is just used to make it easier to find
2894 // and potentially change this stuff later; currently it just
2895 // points to jQuery.expando
2896 var internalKey = jQuery.expando,
2897 internalCache = this[ internalKey ];
2898 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2899 jQuery.event.trigger( event, data, internalCache.handle.elem );
2905 // Don't do events on text and comment nodes
2906 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2910 // Clean up the event in case it is being reused
2911 event.result = undefined;
2912 event.target = elem;
2914 // Clone any incoming data and prepend the event, creating the handler arg list
2915 data = data != null ? jQuery.makeArray( data ) : [];
2916 data.unshift( event );
2919 // IE doesn't like method names with a colon (#3533, #8272)
2920 ontype = type.indexOf(":") < 0 ? "on" + type : "";
2922 // Fire event on the current element, then bubble up the DOM tree
2924 var handle = jQuery._data( cur, "handle" );
2926 event.currentTarget = cur;
2928 handle.apply( cur, data );
2931 // Trigger an inline bound script
2932 if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2933 event.result = false;
2934 event.preventDefault();
2937 // Bubble up to document, then to window
2938 cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2939 } while ( cur && !event.isPropagationStopped() );
2941 // If nobody prevented the default action, do it now
2942 if ( !event.isDefaultPrevented() ) {
2944 special = jQuery.event.special[ type ] || {};
2946 if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2947 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2949 // Call a native DOM method on the target with the same name name as the event.
2950 // Can't use an .isFunction)() check here because IE6/7 fails that test.
2951 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2953 if ( ontype && elem[ type ] ) {
2954 // Don't re-trigger an onFOO event when we call its FOO() method
2955 old = elem[ ontype ];
2958 elem[ ontype ] = null;
2961 jQuery.event.triggered = type;
2964 } catch ( ieError ) {}
2967 elem[ ontype ] = old;
2970 jQuery.event.triggered = undefined;
2974 return event.result;
2977 handle: function( event ) {
2978 event = jQuery.event.fix( event || window.event );
2979 // Snapshot the handlers list since a called handler may add/remove events.
2980 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2981 run_all = !event.exclusive && !event.namespace,
2982 args = Array.prototype.slice.call( arguments, 0 );
2984 // Use the fix-ed Event rather than the (read-only) native event
2986 event.currentTarget = this;
2988 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2989 var handleObj = handlers[ j ];
2991 // Triggered event must 1) be non-exclusive and have no namespace, or
2992 // 2) have namespace(s) a subset or equal to those in the bound event.
2993 if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2994 // Pass in a reference to the handler function itself
2995 // So that we can later remove it
2996 event.handler = handleObj.handler;
2997 event.data = handleObj.data;
2998 event.handleObj = handleObj;
3000 var ret = handleObj.handler.apply( this, args );
3002 if ( ret !== undefined ) {
3004 if ( ret === false ) {
3005 event.preventDefault();
3006 event.stopPropagation();
3010 if ( event.isImmediatePropagationStopped() ) {
3015 return event.result;
3018 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(" "),
3020 fix: function( event ) {
3021 if ( event[ jQuery.expando ] ) {
3025 // store a copy of the original event object
3026 // and "clone" to set read-only properties
3027 var originalEvent = event;
3028 event = jQuery.Event( originalEvent );
3030 for ( var i = this.props.length, prop; i; ) {
3031 prop = this.props[ --i ];
3032 event[ prop ] = originalEvent[ prop ];
3035 // Fix target property, if necessary
3036 if ( !event.target ) {
3037 // Fixes #1925 where srcElement might not be defined either
3038 event.target = event.srcElement || document;
3041 // check if target is a textnode (safari)
3042 if ( event.target.nodeType === 3 ) {
3043 event.target = event.target.parentNode;
3046 // Add relatedTarget, if necessary
3047 if ( !event.relatedTarget && event.fromElement ) {
3048 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
3051 // Calculate pageX/Y if missing and clientX/Y available
3052 if ( event.pageX == null && event.clientX != null ) {
3053 var eventDocument = event.target.ownerDocument || document,
3054 doc = eventDocument.documentElement,
3055 body = eventDocument.body;
3057 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
3058 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
3061 // Add which for key events
3062 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3063 event.which = event.charCode != null ? event.charCode : event.keyCode;
3066 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3067 if ( !event.metaKey && event.ctrlKey ) {
3068 event.metaKey = event.ctrlKey;
3071 // Add which for click: 1 === left; 2 === middle; 3 === right
3072 // Note: button is not normalized, so don't use it
3073 if ( !event.which && event.button !== undefined ) {
3074 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3080 // Deprecated, use jQuery.guid instead
3083 // Deprecated, use jQuery.proxy instead
3084 proxy: jQuery.proxy,
3088 // Make sure the ready event is setup
3089 setup: jQuery.bindReady,
3090 teardown: jQuery.noop
3094 add: function( handleObj ) {
3095 jQuery.event.add( this,
3096 liveConvert( handleObj.origType, handleObj.selector ),
3097 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3100 remove: function( handleObj ) {
3101 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3106 setup: function( data, namespaces, eventHandle ) {
3107 // We only want to do this special case on windows
3108 if ( jQuery.isWindow( this ) ) {
3109 this.onbeforeunload = eventHandle;
3113 teardown: function( namespaces, eventHandle ) {
3114 if ( this.onbeforeunload === eventHandle ) {
3115 this.onbeforeunload = null;
3122 jQuery.removeEvent = document.removeEventListener ?
3123 function( elem, type, handle ) {
3124 if ( elem.removeEventListener ) {
3125 elem.removeEventListener( type, handle, false );
3128 function( elem, type, handle ) {
3129 if ( elem.detachEvent ) {
3130 elem.detachEvent( "on" + type, handle );
3134 jQuery.Event = function( src, props ) {
3135 // Allow instantiation without the 'new' keyword
3136 if ( !this.preventDefault ) {
3137 return new jQuery.Event( src, props );
3141 if ( src && src.type ) {
3142 this.originalEvent = src;
3143 this.type = src.type;
3145 // Events bubbling up the document may have been marked as prevented
3146 // by a handler lower down the tree; reflect the correct value.
3147 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3148 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3155 // Put explicitly provided properties onto the event object
3157 jQuery.extend( this, props );
3160 // timeStamp is buggy for some events on Firefox(#3843)
3161 // So we won't rely on the native value
3162 this.timeStamp = jQuery.now();
3165 this[ jQuery.expando ] = true;
3168 function returnFalse() {
3171 function returnTrue() {
3175 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3176 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3177 jQuery.Event.prototype = {
3178 preventDefault: function() {
3179 this.isDefaultPrevented = returnTrue;
3181 var e = this.originalEvent;
3186 // if preventDefault exists run it on the original event
3187 if ( e.preventDefault ) {
3190 // otherwise set the returnValue property of the original event to false (IE)
3192 e.returnValue = false;
3195 stopPropagation: function() {
3196 this.isPropagationStopped = returnTrue;
3198 var e = this.originalEvent;
3202 // if stopPropagation exists run it on the original event
3203 if ( e.stopPropagation ) {
3204 e.stopPropagation();
3206 // otherwise set the cancelBubble property of the original event to true (IE)
3207 e.cancelBubble = true;
3209 stopImmediatePropagation: function() {
3210 this.isImmediatePropagationStopped = returnTrue;
3211 this.stopPropagation();
3213 isDefaultPrevented: returnFalse,
3214 isPropagationStopped: returnFalse,
3215 isImmediatePropagationStopped: returnFalse
3218 // Checks if an event happened on an element within another element
3219 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3220 var withinElement = function( event ) {
3222 // Check if mouse(over|out) are still within the same parent element
3223 var related = event.relatedTarget,
3225 eventType = event.type;
3227 event.type = event.data;
3229 if ( related !== this ) {
3232 inside = jQuery.contains( this, related );
3237 jQuery.event.handle.apply( this, arguments );
3239 event.type = eventType;
3244 // In case of event delegation, we only need to rename the event.type,
3245 // liveHandler will take care of the rest.
3246 delegate = function( event ) {
3247 event.type = event.data;
3248 jQuery.event.handle.apply( this, arguments );
3251 // Create mouseenter and mouseleave events
3253 mouseenter: "mouseover",
3254 mouseleave: "mouseout"
3255 }, function( orig, fix ) {
3256 jQuery.event.special[ orig ] = {
3257 setup: function( data ) {
3258 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3260 teardown: function( data ) {
3261 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3266 // submit delegation
3267 if ( !jQuery.support.submitBubbles ) {
3269 jQuery.event.special.submit = {
3270 setup: function( data, namespaces ) {
3271 if ( !jQuery.nodeName( this, "form" ) ) {
3272 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3273 var elem = e.target,
3274 type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3276 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3277 trigger( "submit", this, arguments );
3281 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3282 var elem = e.target,
3283 type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3285 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3286 trigger( "submit", this, arguments );
3295 teardown: function( namespaces ) {
3296 jQuery.event.remove( this, ".specialSubmit" );
3302 // change delegation, happens here so we have bind.
3303 if ( !jQuery.support.changeBubbles ) {
3307 getVal = function( elem ) {
3308 var type = jQuery.nodeName( elem, "input" ) ? elem.type : "",
3311 if ( type === "radio" || type === "checkbox" ) {
3314 } else if ( type === "select-multiple" ) {
3315 val = elem.selectedIndex > -1 ?
3316 jQuery.map( elem.options, function( elem ) {
3317 return elem.selected;
3321 } else if ( jQuery.nodeName( elem, "select" ) ) {
3322 val = elem.selectedIndex;
3328 testChange = function testChange( e ) {
3329 var elem = e.target, data, val;
3331 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3335 data = jQuery._data( elem, "_change_data" );
3338 // the current data will be also retrieved by beforeactivate
3339 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3340 jQuery._data( elem, "_change_data", val );
3343 if ( data === undefined || val === data ) {
3347 if ( data != null || val ) {
3349 e.liveFired = undefined;
3350 jQuery.event.trigger( e, arguments[1], elem );
3354 jQuery.event.special.change = {
3356 focusout: testChange,
3358 beforedeactivate: testChange,
3360 click: function( e ) {
3361 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3363 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3364 testChange.call( this, e );
3368 // Change has to be called before submit
3369 // Keydown will be called before keypress, which is used in submit-event delegation
3370 keydown: function( e ) {
3371 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3373 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3374 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3375 type === "select-multiple" ) {
3376 testChange.call( this, e );
3380 // Beforeactivate happens also before the previous element is blurred
3381 // with this event you can't trigger a change event, but you can store
3383 beforeactivate: function( e ) {
3384 var elem = e.target;
3385 jQuery._data( elem, "_change_data", getVal(elem) );
3389 setup: function( data, namespaces ) {
3390 if ( this.type === "file" ) {
3394 for ( var type in changeFilters ) {
3395 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3398 return rformElems.test( this.nodeName );
3401 teardown: function( namespaces ) {
3402 jQuery.event.remove( this, ".specialChange" );
3404 return rformElems.test( this.nodeName );
3408 changeFilters = jQuery.event.special.change.filters;
3410 // Handle when the input is .focus()'d
3411 changeFilters.focus = changeFilters.beforeactivate;
3414 function trigger( type, elem, args ) {
3415 // Piggyback on a donor event to simulate a different one.
3416 // Fake originalEvent to avoid donor's stopPropagation, but if the
3417 // simulated event prevents default then we do the same on the donor.
3418 // Don't pass args or remember liveFired; they apply to the donor event.
3419 var event = jQuery.extend( {}, args[ 0 ] );
3421 event.originalEvent = {};
3422 event.liveFired = undefined;
3423 jQuery.event.handle.call( elem, event );
3424 if ( event.isDefaultPrevented() ) {
3425 args[ 0 ].preventDefault();
3429 // Create "bubbling" focus and blur events
3430 if ( !jQuery.support.focusinBubbles ) {
3431 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3433 // Attach a single capturing handler while someone wants focusin/focusout
3436 jQuery.event.special[ fix ] = {
3438 if ( attaches++ === 0 ) {
3439 document.addEventListener( orig, handler, true );
3442 teardown: function() {
3443 if ( --attaches === 0 ) {
3444 document.removeEventListener( orig, handler, true );
3449 function handler( donor ) {
3450 // Donor event is always a native one; fix it and switch its type.
3451 // Let focusin/out handler cancel the donor focus/blur event.
3452 var e = jQuery.event.fix( donor );
3454 e.originalEvent = {};
3455 jQuery.event.trigger( e, null, e.target );
3456 if ( e.isDefaultPrevented() ) {
3457 donor.preventDefault();
3463 jQuery.each(["bind", "one"], function( i, name ) {
3464 jQuery.fn[ name ] = function( type, data, fn ) {
3467 // Handle object literals
3468 if ( typeof type === "object" ) {
3469 for ( var key in type ) {
3470 this[ name ](key, data, type[key], fn);
3475 if ( arguments.length === 2 || data === false ) {
3480 if ( name === "one" ) {
3481 handler = function( event ) {
3482 jQuery( this ).unbind( event, handler );
3483 return fn.apply( this, arguments );
3485 handler.guid = fn.guid || jQuery.guid++;
3490 if ( type === "unload" && name !== "one" ) {
3491 this.one( type, data, fn );
3494 for ( var i = 0, l = this.length; i < l; i++ ) {
3495 jQuery.event.add( this[i], type, handler, data );
3504 unbind: function( type, fn ) {
3505 // Handle object literals
3506 if ( typeof type === "object" && !type.preventDefault ) {
3507 for ( var key in type ) {
3508 this.unbind(key, type[key]);
3512 for ( var i = 0, l = this.length; i < l; i++ ) {
3513 jQuery.event.remove( this[i], type, fn );
3520 delegate: function( selector, types, data, fn ) {
3521 return this.live( types, data, fn, selector );
3524 undelegate: function( selector, types, fn ) {
3525 if ( arguments.length === 0 ) {
3526 return this.unbind( "live" );
3529 return this.die( types, null, fn, selector );
3533 trigger: function( type, data ) {
3534 return this.each(function() {
3535 jQuery.event.trigger( type, data, this );
3539 triggerHandler: function( type, data ) {
3541 return jQuery.event.trigger( type, data, this[0], true );
3545 toggle: function( fn ) {
3546 // Save reference to arguments for access in closure
3547 var args = arguments,
3548 guid = fn.guid || jQuery.guid++,
3550 toggler = function( event ) {
3551 // Figure out which function to execute
3552 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3553 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3555 // Make sure that clicks stop
3556 event.preventDefault();
3558 // and execute the function
3559 return args[ lastToggle ].apply( this, arguments ) || false;
3562 // link all the functions, so any of them can unbind this click handler
3563 toggler.guid = guid;
3564 while ( i < args.length ) {
3565 args[ i++ ].guid = guid;
3568 return this.click( toggler );
3571 hover: function( fnOver, fnOut ) {
3572 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3579 mouseenter: "mouseover",
3580 mouseleave: "mouseout"
3583 jQuery.each(["live", "die"], function( i, name ) {
3584 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3585 var type, i = 0, match, namespaces, preType,
3586 selector = origSelector || this.selector,
3587 context = origSelector ? this : jQuery( this.context );
3589 if ( typeof types === "object" && !types.preventDefault ) {
3590 for ( var key in types ) {
3591 context[ name ]( key, data, types[key], selector );
3597 if ( name === "die" && !types &&
3598 origSelector && origSelector.charAt(0) === "." ) {
3600 context.unbind( origSelector );
3605 if ( data === false || jQuery.isFunction( data ) ) {
3606 fn = data || returnFalse;
3610 types = (types || "").split(" ");
3612 while ( (type = types[ i++ ]) != null ) {
3613 match = rnamespaces.exec( type );
3617 namespaces = match[0];
3618 type = type.replace( rnamespaces, "" );
3621 if ( type === "hover" ) {
3622 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3628 if ( liveMap[ type ] ) {
3629 types.push( liveMap[ type ] + namespaces );
3630 type = type + namespaces;
3633 type = (liveMap[ type ] || type) + namespaces;
3636 if ( name === "live" ) {
3637 // bind live handler
3638 for ( var j = 0, l = context.length; j < l; j++ ) {
3639 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3640 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3644 // unbind live handler
3645 context.unbind( "live." + liveConvert( type, selector ), fn );
3653 function liveHandler( event ) {
3654 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3657 events = jQuery._data( this, "events" );
3659 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3660 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3664 if ( event.namespace ) {
3665 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3668 event.liveFired = this;
3670 var live = events.live.slice(0);
3672 for ( j = 0; j < live.length; j++ ) {
3673 handleObj = live[j];
3675 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3676 selectors.push( handleObj.selector );
3679 live.splice( j--, 1 );
3683 match = jQuery( event.target ).closest( selectors, event.currentTarget );
3685 for ( i = 0, l = match.length; i < l; i++ ) {
3688 for ( j = 0; j < live.length; j++ ) {
3689 handleObj = live[j];
3691 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3695 // Those two events require additional checking
3696 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3697 event.type = handleObj.preType;
3698 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3700 // Make sure not to accidentally match a child element with the same selector
3701 if ( related && jQuery.contains( elem, related ) ) {
3706 if ( !related || related !== elem ) {
3707 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3713 for ( i = 0, l = elems.length; i < l; i++ ) {
3716 if ( maxLevel && match.level > maxLevel ) {
3720 event.currentTarget = match.elem;
3721 event.data = match.handleObj.data;
3722 event.handleObj = match.handleObj;
3724 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3726 if ( ret === false || event.isPropagationStopped() ) {
3727 maxLevel = match.level;
3729 if ( ret === false ) {
3732 if ( event.isImmediatePropagationStopped() ) {
3741 function liveConvert( type, selector ) {
3742 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3745 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3746 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3747 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3749 // Handle event binding
3750 jQuery.fn[ name ] = function( data, fn ) {
3756 return arguments.length > 0 ?
3757 this.bind( name, data, fn ) :
3758 this.trigger( name );
3761 if ( jQuery.attrFn ) {
3762 jQuery.attrFn[ name ] = true;
3769 * Sizzle CSS Selector Engine
3770 * Copyright 2011, The Dojo Foundation
3771 * Released under the MIT, BSD, and GPL Licenses.
3772 * More information: http://sizzlejs.com/
3776 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3778 toString = Object.prototype.toString,
3779 hasDuplicate = false,
3780 baseHasDuplicate = true,
3784 // Here we check if the JavaScript engine is using some sort of
3785 // optimization where it does not always call our comparision
3786 // function. If that is the case, discard the hasDuplicate value.
3787 // Thus far that includes Google Chrome.
3788 [0, 0].sort(function() {
3789 baseHasDuplicate = false;
3793 var Sizzle = function( selector, context, results, seed ) {
3794 results = results || [];
3795 context = context || document;
3797 var origContext = context;
3799 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3803 if ( !selector || typeof selector !== "string" ) {
3807 var m, set, checkSet, extra, ret, cur, pop, i,
3809 contextXML = Sizzle.isXML( context ),
3813 // Reset the position of the chunker regexp (start from head)
3816 m = chunker.exec( soFar );
3830 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3832 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3833 set = posProcess( parts[0] + parts[1], context );
3836 set = Expr.relative[ parts[0] ] ?
3838 Sizzle( parts.shift(), context );
3840 while ( parts.length ) {
3841 selector = parts.shift();
3843 if ( Expr.relative[ selector ] ) {
3844 selector += parts.shift();
3847 set = posProcess( selector, set );
3852 // Take a shortcut and set the context if the root selector is an ID
3853 // (but not if it'll be faster if the inner selector is an ID)
3854 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3855 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3857 ret = Sizzle.find( parts.shift(), context, contextXML );
3858 context = ret.expr ?
3859 Sizzle.filter( ret.expr, ret.set )[0] :
3865 { expr: parts.pop(), set: makeArray(seed) } :
3866 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3869 Sizzle.filter( ret.expr, ret.set ) :
3872 if ( parts.length > 0 ) {
3873 checkSet = makeArray( set );
3879 while ( parts.length ) {
3883 if ( !Expr.relative[ cur ] ) {
3889 if ( pop == null ) {
3893 Expr.relative[ cur ]( checkSet, pop, contextXML );
3897 checkSet = parts = [];
3906 Sizzle.error( cur || selector );
3909 if ( toString.call(checkSet) === "[object Array]" ) {
3911 results.push.apply( results, checkSet );
3913 } else if ( context && context.nodeType === 1 ) {
3914 for ( i = 0; checkSet[i] != null; i++ ) {
3915 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3916 results.push( set[i] );
3921 for ( i = 0; checkSet[i] != null; i++ ) {
3922 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3923 results.push( set[i] );
3929 makeArray( checkSet, results );
3933 Sizzle( extra, origContext, results, seed );
3934 Sizzle.uniqueSort( results );
3940 Sizzle.uniqueSort = function( results ) {
3942 hasDuplicate = baseHasDuplicate;
3943 results.sort( sortOrder );
3945 if ( hasDuplicate ) {
3946 for ( var i = 1; i < results.length; i++ ) {
3947 if ( results[i] === results[ i - 1 ] ) {
3948 results.splice( i--, 1 );
3957 Sizzle.matches = function( expr, set ) {
3958 return Sizzle( expr, null, null, set );
3961 Sizzle.matchesSelector = function( node, expr ) {
3962 return Sizzle( expr, null, null, [node] ).length > 0;
3965 Sizzle.find = function( expr, context, isXML ) {
3972 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3974 type = Expr.order[i];
3976 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3977 var left = match[1];
3978 match.splice( 1, 1 );
3980 if ( left.substr( left.length - 1 ) !== "\\" ) {
3981 match[1] = (match[1] || "").replace( rBackslash, "" );
3982 set = Expr.find[ type ]( match, context, isXML );
3984 if ( set != null ) {
3985 expr = expr.replace( Expr.match[ type ], "" );
3993 set = typeof context.getElementsByTagName !== "undefined" ?
3994 context.getElementsByTagName( "*" ) :
3998 return { set: set, expr: expr };
4001 Sizzle.filter = function( expr, set, inplace, not ) {
4002 var match, anyFound,
4006 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4008 while ( expr && set.length ) {
4009 for ( var type in Expr.filter ) {
4010 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4012 filter = Expr.filter[ type ],
4019 if ( left.substr( left.length - 1 ) === "\\" ) {
4023 if ( curLoop === result ) {
4027 if ( Expr.preFilter[ type ] ) {
4028 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4031 anyFound = found = true;
4033 } else if ( match === true ) {
4039 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4041 found = filter( item, match, i, curLoop );
4042 var pass = not ^ !!found;
4044 if ( inplace && found != null ) {
4052 } else if ( pass ) {
4053 result.push( item );
4060 if ( found !== undefined ) {
4065 expr = expr.replace( Expr.match[ type ], "" );
4076 // Improper expression
4077 if ( expr === old ) {
4078 if ( anyFound == null ) {
4079 Sizzle.error( expr );
4092 Sizzle.error = function( msg ) {
4093 throw "Syntax error, unrecognized expression: " + msg;
4096 var Expr = Sizzle.selectors = {
4097 order: [ "ID", "NAME", "TAG" ],
4100 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4101 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4102 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4103 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4104 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4105 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4106 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4107 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4113 "class": "className",
4118 href: function( elem ) {
4119 return elem.getAttribute( "href" );
4121 type: function( elem ) {
4122 return elem.getAttribute( "type" );
4127 "+": function(checkSet, part){
4128 var isPartStr = typeof part === "string",
4129 isTag = isPartStr && !rNonWord.test( part ),
4130 isPartStrNotTag = isPartStr && !isTag;
4133 part = part.toLowerCase();
4136 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4137 if ( (elem = checkSet[i]) ) {
4138 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4140 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4146 if ( isPartStrNotTag ) {
4147 Sizzle.filter( part, checkSet, true );
4151 ">": function( checkSet, part ) {
4153 isPartStr = typeof part === "string",
4155 l = checkSet.length;
4157 if ( isPartStr && !rNonWord.test( part ) ) {
4158 part = part.toLowerCase();
4160 for ( ; i < l; i++ ) {
4164 var parent = elem.parentNode;
4165 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4170 for ( ; i < l; i++ ) {
4174 checkSet[i] = isPartStr ?
4176 elem.parentNode === part;
4181 Sizzle.filter( part, checkSet, true );
4186 "": function(checkSet, part, isXML){
4191 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4192 part = part.toLowerCase();
4194 checkFn = dirNodeCheck;
4197 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4200 "~": function( checkSet, part, isXML ) {
4205 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4206 part = part.toLowerCase();
4208 checkFn = dirNodeCheck;
4211 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4216 ID: function( match, context, isXML ) {
4217 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4218 var m = context.getElementById(match[1]);
4219 // Check parentNode to catch when Blackberry 4.6 returns
4220 // nodes that are no longer in the document #6963
4221 return m && m.parentNode ? [m] : [];
4225 NAME: function( match, context ) {
4226 if ( typeof context.getElementsByName !== "undefined" ) {
4228 results = context.getElementsByName( match[1] );
4230 for ( var i = 0, l = results.length; i < l; i++ ) {
4231 if ( results[i].getAttribute("name") === match[1] ) {
4232 ret.push( results[i] );
4236 return ret.length === 0 ? null : ret;
4240 TAG: function( match, context ) {
4241 if ( typeof context.getElementsByTagName !== "undefined" ) {
4242 return context.getElementsByTagName( match[1] );
4247 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4248 match = " " + match[1].replace( rBackslash, "" ) + " ";
4254 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4256 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4258 result.push( elem );
4261 } else if ( inplace ) {
4270 ID: function( match ) {
4271 return match[1].replace( rBackslash, "" );
4274 TAG: function( match, curLoop ) {
4275 return match[1].replace( rBackslash, "" ).toLowerCase();
4278 CHILD: function( match ) {
4279 if ( match[1] === "nth" ) {
4281 Sizzle.error( match[0] );
4284 match[2] = match[2].replace(/^\+|\s*/g, '');
4286 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4287 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4288 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4289 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4291 // calculate the numbers (first)n+(last) including if they are negative
4292 match[2] = (test[1] + (test[2] || 1)) - 0;
4293 match[3] = test[3] - 0;
4295 else if ( match[2] ) {
4296 Sizzle.error( match[0] );
4299 // TODO: Move to normal caching system
4305 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4306 var name = match[1] = match[1].replace( rBackslash, "" );
4308 if ( !isXML && Expr.attrMap[name] ) {
4309 match[1] = Expr.attrMap[name];
4312 // Handle if an un-quoted value was used
4313 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4315 if ( match[2] === "~=" ) {
4316 match[4] = " " + match[4] + " ";
4322 PSEUDO: function( match, curLoop, inplace, result, not ) {
4323 if ( match[1] === "not" ) {
4324 // If we're dealing with a complex expression, or a simple one
4325 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4326 match[3] = Sizzle(match[3], null, null, curLoop);
4329 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4332 result.push.apply( result, ret );
4338 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4345 POS: function( match ) {
4346 match.unshift( true );
4353 enabled: function( elem ) {
4354 return elem.disabled === false && elem.type !== "hidden";
4357 disabled: function( elem ) {
4358 return elem.disabled === true;
4361 checked: function( elem ) {
4362 return elem.checked === true;
4365 selected: function( elem ) {
4366 // Accessing this property makes selected-by-default
4367 // options in Safari work properly
4368 if ( elem.parentNode ) {
4369 elem.parentNode.selectedIndex;
4372 return elem.selected === true;
4375 parent: function( elem ) {
4376 return !!elem.firstChild;
4379 empty: function( elem ) {
4380 return !elem.firstChild;
4383 has: function( elem, i, match ) {
4384 return !!Sizzle( match[3], elem ).length;
4387 header: function( elem ) {
4388 return (/h\d/i).test( elem.nodeName );
4391 text: function( elem ) {
4392 var attr = elem.getAttribute( "type" ), type = elem.type;
4393 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4394 // use getAttribute instead to test this case
4395 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4398 radio: function( elem ) {
4399 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4402 checkbox: function( elem ) {
4403 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4406 file: function( elem ) {
4407 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4410 password: function( elem ) {
4411 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4414 submit: function( elem ) {
4415 var name = elem.nodeName.toLowerCase();
4416 return (name === "input" || name === "button") && "submit" === elem.type;
4419 image: function( elem ) {
4420 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4423 reset: function( elem ) {
4424 var name = elem.nodeName.toLowerCase();
4425 return (name === "input" || name === "button") && "reset" === elem.type;
4428 button: function( elem ) {
4429 var name = elem.nodeName.toLowerCase();
4430 return name === "input" && "button" === elem.type || name === "button";
4433 input: function( elem ) {
4434 return (/input|select|textarea|button/i).test( elem.nodeName );
4437 focus: function( elem ) {
4438 return elem === elem.ownerDocument.activeElement;
4442 first: function( elem, i ) {
4446 last: function( elem, i, match, array ) {
4447 return i === array.length - 1;
4450 even: function( elem, i ) {
4454 odd: function( elem, i ) {
4458 lt: function( elem, i, match ) {
4459 return i < match[3] - 0;
4462 gt: function( elem, i, match ) {
4463 return i > match[3] - 0;
4466 nth: function( elem, i, match ) {
4467 return match[3] - 0 === i;
4470 eq: function( elem, i, match ) {
4471 return match[3] - 0 === i;
4475 PSEUDO: function( elem, match, i, array ) {
4476 var name = match[1],
4477 filter = Expr.filters[ name ];
4480 return filter( elem, i, match, array );
4482 } else if ( name === "contains" ) {
4483 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4485 } else if ( name === "not" ) {
4488 for ( var j = 0, l = not.length; j < l; j++ ) {
4489 if ( not[j] === elem ) {
4497 Sizzle.error( name );
4501 CHILD: function( elem, match ) {
4502 var type = match[1],
4508 while ( (node = node.previousSibling) ) {
4509 if ( node.nodeType === 1 ) {
4514 if ( type === "first" ) {
4521 while ( (node = node.nextSibling) ) {
4522 if ( node.nodeType === 1 ) {
4530 var first = match[2],
4533 if ( first === 1 && last === 0 ) {
4537 var doneName = match[0],
4538 parent = elem.parentNode;
4540 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4543 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4544 if ( node.nodeType === 1 ) {
4545 node.nodeIndex = ++count;
4549 parent.sizcache = doneName;
4552 var diff = elem.nodeIndex - last;
4554 if ( first === 0 ) {
4558 return ( diff % first === 0 && diff / first >= 0 );
4563 ID: function( elem, match ) {
4564 return elem.nodeType === 1 && elem.getAttribute("id") === match;
4567 TAG: function( elem, match ) {
4568 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4571 CLASS: function( elem, match ) {
4572 return (" " + (elem.className || elem.getAttribute("class")) + " ")
4573 .indexOf( match ) > -1;
4576 ATTR: function( elem, match ) {
4577 var name = match[1],
4578 result = Expr.attrHandle[ name ] ?
4579 Expr.attrHandle[ name ]( elem ) :
4580 elem[ name ] != null ?
4582 elem.getAttribute( name ),
4583 value = result + "",
4587 return result == null ?
4592 value.indexOf(check) >= 0 :
4594 (" " + value + " ").indexOf(check) >= 0 :
4596 value && result !== false :
4600 value.indexOf(check) === 0 :
4602 value.substr(value.length - check.length) === check :
4604 value === check || value.substr(0, check.length + 1) === check + "-" :
4608 POS: function( elem, match, i, array ) {
4609 var name = match[2],
4610 filter = Expr.setFilters[ name ];
4613 return filter( elem, i, match, array );
4619 var origPOS = Expr.match.POS,
4620 fescape = function(all, num){
4621 return "\\" + (num - 0 + 1);
4624 for ( var type in Expr.match ) {
4625 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4626 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4629 var makeArray = function( array, results ) {
4630 array = Array.prototype.slice.call( array, 0 );
4633 results.push.apply( results, array );
4640 // Perform a simple check to determine if the browser is capable of
4641 // converting a NodeList to an array using builtin methods.
4642 // Also verifies that the returned array holds DOM nodes
4643 // (which is not the case in the Blackberry browser)
4645 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4647 // Provide a fallback method if it does not work
4649 makeArray = function( array, results ) {
4651 ret = results || [];
4653 if ( toString.call(array) === "[object Array]" ) {
4654 Array.prototype.push.apply( ret, array );
4657 if ( typeof array.length === "number" ) {
4658 for ( var l = array.length; i < l; i++ ) {
4659 ret.push( array[i] );
4663 for ( ; array[i]; i++ ) {
4664 ret.push( array[i] );
4673 var sortOrder, siblingCheck;
4675 if ( document.documentElement.compareDocumentPosition ) {
4676 sortOrder = function( a, b ) {
4678 hasDuplicate = true;
4682 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4683 return a.compareDocumentPosition ? -1 : 1;
4686 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4690 sortOrder = function( a, b ) {
4691 // The nodes are identical, we can exit early
4693 hasDuplicate = true;
4696 // Fallback to using sourceIndex (in IE) if it's available on both nodes
4697 } else if ( a.sourceIndex && b.sourceIndex ) {
4698 return a.sourceIndex - b.sourceIndex;
4708 // If the nodes are siblings (or identical) we can do a quick check
4709 if ( aup === bup ) {
4710 return siblingCheck( a, b );
4712 // If no parents were found then the nodes are disconnected
4713 } else if ( !aup ) {
4716 } else if ( !bup ) {
4720 // Otherwise they're somewhere else in the tree so we need
4721 // to build up a full list of the parentNodes for comparison
4724 cur = cur.parentNode;
4731 cur = cur.parentNode;
4737 // Start walking down the tree looking for a discrepancy
4738 for ( var i = 0; i < al && i < bl; i++ ) {
4739 if ( ap[i] !== bp[i] ) {
4740 return siblingCheck( ap[i], bp[i] );
4744 // We ended someplace up the tree so do a sibling check
4746 siblingCheck( a, bp[i], -1 ) :
4747 siblingCheck( ap[i], b, 1 );
4750 siblingCheck = function( a, b, ret ) {
4755 var cur = a.nextSibling;
4762 cur = cur.nextSibling;
4769 // Utility function for retreiving the text value of an array of DOM nodes
4770 Sizzle.getText = function( elems ) {
4773 for ( var i = 0; elems[i]; i++ ) {
4776 // Get the text from text nodes and CDATA nodes
4777 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4778 ret += elem.nodeValue;
4780 // Traverse everything else, except comment nodes
4781 } else if ( elem.nodeType !== 8 ) {
4782 ret += Sizzle.getText( elem.childNodes );
4789 // Check to see if the browser returns elements by name when
4790 // querying by getElementById (and provide a workaround)
4792 // We're going to inject a fake input element with a specified name
4793 var form = document.createElement("div"),
4794 id = "script" + (new Date()).getTime(),
4795 root = document.documentElement;
4797 form.innerHTML = "<a name='" + id + "'/>";
4799 // Inject it into the root element, check its status, and remove it quickly
4800 root.insertBefore( form, root.firstChild );
4802 // The workaround has to do additional checks after a getElementById
4803 // Which slows things down for other browsers (hence the branching)
4804 if ( document.getElementById( id ) ) {
4805 Expr.find.ID = function( match, context, isXML ) {
4806 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4807 var m = context.getElementById(match[1]);
4810 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4817 Expr.filter.ID = function( elem, match ) {
4818 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4820 return elem.nodeType === 1 && node && node.nodeValue === match;
4824 root.removeChild( form );
4826 // release memory in IE
4831 // Check to see if the browser returns only elements
4832 // when doing getElementsByTagName("*")
4834 // Create a fake element
4835 var div = document.createElement("div");
4836 div.appendChild( document.createComment("") );
4838 // Make sure no comments are found
4839 if ( div.getElementsByTagName("*").length > 0 ) {
4840 Expr.find.TAG = function( match, context ) {
4841 var results = context.getElementsByTagName( match[1] );
4843 // Filter out possible comments
4844 if ( match[1] === "*" ) {
4847 for ( var i = 0; results[i]; i++ ) {
4848 if ( results[i].nodeType === 1 ) {
4849 tmp.push( results[i] );
4860 // Check to see if an attribute returns normalized href attributes
4861 div.innerHTML = "<a href='#'></a>";
4863 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4864 div.firstChild.getAttribute("href") !== "#" ) {
4866 Expr.attrHandle.href = function( elem ) {
4867 return elem.getAttribute( "href", 2 );
4871 // release memory in IE
4875 if ( document.querySelectorAll ) {
4877 var oldSizzle = Sizzle,
4878 div = document.createElement("div"),
4881 div.innerHTML = "<p class='TEST'></p>";
4883 // Safari can't handle uppercase or unicode characters when
4885 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4889 Sizzle = function( query, context, extra, seed ) {
4890 context = context || document;
4892 // Only use querySelectorAll on non-XML documents
4893 // (ID selectors don't work in non-HTML documents)
4894 if ( !seed && !Sizzle.isXML(context) ) {
4895 // See if we find a selector to speed up
4896 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4898 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4899 // Speed-up: Sizzle("TAG")
4901 return makeArray( context.getElementsByTagName( query ), extra );
4903 // Speed-up: Sizzle(".CLASS")
4904 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4905 return makeArray( context.getElementsByClassName( match[2] ), extra );
4909 if ( context.nodeType === 9 ) {
4910 // Speed-up: Sizzle("body")
4911 // The body element only exists once, optimize finding it
4912 if ( query === "body" && context.body ) {
4913 return makeArray( [ context.body ], extra );
4915 // Speed-up: Sizzle("#ID")
4916 } else if ( match && match[3] ) {
4917 var elem = context.getElementById( match[3] );
4919 // Check parentNode to catch when Blackberry 4.6 returns
4920 // nodes that are no longer in the document #6963
4921 if ( elem && elem.parentNode ) {
4922 // Handle the case where IE and Opera return items
4923 // by name instead of ID
4924 if ( elem.id === match[3] ) {
4925 return makeArray( [ elem ], extra );
4929 return makeArray( [], extra );
4934 return makeArray( context.querySelectorAll(query), extra );
4935 } catch(qsaError) {}
4937 // qSA works strangely on Element-rooted queries
4938 // We can work around this by specifying an extra ID on the root
4939 // and working up from there (Thanks to Andrew Dupont for the technique)
4940 // IE 8 doesn't work on object elements
4941 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4942 var oldContext = context,
4943 old = context.getAttribute( "id" ),
4945 hasParent = context.parentNode,
4946 relativeHierarchySelector = /^\s*[+~]/.test( query );
4949 context.setAttribute( "id", nid );
4951 nid = nid.replace( /'/g, "\\$&" );
4953 if ( relativeHierarchySelector && hasParent ) {
4954 context = context.parentNode;
4958 if ( !relativeHierarchySelector || hasParent ) {
4959 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4962 } catch(pseudoError) {
4965 oldContext.removeAttribute( "id" );
4971 return oldSizzle(query, context, extra, seed);
4974 for ( var prop in oldSizzle ) {
4975 Sizzle[ prop ] = oldSizzle[ prop ];
4978 // release memory in IE
4984 var html = document.documentElement,
4985 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
4988 // Check to see if it's possible to do matchesSelector
4989 // on a disconnected node (IE 9 fails this)
4990 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
4991 pseudoWorks = false;
4994 // This should fail with an exception
4995 // Gecko does not error, returns false instead
4996 matches.call( document.documentElement, "[test!='']:sizzle" );
4998 } catch( pseudoError ) {
5002 Sizzle.matchesSelector = function( node, expr ) {
5003 // Make sure that attribute selectors are quoted
5004 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5006 if ( !Sizzle.isXML( node ) ) {
5008 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5009 var ret = matches.call( node, expr );
5011 // IE 9's matchesSelector returns false on disconnected nodes
5012 if ( ret || !disconnectedMatch ||
5013 // As well, disconnected nodes are said to be in a document
5014 // fragment in IE 9, so check for that
5015 node.document && node.document.nodeType !== 11 ) {
5022 return Sizzle(expr, null, null, [node]).length > 0;
5028 var div = document.createElement("div");
5030 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5032 // Opera can't find a second classname (in 9.6)
5033 // Also, make sure that getElementsByClassName actually exists
5034 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5038 // Safari caches class attributes, doesn't catch changes (in 3.2)
5039 div.lastChild.className = "e";
5041 if ( div.getElementsByClassName("e").length === 1 ) {
5045 Expr.order.splice(1, 0, "CLASS");
5046 Expr.find.CLASS = function( match, context, isXML ) {
5047 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5048 return context.getElementsByClassName(match[1]);
5052 // release memory in IE
5056 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5057 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5058 var elem = checkSet[i];
5066 if ( elem.sizcache === doneName ) {
5067 match = checkSet[elem.sizset];
5071 if ( elem.nodeType === 1 && !isXML ){
5072 elem.sizcache = doneName;
5076 if ( elem.nodeName.toLowerCase() === cur ) {
5084 checkSet[i] = match;
5089 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5090 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5091 var elem = checkSet[i];
5099 if ( elem.sizcache === doneName ) {
5100 match = checkSet[elem.sizset];
5104 if ( elem.nodeType === 1 ) {
5106 elem.sizcache = doneName;
5110 if ( typeof cur !== "string" ) {
5111 if ( elem === cur ) {
5116 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5125 checkSet[i] = match;
5130 if ( document.documentElement.contains ) {
5131 Sizzle.contains = function( a, b ) {
5132 return a !== b && (a.contains ? a.contains(b) : true);
5135 } else if ( document.documentElement.compareDocumentPosition ) {
5136 Sizzle.contains = function( a, b ) {
5137 return !!(a.compareDocumentPosition(b) & 16);
5141 Sizzle.contains = function() {
5146 Sizzle.isXML = function( elem ) {
5147 // documentElement is verified for cases where it doesn't yet exist
5148 // (such as loading iframes in IE - #4833)
5149 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5151 return documentElement ? documentElement.nodeName !== "HTML" : false;
5154 var posProcess = function( selector, context ) {
5158 root = context.nodeType ? [context] : context;
5160 // Position selectors must be done after the filter
5161 // And so must :not(positional) so we move all PSEUDOs to the end
5162 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5164 selector = selector.replace( Expr.match.PSEUDO, "" );
5167 selector = Expr.relative[selector] ? selector + "*" : selector;
5169 for ( var i = 0, l = root.length; i < l; i++ ) {
5170 Sizzle( selector, root[i], tmpSet );
5173 return Sizzle.filter( later, tmpSet );
5177 jQuery.find = Sizzle;
5178 jQuery.expr = Sizzle.selectors;
5179 jQuery.expr[":"] = jQuery.expr.filters;
5180 jQuery.unique = Sizzle.uniqueSort;
5181 jQuery.text = Sizzle.getText;
5182 jQuery.isXMLDoc = Sizzle.isXML;
5183 jQuery.contains = Sizzle.contains;
5189 var runtil = /Until$/,
5190 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5191 // Note: This RegExp should be improved, or likely pulled from Sizzle
5192 rmultiselector = /,/,
5193 isSimple = /^.[^:#\[\.,]*$/,
5194 slice = Array.prototype.slice,
5195 POS = jQuery.expr.match.POS,
5196 // methods guaranteed to produce a unique set when starting from a unique set
5197 guaranteedUnique = {
5205 find: function( selector ) {
5209 if ( typeof selector !== "string" ) {
5210 return jQuery( selector ).filter(function() {
5211 for ( i = 0, l = self.length; i < l; i++ ) {
5212 if ( jQuery.contains( self[ i ], this ) ) {
5219 var ret = this.pushStack( "", "find", selector ),
5222 for ( i = 0, l = this.length; i < l; i++ ) {
5223 length = ret.length;
5224 jQuery.find( selector, this[i], ret );
5227 // Make sure that the results are unique
5228 for ( n = length; n < ret.length; n++ ) {
5229 for ( r = 0; r < length; r++ ) {
5230 if ( ret[r] === ret[n] ) {
5242 has: function( target ) {
5243 var targets = jQuery( target );
5244 return this.filter(function() {
5245 for ( var i = 0, l = targets.length; i < l; i++ ) {
5246 if ( jQuery.contains( this, targets[i] ) ) {
5253 not: function( selector ) {
5254 return this.pushStack( winnow(this, selector, false), "not", selector);
5257 filter: function( selector ) {
5258 return this.pushStack( winnow(this, selector, true), "filter", selector );
5261 is: function( selector ) {
5262 return !!selector && ( typeof selector === "string" ?
5263 jQuery.filter( selector, this ).length > 0 :
5264 this.filter( selector ).length > 0 );
5267 closest: function( selectors, context ) {
5268 var ret = [], i, l, cur = this[0];
5271 if ( jQuery.isArray( selectors ) ) {
5272 var match, selector,
5276 if ( cur && selectors.length ) {
5277 for ( i = 0, l = selectors.length; i < l; i++ ) {
5278 selector = selectors[i];
5280 if ( !matches[ selector ] ) {
5281 matches[ selector ] = POS.test( selector ) ?
5282 jQuery( selector, context || this.context ) :
5287 while ( cur && cur.ownerDocument && cur !== context ) {
5288 for ( selector in matches ) {
5289 match = matches[ selector ];
5291 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5292 ret.push({ selector: selector, elem: cur, level: level });
5296 cur = cur.parentNode;
5305 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5306 jQuery( selectors, context || this.context ) :
5309 for ( i = 0, l = this.length; i < l; i++ ) {
5313 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5318 cur = cur.parentNode;
5319 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5326 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5328 return this.pushStack( ret, "closest", selectors );
5331 // Determine the position of an element within
5332 // the matched set of elements
5333 index: function( elem ) {
5335 // No argument, return index in parent
5337 return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5340 // index in selector
5341 if ( typeof elem === "string" ) {
5342 return jQuery.inArray( this[0], jQuery( elem ) );
5345 // Locate the position of the desired element
5346 return jQuery.inArray(
5347 // If it receives a jQuery object, the first element is used
5348 elem.jquery ? elem[0] : elem, this );
5351 add: function( selector, context ) {
5352 var set = typeof selector === "string" ?
5353 jQuery( selector, context ) :
5354 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5355 all = jQuery.merge( this.get(), set );
5357 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5359 jQuery.unique( all ) );
5362 andSelf: function() {
5363 return this.add( this.prevObject );
5367 // A painfully simple check to see if an element is disconnected
5368 // from a document (should be improved, where feasible).
5369 function isDisconnected( node ) {
5370 return !node || !node.parentNode || node.parentNode.nodeType === 11;
5374 parent: function( elem ) {
5375 var parent = elem.parentNode;
5376 return parent && parent.nodeType !== 11 ? parent : null;
5378 parents: function( elem ) {
5379 return jQuery.dir( elem, "parentNode" );
5381 parentsUntil: function( elem, i, until ) {
5382 return jQuery.dir( elem, "parentNode", until );
5384 next: function( elem ) {
5385 return jQuery.nth( elem, 2, "nextSibling" );
5387 prev: function( elem ) {
5388 return jQuery.nth( elem, 2, "previousSibling" );
5390 nextAll: function( elem ) {
5391 return jQuery.dir( elem, "nextSibling" );
5393 prevAll: function( elem ) {
5394 return jQuery.dir( elem, "previousSibling" );
5396 nextUntil: function( elem, i, until ) {
5397 return jQuery.dir( elem, "nextSibling", until );
5399 prevUntil: function( elem, i, until ) {
5400 return jQuery.dir( elem, "previousSibling", until );
5402 siblings: function( elem ) {
5403 return jQuery.sibling( elem.parentNode.firstChild, elem );
5405 children: function( elem ) {
5406 return jQuery.sibling( elem.firstChild );
5408 contents: function( elem ) {
5409 return jQuery.nodeName( elem, "iframe" ) ?
5410 elem.contentDocument || elem.contentWindow.document :
5411 jQuery.makeArray( elem.childNodes );
5413 }, function( name, fn ) {
5414 jQuery.fn[ name ] = function( until, selector ) {
5415 var ret = jQuery.map( this, fn, until ),
5416 // The variable 'args' was introduced in
5417 // https://github.com/jquery/jquery/commit/52a0238
5418 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5419 // http://code.google.com/p/v8/issues/detail?id=1050
5420 args = slice.call(arguments);
5422 if ( !runtil.test( name ) ) {
5426 if ( selector && typeof selector === "string" ) {
5427 ret = jQuery.filter( selector, ret );
5430 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5432 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5433 ret = ret.reverse();
5436 return this.pushStack( ret, name, args.join(",") );
5441 filter: function( expr, elems, not ) {
5443 expr = ":not(" + expr + ")";
5446 return elems.length === 1 ?
5447 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5448 jQuery.find.matches(expr, elems);
5451 dir: function( elem, dir, until ) {
5455 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5456 if ( cur.nodeType === 1 ) {
5457 matched.push( cur );
5464 nth: function( cur, result, dir, elem ) {
5465 result = result || 1;
5468 for ( ; cur; cur = cur[dir] ) {
5469 if ( cur.nodeType === 1 && ++num === result ) {
5477 sibling: function( n, elem ) {
5480 for ( ; n; n = n.nextSibling ) {
5481 if ( n.nodeType === 1 && n !== elem ) {
5490 // Implement the identical functionality for filter and not
5491 function winnow( elements, qualifier, keep ) {
5493 // Can't pass null or undefined to indexOf in Firefox 4
5494 // Set to 0 to skip string check
5495 qualifier = qualifier || 0;
5497 if ( jQuery.isFunction( qualifier ) ) {
5498 return jQuery.grep(elements, function( elem, i ) {
5499 var retVal = !!qualifier.call( elem, i, elem );
5500 return retVal === keep;
5503 } else if ( qualifier.nodeType ) {
5504 return jQuery.grep(elements, function( elem, i ) {
5505 return (elem === qualifier) === keep;
5508 } else if ( typeof qualifier === "string" ) {
5509 var filtered = jQuery.grep(elements, function( elem ) {
5510 return elem.nodeType === 1;
5513 if ( isSimple.test( qualifier ) ) {
5514 return jQuery.filter(qualifier, filtered, !keep);
5516 qualifier = jQuery.filter( qualifier, filtered );
5520 return jQuery.grep(elements, function( elem, i ) {
5521 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5528 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5529 rleadingWhitespace = /^\s+/,
5530 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5531 rtagName = /<([\w:]+)/,
5533 rhtml = /<|&#?\w+;/,
5534 rnocache = /<(?:script|object|embed|option|style)/i,
5535 // checked="checked" or checked
5536 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5537 rscriptType = /\/(java|ecma)script/i,
5538 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5540 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5541 legend: [ 1, "<fieldset>", "</fieldset>" ],
5542 thead: [ 1, "<table>", "</table>" ],
5543 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5544 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5545 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5546 area: [ 1, "<map>", "</map>" ],
5547 _default: [ 0, "", "" ]
5550 wrapMap.optgroup = wrapMap.option;
5551 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5552 wrapMap.th = wrapMap.td;
5554 // IE can't serialize <link> and <script> tags normally
5555 if ( !jQuery.support.htmlSerialize ) {
5556 wrapMap._default = [ 1, "div<div>", "</div>" ];
5560 text: function( text ) {
5561 if ( jQuery.isFunction(text) ) {
5562 return this.each(function(i) {
5563 var self = jQuery( this );
5565 self.text( text.call(this, i, self.text()) );
5569 if ( typeof text !== "object" && text !== undefined ) {
5570 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5573 return jQuery.text( this );
5576 wrapAll: function( html ) {
5577 if ( jQuery.isFunction( html ) ) {
5578 return this.each(function(i) {
5579 jQuery(this).wrapAll( html.call(this, i) );
5584 // The elements to wrap the target around
5585 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5587 if ( this[0].parentNode ) {
5588 wrap.insertBefore( this[0] );
5591 wrap.map(function() {
5594 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5595 elem = elem.firstChild;
5605 wrapInner: function( html ) {
5606 if ( jQuery.isFunction( html ) ) {
5607 return this.each(function(i) {
5608 jQuery(this).wrapInner( html.call(this, i) );
5612 return this.each(function() {
5613 var self = jQuery( this ),
5614 contents = self.contents();
5616 if ( contents.length ) {
5617 contents.wrapAll( html );
5620 self.append( html );
5625 wrap: function( html ) {
5626 return this.each(function() {
5627 jQuery( this ).wrapAll( html );
5631 unwrap: function() {
5632 return this.parent().each(function() {
5633 if ( !jQuery.nodeName( this, "body" ) ) {
5634 jQuery( this ).replaceWith( this.childNodes );
5639 append: function() {
5640 return this.domManip(arguments, true, function( elem ) {
5641 if ( this.nodeType === 1 ) {
5642 this.appendChild( elem );
5647 prepend: function() {
5648 return this.domManip(arguments, true, function( elem ) {
5649 if ( this.nodeType === 1 ) {
5650 this.insertBefore( elem, this.firstChild );
5655 before: function() {
5656 if ( this[0] && this[0].parentNode ) {
5657 return this.domManip(arguments, false, function( elem ) {
5658 this.parentNode.insertBefore( elem, this );
5660 } else if ( arguments.length ) {
5661 var set = jQuery(arguments[0]);
5662 set.push.apply( set, this.toArray() );
5663 return this.pushStack( set, "before", arguments );
5668 if ( this[0] && this[0].parentNode ) {
5669 return this.domManip(arguments, false, function( elem ) {
5670 this.parentNode.insertBefore( elem, this.nextSibling );
5672 } else if ( arguments.length ) {
5673 var set = this.pushStack( this, "after", arguments );
5674 set.push.apply( set, jQuery(arguments[0]).toArray() );
5679 // keepData is for internal use only--do not document
5680 remove: function( selector, keepData ) {
5681 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5682 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5683 if ( !keepData && elem.nodeType === 1 ) {
5684 jQuery.cleanData( elem.getElementsByTagName("*") );
5685 jQuery.cleanData( [ elem ] );
5688 if ( elem.parentNode ) {
5689 elem.parentNode.removeChild( elem );
5698 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5699 // Remove element nodes and prevent memory leaks
5700 if ( elem.nodeType === 1 ) {
5701 jQuery.cleanData( elem.getElementsByTagName("*") );
5704 // Remove any remaining nodes
5705 while ( elem.firstChild ) {
5706 elem.removeChild( elem.firstChild );
5713 clone: function( dataAndEvents, deepDataAndEvents ) {
5714 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5715 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5717 return this.map( function () {
5718 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5722 html: function( value ) {
5723 if ( value === undefined ) {
5724 return this[0] && this[0].nodeType === 1 ?
5725 this[0].innerHTML.replace(rinlinejQuery, "") :
5728 // See if we can take a shortcut and just use innerHTML
5729 } else if ( typeof value === "string" && !rnocache.test( value ) &&
5730 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5731 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5733 value = value.replace(rxhtmlTag, "<$1></$2>");
5736 for ( var i = 0, l = this.length; i < l; i++ ) {
5737 // Remove element nodes and prevent memory leaks
5738 if ( this[i].nodeType === 1 ) {
5739 jQuery.cleanData( this[i].getElementsByTagName("*") );
5740 this[i].innerHTML = value;
5744 // If using innerHTML throws an exception, use the fallback method
5746 this.empty().append( value );
5749 } else if ( jQuery.isFunction( value ) ) {
5750 this.each(function(i){
5751 var self = jQuery( this );
5753 self.html( value.call(this, i, self.html()) );
5757 this.empty().append( value );
5763 replaceWith: function( value ) {
5764 if ( this[0] && this[0].parentNode ) {
5765 // Make sure that the elements are removed from the DOM before they are inserted
5766 // this can help fix replacing a parent with child elements
5767 if ( jQuery.isFunction( value ) ) {
5768 return this.each(function(i) {
5769 var self = jQuery(this), old = self.html();
5770 self.replaceWith( value.call( this, i, old ) );
5774 if ( typeof value !== "string" ) {
5775 value = jQuery( value ).detach();
5778 return this.each(function() {
5779 var next = this.nextSibling,
5780 parent = this.parentNode;
5782 jQuery( this ).remove();
5785 jQuery(next).before( value );
5787 jQuery(parent).append( value );
5791 return this.length ?
5792 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5797 detach: function( selector ) {
5798 return this.remove( selector, true );
5801 domManip: function( args, table, callback ) {
5802 var results, first, fragment, parent,
5806 // We can't cloneNode fragments that contain checked, in WebKit
5807 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5808 return this.each(function() {
5809 jQuery(this).domManip( args, table, callback, true );
5813 if ( jQuery.isFunction(value) ) {
5814 return this.each(function(i) {
5815 var self = jQuery(this);
5816 args[0] = value.call(this, i, table ? self.html() : undefined);
5817 self.domManip( args, table, callback );
5822 parent = value && value.parentNode;
5824 // If we're in a fragment, just use that instead of building a new one
5825 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5826 results = { fragment: parent };
5829 results = jQuery.buildFragment( args, this, scripts );
5832 fragment = results.fragment;
5834 if ( fragment.childNodes.length === 1 ) {
5835 first = fragment = fragment.firstChild;
5837 first = fragment.firstChild;
5841 table = table && jQuery.nodeName( first, "tr" );
5843 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5846 root(this[i], first) :
5848 // Make sure that we do not leak memory by inadvertently discarding
5849 // the original fragment (which might have attached data) instead of
5850 // using it; in addition, use the original fragment object for the last
5851 // item instead of first because it can end up being emptied incorrectly
5852 // in certain situations (Bug #8070).
5853 // Fragments from the fragment cache must always be cloned and never used
5855 results.cacheable || (l > 1 && i < lastIndex) ?
5856 jQuery.clone( fragment, true, true ) :
5862 if ( scripts.length ) {
5863 jQuery.each( scripts, evalScript );
5871 function root( elem, cur ) {
5872 return jQuery.nodeName(elem, "table") ?
5873 (elem.getElementsByTagName("tbody")[0] ||
5874 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5878 function cloneCopyEvent( src, dest ) {
5880 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5884 var internalKey = jQuery.expando,
5885 oldData = jQuery.data( src ),
5886 curData = jQuery.data( dest, oldData );
5888 // Switch to use the internal data object, if it exists, for the next
5889 // stage of data copying
5890 if ( (oldData = oldData[ internalKey ]) ) {
5891 var events = oldData.events;
5892 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5895 delete curData.handle;
5896 curData.events = {};
5898 for ( var type in events ) {
5899 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5900 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5907 function cloneFixAttributes( src, dest ) {
5910 // We do not need to do anything for non-Elements
5911 if ( dest.nodeType !== 1 ) {
5915 // clearAttributes removes the attributes, which we don't want,
5916 // but also removes the attachEvent events, which we *do* want
5917 if ( dest.clearAttributes ) {
5918 dest.clearAttributes();
5921 // mergeAttributes, in contrast, only merges back on the
5922 // original attributes, not the events
5923 if ( dest.mergeAttributes ) {
5924 dest.mergeAttributes( src );
5927 nodeName = dest.nodeName.toLowerCase();
5929 // IE6-8 fail to clone children inside object elements that use
5930 // the proprietary classid attribute value (rather than the type
5931 // attribute) to identify the type of content to display
5932 if ( nodeName === "object" ) {
5933 dest.outerHTML = src.outerHTML;
5935 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5936 // IE6-8 fails to persist the checked state of a cloned checkbox
5937 // or radio button. Worse, IE6-7 fail to give the cloned element
5938 // a checked appearance if the defaultChecked value isn't also set
5939 if ( src.checked ) {
5940 dest.defaultChecked = dest.checked = src.checked;
5943 // IE6-7 get confused and end up setting the value of a cloned
5944 // checkbox/radio button to an empty string instead of "on"
5945 if ( dest.value !== src.value ) {
5946 dest.value = src.value;
5949 // IE6-8 fails to return the selected option to the default selected
5950 // state when cloning options
5951 } else if ( nodeName === "option" ) {
5952 dest.selected = src.defaultSelected;
5954 // IE6-8 fails to set the defaultValue to the correct value when
5955 // cloning other types of input fields
5956 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5957 dest.defaultValue = src.defaultValue;
5960 // Event data gets referenced instead of copied if the expando
5962 dest.removeAttribute( jQuery.expando );
5965 jQuery.buildFragment = function( args, nodes, scripts ) {
5966 var fragment, cacheable, cacheresults, doc;
5968 // nodes may contain either an explicit document object,
5969 // a jQuery collection or context object.
5970 // If nodes[0] contains a valid object to assign to doc
5971 if ( nodes && nodes[0] ) {
5972 doc = nodes[0].ownerDocument || nodes[0];
5975 // Ensure that an attr object doesn't incorrectly stand in as a document object
5976 // Chrome and Firefox seem to allow this to occur and will throw exception
5978 if ( !doc.createDocumentFragment ) {
5982 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5983 // Cloning options loses the selected state, so don't cache them
5984 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5985 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5986 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5987 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5991 cacheresults = jQuery.fragments[ args[0] ];
5992 if ( cacheresults && cacheresults !== 1 ) {
5993 fragment = cacheresults;
5998 fragment = doc.createDocumentFragment();
5999 jQuery.clean( args, doc, fragment, scripts );
6003 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
6006 return { fragment: fragment, cacheable: cacheable };
6009 jQuery.fragments = {};
6013 prependTo: "prepend",
6014 insertBefore: "before",
6015 insertAfter: "after",
6016 replaceAll: "replaceWith"
6017 }, function( name, original ) {
6018 jQuery.fn[ name ] = function( selector ) {
6020 insert = jQuery( selector ),
6021 parent = this.length === 1 && this[0].parentNode;
6023 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6024 insert[ original ]( this[0] );
6028 for ( var i = 0, l = insert.length; i < l; i++ ) {
6029 var elems = (i > 0 ? this.clone(true) : this).get();
6030 jQuery( insert[i] )[ original ]( elems );
6031 ret = ret.concat( elems );
6034 return this.pushStack( ret, name, insert.selector );
6039 function getAll( elem ) {
6040 if ( "getElementsByTagName" in elem ) {
6041 return elem.getElementsByTagName( "*" );
6043 } else if ( "querySelectorAll" in elem ) {
6044 return elem.querySelectorAll( "*" );
6051 // Used in clean, fixes the defaultChecked property
6052 function fixDefaultChecked( elem ) {
6053 if ( elem.type === "checkbox" || elem.type === "radio" ) {
6054 elem.defaultChecked = elem.checked;
6057 // Finds all inputs and passes them to fixDefaultChecked
6058 function findInputs( elem ) {
6059 if ( jQuery.nodeName( elem, "input" ) ) {
6060 fixDefaultChecked( elem );
6061 } else if ( "getElementsByTagName" in elem ) {
6062 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6067 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6068 var clone = elem.cloneNode(true),
6073 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6074 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6075 // IE copies events bound via attachEvent when using cloneNode.
6076 // Calling detachEvent on the clone will also remove the events
6077 // from the original. In order to get around this, we use some
6078 // proprietary methods to clear the events. Thanks to MooTools
6079 // guys for this hotness.
6081 cloneFixAttributes( elem, clone );
6083 // Using Sizzle here is crazy slow, so we use getElementsByTagName
6085 srcElements = getAll( elem );
6086 destElements = getAll( clone );
6088 // Weird iteration because IE will replace the length property
6089 // with an element if you are cloning the body and one of the
6090 // elements on the page has a name or id of "length"
6091 for ( i = 0; srcElements[i]; ++i ) {
6092 // Ensure that the destination node is not null; Fixes #9587
6093 if ( destElements[i] ) {
6094 cloneFixAttributes( srcElements[i], destElements[i] );
6099 // Copy the events from the original to the clone
6100 if ( dataAndEvents ) {
6101 cloneCopyEvent( elem, clone );
6103 if ( deepDataAndEvents ) {
6104 srcElements = getAll( elem );
6105 destElements = getAll( clone );
6107 for ( i = 0; srcElements[i]; ++i ) {
6108 cloneCopyEvent( srcElements[i], destElements[i] );
6113 srcElements = destElements = null;
6115 // Return the cloned set
6119 clean: function( elems, context, fragment, scripts ) {
6120 var checkScriptType;
6122 context = context || document;
6124 // !context.createElement fails in IE with an error but returns typeof 'object'
6125 if ( typeof context.createElement === "undefined" ) {
6126 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6131 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6132 if ( typeof elem === "number" ) {
6140 // Convert html string into DOM nodes
6141 if ( typeof elem === "string" ) {
6142 if ( !rhtml.test( elem ) ) {
6143 elem = context.createTextNode( elem );
6145 // Fix "XHTML"-style tags in all browsers
6146 elem = elem.replace(rxhtmlTag, "<$1></$2>");
6148 // Trim whitespace, otherwise indexOf won't work as expected
6149 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6150 wrap = wrapMap[ tag ] || wrapMap._default,
6152 div = context.createElement("div");
6154 // Go to html and back, then peel off extra wrappers
6155 div.innerHTML = wrap[1] + elem + wrap[2];
6157 // Move to the right depth
6159 div = div.lastChild;
6162 // Remove IE's autoinserted <tbody> from table fragments
6163 if ( !jQuery.support.tbody ) {
6165 // String was a <table>, *may* have spurious <tbody>
6166 var hasBody = rtbody.test(elem),
6167 tbody = tag === "table" && !hasBody ?
6168 div.firstChild && div.firstChild.childNodes :
6170 // String was a bare <thead> or <tfoot>
6171 wrap[1] === "<table>" && !hasBody ?
6175 for ( j = tbody.length - 1; j >= 0 ; --j ) {
6176 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6177 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6182 // IE completely kills leading whitespace when innerHTML is used
6183 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6184 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6187 elem = div.childNodes;
6191 // Resets defaultChecked for any radios and checkboxes
6192 // about to be appended to the DOM in IE 6/7 (#8060)
6194 if ( !jQuery.support.appendChecked ) {
6195 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6196 for ( j = 0; j < len; j++ ) {
6197 findInputs( elem[j] );
6204 if ( elem.nodeType ) {
6207 ret = jQuery.merge( ret, elem );
6212 checkScriptType = function( elem ) {
6213 return !elem.type || rscriptType.test( elem.type );
6215 for ( i = 0; ret[i]; i++ ) {
6216 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6217 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6220 if ( ret[i].nodeType === 1 ) {
6221 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6223 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6225 fragment.appendChild( ret[i] );
6233 cleanData: function( elems ) {
6234 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6235 deleteExpando = jQuery.support.deleteExpando;
6237 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6238 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6242 id = elem[ jQuery.expando ];
6245 data = cache[ id ] && cache[ id ][ internalKey ];
6247 if ( data && data.events ) {
6248 for ( var type in data.events ) {
6249 if ( special[ type ] ) {
6250 jQuery.event.remove( elem, type );
6252 // This is a shortcut to avoid jQuery.event.remove's overhead
6254 jQuery.removeEvent( elem, type, data.handle );
6258 // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6259 if ( data.handle ) {
6260 data.handle.elem = null;
6264 if ( deleteExpando ) {
6265 delete elem[ jQuery.expando ];
6267 } else if ( elem.removeAttribute ) {
6268 elem.removeAttribute( jQuery.expando );
6277 function evalScript( i, elem ) {
6285 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6288 if ( elem.parentNode ) {
6289 elem.parentNode.removeChild( elem );
6296 var ralpha = /alpha\([^)]*\)/i,
6297 ropacity = /opacity=([^)]*)/,
6298 // fixed for IE9, see #8346
6299 rupper = /([A-Z]|^ms)/g,
6300 rnumpx = /^-?\d+(?:px)?$/i,
6302 rrelNum = /^([\-+])=([\-+.\de]+)/,
6304 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6305 cssWidth = [ "Left", "Right" ],
6306 cssHeight = [ "Top", "Bottom" ],
6312 jQuery.fn.css = function( name, value ) {
6313 // Setting 'undefined' is a no-op
6314 if ( arguments.length === 2 && value === undefined ) {
6318 return jQuery.access( this, name, value, true, function( elem, name, value ) {
6319 return value !== undefined ?
6320 jQuery.style( elem, name, value ) :
6321 jQuery.css( elem, name );
6326 // Add in style property hooks for overriding the default
6327 // behavior of getting and setting a style property
6330 get: function( elem, computed ) {
6332 // We should always get a number back from opacity
6333 var ret = curCSS( elem, "opacity", "opacity" );
6334 return ret === "" ? "1" : ret;
6337 return elem.style.opacity;
6343 // Exclude the following css properties to add px
6345 "fillOpacity": true,
6355 // Add in properties whose names you wish to fix before
6356 // setting or getting the value
6358 // normalize float css property
6359 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6362 // Get and set the style property on a DOM Node
6363 style: function( elem, name, value, extra ) {
6364 // Don't set styles on text and comment nodes
6365 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6369 // Make sure that we're working with the right name
6370 var ret, type, origName = jQuery.camelCase( name ),
6371 style = elem.style, hooks = jQuery.cssHooks[ origName ];
6373 name = jQuery.cssProps[ origName ] || origName;
6375 // Check if we're setting a value
6376 if ( value !== undefined ) {
6377 type = typeof value;
6379 // convert relative number strings (+= or -=) to relative numbers. #7345
6380 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6381 value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
6386 // Make sure that NaN and null values aren't set. See: #7116
6387 if ( value == null || type === "number" && isNaN( value ) ) {
6391 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6392 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6396 // If a hook was provided, use that value, otherwise just set the specified value
6397 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6398 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6401 style[ name ] = value;
6406 // If a hook was provided get the non-computed value from there
6407 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6411 // Otherwise just get the value from the style object
6412 return style[ name ];
6416 css: function( elem, name, extra ) {
6419 // Make sure that we're working with the right name
6420 name = jQuery.camelCase( name );
6421 hooks = jQuery.cssHooks[ name ];
6422 name = jQuery.cssProps[ name ] || name;
6424 // cssFloat needs a special treatment
6425 if ( name === "cssFloat" ) {
6429 // If a hook was provided get the computed value from there
6430 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6433 // Otherwise, if a way to get the computed value exists, use that
6434 } else if ( curCSS ) {
6435 return curCSS( elem, name );
6439 // A method for quickly swapping in/out CSS properties to get correct calculations
6440 swap: function( elem, options, callback ) {
6443 // Remember the old values, and insert the new ones
6444 for ( var name in options ) {
6445 old[ name ] = elem.style[ name ];
6446 elem.style[ name ] = options[ name ];
6449 callback.call( elem );
6451 // Revert the old values
6452 for ( name in options ) {
6453 elem.style[ name ] = old[ name ];
6458 // DEPRECATED, Use jQuery.css() instead
6459 jQuery.curCSS = jQuery.css;
6461 jQuery.each(["height", "width"], function( i, name ) {
6462 jQuery.cssHooks[ name ] = {
6463 get: function( elem, computed, extra ) {
6467 if ( elem.offsetWidth !== 0 ) {
6468 return getWH( elem, name, extra );
6470 jQuery.swap( elem, cssShow, function() {
6471 val = getWH( elem, name, extra );
6479 set: function( elem, value ) {
6480 if ( rnumpx.test( value ) ) {
6481 // ignore negative width and height values #1599
6482 value = parseFloat( value );
6485 return value + "px";
6495 if ( !jQuery.support.opacity ) {
6496 jQuery.cssHooks.opacity = {
6497 get: function( elem, computed ) {
6498 // IE uses filters for opacity
6499 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6500 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6501 computed ? "1" : "";
6504 set: function( elem, value ) {
6505 var style = elem.style,
6506 currentStyle = elem.currentStyle,
6507 opacity = jQuery.isNaN( value ) ? "" : "alpha(opacity=" + value * 100 + ")",
6508 filter = currentStyle && currentStyle.filter || style.filter || "";
6510 // IE has trouble with opacity if it does not have layout
6511 // Force it by setting the zoom level
6514 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6515 if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
6517 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6518 // if "filter:" is present at all, clearType is disabled, we want to avoid this
6519 // style.removeAttribute is IE Only, but so apparently is this code path...
6520 style.removeAttribute( "filter" );
6522 // if there there is no filter style applied in a css rule, we are done
6523 if ( currentStyle && !currentStyle.filter ) {
6528 // otherwise, set new filter values
6529 style.filter = ralpha.test( filter ) ?
6530 filter.replace( ralpha, opacity ) :
6531 filter + " " + opacity;
6537 // This hook cannot be added until DOM ready because the support test
6538 // for it is not run until after DOM ready
6539 if ( !jQuery.support.reliableMarginRight ) {
6540 jQuery.cssHooks.marginRight = {
6541 get: function( elem, computed ) {
6542 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6543 // Work around by temporarily setting element display to inline-block
6545 jQuery.swap( elem, { "display": "inline-block" }, function() {
6547 ret = curCSS( elem, "margin-right", "marginRight" );
6549 ret = elem.style.marginRight;
6558 if ( document.defaultView && document.defaultView.getComputedStyle ) {
6559 getComputedStyle = function( elem, name ) {
6560 var ret, defaultView, computedStyle;
6562 name = name.replace( rupper, "-$1" ).toLowerCase();
6564 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6568 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6569 ret = computedStyle.getPropertyValue( name );
6570 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6571 ret = jQuery.style( elem, name );
6579 if ( document.documentElement.currentStyle ) {
6580 currentStyle = function( elem, name ) {
6582 ret = elem.currentStyle && elem.currentStyle[ name ],
6583 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6586 // From the awesome hack by Dean Edwards
6587 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6589 // If we're not dealing with a regular pixel number
6590 // but a number that has a weird ending, we need to convert it to pixels
6591 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6592 // Remember the original values
6595 // Put in the new values to get a computed value out
6597 elem.runtimeStyle.left = elem.currentStyle.left;
6599 style.left = name === "fontSize" ? "1em" : (ret || 0);
6600 ret = style.pixelLeft + "px";
6602 // Revert the changed values
6605 elem.runtimeStyle.left = rsLeft;
6609 return ret === "" ? "auto" : ret;
6613 curCSS = getComputedStyle || currentStyle;
6615 function getWH( elem, name, extra ) {
6617 // Start with offset property
6618 var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6619 which = name === "width" ? cssWidth : cssHeight;
6622 if ( extra !== "border" ) {
6623 jQuery.each( which, function() {
6625 val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6627 if ( extra === "margin" ) {
6628 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6630 val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6638 // Fall back to computed then uncomputed css if necessary
6639 val = curCSS( elem, name, name );
6640 if ( val < 0 || val == null ) {
6641 val = elem.style[ name ] || 0;
6643 // Normalize "", auto, and prepare for extra
6644 val = parseFloat( val ) || 0;
6646 // Add padding, border, margin
6648 jQuery.each( which, function() {
6649 val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6650 if ( extra !== "padding" ) {
6651 val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6653 if ( extra === "margin" ) {
6654 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6662 if ( jQuery.expr && jQuery.expr.filters ) {
6663 jQuery.expr.filters.hidden = function( elem ) {
6664 var width = elem.offsetWidth,
6665 height = elem.offsetHeight;
6667 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6670 jQuery.expr.filters.visible = function( elem ) {
6671 return !jQuery.expr.filters.hidden( elem );
6682 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6683 rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6684 // #7653, #8125, #8152: local protocol detection
6685 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
6686 rnoContent = /^(?:GET|HEAD)$/,
6687 rprotocol = /^\/\//,
6689 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6690 rselectTextarea = /^(?:select|textarea)/i,
6691 rspacesAjax = /\s+/,
6692 rts = /([?&])_=[^&]*/,
6693 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6695 // Keep a copy of the old load method
6696 _load = jQuery.fn.load,
6699 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6700 * 2) These are called:
6701 * - BEFORE asking for a transport
6702 * - AFTER param serialization (s.data is a string if s.processData is true)
6703 * 3) key is the dataType
6704 * 4) the catchall symbol "*" can be used
6705 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6709 /* Transports bindings
6710 * 1) key is the dataType
6711 * 2) the catchall symbol "*" can be used
6712 * 3) selection will start with transport dataType and THEN go to "*" if needed
6716 // Document location
6719 // Document location segments
6722 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
6723 allTypes = ["*/"] + ["*"];
6725 // #8138, IE may throw an exception when accessing
6726 // a field from window.location if document.domain has been set
6728 ajaxLocation = location.href;
6730 // Use the href attribute of an A element
6731 // since IE will modify it given document.location
6732 ajaxLocation = document.createElement( "a" );
6733 ajaxLocation.href = "";
6734 ajaxLocation = ajaxLocation.href;
6737 // Segment location into parts
6738 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6740 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6741 function addToPrefiltersOrTransports( structure ) {
6743 // dataTypeExpression is optional and defaults to "*"
6744 return function( dataTypeExpression, func ) {
6746 if ( typeof dataTypeExpression !== "string" ) {
6747 func = dataTypeExpression;
6748 dataTypeExpression = "*";
6751 if ( jQuery.isFunction( func ) ) {
6752 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6754 length = dataTypes.length,
6759 // For each dataType in the dataTypeExpression
6760 for(; i < length; i++ ) {
6761 dataType = dataTypes[ i ];
6762 // We control if we're asked to add before
6763 // any existing element
6764 placeBefore = /^\+/.test( dataType );
6765 if ( placeBefore ) {
6766 dataType = dataType.substr( 1 ) || "*";
6768 list = structure[ dataType ] = structure[ dataType ] || [];
6769 // then we add to the structure accordingly
6770 list[ placeBefore ? "unshift" : "push" ]( func );
6776 // Base inspection function for prefilters and transports
6777 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6778 dataType /* internal */, inspected /* internal */ ) {
6780 dataType = dataType || options.dataTypes[ 0 ];
6781 inspected = inspected || {};
6783 inspected[ dataType ] = true;
6785 var list = structure[ dataType ],
6787 length = list ? list.length : 0,
6788 executeOnly = ( structure === prefilters ),
6791 for(; i < length && ( executeOnly || !selection ); i++ ) {
6792 selection = list[ i ]( options, originalOptions, jqXHR );
6793 // If we got redirected to another dataType
6794 // we try there if executing only and not done already
6795 if ( typeof selection === "string" ) {
6796 if ( !executeOnly || inspected[ selection ] ) {
6797 selection = undefined;
6799 options.dataTypes.unshift( selection );
6800 selection = inspectPrefiltersOrTransports(
6801 structure, options, originalOptions, jqXHR, selection, inspected );
6805 // If we're only executing or nothing was selected
6806 // we try the catchall dataType if not done already
6807 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6808 selection = inspectPrefiltersOrTransports(
6809 structure, options, originalOptions, jqXHR, "*", inspected );
6811 // unnecessary when only executing (prefilters)
6812 // but it'll be ignored by the caller in that case
6816 // A special extend for ajax options
6817 // that takes "flat" options (not to be deep extended)
6819 function ajaxExtend( target, src ) {
6821 flatOptions = jQuery.ajaxSettings.flatOptions || {};
6823 if ( src[ key ] !== undefined ) {
6824 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
6828 jQuery.extend( true, target, deep );
6833 load: function( url, params, callback ) {
6834 if ( typeof url !== "string" && _load ) {
6835 return _load.apply( this, arguments );
6837 // Don't do a request if no elements are being requested
6838 } else if ( !this.length ) {
6842 var off = url.indexOf( " " );
6844 var selector = url.slice( off, url.length );
6845 url = url.slice( 0, off );
6848 // Default to a GET request
6851 // If the second parameter was provided
6853 // If it's a function
6854 if ( jQuery.isFunction( params ) ) {
6855 // We assume that it's the callback
6859 // Otherwise, build a param string
6860 } else if ( typeof params === "object" ) {
6861 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6868 // Request the remote document
6874 // Complete callback (responseText is used internally)
6875 complete: function( jqXHR, status, responseText ) {
6876 // Store the response as specified by the jqXHR object
6877 responseText = jqXHR.responseText;
6878 // If successful, inject the HTML into all the matched elements
6879 if ( jqXHR.isResolved() ) {
6880 // #4825: Get the actual response in case
6881 // a dataFilter is present in ajaxSettings
6882 jqXHR.done(function( r ) {
6885 // See if a selector was specified
6886 self.html( selector ?
6887 // Create a dummy div to hold the results
6889 // inject the contents of the document in, removing the scripts
6890 // to avoid any 'Permission Denied' errors in IE
6891 .append(responseText.replace(rscript, ""))
6893 // Locate the specified elements
6896 // If not, just inject the full result
6901 self.each( callback, [ responseText, status, jqXHR ] );
6909 serialize: function() {
6910 return jQuery.param( this.serializeArray() );
6913 serializeArray: function() {
6914 return this.map(function(){
6915 return this.elements ? jQuery.makeArray( this.elements ) : this;
6918 return this.name && !this.disabled &&
6919 ( this.checked || rselectTextarea.test( this.nodeName ) ||
6920 rinput.test( this.type ) );
6922 .map(function( i, elem ){
6923 var val = jQuery( this ).val();
6925 return val == null ?
6927 jQuery.isArray( val ) ?
6928 jQuery.map( val, function( val, i ){
6929 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6931 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6936 // Attach a bunch of functions for handling common AJAX events
6937 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6938 jQuery.fn[ o ] = function( f ){
6939 return this.bind( o, f );
6943 jQuery.each( [ "get", "post" ], function( i, method ) {
6944 jQuery[ method ] = function( url, data, callback, type ) {
6945 // shift arguments if data argument was omitted
6946 if ( jQuery.isFunction( data ) ) {
6947 type = type || callback;
6952 return jQuery.ajax({
6964 getScript: function( url, callback ) {
6965 return jQuery.get( url, undefined, callback, "script" );
6968 getJSON: function( url, data, callback ) {
6969 return jQuery.get( url, data, callback, "json" );
6972 // Creates a full fledged settings object into target
6973 // with both ajaxSettings and settings fields.
6974 // If target is omitted, writes into ajaxSettings.
6975 ajaxSetup: function( target, settings ) {
6977 // Building a settings object
6978 ajaxExtend( target, jQuery.ajaxSettings );
6980 // Extending ajaxSettings
6982 target = jQuery.ajaxSettings;
6984 ajaxExtend( target, settings );
6990 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
6993 contentType: "application/x-www-form-urlencoded",
7008 xml: "application/xml, text/xml",
7011 json: "application/json, text/javascript",
7023 text: "responseText"
7026 // List of data converters
7027 // 1) key format is "source_type destination_type" (a single space in-between)
7028 // 2) the catchall symbol "*" can be used for source_type
7031 // Convert anything to text
7032 "* text": window.String,
7034 // Text to html (true = no transformation)
7037 // Evaluate text as a json expression
7038 "text json": jQuery.parseJSON,
7040 // Parse text as xml
7041 "text xml": jQuery.parseXML
7044 // For options that shouldn't be deep extended:
7045 // you can add your own custom options here if
7046 // and when you create one that shouldn't be
7047 // deep extended (see ajaxExtend)
7054 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7055 ajaxTransport: addToPrefiltersOrTransports( transports ),
7058 ajax: function( url, options ) {
7060 // If url is an object, simulate pre-1.5 signature
7061 if ( typeof url === "object" ) {
7066 // Force options to be an object
7067 options = options || {};
7069 var // Create the final options object
7070 s = jQuery.ajaxSetup( {}, options ),
7071 // Callbacks context
7072 callbackContext = s.context || s,
7073 // Context for global events
7074 // It's the callbackContext if one was provided in the options
7075 // and if it's a DOM node or a jQuery collection
7076 globalEventContext = callbackContext !== s &&
7077 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7078 jQuery( callbackContext ) : jQuery.event,
7080 deferred = jQuery.Deferred(),
7081 completeDeferred = jQuery._Deferred(),
7082 // Status-dependent callbacks
7083 statusCode = s.statusCode || {},
7086 // Headers (they are sent all at once)
7087 requestHeaders = {},
7088 requestHeadersNames = {},
7090 responseHeadersString,
7096 // Cross-domain detection vars
7100 // To know if global events are to be dispatched
7109 // Caches the header
7110 setRequestHeader: function( name, value ) {
7112 var lname = name.toLowerCase();
7113 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7114 requestHeaders[ name ] = value;
7120 getAllResponseHeaders: function() {
7121 return state === 2 ? responseHeadersString : null;
7124 // Builds headers hashtable if needed
7125 getResponseHeader: function( key ) {
7127 if ( state === 2 ) {
7128 if ( !responseHeaders ) {
7129 responseHeaders = {};
7130 while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7131 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7134 match = responseHeaders[ key.toLowerCase() ];
7136 return match === undefined ? null : match;
7139 // Overrides response content-type header
7140 overrideMimeType: function( type ) {
7147 // Cancel the request
7148 abort: function( statusText ) {
7149 statusText = statusText || "abort";
7151 transport.abort( statusText );
7153 done( 0, statusText );
7158 // Callback for when everything is done
7159 // It is defined here because jslint complains if it is declared
7160 // at the end of the function (which would be more logical and readable)
7161 function done( status, nativeStatusText, responses, headers ) {
7164 if ( state === 2 ) {
7168 // State is "done" now
7171 // Clear timeout if it exists
7172 if ( timeoutTimer ) {
7173 clearTimeout( timeoutTimer );
7176 // Dereference transport for early garbage collection
7177 // (no matter how long the jqXHR object will be used)
7178 transport = undefined;
7180 // Cache response headers
7181 responseHeadersString = headers || "";
7184 jqXHR.readyState = status > 0 ? 4 : 0;
7189 statusText = nativeStatusText,
7190 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7194 // If successful, handle type chaining
7195 if ( status >= 200 && status < 300 || status === 304 ) {
7197 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7198 if ( s.ifModified ) {
7200 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7201 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7203 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7204 jQuery.etag[ ifModifiedKey ] = etag;
7209 if ( status === 304 ) {
7211 statusText = "notmodified";
7218 success = ajaxConvert( s, response );
7219 statusText = "success";
7222 // We have a parsererror
7223 statusText = "parsererror";
7228 // We extract error from statusText
7229 // then normalize statusText and status for non-aborts
7231 if( !statusText || status ) {
7232 statusText = "error";
7239 // Set data for the fake xhr object
7240 jqXHR.status = status;
7241 jqXHR.statusText = "" + ( nativeStatusText || statusText );
7245 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7247 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7250 // Status-dependent callbacks
7251 jqXHR.statusCode( statusCode );
7252 statusCode = undefined;
7254 if ( fireGlobals ) {
7255 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7256 [ jqXHR, s, isSuccess ? success : error ] );
7260 completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7262 if ( fireGlobals ) {
7263 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7264 // Handle the global AJAX counter
7265 if ( !( --jQuery.active ) ) {
7266 jQuery.event.trigger( "ajaxStop" );
7272 deferred.promise( jqXHR );
7273 jqXHR.success = jqXHR.done;
7274 jqXHR.error = jqXHR.fail;
7275 jqXHR.complete = completeDeferred.done;
7277 // Status-dependent callbacks
7278 jqXHR.statusCode = function( map ) {
7283 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7286 tmp = map[ jqXHR.status ];
7287 jqXHR.then( tmp, tmp );
7293 // Remove hash character (#7531: and string promotion)
7294 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7295 // We also use the url parameter if available
7296 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7298 // Extract dataTypes list
7299 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7301 // Determine if a cross-domain request is in order
7302 if ( s.crossDomain == null ) {
7303 parts = rurl.exec( s.url.toLowerCase() );
7304 s.crossDomain = !!( parts &&
7305 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7306 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7307 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7311 // Convert data if not already a string
7312 if ( s.data && s.processData && typeof s.data !== "string" ) {
7313 s.data = jQuery.param( s.data, s.traditional );
7317 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7319 // If request was aborted inside a prefiler, stop there
7320 if ( state === 2 ) {
7324 // We can fire global events as of now if asked to
7325 fireGlobals = s.global;
7327 // Uppercase the type
7328 s.type = s.type.toUpperCase();
7330 // Determine if request has content
7331 s.hasContent = !rnoContent.test( s.type );
7333 // Watch for a new set of requests
7334 if ( fireGlobals && jQuery.active++ === 0 ) {
7335 jQuery.event.trigger( "ajaxStart" );
7338 // More options handling for requests with no content
7339 if ( !s.hasContent ) {
7341 // If data is available, append data to url
7343 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7344 // #9682: remove data so that it's not used in an eventual retry
7348 // Get ifModifiedKey before adding the anti-cache parameter
7349 ifModifiedKey = s.url;
7351 // Add anti-cache in url if needed
7352 if ( s.cache === false ) {
7354 var ts = jQuery.now(),
7355 // try replacing _= if it is there
7356 ret = s.url.replace( rts, "$1_=" + ts );
7358 // if nothing was replaced, add timestamp to the end
7359 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7363 // Set the correct header, if data is being sent
7364 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7365 jqXHR.setRequestHeader( "Content-Type", s.contentType );
7368 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7369 if ( s.ifModified ) {
7370 ifModifiedKey = ifModifiedKey || s.url;
7371 if ( jQuery.lastModified[ ifModifiedKey ] ) {
7372 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7374 if ( jQuery.etag[ ifModifiedKey ] ) {
7375 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7379 // Set the Accepts header for the server, depending on the dataType
7380 jqXHR.setRequestHeader(
7382 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7383 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7387 // Check for headers option
7388 for ( i in s.headers ) {
7389 jqXHR.setRequestHeader( i, s.headers[ i ] );
7392 // Allow custom headers/mimetypes and early abort
7393 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7394 // Abort if not done already
7400 // Install callbacks on deferreds
7401 for ( i in { success: 1, error: 1, complete: 1 } ) {
7402 jqXHR[ i ]( s[ i ] );
7406 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7408 // If no transport, we auto-abort
7410 done( -1, "No Transport" );
7412 jqXHR.readyState = 1;
7413 // Send global event
7414 if ( fireGlobals ) {
7415 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7418 if ( s.async && s.timeout > 0 ) {
7419 timeoutTimer = setTimeout( function(){
7420 jqXHR.abort( "timeout" );
7426 transport.send( requestHeaders, done );
7428 // Propagate exception as error if not done
7431 // Simply rethrow otherwise
7441 // Serialize an array of form elements or a set of
7442 // key/values into a query string
7443 param: function( a, traditional ) {
7445 add = function( key, value ) {
7446 // If value is a function, invoke it and return its value
7447 value = jQuery.isFunction( value ) ? value() : value;
7448 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7451 // Set traditional to true for jQuery <= 1.3.2 behavior.
7452 if ( traditional === undefined ) {
7453 traditional = jQuery.ajaxSettings.traditional;
7456 // If an array was passed in, assume that it is an array of form elements.
7457 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7458 // Serialize the form elements
7459 jQuery.each( a, function() {
7460 add( this.name, this.value );
7464 // If traditional, encode the "old" way (the way 1.3.2 or older
7465 // did it), otherwise encode params recursively.
7466 for ( var prefix in a ) {
7467 buildParams( prefix, a[ prefix ], traditional, add );
7471 // Return the resulting serialization
7472 return s.join( "&" ).replace( r20, "+" );
7476 function buildParams( prefix, obj, traditional, add ) {
7477 if ( jQuery.isArray( obj ) ) {
7478 // Serialize array item.
7479 jQuery.each( obj, function( i, v ) {
7480 if ( traditional || rbracket.test( prefix ) ) {
7481 // Treat each array item as a scalar.
7485 // If array item is non-scalar (array or object), encode its
7486 // numeric index to resolve deserialization ambiguity issues.
7487 // Note that rack (as of 1.0.0) can't currently deserialize
7488 // nested arrays properly, and attempting to do so may cause
7489 // a server error. Possible fixes are to modify rack's
7490 // deserialization algorithm or to provide an option or flag
7491 // to force array serialization to be shallow.
7492 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7496 } else if ( !traditional && obj != null && typeof obj === "object" ) {
7497 // Serialize object item.
7498 for ( var name in obj ) {
7499 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7503 // Serialize scalar item.
7508 // This is still on the jQuery object... for now
7509 // Want to move this to jQuery.ajax some day
7512 // Counter for holding the number of active queries
7515 // Last-Modified header cache for next request
7521 /* Handles responses to an ajax request:
7522 * - sets all responseXXX fields accordingly
7523 * - finds the right dataType (mediates between content-type and expected dataType)
7524 * - returns the corresponding response
7526 function ajaxHandleResponses( s, jqXHR, responses ) {
7528 var contents = s.contents,
7529 dataTypes = s.dataTypes,
7530 responseFields = s.responseFields,
7536 // Fill responseXXX fields
7537 for( type in responseFields ) {
7538 if ( type in responses ) {
7539 jqXHR[ responseFields[type] ] = responses[ type ];
7543 // Remove auto dataType and get content-type in the process
7544 while( dataTypes[ 0 ] === "*" ) {
7546 if ( ct === undefined ) {
7547 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7551 // Check if we're dealing with a known content-type
7553 for ( type in contents ) {
7554 if ( contents[ type ] && contents[ type ].test( ct ) ) {
7555 dataTypes.unshift( type );
7561 // Check to see if we have a response for the expected dataType
7562 if ( dataTypes[ 0 ] in responses ) {
7563 finalDataType = dataTypes[ 0 ];
7565 // Try convertible dataTypes
7566 for ( type in responses ) {
7567 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7568 finalDataType = type;
7571 if ( !firstDataType ) {
7572 firstDataType = type;
7575 // Or just use first one
7576 finalDataType = finalDataType || firstDataType;
7579 // If we found a dataType
7580 // We add the dataType to the list if needed
7581 // and return the corresponding response
7582 if ( finalDataType ) {
7583 if ( finalDataType !== dataTypes[ 0 ] ) {
7584 dataTypes.unshift( finalDataType );
7586 return responses[ finalDataType ];
7590 // Chain conversions given the request and the original response
7591 function ajaxConvert( s, response ) {
7593 // Apply the dataFilter if provided
7594 if ( s.dataFilter ) {
7595 response = s.dataFilter( response, s.dataType );
7598 var dataTypes = s.dataTypes,
7602 length = dataTypes.length,
7604 // Current and previous dataTypes
7605 current = dataTypes[ 0 ],
7607 // Conversion expression
7609 // Conversion function
7611 // Conversion functions (transitive conversion)
7615 // For each dataType in the chain
7616 for( i = 1; i < length; i++ ) {
7618 // Create converters map
7619 // with lowercased keys
7621 for( key in s.converters ) {
7622 if( typeof key === "string" ) {
7623 converters[ key.toLowerCase() ] = s.converters[ key ];
7628 // Get the dataTypes
7630 current = dataTypes[ i ];
7632 // If current is auto dataType, update it to prev
7633 if( current === "*" ) {
7635 // If no auto and dataTypes are actually different
7636 } else if ( prev !== "*" && prev !== current ) {
7638 // Get the converter
7639 conversion = prev + " " + current;
7640 conv = converters[ conversion ] || converters[ "* " + current ];
7642 // If there is no direct converter, search transitively
7645 for( conv1 in converters ) {
7646 tmp = conv1.split( " " );
7647 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7648 conv2 = converters[ tmp[1] + " " + current ];
7650 conv1 = converters[ conv1 ];
7651 if ( conv1 === true ) {
7653 } else if ( conv2 === true ) {
7661 // If we found no converter, dispatch an error
7662 if ( !( conv || conv2 ) ) {
7663 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7665 // If found converter is not an equivalence
7666 if ( conv !== true ) {
7667 // Convert with 1 or 2 converters accordingly
7668 response = conv ? conv( response ) : conv2( conv1(response) );
7678 var jsc = jQuery.now(),
7679 jsre = /(\=)\?(&|$)|\?\?/i;
7681 // Default jsonp settings
7684 jsonpCallback: function() {
7685 return jQuery.expando + "_" + ( jsc++ );
7689 // Detect, normalize options and install callbacks for jsonp requests
7690 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7692 var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7693 ( typeof s.data === "string" );
7695 if ( s.dataTypes[ 0 ] === "jsonp" ||
7696 s.jsonp !== false && ( jsre.test( s.url ) ||
7697 inspectData && jsre.test( s.data ) ) ) {
7699 var responseContainer,
7700 jsonpCallback = s.jsonpCallback =
7701 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7702 previous = window[ jsonpCallback ],
7705 replace = "$1" + jsonpCallback + "$2";
7707 if ( s.jsonp !== false ) {
7708 url = url.replace( jsre, replace );
7709 if ( s.url === url ) {
7710 if ( inspectData ) {
7711 data = data.replace( jsre, replace );
7713 if ( s.data === data ) {
7714 // Add callback manually
7715 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7724 window[ jsonpCallback ] = function( response ) {
7725 responseContainer = [ response ];
7728 // Clean-up function
7729 jqXHR.always(function() {
7730 // Set callback back to previous value
7731 window[ jsonpCallback ] = previous;
7732 // Call if it was a function and we have a response
7733 if ( responseContainer && jQuery.isFunction( previous ) ) {
7734 window[ jsonpCallback ]( responseContainer[ 0 ] );
7738 // Use data converter to retrieve json after script execution
7739 s.converters["script json"] = function() {
7740 if ( !responseContainer ) {
7741 jQuery.error( jsonpCallback + " was not called" );
7743 return responseContainer[ 0 ];
7746 // force json dataType
7747 s.dataTypes[ 0 ] = "json";
7749 // Delegate to script
7757 // Install script dataType
7760 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7763 script: /javascript|ecmascript/
7766 "text script": function( text ) {
7767 jQuery.globalEval( text );
7773 // Handle cache's special case and global
7774 jQuery.ajaxPrefilter( "script", function( s ) {
7775 if ( s.cache === undefined ) {
7778 if ( s.crossDomain ) {
7784 // Bind script tag hack transport
7785 jQuery.ajaxTransport( "script", function(s) {
7787 // This transport only deals with cross domain requests
7788 if ( s.crossDomain ) {
7791 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7795 send: function( _, callback ) {
7797 script = document.createElement( "script" );
7799 script.async = "async";
7801 if ( s.scriptCharset ) {
7802 script.charset = s.scriptCharset;
7807 // Attach handlers for all browsers
7808 script.onload = script.onreadystatechange = function( _, isAbort ) {
7810 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7812 // Handle memory leak in IE
7813 script.onload = script.onreadystatechange = null;
7815 // Remove the script
7816 if ( head && script.parentNode ) {
7817 head.removeChild( script );
7820 // Dereference the script
7823 // Callback if not abort
7825 callback( 200, "success" );
7829 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
7830 // This arises when a base node is used (#2709 and #4378).
7831 head.insertBefore( script, head.firstChild );
7836 script.onload( 0, 1 );
7846 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7847 xhrOnUnloadAbort = window.ActiveXObject ? function() {
7848 // Abort all pending requests
7849 for ( var key in xhrCallbacks ) {
7850 xhrCallbacks[ key ]( 0, 1 );
7856 // Functions to create xhrs
7857 function createStandardXHR() {
7859 return new window.XMLHttpRequest();
7863 function createActiveXHR() {
7865 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7869 // Create the request object
7870 // (This is still attached to ajaxSettings for backward compatibility)
7871 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7872 /* Microsoft failed to properly
7873 * implement the XMLHttpRequest in IE7 (can't request local files),
7874 * so we use the ActiveXObject when it is available
7875 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7876 * we need a fallback.
7879 return !this.isLocal && createStandardXHR() || createActiveXHR();
7881 // For all other browsers, use the standard XMLHttpRequest object
7884 // Determine support properties
7886 jQuery.extend( jQuery.support, {
7888 cors: !!xhr && ( "withCredentials" in xhr )
7890 })( jQuery.ajaxSettings.xhr() );
7892 // Create transport if the browser can provide an xhr
7893 if ( jQuery.support.ajax ) {
7895 jQuery.ajaxTransport(function( s ) {
7896 // Cross domain only allowed if supported through XMLHttpRequest
7897 if ( !s.crossDomain || jQuery.support.cors ) {
7902 send: function( headers, complete ) {
7910 // Passing null username, generates a login popup on Opera (#2865)
7912 xhr.open( s.type, s.url, s.async, s.username, s.password );
7914 xhr.open( s.type, s.url, s.async );
7917 // Apply custom fields if provided
7918 if ( s.xhrFields ) {
7919 for ( i in s.xhrFields ) {
7920 xhr[ i ] = s.xhrFields[ i ];
7924 // Override mime type if needed
7925 if ( s.mimeType && xhr.overrideMimeType ) {
7926 xhr.overrideMimeType( s.mimeType );
7929 // X-Requested-With header
7930 // For cross-domain requests, seeing as conditions for a preflight are
7931 // akin to a jigsaw puzzle, we simply never set it to be sure.
7932 // (it can always be set on a per-request basis or even using ajaxSetup)
7933 // For same-domain requests, won't change header if already provided.
7934 if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7935 headers[ "X-Requested-With" ] = "XMLHttpRequest";
7938 // Need an extra try/catch for cross domain requests in Firefox 3
7940 for ( i in headers ) {
7941 xhr.setRequestHeader( i, headers[ i ] );
7945 // Do send the request
7946 // This may raise an exception which is actually
7947 // handled in jQuery.ajax (so no try/catch here)
7948 xhr.send( ( s.hasContent && s.data ) || null );
7951 callback = function( _, isAbort ) {
7959 // Firefox throws exceptions when accessing properties
7960 // of an xhr when a network error occured
7961 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7964 // Was never called and is aborted or complete
7965 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7968 callback = undefined;
7970 // Do not keep as active anymore
7972 xhr.onreadystatechange = jQuery.noop;
7973 if ( xhrOnUnloadAbort ) {
7974 delete xhrCallbacks[ handle ];
7980 // Abort it manually if needed
7981 if ( xhr.readyState !== 4 ) {
7985 status = xhr.status;
7986 responseHeaders = xhr.getAllResponseHeaders();
7988 xml = xhr.responseXML;
7990 // Construct response list
7991 if ( xml && xml.documentElement /* #4958 */ ) {
7992 responses.xml = xml;
7994 responses.text = xhr.responseText;
7996 // Firefox throws an exception when accessing
7997 // statusText for faulty cross-domain requests
7999 statusText = xhr.statusText;
8001 // We normalize with Webkit giving an empty statusText
8005 // Filter status for non standard behaviors
8007 // If the request is local and we have data: assume a success
8008 // (success with no data won't get notified, that's the best we
8009 // can do given current implementations)
8010 if ( !status && s.isLocal && !s.crossDomain ) {
8011 status = responses.text ? 200 : 404;
8012 // IE - #1450: sometimes returns 1223 when it should be 204
8013 } else if ( status === 1223 ) {
8018 } catch( firefoxAccessException ) {
8020 complete( -1, firefoxAccessException );
8024 // Call complete if needed
8026 complete( status, statusText, responses, responseHeaders );
8030 // if we're in sync mode or it's in cache
8031 // and has been retrieved directly (IE6 & IE7)
8032 // we need to manually fire the callback
8033 if ( !s.async || xhr.readyState === 4 ) {
8037 if ( xhrOnUnloadAbort ) {
8038 // Create the active xhrs callbacks list if needed
8039 // and attach the unload handler
8040 if ( !xhrCallbacks ) {
8042 jQuery( window ).unload( xhrOnUnloadAbort );
8044 // Add to list of active xhrs callbacks
8045 xhrCallbacks[ handle ] = callback;
8047 xhr.onreadystatechange = callback;
8064 var elemdisplay = {},
8066 rfxtypes = /^(?:toggle|show|hide)$/,
8067 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8070 // height animations
8071 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8073 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8074 // opacity animations
8080 show: function( speed, easing, callback ) {
8083 if ( speed || speed === 0 ) {
8084 return this.animate( genFx("show", 3), speed, easing, callback);
8087 for ( var i = 0, j = this.length; i < j; i++ ) {
8091 display = elem.style.display;
8093 // Reset the inline display of this element to learn if it is
8094 // being hidden by cascaded rules or not
8095 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8096 display = elem.style.display = "";
8099 // Set elements which have been overridden with display: none
8100 // in a stylesheet to whatever the default browser style is
8101 // for such an element
8102 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
8103 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
8108 // Set the display of most of the elements in a second loop
8109 // to avoid the constant reflow
8110 for ( i = 0; i < j; i++ ) {
8114 display = elem.style.display;
8116 if ( display === "" || display === "none" ) {
8117 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8126 hide: function( speed, easing, callback ) {
8127 if ( speed || speed === 0 ) {
8128 return this.animate( genFx("hide", 3), speed, easing, callback);
8131 for ( var i = 0, j = this.length; i < j; i++ ) {
8132 if ( this[i].style ) {
8133 var display = jQuery.css( this[i], "display" );
8135 if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8136 jQuery._data( this[i], "olddisplay", display );
8141 // Set the display of the elements in a second loop
8142 // to avoid the constant reflow
8143 for ( i = 0; i < j; i++ ) {
8144 if ( this[i].style ) {
8145 this[i].style.display = "none";
8153 // Save the old toggle function
8154 _toggle: jQuery.fn.toggle,
8156 toggle: function( fn, fn2, callback ) {
8157 var bool = typeof fn === "boolean";
8159 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8160 this._toggle.apply( this, arguments );
8162 } else if ( fn == null || bool ) {
8163 this.each(function() {
8164 var state = bool ? fn : jQuery(this).is(":hidden");
8165 jQuery(this)[ state ? "show" : "hide" ]();
8169 this.animate(genFx("toggle", 3), fn, fn2, callback);
8175 fadeTo: function( speed, to, easing, callback ) {
8176 return this.filter(":hidden").css("opacity", 0).show().end()
8177 .animate({opacity: to}, speed, easing, callback);
8180 animate: function( prop, speed, easing, callback ) {
8181 var optall = jQuery.speed(speed, easing, callback);
8183 if ( jQuery.isEmptyObject( prop ) ) {
8184 return this.each( optall.complete, [ false ] );
8187 // Do not change referenced properties as per-property easing will be lost
8188 prop = jQuery.extend( {}, prop );
8190 return this[ optall.queue === false ? "each" : "queue" ](function() {
8191 // XXX 'this' does not always have a nodeName when running the
8194 if ( optall.queue === false ) {
8195 jQuery._mark( this );
8198 var opt = jQuery.extend( {}, optall ),
8199 isElement = this.nodeType === 1,
8200 hidden = isElement && jQuery(this).is(":hidden"),
8203 parts, start, end, unit;
8205 // will store per property easing and be used to determine when an animation is complete
8206 opt.animatedProperties = {};
8210 // property name normalization
8211 name = jQuery.camelCase( p );
8213 prop[ name ] = prop[ p ];
8219 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8220 if ( jQuery.isArray( val ) ) {
8221 opt.animatedProperties[ name ] = val[ 1 ];
8222 val = prop[ name ] = val[ 0 ];
8224 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8227 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8228 return opt.complete.call( this );
8231 if ( isElement && ( name === "height" || name === "width" ) ) {
8232 // Make sure that nothing sneaks out
8233 // Record all 3 overflow attributes because IE does not
8234 // change the overflow attribute when overflowX and
8235 // overflowY are set to the same value
8236 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8238 // Set display property to inline-block for height/width
8239 // animations on inline elements that are having width/height
8241 if ( jQuery.css( this, "display" ) === "inline" &&
8242 jQuery.css( this, "float" ) === "none" ) {
8243 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8244 this.style.display = "inline-block";
8247 display = defaultDisplay( this.nodeName );
8249 // inline-level elements accept inline-block;
8250 // block-level elements need to be inline with layout
8251 if ( display === "inline" ) {
8252 this.style.display = "inline-block";
8255 this.style.display = "inline";
8256 this.style.zoom = 1;
8263 if ( opt.overflow != null ) {
8264 this.style.overflow = "hidden";
8268 e = new jQuery.fx( this, opt, p );
8271 if ( rfxtypes.test(val) ) {
8272 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8275 parts = rfxnum.exec( val );
8279 end = parseFloat( parts[2] );
8280 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8282 // We need to compute starting value
8283 if ( unit !== "px" ) {
8284 jQuery.style( this, p, (end || 1) + unit);
8285 start = ((end || 1) / e.cur()) * start;
8286 jQuery.style( this, p, start + unit);
8289 // If a +=/-= token was provided, we're doing a relative animation
8291 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8294 e.custom( start, end, unit );
8297 e.custom( start, val, "" );
8302 // For JS strict compliance
8307 stop: function( clearQueue, gotoEnd ) {
8312 this.each(function() {
8313 var timers = jQuery.timers,
8315 // clear marker counters if we know they won't be
8317 jQuery._unmark( true, this );
8320 if ( timers[i].elem === this ) {
8322 // force the next step to be the last
8326 timers.splice(i, 1);
8331 // start the next in the queue if the last step wasn't forced
8341 // Animations created synchronously will run synchronously
8342 function createFxNow() {
8343 setTimeout( clearFxNow, 0 );
8344 return ( fxNow = jQuery.now() );
8347 function clearFxNow() {
8351 // Generate parameters to create a standard animation
8352 function genFx( type, num ) {
8355 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8362 // Generate shortcuts for custom animations
8364 slideDown: genFx("show", 1),
8365 slideUp: genFx("hide", 1),
8366 slideToggle: genFx("toggle", 1),
8367 fadeIn: { opacity: "show" },
8368 fadeOut: { opacity: "hide" },
8369 fadeToggle: { opacity: "toggle" }
8370 }, function( name, props ) {
8371 jQuery.fn[ name ] = function( speed, easing, callback ) {
8372 return this.animate( props, speed, easing, callback );
8377 speed: function( speed, easing, fn ) {
8378 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8379 complete: fn || !fn && easing ||
8380 jQuery.isFunction( speed ) && speed,
8382 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8385 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8386 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8389 opt.old = opt.complete;
8390 opt.complete = function( noUnmark ) {
8391 if ( jQuery.isFunction( opt.old ) ) {
8392 opt.old.call( this );
8395 if ( opt.queue !== false ) {
8396 jQuery.dequeue( this );
8397 } else if ( noUnmark !== false ) {
8398 jQuery._unmark( this );
8406 linear: function( p, n, firstNum, diff ) {
8407 return firstNum + diff * p;
8409 swing: function( p, n, firstNum, diff ) {
8410 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8416 fx: function( elem, options, prop ) {
8417 this.options = options;
8421 options.orig = options.orig || {};
8426 jQuery.fx.prototype = {
8427 // Simple function for setting a style value
8428 update: function() {
8429 if ( this.options.step ) {
8430 this.options.step.call( this.elem, this.now, this );
8433 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8436 // Get the current size
8438 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8439 return this.elem[ this.prop ];
8443 r = jQuery.css( this.elem, this.prop );
8444 // Empty strings, null, undefined and "auto" are converted to 0,
8445 // complex values such as "rotate(1rad)" are returned as is,
8446 // simple values such as "10px" are parsed to Float.
8447 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8450 // Start an animation from one number to another
8451 custom: function( from, to, unit ) {
8455 this.startTime = fxNow || createFxNow();
8458 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8459 this.now = this.start;
8460 this.pos = this.state = 0;
8462 function t( gotoEnd ) {
8463 return self.step(gotoEnd);
8468 if ( t() && jQuery.timers.push(t) && !timerId ) {
8469 timerId = setInterval( fx.tick, fx.interval );
8473 // Simple 'show' function
8475 // Remember where we started, so that we can go back to it later
8476 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8477 this.options.show = true;
8479 // Begin the animation
8480 // Make sure that we start at a small width/height to avoid any
8482 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8484 // Start by showing the element
8485 jQuery( this.elem ).show();
8488 // Simple 'hide' function
8490 // Remember where we started, so that we can go back to it later
8491 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8492 this.options.hide = true;
8494 // Begin the animation
8495 this.custom(this.cur(), 0);
8498 // Each step of an animation
8499 step: function( gotoEnd ) {
8500 var t = fxNow || createFxNow(),
8503 options = this.options,
8506 if ( gotoEnd || t >= options.duration + this.startTime ) {
8507 this.now = this.end;
8508 this.pos = this.state = 1;
8511 options.animatedProperties[ this.prop ] = true;
8513 for ( i in options.animatedProperties ) {
8514 if ( options.animatedProperties[i] !== true ) {
8520 // Reset the overflow
8521 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8523 jQuery.each( [ "", "X", "Y" ], function (index, value) {
8524 elem.style[ "overflow" + value ] = options.overflow[index];
8528 // Hide the element if the "hide" operation was done
8529 if ( options.hide ) {
8530 jQuery(elem).hide();
8533 // Reset the properties, if the item has been hidden or shown
8534 if ( options.hide || options.show ) {
8535 for ( var p in options.animatedProperties ) {
8536 jQuery.style( elem, p, options.orig[p] );
8540 // Execute the complete function
8541 options.complete.call( elem );
8547 // classical easing cannot be used with an Infinity duration
8548 if ( options.duration == Infinity ) {
8551 n = t - this.startTime;
8552 this.state = n / options.duration;
8554 // Perform the easing function, defaults to swing
8555 this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8556 this.now = this.start + ((this.end - this.start) * this.pos);
8558 // Perform the next step of the animation
8566 jQuery.extend( jQuery.fx, {
8568 for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8569 if ( !timers[i]() ) {
8570 timers.splice(i--, 1);
8574 if ( !timers.length ) {
8582 clearInterval( timerId );
8594 opacity: function( fx ) {
8595 jQuery.style( fx.elem, "opacity", fx.now );
8598 _default: function( fx ) {
8599 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8600 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8602 fx.elem[ fx.prop ] = fx.now;
8608 if ( jQuery.expr && jQuery.expr.filters ) {
8609 jQuery.expr.filters.animated = function( elem ) {
8610 return jQuery.grep(jQuery.timers, function( fn ) {
8611 return elem === fn.elem;
8616 // Try to restore the default display value of an element
8617 function defaultDisplay( nodeName ) {
8619 if ( !elemdisplay[ nodeName ] ) {
8621 var body = document.body,
8622 elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
8623 display = elem.css( "display" );
8627 // If the simple way fails,
8628 // get element's real default display by attaching it to a temp iframe
8629 if ( display === "none" || display === "" ) {
8630 // No iframe to use yet, so create it
8632 iframe = document.createElement( "iframe" );
8633 iframe.frameBorder = iframe.width = iframe.height = 0;
8636 body.appendChild( iframe );
8638 // Create a cacheable copy of the iframe document on first call.
8639 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
8640 // document to it; WebKit & Firefox won't allow reusing the iframe document.
8641 if ( !iframeDoc || !iframe.createElement ) {
8642 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8643 iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
8647 elem = iframeDoc.createElement( nodeName );
8649 iframeDoc.body.appendChild( elem );
8651 display = jQuery.css( elem, "display" );
8653 body.removeChild( iframe );
8656 // Store the correct default display
8657 elemdisplay[ nodeName ] = display;
8660 return elemdisplay[ nodeName ];
8666 var rtable = /^t(?:able|d|h)$/i,
8667 rroot = /^(?:body|html)$/i;
8669 if ( "getBoundingClientRect" in document.documentElement ) {
8670 jQuery.fn.offset = function( options ) {
8671 var elem = this[0], box;
8674 return this.each(function( i ) {
8675 jQuery.offset.setOffset( this, options, i );
8679 if ( !elem || !elem.ownerDocument ) {
8683 if ( elem === elem.ownerDocument.body ) {
8684 return jQuery.offset.bodyOffset( elem );
8688 box = elem.getBoundingClientRect();
8691 var doc = elem.ownerDocument,
8692 docElem = doc.documentElement;
8694 // Make sure we're not dealing with a disconnected DOM node
8695 if ( !box || !jQuery.contains( docElem, elem ) ) {
8696 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8699 var body = doc.body,
8700 win = getWindow(doc),
8701 clientTop = docElem.clientTop || body.clientTop || 0,
8702 clientLeft = docElem.clientLeft || body.clientLeft || 0,
8703 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
8704 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8705 top = box.top + scrollTop - clientTop,
8706 left = box.left + scrollLeft - clientLeft;
8708 return { top: top, left: left };
8712 jQuery.fn.offset = function( options ) {
8716 return this.each(function( i ) {
8717 jQuery.offset.setOffset( this, options, i );
8721 if ( !elem || !elem.ownerDocument ) {
8725 if ( elem === elem.ownerDocument.body ) {
8726 return jQuery.offset.bodyOffset( elem );
8729 jQuery.offset.initialize();
8732 offsetParent = elem.offsetParent,
8733 prevOffsetParent = elem,
8734 doc = elem.ownerDocument,
8735 docElem = doc.documentElement,
8737 defaultView = doc.defaultView,
8738 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8739 top = elem.offsetTop,
8740 left = elem.offsetLeft;
8742 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8743 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8747 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8748 top -= elem.scrollTop;
8749 left -= elem.scrollLeft;
8751 if ( elem === offsetParent ) {
8752 top += elem.offsetTop;
8753 left += elem.offsetLeft;
8755 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8756 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8757 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8760 prevOffsetParent = offsetParent;
8761 offsetParent = elem.offsetParent;
8764 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8765 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8766 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8769 prevComputedStyle = computedStyle;
8772 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8773 top += body.offsetTop;
8774 left += body.offsetLeft;
8777 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8778 top += Math.max( docElem.scrollTop, body.scrollTop );
8779 left += Math.max( docElem.scrollLeft, body.scrollLeft );
8782 return { top: top, left: left };
8787 initialize: function() {
8788 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8789 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>";
8791 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8793 container.innerHTML = html;
8794 body.insertBefore( container, body.firstChild );
8795 innerDiv = container.firstChild;
8796 checkDiv = innerDiv.firstChild;
8797 td = innerDiv.nextSibling.firstChild.firstChild;
8799 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8800 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8802 checkDiv.style.position = "fixed";
8803 checkDiv.style.top = "20px";
8805 // safari subtracts parent border width here which is 5px
8806 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8807 checkDiv.style.position = checkDiv.style.top = "";
8809 innerDiv.style.overflow = "hidden";
8810 innerDiv.style.position = "relative";
8812 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8814 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8816 body.removeChild( container );
8817 jQuery.offset.initialize = jQuery.noop;
8820 bodyOffset: function( body ) {
8821 var top = body.offsetTop,
8822 left = body.offsetLeft;
8824 jQuery.offset.initialize();
8826 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8827 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8828 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8831 return { top: top, left: left };
8834 setOffset: function( elem, options, i ) {
8835 var position = jQuery.css( elem, "position" );
8837 // set position first, in-case top/left are set even on static elem
8838 if ( position === "static" ) {
8839 elem.style.position = "relative";
8842 var curElem = jQuery( elem ),
8843 curOffset = curElem.offset(),
8844 curCSSTop = jQuery.css( elem, "top" ),
8845 curCSSLeft = jQuery.css( elem, "left" ),
8846 calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8847 props = {}, curPosition = {}, curTop, curLeft;
8849 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8850 if ( calculatePosition ) {
8851 curPosition = curElem.position();
8852 curTop = curPosition.top;
8853 curLeft = curPosition.left;
8855 curTop = parseFloat( curCSSTop ) || 0;
8856 curLeft = parseFloat( curCSSLeft ) || 0;
8859 if ( jQuery.isFunction( options ) ) {
8860 options = options.call( elem, i, curOffset );
8863 if (options.top != null) {
8864 props.top = (options.top - curOffset.top) + curTop;
8866 if (options.left != null) {
8867 props.left = (options.left - curOffset.left) + curLeft;
8870 if ( "using" in options ) {
8871 options.using.call( elem, props );
8873 curElem.css( props );
8880 position: function() {
8887 // Get *real* offsetParent
8888 offsetParent = this.offsetParent(),
8890 // Get correct offsets
8891 offset = this.offset(),
8892 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8894 // Subtract element margins
8895 // note: when an element has margin: auto the offsetLeft and marginLeft
8896 // are the same in Safari causing offset.left to incorrectly be 0
8897 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8898 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8900 // Add offsetParent borders
8901 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8902 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8904 // Subtract the two offsets
8906 top: offset.top - parentOffset.top,
8907 left: offset.left - parentOffset.left
8911 offsetParent: function() {
8912 return this.map(function() {
8913 var offsetParent = this.offsetParent || document.body;
8914 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8915 offsetParent = offsetParent.offsetParent;
8917 return offsetParent;
8923 // Create scrollLeft and scrollTop methods
8924 jQuery.each( ["Left", "Top"], function( i, name ) {
8925 var method = "scroll" + name;
8927 jQuery.fn[ method ] = function( val ) {
8930 if ( val === undefined ) {
8937 win = getWindow( elem );
8939 // Return the scroll offset
8940 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8941 jQuery.support.boxModel && win.document.documentElement[ method ] ||
8942 win.document.body[ method ] :
8946 // Set the scroll offset
8947 return this.each(function() {
8948 win = getWindow( this );
8952 !i ? val : jQuery( win ).scrollLeft(),
8953 i ? val : jQuery( win ).scrollTop()
8957 this[ method ] = val;
8963 function getWindow( elem ) {
8964 return jQuery.isWindow( elem ) ?
8966 elem.nodeType === 9 ?
8967 elem.defaultView || elem.parentWindow :
8974 // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
8975 jQuery.each([ "Height", "Width" ], function( i, name ) {
8977 var type = name.toLowerCase();
8979 // innerHeight and innerWidth
8980 jQuery.fn[ "inner" + name ] = function() {
8982 return elem && elem.style ?
8983 parseFloat( jQuery.css( elem, type, "padding" ) ) :
8987 // outerHeight and outerWidth
8988 jQuery.fn[ "outer" + name ] = function( margin ) {
8990 return elem && elem.style ?
8991 parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
8995 jQuery.fn[ type ] = function( size ) {
8996 // Get window width or height
8999 return size == null ? null : this;
9002 if ( jQuery.isFunction( size ) ) {
9003 return this.each(function( i ) {
9004 var self = jQuery( this );
9005 self[ type ]( size.call( this, i, self[ type ]() ) );
9009 if ( jQuery.isWindow( elem ) ) {
9010 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
9011 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9012 var docElemProp = elem.document.documentElement[ "client" + name ],
9013 body = elem.document.body;
9014 return elem.document.compatMode === "CSS1Compat" && docElemProp ||
9015 body && body[ "client" + name ] || docElemProp;
9017 // Get document width or height
9018 } else if ( elem.nodeType === 9 ) {
9019 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9021 elem.documentElement["client" + name],
9022 elem.body["scroll" + name], elem.documentElement["scroll" + name],
9023 elem.body["offset" + name], elem.documentElement["offset" + name]
9026 // Get or set width or height on the element
9027 } else if ( size === undefined ) {
9028 var orig = jQuery.css( elem, type ),
9029 ret = parseFloat( orig );
9031 return jQuery.isNaN( ret ) ? orig : ret;
9033 // Set the width or height on the element (default to pixels if value is unitless)
9035 return this.css( type, typeof size === "string" ? size : size + "px" );
9042 // Expose jQuery to the global object
9043 window.jQuery = window.$ = jQuery;