2 * Copyright 2010-2013 Ben Birch
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this software except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * jQuery JavaScript Library v1.6.1
20 * Copyright 2011, John Resig
21 * Dual licensed under the MIT or GPL Version 2 licenses.
22 * http://jquery.org/license
25 * http://sizzlejs.com/
26 * Copyright 2011, The Dojo Foundation
27 * Released under the MIT, BSD, and GPL Licenses.
29 * Date: Thu May 12 15:04:36 2011 -0400
31 (function( window, undefined ) {
33 // Use the correct document accordingly with window argument (sandbox)
34 var document = window.document,
35 navigator = window.navigator,
36 location = window.location;
37 var jQuery = (function() {
39 // Define a local copy of jQuery
40 var jQuery = function( selector, context ) {
41 // The jQuery object is actually just the init constructor 'enhanced'
42 return new jQuery.fn.init( selector, context, rootjQuery );
45 // Map over jQuery in case of overwrite
46 _jQuery = window.jQuery,
48 // Map over the $ in case of overwrite
51 // A central reference to the root jQuery(document)
54 // A simple way to check for HTML strings or ID strings
55 // (both of which we optimize for)
56 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
58 // Check if a string has a non-whitespace character in it
61 // Used for trimming whitespace
68 // Match a standalone tag
69 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
72 rvalidchars = /^[\],:{}\s]*$/,
73 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
74 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
75 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
78 rwebkit = /(webkit)[ \/]([\w.]+)/,
79 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
80 rmsie = /(msie) ([\w.]+)/,
81 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
83 // Keep a UserAgent string for use with jQuery.browser
84 userAgent = navigator.userAgent,
86 // For matching the engine and version of the browser
89 // The deferred used on DOM ready
92 // The ready event handler
95 // Save a reference to some core methods
96 toString = Object.prototype.toString,
97 hasOwn = Object.prototype.hasOwnProperty,
98 push = Array.prototype.push,
99 slice = Array.prototype.slice,
100 trim = String.prototype.trim,
101 indexOf = Array.prototype.indexOf,
103 // [[Class]] -> type pairs
106 jQuery.fn = jQuery.prototype = {
108 init: function( selector, context, rootjQuery ) {
109 var match, elem, ret, doc;
111 // Handle $(""), $(null), or $(undefined)
116 // Handle $(DOMElement)
117 if ( selector.nodeType ) {
118 this.context = this[0] = selector;
123 // The body element only exists once, optimize finding it
124 if ( selector === "body" && !context && document.body ) {
125 this.context = document;
126 this[0] = document.body;
127 this.selector = selector;
132 // Handle HTML strings
133 if ( typeof selector === "string" ) {
134 // Are we dealing with HTML string or an ID?
135 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
136 // Assume that strings that start and end with <> are HTML and skip the regex check
137 match = [ null, selector, null ];
140 match = quickExpr.exec( selector );
143 // Verify a match, and that no context was specified for #id
144 if ( match && (match[1] || !context) ) {
146 // HANDLE: $(html) -> $(array)
148 context = context instanceof jQuery ? context[0] : context;
149 doc = (context ? context.ownerDocument || context : document);
151 // If a single string is passed in and it's a single tag
152 // just do a createElement and skip the rest
153 ret = rsingleTag.exec( selector );
156 if ( jQuery.isPlainObject( context ) ) {
157 selector = [ document.createElement( ret[1] ) ];
158 jQuery.fn.attr.call( selector, context, true );
161 selector = [ doc.createElement( ret[1] ) ];
165 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
166 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
169 return jQuery.merge( this, selector );
173 elem = document.getElementById( match[2] );
175 // Check parentNode to catch when Blackberry 4.6 returns
176 // nodes that are no longer in the document #6963
177 if ( elem && elem.parentNode ) {
178 // Handle the case where IE and Opera return items
179 // by name instead of ID
180 if ( elem.id !== match[2] ) {
181 return rootjQuery.find( selector );
184 // Otherwise, we inject the element directly into the jQuery object
189 this.context = document;
190 this.selector = selector;
194 // HANDLE: $(expr, $(...))
195 } else if ( !context || context.jquery ) {
196 return (context || rootjQuery).find( selector );
198 // HANDLE: $(expr, context)
199 // (which is just equivalent to: $(context).find(expr)
201 return this.constructor( context ).find( selector );
204 // HANDLE: $(function)
205 // Shortcut for document ready
206 } else if ( jQuery.isFunction( selector ) ) {
207 return rootjQuery.ready( selector );
210 if (selector.selector !== undefined) {
211 this.selector = selector.selector;
212 this.context = selector.context;
215 return jQuery.makeArray( selector, this );
218 // Start with an empty selector
221 // The current version of jQuery being used
224 // The default length of a jQuery object is 0
227 // The number of elements contained in the matched element set
232 toArray: function() {
233 return slice.call( this, 0 );
236 // Get the Nth element in the matched element set OR
237 // Get the whole matched element set as a clean array
238 get: function( num ) {
241 // Return a 'clean' array
244 // Return just the object
245 ( num < 0 ? this[ this.length + num ] : this[ num ] );
248 // Take an array of elements and push it onto the stack
249 // (returning the new matched element set)
250 pushStack: function( elems, name, selector ) {
251 // Build a new jQuery matched element set
252 var ret = this.constructor();
254 if ( jQuery.isArray( elems ) ) {
255 push.apply( ret, elems );
258 jQuery.merge( ret, elems );
261 // Add the old object onto the stack (as a reference)
262 ret.prevObject = this;
264 ret.context = this.context;
266 if ( name === "find" ) {
267 ret.selector = this.selector + (this.selector ? " " : "") + selector;
269 ret.selector = this.selector + "." + name + "(" + selector + ")";
272 // Return the newly-formed element set
276 // Execute a callback for every element in the matched set.
277 // (You can seed the arguments with an array of args, but this is
278 // only used internally.)
279 each: function( callback, args ) {
280 return jQuery.each( this, callback, args );
283 ready: function( fn ) {
284 // Attach the listeners
288 readyList.done( fn );
296 this.slice( i, +i + 1 );
304 return this.eq( -1 );
308 return this.pushStack( slice.apply( this, arguments ),
309 "slice", slice.call(arguments).join(",") );
312 map: function( callback ) {
313 return this.pushStack( jQuery.map(this, function( elem, i ) {
314 return callback.call( elem, i, elem );
319 return this.prevObject || this.constructor(null);
322 // For internal use only.
323 // Behaves like an Array's method, not like a jQuery method.
329 // Give the init function the jQuery prototype for later instantiation
330 jQuery.fn.init.prototype = jQuery.fn;
332 jQuery.extend = jQuery.fn.extend = function() {
333 var options, name, src, copy, copyIsArray, clone,
334 target = arguments[0] || {},
336 length = arguments.length,
339 // Handle a deep copy situation
340 if ( typeof target === "boolean" ) {
342 target = arguments[1] || {};
343 // skip the boolean and the target
347 // Handle case when target is a string or something (possible in deep copy)
348 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
352 // extend jQuery itself if only one argument is passed
353 if ( length === i ) {
358 for ( ; i < length; i++ ) {
359 // Only deal with non-null/undefined values
360 if ( (options = arguments[ i ]) != null ) {
361 // Extend the base object
362 for ( name in options ) {
363 src = target[ name ];
364 copy = options[ name ];
366 // Prevent never-ending loop
367 if ( target === copy ) {
371 // Recurse if we're merging plain objects or arrays
372 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
375 clone = src && jQuery.isArray(src) ? src : [];
378 clone = src && jQuery.isPlainObject(src) ? src : {};
381 // Never move original objects, clone them
382 target[ name ] = jQuery.extend( deep, clone, copy );
384 // Don't bring in undefined values
385 } else if ( copy !== undefined ) {
386 target[ name ] = copy;
392 // Return the modified object
397 noConflict: function( deep ) {
398 if ( window.$ === jQuery ) {
402 if ( deep && window.jQuery === jQuery ) {
403 window.jQuery = _jQuery;
409 // Is the DOM ready to be used? Set to true once it occurs.
412 // A counter to track how many items to wait for before
413 // the ready event fires. See #6781
416 // Hold (or release) the ready event
417 holdReady: function( hold ) {
421 jQuery.ready( true );
425 // Handle when the DOM is ready
426 ready: function( wait ) {
427 // Either a released hold or an DOMready/load event and not yet ready
428 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
429 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
430 if ( !document.body ) {
431 return setTimeout( jQuery.ready, 1 );
434 // Remember that the DOM is ready
435 jQuery.isReady = true;
437 // If a normal DOM Ready event fired, decrement, and wait if need be
438 if ( wait !== true && --jQuery.readyWait > 0 ) {
442 // If there are functions bound, to execute
443 readyList.resolveWith( document, [ jQuery ] );
445 // Trigger any bound ready events
446 if ( jQuery.fn.trigger ) {
447 jQuery( document ).trigger( "ready" ).unbind( "ready" );
452 bindReady: function() {
457 readyList = jQuery._Deferred();
459 // Catch cases where $(document).ready() is called after the
460 // browser event has already occurred.
461 if ( document.readyState === "complete" ) {
462 // Handle it asynchronously to allow scripts the opportunity to delay ready
463 return setTimeout( jQuery.ready, 1 );
466 // Mozilla, Opera and webkit nightlies currently support this event
467 if ( document.addEventListener ) {
468 // Use the handy event callback
469 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
471 // A fallback to window.onload, that will always work
472 window.addEventListener( "load", jQuery.ready, false );
474 // If IE event model is used
475 } else if ( document.attachEvent ) {
476 // ensure firing before onload,
477 // maybe late but safe also for iframes
478 document.attachEvent( "onreadystatechange", DOMContentLoaded );
480 // A fallback to window.onload, that will always work
481 window.attachEvent( "onload", jQuery.ready );
483 // If IE and not a frame
484 // continually check to see if the document is ready
485 var toplevel = false;
488 toplevel = window.frameElement == null;
491 if ( document.documentElement.doScroll && toplevel ) {
497 // See test/unit/core.js for details concerning isFunction.
498 // Since version 1.3, DOM methods and functions like alert
499 // aren't supported. They return false on IE (#2968).
500 isFunction: function( obj ) {
501 return jQuery.type(obj) === "function";
504 isArray: Array.isArray || function( obj ) {
505 return jQuery.type(obj) === "array";
508 // A crude way of determining if an object is a window
509 isWindow: function( obj ) {
510 return obj && typeof obj === "object" && "setInterval" in obj;
513 isNaN: function( obj ) {
514 return obj == null || !rdigit.test( obj ) || isNaN( obj );
517 type: function( obj ) {
520 class2type[ toString.call(obj) ] || "object";
523 isPlainObject: function( obj ) {
524 // Must be an Object.
525 // Because of IE, we also have to check the presence of the constructor property.
526 // Make sure that DOM nodes and window objects don't pass through, as well
527 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
531 // Not own constructor property must be Object
532 if ( obj.constructor &&
533 !hasOwn.call(obj, "constructor") &&
534 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
538 // Own properties are enumerated firstly, so to speed up,
539 // if last one is own, then all properties are own.
542 for ( key in obj ) {}
544 return key === undefined || hasOwn.call( obj, key );
547 isEmptyObject: function( obj ) {
548 for ( var name in obj ) {
554 error: function( msg ) {
558 parseJSON: function( data ) {
559 if ( typeof data !== "string" || !data ) {
563 // Make sure leading/trailing whitespace is removed (IE can't handle it)
564 data = jQuery.trim( data );
566 // Attempt to parse using the native JSON parser first
567 if ( window.JSON && window.JSON.parse ) {
568 return window.JSON.parse( data );
571 // Make sure the incoming data is actual JSON
572 // Logic borrowed from http://json.org/json2.js
573 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
574 .replace( rvalidtokens, "]" )
575 .replace( rvalidbraces, "")) ) {
577 return (new Function( "return " + data ))();
580 jQuery.error( "Invalid JSON: " + data );
583 // Cross-browser xml parsing
584 // (xml & tmp used internally)
585 parseXML: function( data , xml , tmp ) {
587 if ( window.DOMParser ) { // Standard
588 tmp = new DOMParser();
589 xml = tmp.parseFromString( data , "text/xml" );
591 xml = new ActiveXObject( "Microsoft.XMLDOM" );
596 tmp = xml.documentElement;
598 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
599 jQuery.error( "Invalid XML: " + data );
607 // Evaluates a script in a global context
608 // Workarounds based on findings by Jim Driscoll
609 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
610 globalEval: function( data ) {
611 if ( data && rnotwhite.test( data ) ) {
612 // We use execScript on Internet Explorer
613 // We use an anonymous function so that context is window
614 // rather than jQuery in Firefox
615 ( window.execScript || function( data ) {
616 window[ "eval" ].call( window, data );
621 nodeName: function( elem, name ) {
622 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
625 // args is for internal usage only
626 each: function( object, callback, args ) {
628 length = object.length,
629 isObj = length === undefined || jQuery.isFunction( object );
633 for ( name in object ) {
634 if ( callback.apply( object[ name ], args ) === false ) {
639 for ( ; i < length; ) {
640 if ( callback.apply( object[ i++ ], args ) === false ) {
646 // A special, fast, case for the most common use of each
649 for ( name in object ) {
650 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
655 for ( ; i < length; ) {
656 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
666 // Use native String.trim function wherever possible
669 return text == null ?
674 // Otherwise use our own trimming functionality
676 return text == null ?
678 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
681 // results is for internal usage only
682 makeArray: function( array, results ) {
683 var ret = results || [];
685 if ( array != null ) {
686 // The window, strings (and functions) also have 'length'
687 // The extra typeof function check is to prevent crashes
688 // in Safari 2 (See: #3039)
689 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
690 var type = jQuery.type( array );
692 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
693 push.call( ret, array );
695 jQuery.merge( ret, array );
702 inArray: function( elem, array ) {
705 return indexOf.call( array, elem );
708 for ( var i = 0, length = array.length; i < length; i++ ) {
709 if ( array[ i ] === elem ) {
717 merge: function( first, second ) {
718 var i = first.length,
721 if ( typeof second.length === "number" ) {
722 for ( var l = second.length; j < l; j++ ) {
723 first[ i++ ] = second[ j ];
727 while ( second[j] !== undefined ) {
728 first[ i++ ] = second[ j++ ];
737 grep: function( elems, callback, inv ) {
738 var ret = [], retVal;
741 // Go through the array, only saving the items
742 // that pass the validator function
743 for ( var i = 0, length = elems.length; i < length; i++ ) {
744 retVal = !!callback( elems[ i ], i );
745 if ( inv !== retVal ) {
746 ret.push( elems[ i ] );
753 // arg is for internal usage only
754 map: function( elems, callback, arg ) {
755 var value, key, ret = [],
757 length = elems.length,
758 // jquery objects are treated as arrays
759 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
761 // Go through the array, translating each of the items to their
763 for ( ; i < length; i++ ) {
764 value = callback( elems[ i ], i, arg );
766 if ( value != null ) {
767 ret[ ret.length ] = value;
771 // Go through every key on the object,
773 for ( key in elems ) {
774 value = callback( elems[ key ], key, arg );
776 if ( value != null ) {
777 ret[ ret.length ] = value;
782 // Flatten any nested arrays
783 return ret.concat.apply( [], ret );
786 // A global GUID counter for objects
789 // Bind a function to a context, optionally partially applying any
791 proxy: function( fn, context ) {
792 if ( typeof context === "string" ) {
793 var tmp = fn[ context ];
798 // Quick check to determine if target is callable, in the spec
799 // this throws a TypeError, but we will just return undefined.
800 if ( !jQuery.isFunction( fn ) ) {
805 var args = slice.call( arguments, 2 ),
807 return fn.apply( context, args.concat( slice.call( arguments ) ) );
810 // Set the guid of unique handler to the same of original handler, so it can be removed
811 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
816 // Mutifunctional method to get and set values to a collection
817 // The value/s can be optionally by executed if its a function
818 access: function( elems, key, value, exec, fn, pass ) {
819 var length = elems.length;
821 // Setting many attributes
822 if ( typeof key === "object" ) {
823 for ( var k in key ) {
824 jQuery.access( elems, k, key[k], exec, fn, value );
829 // Setting one attribute
830 if ( value !== undefined ) {
831 // Optionally, function values get executed if exec is true
832 exec = !pass && exec && jQuery.isFunction(value);
834 for ( var i = 0; i < length; i++ ) {
835 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
841 // Getting an attribute
842 return length ? fn( elems[0], key ) : undefined;
846 return (new Date()).getTime();
849 // Use of jQuery.browser is frowned upon.
850 // More details: http://docs.jquery.com/Utilities/jQuery.browser
851 uaMatch: function( ua ) {
852 ua = ua.toLowerCase();
854 var match = rwebkit.exec( ua ) ||
857 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
860 return { browser: match[1] || "", version: match[2] || "0" };
864 function jQuerySub( selector, context ) {
865 return new jQuerySub.fn.init( selector, context );
867 jQuery.extend( true, jQuerySub, this );
868 jQuerySub.superclass = this;
869 jQuerySub.fn = jQuerySub.prototype = this();
870 jQuerySub.fn.constructor = jQuerySub;
871 jQuerySub.sub = this.sub;
872 jQuerySub.fn.init = function init( selector, context ) {
873 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
874 context = jQuerySub( context );
877 return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
879 jQuerySub.fn.init.prototype = jQuerySub.fn;
880 var rootjQuerySub = jQuerySub(document);
887 // Populate the class2type map
888 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
889 class2type[ "[object " + name + "]" ] = name.toLowerCase();
892 browserMatch = jQuery.uaMatch( userAgent );
893 if ( browserMatch.browser ) {
894 jQuery.browser[ browserMatch.browser ] = true;
895 jQuery.browser.version = browserMatch.version;
898 // Deprecated, use jQuery.browser.webkit instead
899 if ( jQuery.browser.webkit ) {
900 jQuery.browser.safari = true;
903 // IE doesn't match non-breaking spaces with \s
904 if ( rnotwhite.test( "\xA0" ) ) {
905 trimLeft = /^[\s\xA0]+/;
906 trimRight = /[\s\xA0]+$/;
909 // All jQuery objects should point back to these
910 rootjQuery = jQuery(document);
912 // Cleanup functions for the document ready method
913 if ( document.addEventListener ) {
914 DOMContentLoaded = function() {
915 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
919 } else if ( document.attachEvent ) {
920 DOMContentLoaded = function() {
921 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
922 if ( document.readyState === "complete" ) {
923 document.detachEvent( "onreadystatechange", DOMContentLoaded );
929 // The DOM ready check for Internet Explorer
930 function doScrollCheck() {
931 if ( jQuery.isReady ) {
936 // If IE is used, use the trick by Diego Perini
937 // http://javascript.nwbox.com/IEContentLoaded/
938 document.documentElement.doScroll("left");
940 setTimeout( doScrollCheck, 1 );
944 // and execute any waiting functions
948 // Expose jQuery to the global object
954 var // Promise methods
955 promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
956 // Static reference to slice
957 sliceDeferred = [].slice;
960 // Create a simple deferred (one callbacks list)
961 _Deferred: function() {
962 var // callbacks list
964 // stored [ context , args ]
966 // to avoid firing when already doing so
968 // flag to know if the deferred has been cancelled
970 // the deferred itself
973 // done( f1, f2, ...)
976 var args = arguments,
986 for ( i = 0, length = args.length; i < length; i++ ) {
988 type = jQuery.type( elem );
989 if ( type === "array" ) {
990 deferred.done.apply( deferred, elem );
991 } else if ( type === "function" ) {
992 callbacks.push( elem );
996 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
1002 // resolve with given context and args
1003 resolveWith: function( context, args ) {
1004 if ( !cancelled && !fired && !firing ) {
1005 // make sure args are available (#8421)
1009 while( callbacks[ 0 ] ) {
1010 callbacks.shift().apply( context, args );
1014 fired = [ context, args ];
1021 // resolve with this as context and given arguments
1022 resolve: function() {
1023 deferred.resolveWith( this, arguments );
1027 // Has this deferred been resolved?
1028 isResolved: function() {
1029 return !!( firing || fired );
1033 cancel: function() {
1043 // Full fledged deferred (two callbacks list)
1044 Deferred: function( func ) {
1045 var deferred = jQuery._Deferred(),
1046 failDeferred = jQuery._Deferred(),
1048 // Add errorDeferred methods, then and promise
1049 jQuery.extend( deferred, {
1050 then: function( doneCallbacks, failCallbacks ) {
1051 deferred.done( doneCallbacks ).fail( failCallbacks );
1054 always: function() {
1055 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1057 fail: failDeferred.done,
1058 rejectWith: failDeferred.resolveWith,
1059 reject: failDeferred.resolve,
1060 isRejected: failDeferred.isResolved,
1061 pipe: function( fnDone, fnFail ) {
1062 return jQuery.Deferred(function( newDefer ) {
1064 done: [ fnDone, "resolve" ],
1065 fail: [ fnFail, "reject" ]
1066 }, function( handler, data ) {
1070 if ( jQuery.isFunction( fn ) ) {
1071 deferred[ handler ](function() {
1072 returned = fn.apply( this, arguments );
1073 if ( returned && jQuery.isFunction( returned.promise ) ) {
1074 returned.promise().then( newDefer.resolve, newDefer.reject );
1076 newDefer[ action ]( returned );
1080 deferred[ handler ]( newDefer[ action ] );
1085 // Get a promise for this deferred
1086 // If obj is provided, the promise aspect is added to the object
1087 promise: function( obj ) {
1088 if ( obj == null ) {
1094 var i = promiseMethods.length;
1096 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1101 // Make sure only one callback list will be used
1102 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1104 delete deferred.cancel;
1105 // Call given func if any
1107 func.call( deferred, deferred );
1113 when: function( firstParam ) {
1114 var args = arguments,
1116 length = args.length,
1118 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1121 function resolveFunc( i ) {
1122 return function( value ) {
1123 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1124 if ( !( --count ) ) {
1125 // Strange bug in FF4:
1126 // Values changed onto the arguments object sometimes end up as undefined values
1127 // outside the $.when method. Cloning the object into a fresh array solves the issue
1128 deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1133 for( ; i < length; i++ ) {
1134 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1135 args[ i ].promise().then( resolveFunc(i), deferred.reject );
1141 deferred.resolveWith( deferred, args );
1143 } else if ( deferred !== firstParam ) {
1144 deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1146 return deferred.promise();
1152 jQuery.support = (function() {
1154 var div = document.createElement( "div" ),
1155 documentElement = document.documentElement,
1172 // Preliminary tests
1173 div.setAttribute("className", "t");
1174 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1176 all = div.getElementsByTagName( "*" );
1177 a = div.getElementsByTagName( "a" )[ 0 ];
1179 // Can't get basic test support
1180 if ( !all || !all.length || !a ) {
1184 // First batch of supports tests
1185 select = document.createElement( "select" );
1186 opt = select.appendChild( document.createElement("option") );
1187 input = div.getElementsByTagName( "input" )[ 0 ];
1190 // IE strips leading whitespace when .innerHTML is used
1191 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1193 // Make sure that tbody elements aren't automatically inserted
1194 // IE will insert them into empty tables
1195 tbody: !div.getElementsByTagName( "tbody" ).length,
1197 // Make sure that link elements get serialized correctly by innerHTML
1198 // This requires a wrapper element in IE
1199 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1201 // Get the style information from getAttribute
1202 // (IE uses .cssText instead)
1203 style: /top/.test( a.getAttribute("style") ),
1205 // Make sure that URLs aren't manipulated
1206 // (IE normalizes it by default)
1207 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1209 // Make sure that element opacity exists
1210 // (IE uses filter instead)
1211 // Use a regex to work around a WebKit issue. See #5145
1212 opacity: /^0.55$/.test( a.style.opacity ),
1214 // Verify style float existence
1215 // (IE uses styleFloat instead of cssFloat)
1216 cssFloat: !!a.style.cssFloat,
1218 // Make sure that if no value is specified for a checkbox
1219 // that it defaults to "on".
1220 // (WebKit defaults to "" instead)
1221 checkOn: ( input.value === "on" ),
1223 // Make sure that a selected-by-default option has a working selected property.
1224 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1225 optSelected: opt.selected,
1227 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1228 getSetAttribute: div.className !== "t",
1230 // Will be defined later
1231 submitBubbles: true,
1232 changeBubbles: true,
1233 focusinBubbles: false,
1234 deleteExpando: true,
1236 inlineBlockNeedsLayout: false,
1237 shrinkWrapBlocks: false,
1238 reliableMarginRight: true
1241 // Make sure checked status is properly cloned
1242 input.checked = true;
1243 support.noCloneChecked = input.cloneNode( true ).checked;
1245 // Make sure that the options inside disabled selects aren't marked as disabled
1246 // (WebKit marks them as disabled)
1247 select.disabled = true;
1248 support.optDisabled = !opt.disabled;
1250 // Test to see if it's possible to delete an expando from an element
1251 // Fails in Internet Explorer
1255 support.deleteExpando = false;
1258 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1259 div.attachEvent( "onclick", function click() {
1260 // Cloning a node shouldn't copy over any
1261 // bound event handlers (IE does this)
1262 support.noCloneEvent = false;
1263 div.detachEvent( "onclick", click );
1265 div.cloneNode( true ).fireEvent( "onclick" );
1268 // Check if a radio maintains it's value
1269 // after being appended to the DOM
1270 input = document.createElement("input");
1272 input.setAttribute("type", "radio");
1273 support.radioValue = input.value === "t";
1275 input.setAttribute("checked", "checked");
1276 div.appendChild( input );
1277 fragment = document.createDocumentFragment();
1278 fragment.appendChild( div.firstChild );
1280 // WebKit doesn't clone checked state correctly in fragments
1281 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1285 // Figure out if the W3C box model works as expected
1286 div.style.width = div.style.paddingLeft = "1px";
1288 // We use our own, invisible, body
1289 body = document.createElement( "body" );
1291 visibility: "hidden",
1296 // Set background to avoid IE crashes when removing (#9028)
1299 for ( i in bodyStyle ) {
1300 body.style[ i ] = bodyStyle[ i ];
1302 body.appendChild( div );
1303 documentElement.insertBefore( body, documentElement.firstChild );
1305 // Check if a disconnected checkbox will retain its checked
1306 // value of true after appended to the DOM (IE6/7)
1307 support.appendChecked = input.checked;
1309 support.boxModel = div.offsetWidth === 2;
1311 if ( "zoom" in div.style ) {
1312 // Check if natively block-level elements act like inline-block
1313 // elements when setting their display to 'inline' and giving
1315 // (IE < 8 does this)
1316 div.style.display = "inline";
1318 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1320 // Check if elements with layout shrink-wrap their children
1322 div.style.display = "";
1323 div.innerHTML = "<div style='width:4px;'></div>";
1324 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1327 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1328 tds = div.getElementsByTagName( "td" );
1330 // Check if table cells still have offsetWidth/Height when they are set
1331 // to display:none and there are still other visible table cells in a
1332 // table row; if so, offsetWidth/Height are not reliable for use when
1333 // determining if an element has been hidden directly using
1334 // display:none (it is still safe to use offsets if a parent element is
1335 // hidden; don safety goggles and see bug #4512 for more information).
1336 // (only IE 8 fails this test)
1337 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1339 tds[ 0 ].style.display = "";
1340 tds[ 1 ].style.display = "none";
1342 // Check if empty table cells still have offsetWidth/Height
1343 // (IE < 8 fail this test)
1344 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1347 // Check if div with explicit width and no margin-right incorrectly
1348 // gets computed margin-right based on width of container. For more
1349 // info see bug #3333
1350 // Fails in WebKit before Feb 2011 nightlies
1351 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1352 if ( document.defaultView && document.defaultView.getComputedStyle ) {
1353 marginDiv = document.createElement( "div" );
1354 marginDiv.style.width = "0";
1355 marginDiv.style.marginRight = "0";
1356 div.appendChild( marginDiv );
1357 support.reliableMarginRight =
1358 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1361 // Remove the body element we added
1362 body.innerHTML = "";
1363 documentElement.removeChild( body );
1365 // Technique from Juriy Zaytsev
1366 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1367 // We only care about the case where non-standard event systems
1368 // are used, namely in IE. Short-circuiting here helps us to
1369 // avoid an eval call (in setAttribute) which can cause CSP
1370 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1371 if ( div.attachEvent ) {
1377 eventName = "on" + i;
1378 isSupported = ( eventName in div );
1379 if ( !isSupported ) {
1380 div.setAttribute( eventName, "return;" );
1381 isSupported = ( typeof div[ eventName ] === "function" );
1383 support[ i + "Bubbles" ] = isSupported;
1390 // Keep track of boxModel
1391 jQuery.boxModel = jQuery.support.boxModel;
1396 var rbrace = /^(?:\{.*\}|\[.*\])$/,
1397 rmultiDash = /([a-z])([A-Z])/g;
1402 // Please use with caution
1405 // Unique for each copy of jQuery on the page
1406 // Non-digits removed to match rinlinejQuery
1407 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1409 // The following elements throw uncatchable exceptions if you
1410 // attempt to add expando properties to them.
1413 // Ban all objects except for Flash (which handle expandos)
1414 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1418 hasData: function( elem ) {
1419 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1421 return !!elem && !isEmptyDataObject( elem );
1424 data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1425 if ( !jQuery.acceptData( elem ) ) {
1429 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1431 // We have to handle DOM nodes and JS objects differently because IE6-7
1432 // can't GC object references properly across the DOM-JS boundary
1433 isNode = elem.nodeType,
1435 // Only DOM nodes need the global jQuery cache; JS object data is
1436 // attached directly to the object so GC can occur automatically
1437 cache = isNode ? jQuery.cache : elem,
1439 // Only defining an ID for JS objects if its cache already exists allows
1440 // the code to shortcut on the same path as a DOM node with no cache
1441 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1443 // Avoid doing any more work than we need to when trying to get data on an
1444 // object that has no data at all
1445 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1450 // Only DOM nodes need a new unique ID for each element since their data
1451 // ends up in the global cache
1453 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1455 id = jQuery.expando;
1459 if ( !cache[ id ] ) {
1462 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1463 // metadata on plain JS objects when the object is serialized using
1466 cache[ id ].toJSON = jQuery.noop;
1470 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1471 // shallow copied over onto the existing cache
1472 if ( typeof name === "object" || typeof name === "function" ) {
1474 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1476 cache[ id ] = jQuery.extend(cache[ id ], name);
1480 thisCache = cache[ id ];
1482 // Internal jQuery data is stored in a separate object inside the object's data
1483 // cache in order to avoid key collisions between internal data and user-defined
1486 if ( !thisCache[ internalKey ] ) {
1487 thisCache[ internalKey ] = {};
1490 thisCache = thisCache[ internalKey ];
1493 if ( data !== undefined ) {
1494 thisCache[ jQuery.camelCase( name ) ] = data;
1497 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1498 // not attempt to inspect the internal events object using jQuery.data, as this
1499 // internal data object is undocumented and subject to change.
1500 if ( name === "events" && !thisCache[name] ) {
1501 return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1504 return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;
1507 removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1508 if ( !jQuery.acceptData( elem ) ) {
1512 var internalKey = jQuery.expando, isNode = elem.nodeType,
1514 // See jQuery.data for more information
1515 cache = isNode ? jQuery.cache : elem,
1517 // See jQuery.data for more information
1518 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1520 // If there is already no cache entry for this object, there is no
1521 // purpose in continuing
1522 if ( !cache[ id ] ) {
1527 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1530 delete thisCache[ name ];
1532 // If there is no data left in the cache, we want to continue
1533 // and let the cache object itself get destroyed
1534 if ( !isEmptyDataObject(thisCache) ) {
1540 // See jQuery.data for more information
1542 delete cache[ id ][ internalKey ];
1544 // Don't destroy the parent cache unless the internal data object
1545 // had been the only thing left in it
1546 if ( !isEmptyDataObject(cache[ id ]) ) {
1551 var internalCache = cache[ id ][ internalKey ];
1553 // Browsers that fail expando deletion also refuse to delete expandos on
1554 // the window, but it will allow it on all other JS objects; other browsers
1556 if ( jQuery.support.deleteExpando || cache != window ) {
1562 // We destroyed the entire user cache at once because it's faster than
1563 // iterating through each key, but we need to continue to persist internal
1564 // data if it existed
1565 if ( internalCache ) {
1567 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1568 // metadata on plain JS objects when the object is serialized using
1571 cache[ id ].toJSON = jQuery.noop;
1574 cache[ id ][ internalKey ] = internalCache;
1576 // Otherwise, we need to eliminate the expando on the node to avoid
1577 // false lookups in the cache for entries that no longer exist
1578 } else if ( isNode ) {
1579 // IE does not allow us to delete expando properties from nodes,
1580 // nor does it have a removeAttribute function on Document nodes;
1581 // we must handle all of these cases
1582 if ( jQuery.support.deleteExpando ) {
1583 delete elem[ jQuery.expando ];
1584 } else if ( elem.removeAttribute ) {
1585 elem.removeAttribute( jQuery.expando );
1587 elem[ jQuery.expando ] = null;
1592 // For internal use only.
1593 _data: function( elem, name, data ) {
1594 return jQuery.data( elem, name, data, true );
1597 // A method for determining if a DOM node can handle the data expando
1598 acceptData: function( elem ) {
1599 if ( elem.nodeName ) {
1600 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1603 return !(match === true || elem.getAttribute("classid") !== match);
1612 data: function( key, value ) {
1615 if ( typeof key === "undefined" ) {
1616 if ( this.length ) {
1617 data = jQuery.data( this[0] );
1619 if ( this[0].nodeType === 1 ) {
1620 var attr = this[0].attributes, name;
1621 for ( var i = 0, l = attr.length; i < l; i++ ) {
1622 name = attr[i].name;
1624 if ( name.indexOf( "data-" ) === 0 ) {
1625 name = jQuery.camelCase( name.substring(5) );
1627 dataAttr( this[0], name, data[ name ] );
1635 } else if ( typeof key === "object" ) {
1636 return this.each(function() {
1637 jQuery.data( this, key );
1641 var parts = key.split(".");
1642 parts[1] = parts[1] ? "." + parts[1] : "";
1644 if ( value === undefined ) {
1645 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1647 // Try to fetch any internally stored data first
1648 if ( data === undefined && this.length ) {
1649 data = jQuery.data( this[0], key );
1650 data = dataAttr( this[0], key, data );
1653 return data === undefined && parts[1] ?
1654 this.data( parts[0] ) :
1658 return this.each(function() {
1659 var $this = jQuery( this ),
1660 args = [ parts[0], value ];
1662 $this.triggerHandler( "setData" + parts[1] + "!", args );
1663 jQuery.data( this, key, value );
1664 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1669 removeData: function( key ) {
1670 return this.each(function() {
1671 jQuery.removeData( this, key );
1676 function dataAttr( elem, key, data ) {
1677 // If nothing was found internally, try to fetch any
1678 // data from the HTML5 data-* attribute
1679 if ( data === undefined && elem.nodeType === 1 ) {
1680 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1682 data = elem.getAttribute( name );
1684 if ( typeof data === "string" ) {
1686 data = data === "true" ? true :
1687 data === "false" ? false :
1688 data === "null" ? null :
1689 !jQuery.isNaN( data ) ? parseFloat( data ) :
1690 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1694 // Make sure we set the data so it isn't changed later
1695 jQuery.data( elem, key, data );
1705 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1706 // property to be considered empty objects; this property always exists in
1707 // order to make sure JSON.stringify does not expose internal metadata
1708 function isEmptyDataObject( obj ) {
1709 for ( var name in obj ) {
1710 if ( name !== "toJSON" ) {
1721 function handleQueueMarkDefer( elem, type, src ) {
1722 var deferDataKey = type + "defer",
1723 queueDataKey = type + "queue",
1724 markDataKey = type + "mark",
1725 defer = jQuery.data( elem, deferDataKey, undefined, true );
1727 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1728 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1729 // Give room for hard-coded callbacks to fire first
1730 // and eventually mark/queue something else on the element
1731 setTimeout( function() {
1732 if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1733 !jQuery.data( elem, markDataKey, undefined, true ) ) {
1734 jQuery.removeData( elem, deferDataKey, true );
1743 _mark: function( elem, type ) {
1745 type = (type || "fx") + "mark";
1746 jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1750 _unmark: function( force, elem, type ) {
1751 if ( force !== true ) {
1757 type = type || "fx";
1758 var key = type + "mark",
1759 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1761 jQuery.data( elem, key, count, true );
1763 jQuery.removeData( elem, key, true );
1764 handleQueueMarkDefer( elem, type, "mark" );
1769 queue: function( elem, type, data ) {
1771 type = (type || "fx") + "queue";
1772 var q = jQuery.data( elem, type, undefined, true );
1773 // Speed up dequeue by getting out quickly if this is just a lookup
1775 if ( !q || jQuery.isArray(data) ) {
1776 q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1785 dequeue: function( elem, type ) {
1786 type = type || "fx";
1788 var queue = jQuery.queue( elem, type ),
1792 // If the fx queue is dequeued, always remove the progress sentinel
1793 if ( fn === "inprogress" ) {
1798 // Add a progress sentinel to prevent the fx queue from being
1799 // automatically dequeued
1800 if ( type === "fx" ) {
1801 queue.unshift("inprogress");
1804 fn.call(elem, function() {
1805 jQuery.dequeue(elem, type);
1809 if ( !queue.length ) {
1810 jQuery.removeData( elem, type + "queue", true );
1811 handleQueueMarkDefer( elem, type, "queue" );
1817 queue: function( type, data ) {
1818 if ( typeof type !== "string" ) {
1823 if ( data === undefined ) {
1824 return jQuery.queue( this[0], type );
1826 return this.each(function() {
1827 var queue = jQuery.queue( this, type, data );
1829 if ( type === "fx" && queue[0] !== "inprogress" ) {
1830 jQuery.dequeue( this, type );
1834 dequeue: function( type ) {
1835 return this.each(function() {
1836 jQuery.dequeue( this, type );
1839 // Based off of the plugin by Clint Helfers, with permission.
1840 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1841 delay: function( time, type ) {
1842 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1843 type = type || "fx";
1845 return this.queue( type, function() {
1847 setTimeout(function() {
1848 jQuery.dequeue( elem, type );
1852 clearQueue: function( type ) {
1853 return this.queue( type || "fx", [] );
1855 // Get a promise resolved when queues of a certain type
1856 // are emptied (fx is the type by default)
1857 promise: function( type, object ) {
1858 if ( typeof type !== "string" ) {
1862 type = type || "fx";
1863 var defer = jQuery.Deferred(),
1865 i = elements.length,
1867 deferDataKey = type + "defer",
1868 queueDataKey = type + "queue",
1869 markDataKey = type + "mark",
1871 function resolve() {
1872 if ( !( --count ) ) {
1873 defer.resolveWith( elements, [ elements ] );
1877 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1878 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1879 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1880 jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1882 tmp.done( resolve );
1886 return defer.promise();
1893 var rclass = /[\n\t\r]/g,
1896 rtype = /^(?:button|input)$/i,
1897 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1898 rclickable = /^a(?:rea)?$/i,
1899 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1900 rinvalidChar = /\:/,
1904 attr: function( name, value ) {
1905 return jQuery.access( this, name, value, true, jQuery.attr );
1908 removeAttr: function( name ) {
1909 return this.each(function() {
1910 jQuery.removeAttr( this, name );
1914 prop: function( name, value ) {
1915 return jQuery.access( this, name, value, true, jQuery.prop );
1918 removeProp: function( name ) {
1919 name = jQuery.propFix[ name ] || name;
1920 return this.each(function() {
1921 // try/catch handles cases where IE balks (such as removing a property on window)
1923 this[ name ] = undefined;
1924 delete this[ name ];
1929 addClass: function( value ) {
1930 if ( jQuery.isFunction( value ) ) {
1931 return this.each(function(i) {
1932 var self = jQuery(this);
1933 self.addClass( value.call(this, i, self.attr("class") || "") );
1937 if ( value && typeof value === "string" ) {
1938 var classNames = (value || "").split( rspace );
1940 for ( var i = 0, l = this.length; i < l; i++ ) {
1943 if ( elem.nodeType === 1 ) {
1944 if ( !elem.className ) {
1945 elem.className = value;
1948 var className = " " + elem.className + " ",
1949 setClass = elem.className;
1951 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1952 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1953 setClass += " " + classNames[c];
1956 elem.className = jQuery.trim( setClass );
1965 removeClass: function( value ) {
1966 if ( jQuery.isFunction(value) ) {
1967 return this.each(function(i) {
1968 var self = jQuery(this);
1969 self.removeClass( value.call(this, i, self.attr("class")) );
1973 if ( (value && typeof value === "string") || value === undefined ) {
1974 var classNames = (value || "").split( rspace );
1976 for ( var i = 0, l = this.length; i < l; i++ ) {
1979 if ( elem.nodeType === 1 && elem.className ) {
1981 var className = (" " + elem.className + " ").replace(rclass, " ");
1982 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1983 className = className.replace(" " + classNames[c] + " ", " ");
1985 elem.className = jQuery.trim( className );
1988 elem.className = "";
1997 toggleClass: function( value, stateVal ) {
1998 var type = typeof value,
1999 isBool = typeof stateVal === "boolean";
2001 if ( jQuery.isFunction( value ) ) {
2002 return this.each(function(i) {
2003 var self = jQuery(this);
2004 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
2008 return this.each(function() {
2009 if ( type === "string" ) {
2010 // toggle individual class names
2013 self = jQuery( this ),
2015 classNames = value.split( rspace );
2017 while ( (className = classNames[ i++ ]) ) {
2018 // check each className given, space seperated list
2019 state = isBool ? state : !self.hasClass( className );
2020 self[ state ? "addClass" : "removeClass" ]( className );
2023 } else if ( type === "undefined" || type === "boolean" ) {
2024 if ( this.className ) {
2025 // store className if set
2026 jQuery._data( this, "__className__", this.className );
2029 // toggle whole className
2030 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2035 hasClass: function( selector ) {
2036 var className = " " + selector + " ";
2037 for ( var i = 0, l = this.length; i < l; i++ ) {
2038 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2046 val: function( value ) {
2050 if ( !arguments.length ) {
2052 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2054 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2058 return (elem.value || "").replace(rreturn, "");
2064 var isFunction = jQuery.isFunction( value );
2066 return this.each(function( i ) {
2067 var self = jQuery(this), val;
2069 if ( this.nodeType !== 1 ) {
2074 val = value.call( this, i, self.val() );
2079 // Treat null/undefined as ""; convert numbers to string
2080 if ( val == null ) {
2082 } else if ( typeof val === "number" ) {
2084 } else if ( jQuery.isArray( val ) ) {
2085 val = jQuery.map(val, function ( value ) {
2086 return value == null ? "" : value + "";
2090 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2092 // If set returns undefined, fall back to normal setting
2093 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2103 get: function( elem ) {
2104 // attributes.value is undefined in Blackberry 4.7 but
2105 // uses .value. See #6932
2106 var val = elem.attributes.value;
2107 return !val || val.specified ? elem.value : elem.text;
2111 get: function( elem ) {
2113 index = elem.selectedIndex,
2115 options = elem.options,
2116 one = elem.type === "select-one";
2118 // Nothing was selected
2123 // Loop through all the selected options
2124 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2125 var option = options[ i ];
2127 // Don't return options that are disabled or in a disabled optgroup
2128 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2129 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2131 // Get the specific value for the option
2132 value = jQuery( option ).val();
2134 // We don't need an array for one selects
2139 // Multi-Selects return an array
2140 values.push( value );
2144 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2145 if ( one && !values.length && options.length ) {
2146 return jQuery( options[ index ] ).val();
2152 set: function( elem, value ) {
2153 var values = jQuery.makeArray( value );
2155 jQuery(elem).find("option").each(function() {
2156 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2159 if ( !values.length ) {
2160 elem.selectedIndex = -1;
2179 // Always normalize to ensure hook usage
2180 tabindex: "tabIndex"
2183 attr: function( elem, name, value, pass ) {
2184 var nType = elem.nodeType;
2186 // don't get/set attributes on text, comment and attribute nodes
2187 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2191 if ( pass && name in jQuery.attrFn ) {
2192 return jQuery( elem )[ name ]( value );
2195 // Fallback to prop when attributes are not supported
2196 if ( !("getAttribute" in elem) ) {
2197 return jQuery.prop( elem, name, value );
2201 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2203 // Normalize the name if needed
2204 name = notxml && jQuery.attrFix[ name ] || name;
2206 hooks = jQuery.attrHooks[ name ];
2209 // Use boolHook for boolean attributes
2210 if ( rboolean.test( name ) &&
2211 (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
2215 // Use formHook for forms and if the name contains certain characters
2216 } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
2221 if ( value !== undefined ) {
2223 if ( value === null ) {
2224 jQuery.removeAttr( elem, name );
2227 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2231 elem.setAttribute( name, "" + value );
2235 } else if ( hooks && "get" in hooks && notxml ) {
2236 return hooks.get( elem, name );
2240 ret = elem.getAttribute( name );
2242 // Non-existent attributes return null, we normalize to undefined
2243 return ret === null ?
2249 removeAttr: function( elem, name ) {
2251 if ( elem.nodeType === 1 ) {
2252 name = jQuery.attrFix[ name ] || name;
2254 if ( jQuery.support.getSetAttribute ) {
2255 // Use removeAttribute in browsers that support it
2256 elem.removeAttribute( name );
2258 jQuery.attr( elem, name, "" );
2259 elem.removeAttributeNode( elem.getAttributeNode( name ) );
2262 // Set corresponding property to false for boolean attributes
2263 if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2264 elem[ propName ] = false;
2271 set: function( elem, value ) {
2272 // We can't allow the type property to be changed (since it causes problems in IE)
2273 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2274 jQuery.error( "type property can't be changed" );
2275 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2276 // Setting the type on a radio button after the value resets the value in IE6-9
2277 // Reset value to it's default in case type is set after value
2278 // This is for element creation
2279 var val = elem.value;
2280 elem.setAttribute( "type", value );
2289 get: function( elem ) {
2290 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2291 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2292 var attributeNode = elem.getAttributeNode("tabIndex");
2294 return attributeNode && attributeNode.specified ?
2295 parseInt( attributeNode.value, 10 ) :
2296 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2304 tabindex: "tabIndex",
2305 readonly: "readOnly",
2307 "class": "className",
2308 maxlength: "maxLength",
2309 cellspacing: "cellSpacing",
2310 cellpadding: "cellPadding",
2314 frameborder: "frameBorder",
2315 contenteditable: "contentEditable"
2318 prop: function( elem, name, value ) {
2319 var nType = elem.nodeType;
2321 // don't get/set properties on text, comment and attribute nodes
2322 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2327 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2329 // Try to normalize/fix the name
2330 name = notxml && jQuery.propFix[ name ] || name;
2332 hooks = jQuery.propHooks[ name ];
2334 if ( value !== undefined ) {
2335 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2339 return (elem[ name ] = value);
2343 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2347 return elem[ name ];
2355 // Hook for boolean attributes
2357 get: function( elem, name ) {
2358 // Align boolean attributes with corresponding properties
2359 return elem[ jQuery.propFix[ name ] || name ] ?
2360 name.toLowerCase() :
2363 set: function( elem, value, name ) {
2365 if ( value === false ) {
2366 // Remove boolean attributes when set to false
2367 jQuery.removeAttr( elem, name );
2369 // value is true since we know at this point it's type boolean and not false
2370 // Set boolean attributes to the same name and set the DOM property
2371 propName = jQuery.propFix[ name ] || name;
2372 if ( propName in elem ) {
2373 // Only set the IDL specifically if it already exists on the element
2374 elem[ propName ] = value;
2377 elem.setAttribute( name, name.toLowerCase() );
2383 // Use the value property for back compat
2384 // Use the formHook for button elements in IE6/7 (#1954)
2385 jQuery.attrHooks.value = {
2386 get: function( elem, name ) {
2387 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2388 return formHook.get( elem, name );
2392 set: function( elem, value, name ) {
2393 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2394 return formHook.set( elem, value, name );
2396 // Does not return so that setAttribute is also used
2401 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2402 if ( !jQuery.support.getSetAttribute ) {
2404 // propFix is more comprehensive and contains all fixes
2405 jQuery.attrFix = jQuery.propFix;
2407 // Use this for any attribute on a form in IE6/7
2408 formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
2409 get: function( elem, name ) {
2411 ret = elem.getAttributeNode( name );
2412 // Return undefined if nodeValue is empty string
2413 return ret && ret.nodeValue !== "" ?
2417 set: function( elem, value, name ) {
2418 // Check form objects in IE (multiple bugs related)
2419 // Only use nodeValue if the attribute node exists on the form
2420 var ret = elem.getAttributeNode( name );
2422 ret.nodeValue = value;
2428 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2429 // This is for removals
2430 jQuery.each([ "width", "height" ], function( i, name ) {
2431 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2432 set: function( elem, value ) {
2433 if ( value === "" ) {
2434 elem.setAttribute( name, "auto" );
2443 // Some attributes require a special call on IE
2444 if ( !jQuery.support.hrefNormalized ) {
2445 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2446 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2447 get: function( elem ) {
2448 var ret = elem.getAttribute( name, 2 );
2449 return ret === null ? undefined : ret;
2455 if ( !jQuery.support.style ) {
2456 jQuery.attrHooks.style = {
2457 get: function( elem ) {
2458 // Return undefined in the case of empty string
2459 // Normalize to lowercase since IE uppercases css property names
2460 return elem.style.cssText.toLowerCase() || undefined;
2462 set: function( elem, value ) {
2463 return (elem.style.cssText = "" + value);
2468 // Safari mis-reports the default selected property of an option
2469 // Accessing the parent's selectedIndex property fixes it
2470 if ( !jQuery.support.optSelected ) {
2471 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2472 get: function( elem ) {
2473 var parent = elem.parentNode;
2476 parent.selectedIndex;
2478 // Make sure that it also works with optgroups, see #5701
2479 if ( parent.parentNode ) {
2480 parent.parentNode.selectedIndex;
2487 // Radios and checkboxes getter/setter
2488 if ( !jQuery.support.checkOn ) {
2489 jQuery.each([ "radio", "checkbox" ], function() {
2490 jQuery.valHooks[ this ] = {
2491 get: function( elem ) {
2492 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2493 return elem.getAttribute("value") === null ? "on" : elem.value;
2498 jQuery.each([ "radio", "checkbox" ], function() {
2499 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2500 set: function( elem, value ) {
2501 if ( jQuery.isArray( value ) ) {
2502 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2511 var hasOwn = Object.prototype.hasOwnProperty,
2512 rnamespaces = /\.(.*)$/,
2513 rformElems = /^(?:textarea|input|select)$/i,
2516 rescape = /[^\w\s.|`]/g,
2517 fcleanup = function( nm ) {
2518 return nm.replace(rescape, "\\$&");
2522 * A number of helper functions used for managing events.
2523 * Many of the ideas behind this code originated from
2524 * Dean Edwards' addEvent library.
2528 // Bind an event to an element
2529 // Original by Dean Edwards
2530 add: function( elem, types, handler, data ) {
2531 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2535 if ( handler === false ) {
2536 handler = returnFalse;
2537 } else if ( !handler ) {
2538 // Fixes bug #7229. Fix recommended by jdalton
2542 var handleObjIn, handleObj;
2544 if ( handler.handler ) {
2545 handleObjIn = handler;
2546 handler = handleObjIn.handler;
2549 // Make sure that the function being executed has a unique ID
2550 if ( !handler.guid ) {
2551 handler.guid = jQuery.guid++;
2554 // Init the element's event structure
2555 var elemData = jQuery._data( elem );
2557 // If no elemData is found then we must be trying to bind to one of the
2558 // banned noData elements
2563 var events = elemData.events,
2564 eventHandle = elemData.handle;
2567 elemData.events = events = {};
2570 if ( !eventHandle ) {
2571 elemData.handle = eventHandle = function( e ) {
2572 // Discard the second event of a jQuery.event.trigger() and
2573 // when an event is called after a page has unloaded
2574 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2575 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2580 // Add elem as a property of the handle function
2581 // This is to prevent a memory leak with non-native events in IE.
2582 eventHandle.elem = elem;
2584 // Handle multiple events separated by a space
2585 // jQuery(...).bind("mouseover mouseout", fn);
2586 types = types.split(" ");
2588 var type, i = 0, namespaces;
2590 while ( (type = types[ i++ ]) ) {
2591 handleObj = handleObjIn ?
2592 jQuery.extend({}, handleObjIn) :
2593 { handler: handler, data: data };
2595 // Namespaced event handlers
2596 if ( type.indexOf(".") > -1 ) {
2597 namespaces = type.split(".");
2598 type = namespaces.shift();
2599 handleObj.namespace = namespaces.slice(0).sort().join(".");
2603 handleObj.namespace = "";
2606 handleObj.type = type;
2607 if ( !handleObj.guid ) {
2608 handleObj.guid = handler.guid;
2611 // Get the current list of functions bound to this event
2612 var handlers = events[ type ],
2613 special = jQuery.event.special[ type ] || {};
2615 // Init the event handler queue
2617 handlers = events[ type ] = [];
2619 // Check for a special event handler
2620 // Only use addEventListener/attachEvent if the special
2621 // events handler returns false
2622 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2623 // Bind the global event handler to the element
2624 if ( elem.addEventListener ) {
2625 elem.addEventListener( type, eventHandle, false );
2627 } else if ( elem.attachEvent ) {
2628 elem.attachEvent( "on" + type, eventHandle );
2633 if ( special.add ) {
2634 special.add.call( elem, handleObj );
2636 if ( !handleObj.handler.guid ) {
2637 handleObj.handler.guid = handler.guid;
2641 // Add the function to the element's handler list
2642 handlers.push( handleObj );
2644 // Keep track of which events have been used, for event optimization
2645 jQuery.event.global[ type ] = true;
2648 // Nullify elem to prevent memory leaks in IE
2654 // Detach an event or set of events from an element
2655 remove: function( elem, types, handler, pos ) {
2656 // don't do events on text and comment nodes
2657 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2661 if ( handler === false ) {
2662 handler = returnFalse;
2665 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2666 elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2667 events = elemData && elemData.events;
2669 if ( !elemData || !events ) {
2673 // types is actually an event object here
2674 if ( types && types.type ) {
2675 handler = types.handler;
2679 // Unbind all events for the element
2680 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2681 types = types || "";
2683 for ( type in events ) {
2684 jQuery.event.remove( elem, type + types );
2690 // Handle multiple events separated by a space
2691 // jQuery(...).unbind("mouseover mouseout", fn);
2692 types = types.split(" ");
2694 while ( (type = types[ i++ ]) ) {
2697 all = type.indexOf(".") < 0;
2701 // Namespaced event handlers
2702 namespaces = type.split(".");
2703 type = namespaces.shift();
2705 namespace = new RegExp("(^|\\.)" +
2706 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2709 eventType = events[ type ];
2716 for ( j = 0; j < eventType.length; j++ ) {
2717 handleObj = eventType[ j ];
2719 if ( all || namespace.test( handleObj.namespace ) ) {
2720 jQuery.event.remove( elem, origType, handleObj.handler, j );
2721 eventType.splice( j--, 1 );
2728 special = jQuery.event.special[ type ] || {};
2730 for ( j = pos || 0; j < eventType.length; j++ ) {
2731 handleObj = eventType[ j ];
2733 if ( handler.guid === handleObj.guid ) {
2734 // remove the given handler for the given type
2735 if ( all || namespace.test( handleObj.namespace ) ) {
2736 if ( pos == null ) {
2737 eventType.splice( j--, 1 );
2740 if ( special.remove ) {
2741 special.remove.call( elem, handleObj );
2745 if ( pos != null ) {
2751 // remove generic event handler if no more handlers exist
2752 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2753 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2754 jQuery.removeEvent( elem, type, elemData.handle );
2758 delete events[ type ];
2762 // Remove the expando if it's no longer used
2763 if ( jQuery.isEmptyObject( events ) ) {
2764 var handle = elemData.handle;
2769 delete elemData.events;
2770 delete elemData.handle;
2772 if ( jQuery.isEmptyObject( elemData ) ) {
2773 jQuery.removeData( elem, undefined, true );
2778 // Events that are safe to short-circuit if no handlers are attached.
2779 // Native DOM events should not be added, they may have inline handlers.
2786 trigger: function( event, data, elem, onlyHandlers ) {
2787 // Event object or event type
2788 var type = event.type || event,
2792 if ( type.indexOf("!") >= 0 ) {
2793 // Exclusive events trigger only for the exact event (no namespaces)
2794 type = type.slice(0, -1);
2798 if ( type.indexOf(".") >= 0 ) {
2799 // Namespaced trigger; create a regexp to match event type in handle()
2800 namespaces = type.split(".");
2801 type = namespaces.shift();
2805 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2806 // No jQuery handlers for this event type, and it can't have inline handlers
2810 // Caller can pass in an Event, Object, or just an event type string
2811 event = typeof event === "object" ?
2812 // jQuery.Event object
2813 event[ jQuery.expando ] ? event :
2815 new jQuery.Event( type, event ) :
2816 // Just the event type (string)
2817 new jQuery.Event( type );
2820 event.exclusive = exclusive;
2821 event.namespace = namespaces.join(".");
2822 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2824 // triggerHandler() and global events don't bubble or run the default action
2825 if ( onlyHandlers || !elem ) {
2826 event.preventDefault();
2827 event.stopPropagation();
2830 // Handle a global trigger
2832 // TODO: Stop taunting the data cache; remove global events and always attach to document
2833 jQuery.each( jQuery.cache, function() {
2834 // internalKey variable is just used to make it easier to find
2835 // and potentially change this stuff later; currently it just
2836 // points to jQuery.expando
2837 var internalKey = jQuery.expando,
2838 internalCache = this[ internalKey ];
2839 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2840 jQuery.event.trigger( event, data, internalCache.handle.elem );
2846 // Don't do events on text and comment nodes
2847 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2851 // Clean up the event in case it is being reused
2852 event.result = undefined;
2853 event.target = elem;
2855 // Clone any incoming data and prepend the event, creating the handler arg list
2856 data = data ? jQuery.makeArray( data ) : [];
2857 data.unshift( event );
2860 // IE doesn't like method names with a colon (#3533, #8272)
2861 ontype = type.indexOf(":") < 0 ? "on" + type : "";
2863 // Fire event on the current element, then bubble up the DOM tree
2865 var handle = jQuery._data( cur, "handle" );
2867 event.currentTarget = cur;
2869 handle.apply( cur, data );
2872 // Trigger an inline bound script
2873 if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2874 event.result = false;
2875 event.preventDefault();
2878 // Bubble up to document, then to window
2879 cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2880 } while ( cur && !event.isPropagationStopped() );
2882 // If nobody prevented the default action, do it now
2883 if ( !event.isDefaultPrevented() ) {
2885 special = jQuery.event.special[ type ] || {};
2887 if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2888 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2890 // Call a native DOM method on the target with the same name name as the event.
2891 // Can't use an .isFunction)() check here because IE6/7 fails that test.
2892 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2894 if ( ontype && elem[ type ] ) {
2895 // Don't re-trigger an onFOO event when we call its FOO() method
2896 old = elem[ ontype ];
2899 elem[ ontype ] = null;
2902 jQuery.event.triggered = type;
2905 } catch ( ieError ) {}
2908 elem[ ontype ] = old;
2911 jQuery.event.triggered = undefined;
2915 return event.result;
2918 handle: function( event ) {
2919 event = jQuery.event.fix( event || window.event );
2920 // Snapshot the handlers list since a called handler may add/remove events.
2921 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2922 run_all = !event.exclusive && !event.namespace,
2923 args = Array.prototype.slice.call( arguments, 0 );
2925 // Use the fix-ed Event rather than the (read-only) native event
2927 event.currentTarget = this;
2929 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2930 var handleObj = handlers[ j ];
2932 // Triggered event must 1) be non-exclusive and have no namespace, or
2933 // 2) have namespace(s) a subset or equal to those in the bound event.
2934 if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2935 // Pass in a reference to the handler function itself
2936 // So that we can later remove it
2937 event.handler = handleObj.handler;
2938 event.data = handleObj.data;
2939 event.handleObj = handleObj;
2941 var ret = handleObj.handler.apply( this, args );
2943 if ( ret !== undefined ) {
2945 if ( ret === false ) {
2946 event.preventDefault();
2947 event.stopPropagation();
2951 if ( event.isImmediatePropagationStopped() ) {
2956 return event.result;
2959 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2961 fix: function( event ) {
2962 if ( event[ jQuery.expando ] ) {
2966 // store a copy of the original event object
2967 // and "clone" to set read-only properties
2968 var originalEvent = event;
2969 event = jQuery.Event( originalEvent );
2971 for ( var i = this.props.length, prop; i; ) {
2972 prop = this.props[ --i ];
2973 event[ prop ] = originalEvent[ prop ];
2976 // Fix target property, if necessary
2977 if ( !event.target ) {
2978 // Fixes #1925 where srcElement might not be defined either
2979 event.target = event.srcElement || document;
2982 // check if target is a textnode (safari)
2983 if ( event.target.nodeType === 3 ) {
2984 event.target = event.target.parentNode;
2987 // Add relatedTarget, if necessary
2988 if ( !event.relatedTarget && event.fromElement ) {
2989 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2992 // Calculate pageX/Y if missing and clientX/Y available
2993 if ( event.pageX == null && event.clientX != null ) {
2994 var eventDocument = event.target.ownerDocument || document,
2995 doc = eventDocument.documentElement,
2996 body = eventDocument.body;
2998 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2999 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
3002 // Add which for key events
3003 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3004 event.which = event.charCode != null ? event.charCode : event.keyCode;
3007 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3008 if ( !event.metaKey && event.ctrlKey ) {
3009 event.metaKey = event.ctrlKey;
3012 // Add which for click: 1 === left; 2 === middle; 3 === right
3013 // Note: button is not normalized, so don't use it
3014 if ( !event.which && event.button !== undefined ) {
3015 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3021 // Deprecated, use jQuery.guid instead
3024 // Deprecated, use jQuery.proxy instead
3025 proxy: jQuery.proxy,
3029 // Make sure the ready event is setup
3030 setup: jQuery.bindReady,
3031 teardown: jQuery.noop
3035 add: function( handleObj ) {
3036 jQuery.event.add( this,
3037 liveConvert( handleObj.origType, handleObj.selector ),
3038 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3041 remove: function( handleObj ) {
3042 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3047 setup: function( data, namespaces, eventHandle ) {
3048 // We only want to do this special case on windows
3049 if ( jQuery.isWindow( this ) ) {
3050 this.onbeforeunload = eventHandle;
3054 teardown: function( namespaces, eventHandle ) {
3055 if ( this.onbeforeunload === eventHandle ) {
3056 this.onbeforeunload = null;
3063 jQuery.removeEvent = document.removeEventListener ?
3064 function( elem, type, handle ) {
3065 if ( elem.removeEventListener ) {
3066 elem.removeEventListener( type, handle, false );
3069 function( elem, type, handle ) {
3070 if ( elem.detachEvent ) {
3071 elem.detachEvent( "on" + type, handle );
3075 jQuery.Event = function( src, props ) {
3076 // Allow instantiation without the 'new' keyword
3077 if ( !this.preventDefault ) {
3078 return new jQuery.Event( src, props );
3082 if ( src && src.type ) {
3083 this.originalEvent = src;
3084 this.type = src.type;
3086 // Events bubbling up the document may have been marked as prevented
3087 // by a handler lower down the tree; reflect the correct value.
3088 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3089 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3096 // Put explicitly provided properties onto the event object
3098 jQuery.extend( this, props );
3101 // timeStamp is buggy for some events on Firefox(#3843)
3102 // So we won't rely on the native value
3103 this.timeStamp = jQuery.now();
3106 this[ jQuery.expando ] = true;
3109 function returnFalse() {
3112 function returnTrue() {
3116 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3117 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3118 jQuery.Event.prototype = {
3119 preventDefault: function() {
3120 this.isDefaultPrevented = returnTrue;
3122 var e = this.originalEvent;
3127 // if preventDefault exists run it on the original event
3128 if ( e.preventDefault ) {
3131 // otherwise set the returnValue property of the original event to false (IE)
3133 e.returnValue = false;
3136 stopPropagation: function() {
3137 this.isPropagationStopped = returnTrue;
3139 var e = this.originalEvent;
3143 // if stopPropagation exists run it on the original event
3144 if ( e.stopPropagation ) {
3145 e.stopPropagation();
3147 // otherwise set the cancelBubble property of the original event to true (IE)
3148 e.cancelBubble = true;
3150 stopImmediatePropagation: function() {
3151 this.isImmediatePropagationStopped = returnTrue;
3152 this.stopPropagation();
3154 isDefaultPrevented: returnFalse,
3155 isPropagationStopped: returnFalse,
3156 isImmediatePropagationStopped: returnFalse
3159 // Checks if an event happened on an element within another element
3160 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3161 var withinElement = function( event ) {
3162 // Check if mouse(over|out) are still within the same parent element
3163 var parent = event.relatedTarget;
3165 // set the correct event type
3166 event.type = event.data;
3168 // Firefox sometimes assigns relatedTarget a XUL element
3169 // which we cannot access the parentNode property of
3172 // Chrome does something similar, the parentNode property
3173 // can be accessed but is null.
3174 if ( parent && parent !== document && !parent.parentNode ) {
3178 // Traverse up the tree
3179 while ( parent && parent !== this ) {
3180 parent = parent.parentNode;
3183 if ( parent !== this ) {
3184 // handle event if we actually just moused on to a non sub-element
3185 jQuery.event.handle.apply( this, arguments );
3188 // assuming we've left the element since we most likely mousedover a xul element
3192 // In case of event delegation, we only need to rename the event.type,
3193 // liveHandler will take care of the rest.
3194 delegate = function( event ) {
3195 event.type = event.data;
3196 jQuery.event.handle.apply( this, arguments );
3199 // Create mouseenter and mouseleave events
3201 mouseenter: "mouseover",
3202 mouseleave: "mouseout"
3203 }, function( orig, fix ) {
3204 jQuery.event.special[ orig ] = {
3205 setup: function( data ) {
3206 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3208 teardown: function( data ) {
3209 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3214 // submit delegation
3215 if ( !jQuery.support.submitBubbles ) {
3217 jQuery.event.special.submit = {
3218 setup: function( data, namespaces ) {
3219 if ( !jQuery.nodeName( this, "form" ) ) {
3220 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3221 var elem = e.target,
3224 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3225 trigger( "submit", this, arguments );
3229 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3230 var elem = e.target,
3233 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3234 trigger( "submit", this, arguments );
3243 teardown: function( namespaces ) {
3244 jQuery.event.remove( this, ".specialSubmit" );
3250 // change delegation, happens here so we have bind.
3251 if ( !jQuery.support.changeBubbles ) {
3255 getVal = function( elem ) {
3256 var type = elem.type, val = elem.value;
3258 if ( type === "radio" || type === "checkbox" ) {
3261 } else if ( type === "select-multiple" ) {
3262 val = elem.selectedIndex > -1 ?
3263 jQuery.map( elem.options, function( elem ) {
3264 return elem.selected;
3268 } else if ( jQuery.nodeName( elem, "select" ) ) {
3269 val = elem.selectedIndex;
3275 testChange = function testChange( e ) {
3276 var elem = e.target, data, val;
3278 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3282 data = jQuery._data( elem, "_change_data" );
3285 // the current data will be also retrieved by beforeactivate
3286 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3287 jQuery._data( elem, "_change_data", val );
3290 if ( data === undefined || val === data ) {
3294 if ( data != null || val ) {
3296 e.liveFired = undefined;
3297 jQuery.event.trigger( e, arguments[1], elem );
3301 jQuery.event.special.change = {
3303 focusout: testChange,
3305 beforedeactivate: testChange,
3307 click: function( e ) {
3308 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3310 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3311 testChange.call( this, e );
3315 // Change has to be called before submit
3316 // Keydown will be called before keypress, which is used in submit-event delegation
3317 keydown: function( e ) {
3318 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3320 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3321 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3322 type === "select-multiple" ) {
3323 testChange.call( this, e );
3327 // Beforeactivate happens also before the previous element is blurred
3328 // with this event you can't trigger a change event, but you can store
3330 beforeactivate: function( e ) {
3331 var elem = e.target;
3332 jQuery._data( elem, "_change_data", getVal(elem) );
3336 setup: function( data, namespaces ) {
3337 if ( this.type === "file" ) {
3341 for ( var type in changeFilters ) {
3342 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3345 return rformElems.test( this.nodeName );
3348 teardown: function( namespaces ) {
3349 jQuery.event.remove( this, ".specialChange" );
3351 return rformElems.test( this.nodeName );
3355 changeFilters = jQuery.event.special.change.filters;
3357 // Handle when the input is .focus()'d
3358 changeFilters.focus = changeFilters.beforeactivate;
3361 function trigger( type, elem, args ) {
3362 // Piggyback on a donor event to simulate a different one.
3363 // Fake originalEvent to avoid donor's stopPropagation, but if the
3364 // simulated event prevents default then we do the same on the donor.
3365 // Don't pass args or remember liveFired; they apply to the donor event.
3366 var event = jQuery.extend( {}, args[ 0 ] );
3368 event.originalEvent = {};
3369 event.liveFired = undefined;
3370 jQuery.event.handle.call( elem, event );
3371 if ( event.isDefaultPrevented() ) {
3372 args[ 0 ].preventDefault();
3376 // Create "bubbling" focus and blur events
3377 if ( !jQuery.support.focusinBubbles ) {
3378 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3380 // Attach a single capturing handler while someone wants focusin/focusout
3383 jQuery.event.special[ fix ] = {
3385 if ( attaches++ === 0 ) {
3386 document.addEventListener( orig, handler, true );
3389 teardown: function() {
3390 if ( --attaches === 0 ) {
3391 document.removeEventListener( orig, handler, true );
3396 function handler( donor ) {
3397 // Donor event is always a native one; fix it and switch its type.
3398 // Let focusin/out handler cancel the donor focus/blur event.
3399 var e = jQuery.event.fix( donor );
3401 e.originalEvent = {};
3402 jQuery.event.trigger( e, null, e.target );
3403 if ( e.isDefaultPrevented() ) {
3404 donor.preventDefault();
3410 jQuery.each(["bind", "one"], function( i, name ) {
3411 jQuery.fn[ name ] = function( type, data, fn ) {
3414 // Handle object literals
3415 if ( typeof type === "object" ) {
3416 for ( var key in type ) {
3417 this[ name ](key, data, type[key], fn);
3422 if ( arguments.length === 2 || data === false ) {
3427 if ( name === "one" ) {
3428 handler = function( event ) {
3429 jQuery( this ).unbind( event, handler );
3430 return fn.apply( this, arguments );
3432 handler.guid = fn.guid || jQuery.guid++;
3437 if ( type === "unload" && name !== "one" ) {
3438 this.one( type, data, fn );
3441 for ( var i = 0, l = this.length; i < l; i++ ) {
3442 jQuery.event.add( this[i], type, handler, data );
3451 unbind: function( type, fn ) {
3452 // Handle object literals
3453 if ( typeof type === "object" && !type.preventDefault ) {
3454 for ( var key in type ) {
3455 this.unbind(key, type[key]);
3459 for ( var i = 0, l = this.length; i < l; i++ ) {
3460 jQuery.event.remove( this[i], type, fn );
3467 delegate: function( selector, types, data, fn ) {
3468 return this.live( types, data, fn, selector );
3471 undelegate: function( selector, types, fn ) {
3472 if ( arguments.length === 0 ) {
3473 return this.unbind( "live" );
3476 return this.die( types, null, fn, selector );
3480 trigger: function( type, data ) {
3481 return this.each(function() {
3482 jQuery.event.trigger( type, data, this );
3486 triggerHandler: function( type, data ) {
3488 return jQuery.event.trigger( type, data, this[0], true );
3492 toggle: function( fn ) {
3493 // Save reference to arguments for access in closure
3494 var args = arguments,
3495 guid = fn.guid || jQuery.guid++,
3497 toggler = function( event ) {
3498 // Figure out which function to execute
3499 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3500 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3502 // Make sure that clicks stop
3503 event.preventDefault();
3505 // and execute the function
3506 return args[ lastToggle ].apply( this, arguments ) || false;
3509 // link all the functions, so any of them can unbind this click handler
3510 toggler.guid = guid;
3511 while ( i < args.length ) {
3512 args[ i++ ].guid = guid;
3515 return this.click( toggler );
3518 hover: function( fnOver, fnOut ) {
3519 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3526 mouseenter: "mouseover",
3527 mouseleave: "mouseout"
3530 jQuery.each(["live", "die"], function( i, name ) {
3531 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3532 var type, i = 0, match, namespaces, preType,
3533 selector = origSelector || this.selector,
3534 context = origSelector ? this : jQuery( this.context );
3536 if ( typeof types === "object" && !types.preventDefault ) {
3537 for ( var key in types ) {
3538 context[ name ]( key, data, types[key], selector );
3544 if ( name === "die" && !types &&
3545 origSelector && origSelector.charAt(0) === "." ) {
3547 context.unbind( origSelector );
3552 if ( data === false || jQuery.isFunction( data ) ) {
3553 fn = data || returnFalse;
3557 types = (types || "").split(" ");
3559 while ( (type = types[ i++ ]) != null ) {
3560 match = rnamespaces.exec( type );
3564 namespaces = match[0];
3565 type = type.replace( rnamespaces, "" );
3568 if ( type === "hover" ) {
3569 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3575 if ( liveMap[ type ] ) {
3576 types.push( liveMap[ type ] + namespaces );
3577 type = type + namespaces;
3580 type = (liveMap[ type ] || type) + namespaces;
3583 if ( name === "live" ) {
3584 // bind live handler
3585 for ( var j = 0, l = context.length; j < l; j++ ) {
3586 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3587 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3591 // unbind live handler
3592 context.unbind( "live." + liveConvert( type, selector ), fn );
3600 function liveHandler( event ) {
3601 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3604 events = jQuery._data( this, "events" );
3606 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3607 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3611 if ( event.namespace ) {
3612 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3615 event.liveFired = this;
3617 var live = events.live.slice(0);
3619 for ( j = 0; j < live.length; j++ ) {
3620 handleObj = live[j];
3622 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3623 selectors.push( handleObj.selector );
3626 live.splice( j--, 1 );
3630 match = jQuery( event.target ).closest( selectors, event.currentTarget );
3632 for ( i = 0, l = match.length; i < l; i++ ) {
3635 for ( j = 0; j < live.length; j++ ) {
3636 handleObj = live[j];
3638 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3642 // Those two events require additional checking
3643 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3644 event.type = handleObj.preType;
3645 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3647 // Make sure not to accidentally match a child element with the same selector
3648 if ( related && jQuery.contains( elem, related ) ) {
3653 if ( !related || related !== elem ) {
3654 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3660 for ( i = 0, l = elems.length; i < l; i++ ) {
3663 if ( maxLevel && match.level > maxLevel ) {
3667 event.currentTarget = match.elem;
3668 event.data = match.handleObj.data;
3669 event.handleObj = match.handleObj;
3671 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3673 if ( ret === false || event.isPropagationStopped() ) {
3674 maxLevel = match.level;
3676 if ( ret === false ) {
3679 if ( event.isImmediatePropagationStopped() ) {
3688 function liveConvert( type, selector ) {
3689 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3692 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3693 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3694 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3696 // Handle event binding
3697 jQuery.fn[ name ] = function( data, fn ) {
3703 return arguments.length > 0 ?
3704 this.bind( name, data, fn ) :
3705 this.trigger( name );
3708 if ( jQuery.attrFn ) {
3709 jQuery.attrFn[ name ] = true;
3716 * Sizzle CSS Selector Engine
3717 * Copyright 2011, The Dojo Foundation
3718 * Released under the MIT, BSD, and GPL Licenses.
3719 * More information: http://sizzlejs.com/
3723 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3725 toString = Object.prototype.toString,
3726 hasDuplicate = false,
3727 baseHasDuplicate = true,
3731 // Here we check if the JavaScript engine is using some sort of
3732 // optimization where it does not always call our comparision
3733 // function. If that is the case, discard the hasDuplicate value.
3734 // Thus far that includes Google Chrome.
3735 [0, 0].sort(function() {
3736 baseHasDuplicate = false;
3740 var Sizzle = function( selector, context, results, seed ) {
3741 results = results || [];
3742 context = context || document;
3744 var origContext = context;
3746 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3750 if ( !selector || typeof selector !== "string" ) {
3754 var m, set, checkSet, extra, ret, cur, pop, i,
3756 contextXML = Sizzle.isXML( context ),
3760 // Reset the position of the chunker regexp (start from head)
3763 m = chunker.exec( soFar );
3777 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3779 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3780 set = posProcess( parts[0] + parts[1], context );
3783 set = Expr.relative[ parts[0] ] ?
3785 Sizzle( parts.shift(), context );
3787 while ( parts.length ) {
3788 selector = parts.shift();
3790 if ( Expr.relative[ selector ] ) {
3791 selector += parts.shift();
3794 set = posProcess( selector, set );
3799 // Take a shortcut and set the context if the root selector is an ID
3800 // (but not if it'll be faster if the inner selector is an ID)
3801 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3802 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3804 ret = Sizzle.find( parts.shift(), context, contextXML );
3805 context = ret.expr ?
3806 Sizzle.filter( ret.expr, ret.set )[0] :
3812 { expr: parts.pop(), set: makeArray(seed) } :
3813 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3816 Sizzle.filter( ret.expr, ret.set ) :
3819 if ( parts.length > 0 ) {
3820 checkSet = makeArray( set );
3826 while ( parts.length ) {
3830 if ( !Expr.relative[ cur ] ) {
3836 if ( pop == null ) {
3840 Expr.relative[ cur ]( checkSet, pop, contextXML );
3844 checkSet = parts = [];
3853 Sizzle.error( cur || selector );
3856 if ( toString.call(checkSet) === "[object Array]" ) {
3858 results.push.apply( results, checkSet );
3860 } else if ( context && context.nodeType === 1 ) {
3861 for ( i = 0; checkSet[i] != null; i++ ) {
3862 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3863 results.push( set[i] );
3868 for ( i = 0; checkSet[i] != null; i++ ) {
3869 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3870 results.push( set[i] );
3876 makeArray( checkSet, results );
3880 Sizzle( extra, origContext, results, seed );
3881 Sizzle.uniqueSort( results );
3887 Sizzle.uniqueSort = function( results ) {
3889 hasDuplicate = baseHasDuplicate;
3890 results.sort( sortOrder );
3892 if ( hasDuplicate ) {
3893 for ( var i = 1; i < results.length; i++ ) {
3894 if ( results[i] === results[ i - 1 ] ) {
3895 results.splice( i--, 1 );
3904 Sizzle.matches = function( expr, set ) {
3905 return Sizzle( expr, null, null, set );
3908 Sizzle.matchesSelector = function( node, expr ) {
3909 return Sizzle( expr, null, null, [node] ).length > 0;
3912 Sizzle.find = function( expr, context, isXML ) {
3919 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3921 type = Expr.order[i];
3923 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3924 var left = match[1];
3925 match.splice( 1, 1 );
3927 if ( left.substr( left.length - 1 ) !== "\\" ) {
3928 match[1] = (match[1] || "").replace( rBackslash, "" );
3929 set = Expr.find[ type ]( match, context, isXML );
3931 if ( set != null ) {
3932 expr = expr.replace( Expr.match[ type ], "" );
3940 set = typeof context.getElementsByTagName !== "undefined" ?
3941 context.getElementsByTagName( "*" ) :
3945 return { set: set, expr: expr };
3948 Sizzle.filter = function( expr, set, inplace, not ) {
3949 var match, anyFound,
3953 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3955 while ( expr && set.length ) {
3956 for ( var type in Expr.filter ) {
3957 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3959 filter = Expr.filter[ type ],
3966 if ( left.substr( left.length - 1 ) === "\\" ) {
3970 if ( curLoop === result ) {
3974 if ( Expr.preFilter[ type ] ) {
3975 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3978 anyFound = found = true;
3980 } else if ( match === true ) {
3986 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3988 found = filter( item, match, i, curLoop );
3989 var pass = not ^ !!found;
3991 if ( inplace && found != null ) {
3999 } else if ( pass ) {
4000 result.push( item );
4007 if ( found !== undefined ) {
4012 expr = expr.replace( Expr.match[ type ], "" );
4023 // Improper expression
4024 if ( expr === old ) {
4025 if ( anyFound == null ) {
4026 Sizzle.error( expr );
4039 Sizzle.error = function( msg ) {
4040 throw "Syntax error, unrecognized expression: " + msg;
4043 var Expr = Sizzle.selectors = {
4044 order: [ "ID", "NAME", "TAG" ],
4047 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4048 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4049 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4050 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4051 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4052 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4053 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4054 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4060 "class": "className",
4065 href: function( elem ) {
4066 return elem.getAttribute( "href" );
4068 type: function( elem ) {
4069 return elem.getAttribute( "type" );
4074 "+": function(checkSet, part){
4075 var isPartStr = typeof part === "string",
4076 isTag = isPartStr && !rNonWord.test( part ),
4077 isPartStrNotTag = isPartStr && !isTag;
4080 part = part.toLowerCase();
4083 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4084 if ( (elem = checkSet[i]) ) {
4085 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4087 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4093 if ( isPartStrNotTag ) {
4094 Sizzle.filter( part, checkSet, true );
4098 ">": function( checkSet, part ) {
4100 isPartStr = typeof part === "string",
4102 l = checkSet.length;
4104 if ( isPartStr && !rNonWord.test( part ) ) {
4105 part = part.toLowerCase();
4107 for ( ; i < l; i++ ) {
4111 var parent = elem.parentNode;
4112 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4117 for ( ; i < l; i++ ) {
4121 checkSet[i] = isPartStr ?
4123 elem.parentNode === part;
4128 Sizzle.filter( part, checkSet, true );
4133 "": function(checkSet, part, isXML){
4138 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4139 part = part.toLowerCase();
4141 checkFn = dirNodeCheck;
4144 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4147 "~": function( checkSet, part, isXML ) {
4152 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4153 part = part.toLowerCase();
4155 checkFn = dirNodeCheck;
4158 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4163 ID: function( match, context, isXML ) {
4164 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4165 var m = context.getElementById(match[1]);
4166 // Check parentNode to catch when Blackberry 4.6 returns
4167 // nodes that are no longer in the document #6963
4168 return m && m.parentNode ? [m] : [];
4172 NAME: function( match, context ) {
4173 if ( typeof context.getElementsByName !== "undefined" ) {
4175 results = context.getElementsByName( match[1] );
4177 for ( var i = 0, l = results.length; i < l; i++ ) {
4178 if ( results[i].getAttribute("name") === match[1] ) {
4179 ret.push( results[i] );
4183 return ret.length === 0 ? null : ret;
4187 TAG: function( match, context ) {
4188 if ( typeof context.getElementsByTagName !== "undefined" ) {
4189 return context.getElementsByTagName( match[1] );
4194 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4195 match = " " + match[1].replace( rBackslash, "" ) + " ";
4201 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4203 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4205 result.push( elem );
4208 } else if ( inplace ) {
4217 ID: function( match ) {
4218 return match[1].replace( rBackslash, "" );
4221 TAG: function( match, curLoop ) {
4222 return match[1].replace( rBackslash, "" ).toLowerCase();
4225 CHILD: function( match ) {
4226 if ( match[1] === "nth" ) {
4228 Sizzle.error( match[0] );
4231 match[2] = match[2].replace(/^\+|\s*/g, '');
4233 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4234 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4235 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4236 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4238 // calculate the numbers (first)n+(last) including if they are negative
4239 match[2] = (test[1] + (test[2] || 1)) - 0;
4240 match[3] = test[3] - 0;
4242 else if ( match[2] ) {
4243 Sizzle.error( match[0] );
4246 // TODO: Move to normal caching system
4252 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4253 var name = match[1] = match[1].replace( rBackslash, "" );
4255 if ( !isXML && Expr.attrMap[name] ) {
4256 match[1] = Expr.attrMap[name];
4259 // Handle if an un-quoted value was used
4260 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4262 if ( match[2] === "~=" ) {
4263 match[4] = " " + match[4] + " ";
4269 PSEUDO: function( match, curLoop, inplace, result, not ) {
4270 if ( match[1] === "not" ) {
4271 // If we're dealing with a complex expression, or a simple one
4272 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4273 match[3] = Sizzle(match[3], null, null, curLoop);
4276 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4279 result.push.apply( result, ret );
4285 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4292 POS: function( match ) {
4293 match.unshift( true );
4300 enabled: function( elem ) {
4301 return elem.disabled === false && elem.type !== "hidden";
4304 disabled: function( elem ) {
4305 return elem.disabled === true;
4308 checked: function( elem ) {
4309 return elem.checked === true;
4312 selected: function( elem ) {
4313 // Accessing this property makes selected-by-default
4314 // options in Safari work properly
4315 if ( elem.parentNode ) {
4316 elem.parentNode.selectedIndex;
4319 return elem.selected === true;
4322 parent: function( elem ) {
4323 return !!elem.firstChild;
4326 empty: function( elem ) {
4327 return !elem.firstChild;
4330 has: function( elem, i, match ) {
4331 return !!Sizzle( match[3], elem ).length;
4334 header: function( elem ) {
4335 return (/h\d/i).test( elem.nodeName );
4338 text: function( elem ) {
4339 var attr = elem.getAttribute( "type" ), type = elem.type;
4340 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4341 // use getAttribute instead to test this case
4342 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4345 radio: function( elem ) {
4346 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4349 checkbox: function( elem ) {
4350 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4353 file: function( elem ) {
4354 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4357 password: function( elem ) {
4358 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4361 submit: function( elem ) {
4362 var name = elem.nodeName.toLowerCase();
4363 return (name === "input" || name === "button") && "submit" === elem.type;
4366 image: function( elem ) {
4367 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4370 reset: function( elem ) {
4371 var name = elem.nodeName.toLowerCase();
4372 return (name === "input" || name === "button") && "reset" === elem.type;
4375 button: function( elem ) {
4376 var name = elem.nodeName.toLowerCase();
4377 return name === "input" && "button" === elem.type || name === "button";
4380 input: function( elem ) {
4381 return (/input|select|textarea|button/i).test( elem.nodeName );
4384 focus: function( elem ) {
4385 return elem === elem.ownerDocument.activeElement;
4389 first: function( elem, i ) {
4393 last: function( elem, i, match, array ) {
4394 return i === array.length - 1;
4397 even: function( elem, i ) {
4401 odd: function( elem, i ) {
4405 lt: function( elem, i, match ) {
4406 return i < match[3] - 0;
4409 gt: function( elem, i, match ) {
4410 return i > match[3] - 0;
4413 nth: function( elem, i, match ) {
4414 return match[3] - 0 === i;
4417 eq: function( elem, i, match ) {
4418 return match[3] - 0 === i;
4422 PSEUDO: function( elem, match, i, array ) {
4423 var name = match[1],
4424 filter = Expr.filters[ name ];
4427 return filter( elem, i, match, array );
4429 } else if ( name === "contains" ) {
4430 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4432 } else if ( name === "not" ) {
4435 for ( var j = 0, l = not.length; j < l; j++ ) {
4436 if ( not[j] === elem ) {
4444 Sizzle.error( name );
4448 CHILD: function( elem, match ) {
4449 var type = match[1],
4455 while ( (node = node.previousSibling) ) {
4456 if ( node.nodeType === 1 ) {
4461 if ( type === "first" ) {
4468 while ( (node = node.nextSibling) ) {
4469 if ( node.nodeType === 1 ) {
4477 var first = match[2],
4480 if ( first === 1 && last === 0 ) {
4484 var doneName = match[0],
4485 parent = elem.parentNode;
4487 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4490 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4491 if ( node.nodeType === 1 ) {
4492 node.nodeIndex = ++count;
4496 parent.sizcache = doneName;
4499 var diff = elem.nodeIndex - last;
4501 if ( first === 0 ) {
4505 return ( diff % first === 0 && diff / first >= 0 );
4510 ID: function( elem, match ) {
4511 return elem.nodeType === 1 && elem.getAttribute("id") === match;
4514 TAG: function( elem, match ) {
4515 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4518 CLASS: function( elem, match ) {
4519 return (" " + (elem.className || elem.getAttribute("class")) + " ")
4520 .indexOf( match ) > -1;
4523 ATTR: function( elem, match ) {
4524 var name = match[1],
4525 result = Expr.attrHandle[ name ] ?
4526 Expr.attrHandle[ name ]( elem ) :
4527 elem[ name ] != null ?
4529 elem.getAttribute( name ),
4530 value = result + "",
4534 return result == null ?
4539 value.indexOf(check) >= 0 :
4541 (" " + value + " ").indexOf(check) >= 0 :
4543 value && result !== false :
4547 value.indexOf(check) === 0 :
4549 value.substr(value.length - check.length) === check :
4551 value === check || value.substr(0, check.length + 1) === check + "-" :
4555 POS: function( elem, match, i, array ) {
4556 var name = match[2],
4557 filter = Expr.setFilters[ name ];
4560 return filter( elem, i, match, array );
4566 var origPOS = Expr.match.POS,
4567 fescape = function(all, num){
4568 return "\\" + (num - 0 + 1);
4571 for ( var type in Expr.match ) {
4572 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4573 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4576 var makeArray = function( array, results ) {
4577 array = Array.prototype.slice.call( array, 0 );
4580 results.push.apply( results, array );
4587 // Perform a simple check to determine if the browser is capable of
4588 // converting a NodeList to an array using builtin methods.
4589 // Also verifies that the returned array holds DOM nodes
4590 // (which is not the case in the Blackberry browser)
4592 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4594 // Provide a fallback method if it does not work
4596 makeArray = function( array, results ) {
4598 ret = results || [];
4600 if ( toString.call(array) === "[object Array]" ) {
4601 Array.prototype.push.apply( ret, array );
4604 if ( typeof array.length === "number" ) {
4605 for ( var l = array.length; i < l; i++ ) {
4606 ret.push( array[i] );
4610 for ( ; array[i]; i++ ) {
4611 ret.push( array[i] );
4620 var sortOrder, siblingCheck;
4622 if ( document.documentElement.compareDocumentPosition ) {
4623 sortOrder = function( a, b ) {
4625 hasDuplicate = true;
4629 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4630 return a.compareDocumentPosition ? -1 : 1;
4633 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4637 sortOrder = function( a, b ) {
4638 // The nodes are identical, we can exit early
4640 hasDuplicate = true;
4643 // Fallback to using sourceIndex (in IE) if it's available on both nodes
4644 } else if ( a.sourceIndex && b.sourceIndex ) {
4645 return a.sourceIndex - b.sourceIndex;
4655 // If the nodes are siblings (or identical) we can do a quick check
4656 if ( aup === bup ) {
4657 return siblingCheck( a, b );
4659 // If no parents were found then the nodes are disconnected
4660 } else if ( !aup ) {
4663 } else if ( !bup ) {
4667 // Otherwise they're somewhere else in the tree so we need
4668 // to build up a full list of the parentNodes for comparison
4671 cur = cur.parentNode;
4678 cur = cur.parentNode;
4684 // Start walking down the tree looking for a discrepancy
4685 for ( var i = 0; i < al && i < bl; i++ ) {
4686 if ( ap[i] !== bp[i] ) {
4687 return siblingCheck( ap[i], bp[i] );
4691 // We ended someplace up the tree so do a sibling check
4693 siblingCheck( a, bp[i], -1 ) :
4694 siblingCheck( ap[i], b, 1 );
4697 siblingCheck = function( a, b, ret ) {
4702 var cur = a.nextSibling;
4709 cur = cur.nextSibling;
4716 // Utility function for retreiving the text value of an array of DOM nodes
4717 Sizzle.getText = function( elems ) {
4720 for ( var i = 0; elems[i]; i++ ) {
4723 // Get the text from text nodes and CDATA nodes
4724 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4725 ret += elem.nodeValue;
4727 // Traverse everything else, except comment nodes
4728 } else if ( elem.nodeType !== 8 ) {
4729 ret += Sizzle.getText( elem.childNodes );
4736 // Check to see if the browser returns elements by name when
4737 // querying by getElementById (and provide a workaround)
4739 // We're going to inject a fake input element with a specified name
4740 var form = document.createElement("div"),
4741 id = "script" + (new Date()).getTime(),
4742 root = document.documentElement;
4744 form.innerHTML = "<a name='" + id + "'/>";
4746 // Inject it into the root element, check its status, and remove it quickly
4747 root.insertBefore( form, root.firstChild );
4749 // The workaround has to do additional checks after a getElementById
4750 // Which slows things down for other browsers (hence the branching)
4751 if ( document.getElementById( id ) ) {
4752 Expr.find.ID = function( match, context, isXML ) {
4753 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4754 var m = context.getElementById(match[1]);
4757 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4764 Expr.filter.ID = function( elem, match ) {
4765 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4767 return elem.nodeType === 1 && node && node.nodeValue === match;
4771 root.removeChild( form );
4773 // release memory in IE
4778 // Check to see if the browser returns only elements
4779 // when doing getElementsByTagName("*")
4781 // Create a fake element
4782 var div = document.createElement("div");
4783 div.appendChild( document.createComment("") );
4785 // Make sure no comments are found
4786 if ( div.getElementsByTagName("*").length > 0 ) {
4787 Expr.find.TAG = function( match, context ) {
4788 var results = context.getElementsByTagName( match[1] );
4790 // Filter out possible comments
4791 if ( match[1] === "*" ) {
4794 for ( var i = 0; results[i]; i++ ) {
4795 if ( results[i].nodeType === 1 ) {
4796 tmp.push( results[i] );
4807 // Check to see if an attribute returns normalized href attributes
4808 div.innerHTML = "<a href='#'></a>";
4810 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4811 div.firstChild.getAttribute("href") !== "#" ) {
4813 Expr.attrHandle.href = function( elem ) {
4814 return elem.getAttribute( "href", 2 );
4818 // release memory in IE
4822 if ( document.querySelectorAll ) {
4824 var oldSizzle = Sizzle,
4825 div = document.createElement("div"),
4828 div.innerHTML = "<p class='TEST'></p>";
4830 // Safari can't handle uppercase or unicode characters when
4832 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4836 Sizzle = function( query, context, extra, seed ) {
4837 context = context || document;
4839 // Only use querySelectorAll on non-XML documents
4840 // (ID selectors don't work in non-HTML documents)
4841 if ( !seed && !Sizzle.isXML(context) ) {
4842 // See if we find a selector to speed up
4843 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4845 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4846 // Speed-up: Sizzle("TAG")
4848 return makeArray( context.getElementsByTagName( query ), extra );
4850 // Speed-up: Sizzle(".CLASS")
4851 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4852 return makeArray( context.getElementsByClassName( match[2] ), extra );
4856 if ( context.nodeType === 9 ) {
4857 // Speed-up: Sizzle("body")
4858 // The body element only exists once, optimize finding it
4859 if ( query === "body" && context.body ) {
4860 return makeArray( [ context.body ], extra );
4862 // Speed-up: Sizzle("#ID")
4863 } else if ( match && match[3] ) {
4864 var elem = context.getElementById( match[3] );
4866 // Check parentNode to catch when Blackberry 4.6 returns
4867 // nodes that are no longer in the document #6963
4868 if ( elem && elem.parentNode ) {
4869 // Handle the case where IE and Opera return items
4870 // by name instead of ID
4871 if ( elem.id === match[3] ) {
4872 return makeArray( [ elem ], extra );
4876 return makeArray( [], extra );
4881 return makeArray( context.querySelectorAll(query), extra );
4882 } catch(qsaError) {}
4884 // qSA works strangely on Element-rooted queries
4885 // We can work around this by specifying an extra ID on the root
4886 // and working up from there (Thanks to Andrew Dupont for the technique)
4887 // IE 8 doesn't work on object elements
4888 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4889 var oldContext = context,
4890 old = context.getAttribute( "id" ),
4892 hasParent = context.parentNode,
4893 relativeHierarchySelector = /^\s*[+~]/.test( query );
4896 context.setAttribute( "id", nid );
4898 nid = nid.replace( /'/g, "\\$&" );
4900 if ( relativeHierarchySelector && hasParent ) {
4901 context = context.parentNode;
4905 if ( !relativeHierarchySelector || hasParent ) {
4906 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4909 } catch(pseudoError) {
4912 oldContext.removeAttribute( "id" );
4918 return oldSizzle(query, context, extra, seed);
4921 for ( var prop in oldSizzle ) {
4922 Sizzle[ prop ] = oldSizzle[ prop ];
4925 // release memory in IE
4931 var html = document.documentElement,
4932 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
4935 // Check to see if it's possible to do matchesSelector
4936 // on a disconnected node (IE 9 fails this)
4937 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
4938 pseudoWorks = false;
4941 // This should fail with an exception
4942 // Gecko does not error, returns false instead
4943 matches.call( document.documentElement, "[test!='']:sizzle" );
4945 } catch( pseudoError ) {
4949 Sizzle.matchesSelector = function( node, expr ) {
4950 // Make sure that attribute selectors are quoted
4951 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4953 if ( !Sizzle.isXML( node ) ) {
4955 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4956 var ret = matches.call( node, expr );
4958 // IE 9's matchesSelector returns false on disconnected nodes
4959 if ( ret || !disconnectedMatch ||
4960 // As well, disconnected nodes are said to be in a document
4961 // fragment in IE 9, so check for that
4962 node.document && node.document.nodeType !== 11 ) {
4969 return Sizzle(expr, null, null, [node]).length > 0;
4975 var div = document.createElement("div");
4977 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4979 // Opera can't find a second classname (in 9.6)
4980 // Also, make sure that getElementsByClassName actually exists
4981 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4985 // Safari caches class attributes, doesn't catch changes (in 3.2)
4986 div.lastChild.className = "e";
4988 if ( div.getElementsByClassName("e").length === 1 ) {
4992 Expr.order.splice(1, 0, "CLASS");
4993 Expr.find.CLASS = function( match, context, isXML ) {
4994 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4995 return context.getElementsByClassName(match[1]);
4999 // release memory in IE
5003 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5004 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5005 var elem = checkSet[i];
5013 if ( elem.sizcache === doneName ) {
5014 match = checkSet[elem.sizset];
5018 if ( elem.nodeType === 1 && !isXML ){
5019 elem.sizcache = doneName;
5023 if ( elem.nodeName.toLowerCase() === cur ) {
5031 checkSet[i] = match;
5036 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5037 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5038 var elem = checkSet[i];
5046 if ( elem.sizcache === doneName ) {
5047 match = checkSet[elem.sizset];
5051 if ( elem.nodeType === 1 ) {
5053 elem.sizcache = doneName;
5057 if ( typeof cur !== "string" ) {
5058 if ( elem === cur ) {
5063 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5072 checkSet[i] = match;
5077 if ( document.documentElement.contains ) {
5078 Sizzle.contains = function( a, b ) {
5079 return a !== b && (a.contains ? a.contains(b) : true);
5082 } else if ( document.documentElement.compareDocumentPosition ) {
5083 Sizzle.contains = function( a, b ) {
5084 return !!(a.compareDocumentPosition(b) & 16);
5088 Sizzle.contains = function() {
5093 Sizzle.isXML = function( elem ) {
5094 // documentElement is verified for cases where it doesn't yet exist
5095 // (such as loading iframes in IE - #4833)
5096 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5098 return documentElement ? documentElement.nodeName !== "HTML" : false;
5101 var posProcess = function( selector, context ) {
5105 root = context.nodeType ? [context] : context;
5107 // Position selectors must be done after the filter
5108 // And so must :not(positional) so we move all PSEUDOs to the end
5109 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5111 selector = selector.replace( Expr.match.PSEUDO, "" );
5114 selector = Expr.relative[selector] ? selector + "*" : selector;
5116 for ( var i = 0, l = root.length; i < l; i++ ) {
5117 Sizzle( selector, root[i], tmpSet );
5120 return Sizzle.filter( later, tmpSet );
5124 jQuery.find = Sizzle;
5125 jQuery.expr = Sizzle.selectors;
5126 jQuery.expr[":"] = jQuery.expr.filters;
5127 jQuery.unique = Sizzle.uniqueSort;
5128 jQuery.text = Sizzle.getText;
5129 jQuery.isXMLDoc = Sizzle.isXML;
5130 jQuery.contains = Sizzle.contains;
5136 var runtil = /Until$/,
5137 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5138 // Note: This RegExp should be improved, or likely pulled from Sizzle
5139 rmultiselector = /,/,
5140 isSimple = /^.[^:#\[\.,]*$/,
5141 slice = Array.prototype.slice,
5142 POS = jQuery.expr.match.POS,
5143 // methods guaranteed to produce a unique set when starting from a unique set
5144 guaranteedUnique = {
5152 find: function( selector ) {
5156 if ( typeof selector !== "string" ) {
5157 return jQuery( selector ).filter(function() {
5158 for ( i = 0, l = self.length; i < l; i++ ) {
5159 if ( jQuery.contains( self[ i ], this ) ) {
5166 var ret = this.pushStack( "", "find", selector ),
5169 for ( i = 0, l = this.length; i < l; i++ ) {
5170 length = ret.length;
5171 jQuery.find( selector, this[i], ret );
5174 // Make sure that the results are unique
5175 for ( n = length; n < ret.length; n++ ) {
5176 for ( r = 0; r < length; r++ ) {
5177 if ( ret[r] === ret[n] ) {
5189 has: function( target ) {
5190 var targets = jQuery( target );
5191 return this.filter(function() {
5192 for ( var i = 0, l = targets.length; i < l; i++ ) {
5193 if ( jQuery.contains( this, targets[i] ) ) {
5200 not: function( selector ) {
5201 return this.pushStack( winnow(this, selector, false), "not", selector);
5204 filter: function( selector ) {
5205 return this.pushStack( winnow(this, selector, true), "filter", selector );
5208 is: function( selector ) {
5209 return !!selector && ( typeof selector === "string" ?
5210 jQuery.filter( selector, this ).length > 0 :
5211 this.filter( selector ).length > 0 );
5214 closest: function( selectors, context ) {
5215 var ret = [], i, l, cur = this[0];
5218 if ( jQuery.isArray( selectors ) ) {
5219 var match, selector,
5223 if ( cur && selectors.length ) {
5224 for ( i = 0, l = selectors.length; i < l; i++ ) {
5225 selector = selectors[i];
5227 if ( !matches[ selector ] ) {
5228 matches[ selector ] = POS.test( selector ) ?
5229 jQuery( selector, context || this.context ) :
5234 while ( cur && cur.ownerDocument && cur !== context ) {
5235 for ( selector in matches ) {
5236 match = matches[ selector ];
5238 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5239 ret.push({ selector: selector, elem: cur, level: level });
5243 cur = cur.parentNode;
5252 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5253 jQuery( selectors, context || this.context ) :
5256 for ( i = 0, l = this.length; i < l; i++ ) {
5260 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5265 cur = cur.parentNode;
5266 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5273 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5275 return this.pushStack( ret, "closest", selectors );
5278 // Determine the position of an element within
5279 // the matched set of elements
5280 index: function( elem ) {
5281 if ( !elem || typeof elem === "string" ) {
5282 return jQuery.inArray( this[0],
5283 // If it receives a string, the selector is used
5284 // If it receives nothing, the siblings are used
5285 elem ? jQuery( elem ) : this.parent().children() );
5287 // Locate the position of the desired element
5288 return jQuery.inArray(
5289 // If it receives a jQuery object, the first element is used
5290 elem.jquery ? elem[0] : elem, this );
5293 add: function( selector, context ) {
5294 var set = typeof selector === "string" ?
5295 jQuery( selector, context ) :
5296 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5297 all = jQuery.merge( this.get(), set );
5299 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5301 jQuery.unique( all ) );
5304 andSelf: function() {
5305 return this.add( this.prevObject );
5309 // A painfully simple check to see if an element is disconnected
5310 // from a document (should be improved, where feasible).
5311 function isDisconnected( node ) {
5312 return !node || !node.parentNode || node.parentNode.nodeType === 11;
5316 parent: function( elem ) {
5317 var parent = elem.parentNode;
5318 return parent && parent.nodeType !== 11 ? parent : null;
5320 parents: function( elem ) {
5321 return jQuery.dir( elem, "parentNode" );
5323 parentsUntil: function( elem, i, until ) {
5324 return jQuery.dir( elem, "parentNode", until );
5326 next: function( elem ) {
5327 return jQuery.nth( elem, 2, "nextSibling" );
5329 prev: function( elem ) {
5330 return jQuery.nth( elem, 2, "previousSibling" );
5332 nextAll: function( elem ) {
5333 return jQuery.dir( elem, "nextSibling" );
5335 prevAll: function( elem ) {
5336 return jQuery.dir( elem, "previousSibling" );
5338 nextUntil: function( elem, i, until ) {
5339 return jQuery.dir( elem, "nextSibling", until );
5341 prevUntil: function( elem, i, until ) {
5342 return jQuery.dir( elem, "previousSibling", until );
5344 siblings: function( elem ) {
5345 return jQuery.sibling( elem.parentNode.firstChild, elem );
5347 children: function( elem ) {
5348 return jQuery.sibling( elem.firstChild );
5350 contents: function( elem ) {
5351 return jQuery.nodeName( elem, "iframe" ) ?
5352 elem.contentDocument || elem.contentWindow.document :
5353 jQuery.makeArray( elem.childNodes );
5355 }, function( name, fn ) {
5356 jQuery.fn[ name ] = function( until, selector ) {
5357 var ret = jQuery.map( this, fn, until ),
5358 // The variable 'args' was introduced in
5359 // https://github.com/jquery/jquery/commit/52a0238
5360 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5361 // http://code.google.com/p/v8/issues/detail?id=1050
5362 args = slice.call(arguments);
5364 if ( !runtil.test( name ) ) {
5368 if ( selector && typeof selector === "string" ) {
5369 ret = jQuery.filter( selector, ret );
5372 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5374 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5375 ret = ret.reverse();
5378 return this.pushStack( ret, name, args.join(",") );
5383 filter: function( expr, elems, not ) {
5385 expr = ":not(" + expr + ")";
5388 return elems.length === 1 ?
5389 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5390 jQuery.find.matches(expr, elems);
5393 dir: function( elem, dir, until ) {
5397 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5398 if ( cur.nodeType === 1 ) {
5399 matched.push( cur );
5406 nth: function( cur, result, dir, elem ) {
5407 result = result || 1;
5410 for ( ; cur; cur = cur[dir] ) {
5411 if ( cur.nodeType === 1 && ++num === result ) {
5419 sibling: function( n, elem ) {
5422 for ( ; n; n = n.nextSibling ) {
5423 if ( n.nodeType === 1 && n !== elem ) {
5432 // Implement the identical functionality for filter and not
5433 function winnow( elements, qualifier, keep ) {
5435 // Can't pass null or undefined to indexOf in Firefox 4
5436 // Set to 0 to skip string check
5437 qualifier = qualifier || 0;
5439 if ( jQuery.isFunction( qualifier ) ) {
5440 return jQuery.grep(elements, function( elem, i ) {
5441 var retVal = !!qualifier.call( elem, i, elem );
5442 return retVal === keep;
5445 } else if ( qualifier.nodeType ) {
5446 return jQuery.grep(elements, function( elem, i ) {
5447 return (elem === qualifier) === keep;
5450 } else if ( typeof qualifier === "string" ) {
5451 var filtered = jQuery.grep(elements, function( elem ) {
5452 return elem.nodeType === 1;
5455 if ( isSimple.test( qualifier ) ) {
5456 return jQuery.filter(qualifier, filtered, !keep);
5458 qualifier = jQuery.filter( qualifier, filtered );
5462 return jQuery.grep(elements, function( elem, i ) {
5463 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5470 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5471 rleadingWhitespace = /^\s+/,
5472 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5473 rtagName = /<([\w:]+)/,
5475 rhtml = /<|&#?\w+;/,
5476 rnocache = /<(?:script|object|embed|option|style)/i,
5477 // checked="checked" or checked
5478 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5479 rscriptType = /\/(java|ecma)script/i,
5480 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5482 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5483 legend: [ 1, "<fieldset>", "</fieldset>" ],
5484 thead: [ 1, "<table>", "</table>" ],
5485 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5486 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5487 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5488 area: [ 1, "<map>", "</map>" ],
5489 _default: [ 0, "", "" ]
5492 wrapMap.optgroup = wrapMap.option;
5493 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5494 wrapMap.th = wrapMap.td;
5496 // IE can't serialize <link> and <script> tags normally
5497 if ( !jQuery.support.htmlSerialize ) {
5498 wrapMap._default = [ 1, "div<div>", "</div>" ];
5502 text: function( text ) {
5503 if ( jQuery.isFunction(text) ) {
5504 return this.each(function(i) {
5505 var self = jQuery( this );
5507 self.text( text.call(this, i, self.text()) );
5511 if ( typeof text !== "object" && text !== undefined ) {
5512 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5515 return jQuery.text( this );
5518 wrapAll: function( html ) {
5519 if ( jQuery.isFunction( html ) ) {
5520 return this.each(function(i) {
5521 jQuery(this).wrapAll( html.call(this, i) );
5526 // The elements to wrap the target around
5527 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5529 if ( this[0].parentNode ) {
5530 wrap.insertBefore( this[0] );
5533 wrap.map(function() {
5536 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5537 elem = elem.firstChild;
5547 wrapInner: function( html ) {
5548 if ( jQuery.isFunction( html ) ) {
5549 return this.each(function(i) {
5550 jQuery(this).wrapInner( html.call(this, i) );
5554 return this.each(function() {
5555 var self = jQuery( this ),
5556 contents = self.contents();
5558 if ( contents.length ) {
5559 contents.wrapAll( html );
5562 self.append( html );
5567 wrap: function( html ) {
5568 return this.each(function() {
5569 jQuery( this ).wrapAll( html );
5573 unwrap: function() {
5574 return this.parent().each(function() {
5575 if ( !jQuery.nodeName( this, "body" ) ) {
5576 jQuery( this ).replaceWith( this.childNodes );
5581 append: function() {
5582 return this.domManip(arguments, true, function( elem ) {
5583 if ( this.nodeType === 1 ) {
5584 this.appendChild( elem );
5589 prepend: function() {
5590 return this.domManip(arguments, true, function( elem ) {
5591 if ( this.nodeType === 1 ) {
5592 this.insertBefore( elem, this.firstChild );
5597 before: function() {
5598 if ( this[0] && this[0].parentNode ) {
5599 return this.domManip(arguments, false, function( elem ) {
5600 this.parentNode.insertBefore( elem, this );
5602 } else if ( arguments.length ) {
5603 var set = jQuery(arguments[0]);
5604 set.push.apply( set, this.toArray() );
5605 return this.pushStack( set, "before", arguments );
5610 if ( this[0] && this[0].parentNode ) {
5611 return this.domManip(arguments, false, function( elem ) {
5612 this.parentNode.insertBefore( elem, this.nextSibling );
5614 } else if ( arguments.length ) {
5615 var set = this.pushStack( this, "after", arguments );
5616 set.push.apply( set, jQuery(arguments[0]).toArray() );
5621 // keepData is for internal use only--do not document
5622 remove: function( selector, keepData ) {
5623 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5624 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5625 if ( !keepData && elem.nodeType === 1 ) {
5626 jQuery.cleanData( elem.getElementsByTagName("*") );
5627 jQuery.cleanData( [ elem ] );
5630 if ( elem.parentNode ) {
5631 elem.parentNode.removeChild( elem );
5640 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5641 // Remove element nodes and prevent memory leaks
5642 if ( elem.nodeType === 1 ) {
5643 jQuery.cleanData( elem.getElementsByTagName("*") );
5646 // Remove any remaining nodes
5647 while ( elem.firstChild ) {
5648 elem.removeChild( elem.firstChild );
5655 clone: function( dataAndEvents, deepDataAndEvents ) {
5656 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5657 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5659 return this.map( function () {
5660 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5664 html: function( value ) {
5665 if ( value === undefined ) {
5666 return this[0] && this[0].nodeType === 1 ?
5667 this[0].innerHTML.replace(rinlinejQuery, "") :
5670 // See if we can take a shortcut and just use innerHTML
5671 } else if ( typeof value === "string" && !rnocache.test( value ) &&
5672 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5673 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5675 value = value.replace(rxhtmlTag, "<$1></$2>");
5678 for ( var i = 0, l = this.length; i < l; i++ ) {
5679 // Remove element nodes and prevent memory leaks
5680 if ( this[i].nodeType === 1 ) {
5681 jQuery.cleanData( this[i].getElementsByTagName("*") );
5682 this[i].innerHTML = value;
5686 // If using innerHTML throws an exception, use the fallback method
5688 this.empty().append( value );
5691 } else if ( jQuery.isFunction( value ) ) {
5692 this.each(function(i){
5693 var self = jQuery( this );
5695 self.html( value.call(this, i, self.html()) );
5699 this.empty().append( value );
5705 replaceWith: function( value ) {
5706 if ( this[0] && this[0].parentNode ) {
5707 // Make sure that the elements are removed from the DOM before they are inserted
5708 // this can help fix replacing a parent with child elements
5709 if ( jQuery.isFunction( value ) ) {
5710 return this.each(function(i) {
5711 var self = jQuery(this), old = self.html();
5712 self.replaceWith( value.call( this, i, old ) );
5716 if ( typeof value !== "string" ) {
5717 value = jQuery( value ).detach();
5720 return this.each(function() {
5721 var next = this.nextSibling,
5722 parent = this.parentNode;
5724 jQuery( this ).remove();
5727 jQuery(next).before( value );
5729 jQuery(parent).append( value );
5733 return this.length ?
5734 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5739 detach: function( selector ) {
5740 return this.remove( selector, true );
5743 domManip: function( args, table, callback ) {
5744 var results, first, fragment, parent,
5748 // We can't cloneNode fragments that contain checked, in WebKit
5749 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5750 return this.each(function() {
5751 jQuery(this).domManip( args, table, callback, true );
5755 if ( jQuery.isFunction(value) ) {
5756 return this.each(function(i) {
5757 var self = jQuery(this);
5758 args[0] = value.call(this, i, table ? self.html() : undefined);
5759 self.domManip( args, table, callback );
5764 parent = value && value.parentNode;
5766 // If we're in a fragment, just use that instead of building a new one
5767 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5768 results = { fragment: parent };
5771 results = jQuery.buildFragment( args, this, scripts );
5774 fragment = results.fragment;
5776 if ( fragment.childNodes.length === 1 ) {
5777 first = fragment = fragment.firstChild;
5779 first = fragment.firstChild;
5783 table = table && jQuery.nodeName( first, "tr" );
5785 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5788 root(this[i], first) :
5790 // Make sure that we do not leak memory by inadvertently discarding
5791 // the original fragment (which might have attached data) instead of
5792 // using it; in addition, use the original fragment object for the last
5793 // item instead of first because it can end up being emptied incorrectly
5794 // in certain situations (Bug #8070).
5795 // Fragments from the fragment cache must always be cloned and never used
5797 results.cacheable || (l > 1 && i < lastIndex) ?
5798 jQuery.clone( fragment, true, true ) :
5804 if ( scripts.length ) {
5805 jQuery.each( scripts, evalScript );
5813 function root( elem, cur ) {
5814 return jQuery.nodeName(elem, "table") ?
5815 (elem.getElementsByTagName("tbody")[0] ||
5816 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5820 function cloneCopyEvent( src, dest ) {
5822 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5826 var internalKey = jQuery.expando,
5827 oldData = jQuery.data( src ),
5828 curData = jQuery.data( dest, oldData );
5830 // Switch to use the internal data object, if it exists, for the next
5831 // stage of data copying
5832 if ( (oldData = oldData[ internalKey ]) ) {
5833 var events = oldData.events;
5834 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5837 delete curData.handle;
5838 curData.events = {};
5840 for ( var type in events ) {
5841 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5842 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5849 function cloneFixAttributes( src, dest ) {
5852 // We do not need to do anything for non-Elements
5853 if ( dest.nodeType !== 1 ) {
5857 // clearAttributes removes the attributes, which we don't want,
5858 // but also removes the attachEvent events, which we *do* want
5859 if ( dest.clearAttributes ) {
5860 dest.clearAttributes();
5863 // mergeAttributes, in contrast, only merges back on the
5864 // original attributes, not the events
5865 if ( dest.mergeAttributes ) {
5866 dest.mergeAttributes( src );
5869 nodeName = dest.nodeName.toLowerCase();
5871 // IE6-8 fail to clone children inside object elements that use
5872 // the proprietary classid attribute value (rather than the type
5873 // attribute) to identify the type of content to display
5874 if ( nodeName === "object" ) {
5875 dest.outerHTML = src.outerHTML;
5877 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5878 // IE6-8 fails to persist the checked state of a cloned checkbox
5879 // or radio button. Worse, IE6-7 fail to give the cloned element
5880 // a checked appearance if the defaultChecked value isn't also set
5881 if ( src.checked ) {
5882 dest.defaultChecked = dest.checked = src.checked;
5885 // IE6-7 get confused and end up setting the value of a cloned
5886 // checkbox/radio button to an empty string instead of "on"
5887 if ( dest.value !== src.value ) {
5888 dest.value = src.value;
5891 // IE6-8 fails to return the selected option to the default selected
5892 // state when cloning options
5893 } else if ( nodeName === "option" ) {
5894 dest.selected = src.defaultSelected;
5896 // IE6-8 fails to set the defaultValue to the correct value when
5897 // cloning other types of input fields
5898 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5899 dest.defaultValue = src.defaultValue;
5902 // Event data gets referenced instead of copied if the expando
5904 dest.removeAttribute( jQuery.expando );
5907 jQuery.buildFragment = function( args, nodes, scripts ) {
5908 var fragment, cacheable, cacheresults,
5909 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5911 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5912 // Cloning options loses the selected state, so don't cache them
5913 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5914 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5915 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5916 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5920 cacheresults = jQuery.fragments[ args[0] ];
5921 if ( cacheresults && cacheresults !== 1 ) {
5922 fragment = cacheresults;
5927 fragment = doc.createDocumentFragment();
5928 jQuery.clean( args, doc, fragment, scripts );
5932 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5935 return { fragment: fragment, cacheable: cacheable };
5938 jQuery.fragments = {};
5942 prependTo: "prepend",
5943 insertBefore: "before",
5944 insertAfter: "after",
5945 replaceAll: "replaceWith"
5946 }, function( name, original ) {
5947 jQuery.fn[ name ] = function( selector ) {
5949 insert = jQuery( selector ),
5950 parent = this.length === 1 && this[0].parentNode;
5952 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5953 insert[ original ]( this[0] );
5957 for ( var i = 0, l = insert.length; i < l; i++ ) {
5958 var elems = (i > 0 ? this.clone(true) : this).get();
5959 jQuery( insert[i] )[ original ]( elems );
5960 ret = ret.concat( elems );
5963 return this.pushStack( ret, name, insert.selector );
5968 function getAll( elem ) {
5969 if ( "getElementsByTagName" in elem ) {
5970 return elem.getElementsByTagName( "*" );
5972 } else if ( "querySelectorAll" in elem ) {
5973 return elem.querySelectorAll( "*" );
5980 // Used in clean, fixes the defaultChecked property
5981 function fixDefaultChecked( elem ) {
5982 if ( elem.type === "checkbox" || elem.type === "radio" ) {
5983 elem.defaultChecked = elem.checked;
5986 // Finds all inputs and passes them to fixDefaultChecked
5987 function findInputs( elem ) {
5988 if ( jQuery.nodeName( elem, "input" ) ) {
5989 fixDefaultChecked( elem );
5990 } else if ( elem.getElementsByTagName ) {
5991 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
5996 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5997 var clone = elem.cloneNode(true),
6002 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6003 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6004 // IE copies events bound via attachEvent when using cloneNode.
6005 // Calling detachEvent on the clone will also remove the events
6006 // from the original. In order to get around this, we use some
6007 // proprietary methods to clear the events. Thanks to MooTools
6008 // guys for this hotness.
6010 cloneFixAttributes( elem, clone );
6012 // Using Sizzle here is crazy slow, so we use getElementsByTagName
6014 srcElements = getAll( elem );
6015 destElements = getAll( clone );
6017 // Weird iteration because IE will replace the length property
6018 // with an element if you are cloning the body and one of the
6019 // elements on the page has a name or id of "length"
6020 for ( i = 0; srcElements[i]; ++i ) {
6021 cloneFixAttributes( srcElements[i], destElements[i] );
6025 // Copy the events from the original to the clone
6026 if ( dataAndEvents ) {
6027 cloneCopyEvent( elem, clone );
6029 if ( deepDataAndEvents ) {
6030 srcElements = getAll( elem );
6031 destElements = getAll( clone );
6033 for ( i = 0; srcElements[i]; ++i ) {
6034 cloneCopyEvent( srcElements[i], destElements[i] );
6039 // Return the cloned set
6043 clean: function( elems, context, fragment, scripts ) {
6044 var checkScriptType;
6046 context = context || document;
6048 // !context.createElement fails in IE with an error but returns typeof 'object'
6049 if ( typeof context.createElement === "undefined" ) {
6050 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6055 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6056 if ( typeof elem === "number" ) {
6064 // Convert html string into DOM nodes
6065 if ( typeof elem === "string" ) {
6066 if ( !rhtml.test( elem ) ) {
6067 elem = context.createTextNode( elem );
6069 // Fix "XHTML"-style tags in all browsers
6070 elem = elem.replace(rxhtmlTag, "<$1></$2>");
6072 // Trim whitespace, otherwise indexOf won't work as expected
6073 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6074 wrap = wrapMap[ tag ] || wrapMap._default,
6076 div = context.createElement("div");
6078 // Go to html and back, then peel off extra wrappers
6079 div.innerHTML = wrap[1] + elem + wrap[2];
6081 // Move to the right depth
6083 div = div.lastChild;
6086 // Remove IE's autoinserted <tbody> from table fragments
6087 if ( !jQuery.support.tbody ) {
6089 // String was a <table>, *may* have spurious <tbody>
6090 var hasBody = rtbody.test(elem),
6091 tbody = tag === "table" && !hasBody ?
6092 div.firstChild && div.firstChild.childNodes :
6094 // String was a bare <thead> or <tfoot>
6095 wrap[1] === "<table>" && !hasBody ?
6099 for ( j = tbody.length - 1; j >= 0 ; --j ) {
6100 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6101 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6106 // IE completely kills leading whitespace when innerHTML is used
6107 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6108 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6111 elem = div.childNodes;
6115 // Resets defaultChecked for any radios and checkboxes
6116 // about to be appended to the DOM in IE 6/7 (#8060)
6118 if ( !jQuery.support.appendChecked ) {
6119 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6120 for ( j = 0; j < len; j++ ) {
6121 findInputs( elem[j] );
6128 if ( elem.nodeType ) {
6131 ret = jQuery.merge( ret, elem );
6136 checkScriptType = function( elem ) {
6137 return !elem.type || rscriptType.test( elem.type );
6139 for ( i = 0; ret[i]; i++ ) {
6140 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6141 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6144 if ( ret[i].nodeType === 1 ) {
6145 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6147 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6149 fragment.appendChild( ret[i] );
6157 cleanData: function( elems ) {
6158 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6159 deleteExpando = jQuery.support.deleteExpando;
6161 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6162 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6166 id = elem[ jQuery.expando ];
6169 data = cache[ id ] && cache[ id ][ internalKey ];
6171 if ( data && data.events ) {
6172 for ( var type in data.events ) {
6173 if ( special[ type ] ) {
6174 jQuery.event.remove( elem, type );
6176 // This is a shortcut to avoid jQuery.event.remove's overhead
6178 jQuery.removeEvent( elem, type, data.handle );
6182 // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6183 if ( data.handle ) {
6184 data.handle.elem = null;
6188 if ( deleteExpando ) {
6189 delete elem[ jQuery.expando ];
6191 } else if ( elem.removeAttribute ) {
6192 elem.removeAttribute( jQuery.expando );
6201 function evalScript( i, elem ) {
6209 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6212 if ( elem.parentNode ) {
6213 elem.parentNode.removeChild( elem );
6220 var ralpha = /alpha\([^)]*\)/i,
6221 ropacity = /opacity=([^)]*)/,
6222 rdashAlpha = /-([a-z])/ig,
6223 // fixed for IE9, see #8346
6224 rupper = /([A-Z]|^ms)/g,
6225 rnumpx = /^-?\d+(?:px)?$/i,
6227 rrelNum = /^[+\-]=/,
6228 rrelNumFilter = /[^+\-\.\de]+/g,
6230 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6231 cssWidth = [ "Left", "Right" ],
6232 cssHeight = [ "Top", "Bottom" ],
6238 fcamelCase = function( all, letter ) {
6239 return letter.toUpperCase();
6242 jQuery.fn.css = function( name, value ) {
6243 // Setting 'undefined' is a no-op
6244 if ( arguments.length === 2 && value === undefined ) {
6248 return jQuery.access( this, name, value, true, function( elem, name, value ) {
6249 return value !== undefined ?
6250 jQuery.style( elem, name, value ) :
6251 jQuery.css( elem, name );
6256 // Add in style property hooks for overriding the default
6257 // behavior of getting and setting a style property
6260 get: function( elem, computed ) {
6262 // We should always get a number back from opacity
6263 var ret = curCSS( elem, "opacity", "opacity" );
6264 return ret === "" ? "1" : ret;
6267 return elem.style.opacity;
6273 // Exclude the following css properties to add px
6284 // Add in properties whose names you wish to fix before
6285 // setting or getting the value
6287 // normalize float css property
6288 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6291 // Get and set the style property on a DOM Node
6292 style: function( elem, name, value, extra ) {
6293 // Don't set styles on text and comment nodes
6294 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6298 // Make sure that we're working with the right name
6299 var ret, type, origName = jQuery.camelCase( name ),
6300 style = elem.style, hooks = jQuery.cssHooks[ origName ];
6302 name = jQuery.cssProps[ origName ] || origName;
6304 // Check if we're setting a value
6305 if ( value !== undefined ) {
6306 type = typeof value;
6308 // Make sure that NaN and null values aren't set. See: #7116
6309 if ( type === "number" && isNaN( value ) || value == null ) {
6313 // convert relative number strings (+= or -=) to relative numbers. #7345
6314 if ( type === "string" && rrelNum.test( value ) ) {
6315 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6318 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6319 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6323 // If a hook was provided, use that value, otherwise just set the specified value
6324 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6325 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6328 style[ name ] = value;
6333 // If a hook was provided get the non-computed value from there
6334 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6338 // Otherwise just get the value from the style object
6339 return style[ name ];
6343 css: function( elem, name, extra ) {
6346 // Make sure that we're working with the right name
6347 name = jQuery.camelCase( name );
6348 hooks = jQuery.cssHooks[ name ];
6349 name = jQuery.cssProps[ name ] || name;
6351 // cssFloat needs a special treatment
6352 if ( name === "cssFloat" ) {
6356 // If a hook was provided get the computed value from there
6357 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6360 // Otherwise, if a way to get the computed value exists, use that
6361 } else if ( curCSS ) {
6362 return curCSS( elem, name );
6366 // A method for quickly swapping in/out CSS properties to get correct calculations
6367 swap: function( elem, options, callback ) {
6370 // Remember the old values, and insert the new ones
6371 for ( var name in options ) {
6372 old[ name ] = elem.style[ name ];
6373 elem.style[ name ] = options[ name ];
6376 callback.call( elem );
6378 // Revert the old values
6379 for ( name in options ) {
6380 elem.style[ name ] = old[ name ];
6384 camelCase: function( string ) {
6385 return string.replace( rdashAlpha, fcamelCase );
6389 // DEPRECATED, Use jQuery.css() instead
6390 jQuery.curCSS = jQuery.css;
6392 jQuery.each(["height", "width"], function( i, name ) {
6393 jQuery.cssHooks[ name ] = {
6394 get: function( elem, computed, extra ) {
6398 if ( elem.offsetWidth !== 0 ) {
6399 val = getWH( elem, name, extra );
6402 jQuery.swap( elem, cssShow, function() {
6403 val = getWH( elem, name, extra );
6408 val = curCSS( elem, name, name );
6410 if ( val === "0px" && currentStyle ) {
6411 val = currentStyle( elem, name, name );
6414 if ( val != null ) {
6415 // Should return "auto" instead of 0, use 0 for
6416 // temporary backwards-compat
6417 return val === "" || val === "auto" ? "0px" : val;
6421 if ( val < 0 || val == null ) {
6422 val = elem.style[ name ];
6424 // Should return "auto" instead of 0, use 0 for
6425 // temporary backwards-compat
6426 return val === "" || val === "auto" ? "0px" : val;
6429 return typeof val === "string" ? val : val + "px";
6433 set: function( elem, value ) {
6434 if ( rnumpx.test( value ) ) {
6435 // ignore negative width and height values #1599
6436 value = parseFloat(value);
6439 return value + "px";
6449 if ( !jQuery.support.opacity ) {
6450 jQuery.cssHooks.opacity = {
6451 get: function( elem, computed ) {
6452 // IE uses filters for opacity
6453 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6454 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6455 computed ? "1" : "";
6458 set: function( elem, value ) {
6459 var style = elem.style,
6460 currentStyle = elem.currentStyle;
6462 // IE has trouble with opacity if it does not have layout
6463 // Force it by setting the zoom level
6466 // Set the alpha filter to set the opacity
6467 var opacity = jQuery.isNaN( value ) ?
6469 "alpha(opacity=" + value * 100 + ")",
6470 filter = currentStyle && currentStyle.filter || style.filter || "";
6472 style.filter = ralpha.test( filter ) ?
6473 filter.replace( ralpha, opacity ) :
6474 filter + " " + opacity;
6480 // This hook cannot be added until DOM ready because the support test
6481 // for it is not run until after DOM ready
6482 if ( !jQuery.support.reliableMarginRight ) {
6483 jQuery.cssHooks.marginRight = {
6484 get: function( elem, computed ) {
6485 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6486 // Work around by temporarily setting element display to inline-block
6488 jQuery.swap( elem, { "display": "inline-block" }, function() {
6490 ret = curCSS( elem, "margin-right", "marginRight" );
6492 ret = elem.style.marginRight;
6501 if ( document.defaultView && document.defaultView.getComputedStyle ) {
6502 getComputedStyle = function( elem, name ) {
6503 var ret, defaultView, computedStyle;
6505 name = name.replace( rupper, "-$1" ).toLowerCase();
6507 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6511 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6512 ret = computedStyle.getPropertyValue( name );
6513 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6514 ret = jQuery.style( elem, name );
6522 if ( document.documentElement.currentStyle ) {
6523 currentStyle = function( elem, name ) {
6525 ret = elem.currentStyle && elem.currentStyle[ name ],
6526 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6529 // From the awesome hack by Dean Edwards
6530 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6532 // If we're not dealing with a regular pixel number
6533 // but a number that has a weird ending, we need to convert it to pixels
6534 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6535 // Remember the original values
6538 // Put in the new values to get a computed value out
6540 elem.runtimeStyle.left = elem.currentStyle.left;
6542 style.left = name === "fontSize" ? "1em" : (ret || 0);
6543 ret = style.pixelLeft + "px";
6545 // Revert the changed values
6548 elem.runtimeStyle.left = rsLeft;
6552 return ret === "" ? "auto" : ret;
6556 curCSS = getComputedStyle || currentStyle;
6558 function getWH( elem, name, extra ) {
6559 var which = name === "width" ? cssWidth : cssHeight,
6560 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
6562 if ( extra === "border" ) {
6566 jQuery.each( which, function() {
6568 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
6571 if ( extra === "margin" ) {
6572 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
6575 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
6582 if ( jQuery.expr && jQuery.expr.filters ) {
6583 jQuery.expr.filters.hidden = function( elem ) {
6584 var width = elem.offsetWidth,
6585 height = elem.offsetHeight;
6587 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6590 jQuery.expr.filters.visible = function( elem ) {
6591 return !jQuery.expr.filters.hidden( elem );
6602 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6603 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6604 // #7653, #8125, #8152: local protocol detection
6605 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
6606 rnoContent = /^(?:GET|HEAD)$/,
6607 rprotocol = /^\/\//,
6609 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6610 rselectTextarea = /^(?:select|textarea)/i,
6611 rspacesAjax = /\s+/,
6612 rts = /([?&])_=[^&]*/,
6613 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6615 // Keep a copy of the old load method
6616 _load = jQuery.fn.load,
6619 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6620 * 2) These are called:
6621 * - BEFORE asking for a transport
6622 * - AFTER param serialization (s.data is a string if s.processData is true)
6623 * 3) key is the dataType
6624 * 4) the catchall symbol "*" can be used
6625 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6629 /* Transports bindings
6630 * 1) key is the dataType
6631 * 2) the catchall symbol "*" can be used
6632 * 3) selection will start with transport dataType and THEN go to "*" if needed
6636 // Document location
6639 // Document location segments
6642 // #8138, IE may throw an exception when accessing
6643 // a field from window.location if document.domain has been set
6645 ajaxLocation = location.href;
6647 // Use the href attribute of an A element
6648 // since IE will modify it given document.location
6649 ajaxLocation = document.createElement( "a" );
6650 ajaxLocation.href = "";
6651 ajaxLocation = ajaxLocation.href;
6654 // Segment location into parts
6655 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6657 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6658 function addToPrefiltersOrTransports( structure ) {
6660 // dataTypeExpression is optional and defaults to "*"
6661 return function( dataTypeExpression, func ) {
6663 if ( typeof dataTypeExpression !== "string" ) {
6664 func = dataTypeExpression;
6665 dataTypeExpression = "*";
6668 if ( jQuery.isFunction( func ) ) {
6669 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6671 length = dataTypes.length,
6676 // For each dataType in the dataTypeExpression
6677 for(; i < length; i++ ) {
6678 dataType = dataTypes[ i ];
6679 // We control if we're asked to add before
6680 // any existing element
6681 placeBefore = /^\+/.test( dataType );
6682 if ( placeBefore ) {
6683 dataType = dataType.substr( 1 ) || "*";
6685 list = structure[ dataType ] = structure[ dataType ] || [];
6686 // then we add to the structure accordingly
6687 list[ placeBefore ? "unshift" : "push" ]( func );
6693 // Base inspection function for prefilters and transports
6694 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6695 dataType /* internal */, inspected /* internal */ ) {
6697 dataType = dataType || options.dataTypes[ 0 ];
6698 inspected = inspected || {};
6700 inspected[ dataType ] = true;
6702 var list = structure[ dataType ],
6704 length = list ? list.length : 0,
6705 executeOnly = ( structure === prefilters ),
6708 for(; i < length && ( executeOnly || !selection ); i++ ) {
6709 selection = list[ i ]( options, originalOptions, jqXHR );
6710 // If we got redirected to another dataType
6711 // we try there if executing only and not done already
6712 if ( typeof selection === "string" ) {
6713 if ( !executeOnly || inspected[ selection ] ) {
6714 selection = undefined;
6716 options.dataTypes.unshift( selection );
6717 selection = inspectPrefiltersOrTransports(
6718 structure, options, originalOptions, jqXHR, selection, inspected );
6722 // If we're only executing or nothing was selected
6723 // we try the catchall dataType if not done already
6724 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6725 selection = inspectPrefiltersOrTransports(
6726 structure, options, originalOptions, jqXHR, "*", inspected );
6728 // unnecessary when only executing (prefilters)
6729 // but it'll be ignored by the caller in that case
6734 load: function( url, params, callback ) {
6735 if ( typeof url !== "string" && _load ) {
6736 return _load.apply( this, arguments );
6738 // Don't do a request if no elements are being requested
6739 } else if ( !this.length ) {
6743 var off = url.indexOf( " " );
6745 var selector = url.slice( off, url.length );
6746 url = url.slice( 0, off );
6749 // Default to a GET request
6752 // If the second parameter was provided
6754 // If it's a function
6755 if ( jQuery.isFunction( params ) ) {
6756 // We assume that it's the callback
6760 // Otherwise, build a param string
6761 } else if ( typeof params === "object" ) {
6762 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6769 // Request the remote document
6775 // Complete callback (responseText is used internally)
6776 complete: function( jqXHR, status, responseText ) {
6777 // Store the response as specified by the jqXHR object
6778 responseText = jqXHR.responseText;
6779 // If successful, inject the HTML into all the matched elements
6780 if ( jqXHR.isResolved() ) {
6781 // #4825: Get the actual response in case
6782 // a dataFilter is present in ajaxSettings
6783 jqXHR.done(function( r ) {
6786 // See if a selector was specified
6787 self.html( selector ?
6788 // Create a dummy div to hold the results
6790 // inject the contents of the document in, removing the scripts
6791 // to avoid any 'Permission Denied' errors in IE
6792 .append(responseText.replace(rscript, ""))
6794 // Locate the specified elements
6797 // If not, just inject the full result
6802 self.each( callback, [ responseText, status, jqXHR ] );
6810 serialize: function() {
6811 return jQuery.param( this.serializeArray() );
6814 serializeArray: function() {
6815 return this.map(function(){
6816 return this.elements ? jQuery.makeArray( this.elements ) : this;
6819 return this.name && !this.disabled &&
6820 ( this.checked || rselectTextarea.test( this.nodeName ) ||
6821 rinput.test( this.type ) );
6823 .map(function( i, elem ){
6824 var val = jQuery( this ).val();
6826 return val == null ?
6828 jQuery.isArray( val ) ?
6829 jQuery.map( val, function( val, i ){
6830 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6832 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6837 // Attach a bunch of functions for handling common AJAX events
6838 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6839 jQuery.fn[ o ] = function( f ){
6840 return this.bind( o, f );
6844 jQuery.each( [ "get", "post" ], function( i, method ) {
6845 jQuery[ method ] = function( url, data, callback, type ) {
6846 // shift arguments if data argument was omitted
6847 if ( jQuery.isFunction( data ) ) {
6848 type = type || callback;
6853 return jQuery.ajax({
6865 getScript: function( url, callback ) {
6866 return jQuery.get( url, undefined, callback, "script" );
6869 getJSON: function( url, data, callback ) {
6870 return jQuery.get( url, data, callback, "json" );
6873 // Creates a full fledged settings object into target
6874 // with both ajaxSettings and settings fields.
6875 // If target is omitted, writes into ajaxSettings.
6876 ajaxSetup: function ( target, settings ) {
6878 // Only one parameter, we extend ajaxSettings
6880 target = jQuery.extend( true, jQuery.ajaxSettings, settings );
6882 // target was provided, we extend into it
6883 jQuery.extend( true, target, jQuery.ajaxSettings, settings );
6885 // Flatten fields we don't want deep extended
6886 for( var field in { context: 1, url: 1 } ) {
6887 if ( field in settings ) {
6888 target[ field ] = settings[ field ];
6889 } else if( field in jQuery.ajaxSettings ) {
6890 target[ field ] = jQuery.ajaxSettings[ field ];
6898 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
6901 contentType: "application/x-www-form-urlencoded",
6916 xml: "application/xml, text/xml",
6919 json: "application/json, text/javascript",
6931 text: "responseText"
6934 // List of data converters
6935 // 1) key format is "source_type destination_type" (a single space in-between)
6936 // 2) the catchall symbol "*" can be used for source_type
6939 // Convert anything to text
6940 "* text": window.String,
6942 // Text to html (true = no transformation)
6945 // Evaluate text as a json expression
6946 "text json": jQuery.parseJSON,
6948 // Parse text as xml
6949 "text xml": jQuery.parseXML
6953 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6954 ajaxTransport: addToPrefiltersOrTransports( transports ),
6957 ajax: function( url, options ) {
6959 // If url is an object, simulate pre-1.5 signature
6960 if ( typeof url === "object" ) {
6965 // Force options to be an object
6966 options = options || {};
6968 var // Create the final options object
6969 s = jQuery.ajaxSetup( {}, options ),
6970 // Callbacks context
6971 callbackContext = s.context || s,
6972 // Context for global events
6973 // It's the callbackContext if one was provided in the options
6974 // and if it's a DOM node or a jQuery collection
6975 globalEventContext = callbackContext !== s &&
6976 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
6977 jQuery( callbackContext ) : jQuery.event,
6979 deferred = jQuery.Deferred(),
6980 completeDeferred = jQuery._Deferred(),
6981 // Status-dependent callbacks
6982 statusCode = s.statusCode || {},
6985 // Headers (they are sent all at once)
6986 requestHeaders = {},
6987 requestHeadersNames = {},
6989 responseHeadersString,
6995 // Cross-domain detection vars
6999 // To know if global events are to be dispatched
7008 // Caches the header
7009 setRequestHeader: function( name, value ) {
7011 var lname = name.toLowerCase();
7012 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7013 requestHeaders[ name ] = value;
7019 getAllResponseHeaders: function() {
7020 return state === 2 ? responseHeadersString : null;
7023 // Builds headers hashtable if needed
7024 getResponseHeader: function( key ) {
7026 if ( state === 2 ) {
7027 if ( !responseHeaders ) {
7028 responseHeaders = {};
7029 while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7030 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7033 match = responseHeaders[ key.toLowerCase() ];
7035 return match === undefined ? null : match;
7038 // Overrides response content-type header
7039 overrideMimeType: function( type ) {
7046 // Cancel the request
7047 abort: function( statusText ) {
7048 statusText = statusText || "abort";
7050 transport.abort( statusText );
7052 done( 0, statusText );
7057 // Callback for when everything is done
7058 // It is defined here because jslint complains if it is declared
7059 // at the end of the function (which would be more logical and readable)
7060 function done( status, statusText, responses, headers ) {
7063 if ( state === 2 ) {
7067 // State is "done" now
7070 // Clear timeout if it exists
7071 if ( timeoutTimer ) {
7072 clearTimeout( timeoutTimer );
7075 // Dereference transport for early garbage collection
7076 // (no matter how long the jqXHR object will be used)
7077 transport = undefined;
7079 // Cache response headers
7080 responseHeadersString = headers || "";
7083 jqXHR.readyState = status ? 4 : 0;
7088 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7092 // If successful, handle type chaining
7093 if ( status >= 200 && status < 300 || status === 304 ) {
7095 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7096 if ( s.ifModified ) {
7098 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7099 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7101 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7102 jQuery.etag[ ifModifiedKey ] = etag;
7107 if ( status === 304 ) {
7109 statusText = "notmodified";
7116 success = ajaxConvert( s, response );
7117 statusText = "success";
7120 // We have a parsererror
7121 statusText = "parsererror";
7126 // We extract error from statusText
7127 // then normalize statusText and status for non-aborts
7129 if( !statusText || status ) {
7130 statusText = "error";
7137 // Set data for the fake xhr object
7138 jqXHR.status = status;
7139 jqXHR.statusText = statusText;
7143 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7145 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7148 // Status-dependent callbacks
7149 jqXHR.statusCode( statusCode );
7150 statusCode = undefined;
7152 if ( fireGlobals ) {
7153 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7154 [ jqXHR, s, isSuccess ? success : error ] );
7158 completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7160 if ( fireGlobals ) {
7161 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7162 // Handle the global AJAX counter
7163 if ( !( --jQuery.active ) ) {
7164 jQuery.event.trigger( "ajaxStop" );
7170 deferred.promise( jqXHR );
7171 jqXHR.success = jqXHR.done;
7172 jqXHR.error = jqXHR.fail;
7173 jqXHR.complete = completeDeferred.done;
7175 // Status-dependent callbacks
7176 jqXHR.statusCode = function( map ) {
7181 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7184 tmp = map[ jqXHR.status ];
7185 jqXHR.then( tmp, tmp );
7191 // Remove hash character (#7531: and string promotion)
7192 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7193 // We also use the url parameter if available
7194 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7196 // Extract dataTypes list
7197 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7199 // Determine if a cross-domain request is in order
7200 if ( s.crossDomain == null ) {
7201 parts = rurl.exec( s.url.toLowerCase() );
7202 s.crossDomain = !!( parts &&
7203 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7204 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7205 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7209 // Convert data if not already a string
7210 if ( s.data && s.processData && typeof s.data !== "string" ) {
7211 s.data = jQuery.param( s.data, s.traditional );
7215 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7217 // If request was aborted inside a prefiler, stop there
7218 if ( state === 2 ) {
7222 // We can fire global events as of now if asked to
7223 fireGlobals = s.global;
7225 // Uppercase the type
7226 s.type = s.type.toUpperCase();
7228 // Determine if request has content
7229 s.hasContent = !rnoContent.test( s.type );
7231 // Watch for a new set of requests
7232 if ( fireGlobals && jQuery.active++ === 0 ) {
7233 jQuery.event.trigger( "ajaxStart" );
7236 // More options handling for requests with no content
7237 if ( !s.hasContent ) {
7239 // If data is available, append data to url
7241 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7244 // Get ifModifiedKey before adding the anti-cache parameter
7245 ifModifiedKey = s.url;
7247 // Add anti-cache in url if needed
7248 if ( s.cache === false ) {
7250 var ts = jQuery.now(),
7251 // try replacing _= if it is there
7252 ret = s.url.replace( rts, "$1_=" + ts );
7254 // if nothing was replaced, add timestamp to the end
7255 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7259 // Set the correct header, if data is being sent
7260 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7261 jqXHR.setRequestHeader( "Content-Type", s.contentType );
7264 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7265 if ( s.ifModified ) {
7266 ifModifiedKey = ifModifiedKey || s.url;
7267 if ( jQuery.lastModified[ ifModifiedKey ] ) {
7268 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7270 if ( jQuery.etag[ ifModifiedKey ] ) {
7271 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7275 // Set the Accepts header for the server, depending on the dataType
7276 jqXHR.setRequestHeader(
7278 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7279 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7283 // Check for headers option
7284 for ( i in s.headers ) {
7285 jqXHR.setRequestHeader( i, s.headers[ i ] );
7288 // Allow custom headers/mimetypes and early abort
7289 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7290 // Abort if not done already
7296 // Install callbacks on deferreds
7297 for ( i in { success: 1, error: 1, complete: 1 } ) {
7298 jqXHR[ i ]( s[ i ] );
7302 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7304 // If no transport, we auto-abort
7306 done( -1, "No Transport" );
7308 jqXHR.readyState = 1;
7309 // Send global event
7310 if ( fireGlobals ) {
7311 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7314 if ( s.async && s.timeout > 0 ) {
7315 timeoutTimer = setTimeout( function(){
7316 jqXHR.abort( "timeout" );
7322 transport.send( requestHeaders, done );
7324 // Propagate exception as error if not done
7327 // Simply rethrow otherwise
7337 // Serialize an array of form elements or a set of
7338 // key/values into a query string
7339 param: function( a, traditional ) {
7341 add = function( key, value ) {
7342 // If value is a function, invoke it and return its value
7343 value = jQuery.isFunction( value ) ? value() : value;
7344 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7347 // Set traditional to true for jQuery <= 1.3.2 behavior.
7348 if ( traditional === undefined ) {
7349 traditional = jQuery.ajaxSettings.traditional;
7352 // If an array was passed in, assume that it is an array of form elements.
7353 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7354 // Serialize the form elements
7355 jQuery.each( a, function() {
7356 add( this.name, this.value );
7360 // If traditional, encode the "old" way (the way 1.3.2 or older
7361 // did it), otherwise encode params recursively.
7362 for ( var prefix in a ) {
7363 buildParams( prefix, a[ prefix ], traditional, add );
7367 // Return the resulting serialization
7368 return s.join( "&" ).replace( r20, "+" );
7372 function buildParams( prefix, obj, traditional, add ) {
7373 if ( jQuery.isArray( obj ) ) {
7374 // Serialize array item.
7375 jQuery.each( obj, function( i, v ) {
7376 if ( traditional || rbracket.test( prefix ) ) {
7377 // Treat each array item as a scalar.
7381 // If array item is non-scalar (array or object), encode its
7382 // numeric index to resolve deserialization ambiguity issues.
7383 // Note that rack (as of 1.0.0) can't currently deserialize
7384 // nested arrays properly, and attempting to do so may cause
7385 // a server error. Possible fixes are to modify rack's
7386 // deserialization algorithm or to provide an option or flag
7387 // to force array serialization to be shallow.
7388 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7392 } else if ( !traditional && obj != null && typeof obj === "object" ) {
7393 // Serialize object item.
7394 for ( var name in obj ) {
7395 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7399 // Serialize scalar item.
7404 // This is still on the jQuery object... for now
7405 // Want to move this to jQuery.ajax some day
7408 // Counter for holding the number of active queries
7411 // Last-Modified header cache for next request
7417 /* Handles responses to an ajax request:
7418 * - sets all responseXXX fields accordingly
7419 * - finds the right dataType (mediates between content-type and expected dataType)
7420 * - returns the corresponding response
7422 function ajaxHandleResponses( s, jqXHR, responses ) {
7424 var contents = s.contents,
7425 dataTypes = s.dataTypes,
7426 responseFields = s.responseFields,
7432 // Fill responseXXX fields
7433 for( type in responseFields ) {
7434 if ( type in responses ) {
7435 jqXHR[ responseFields[type] ] = responses[ type ];
7439 // Remove auto dataType and get content-type in the process
7440 while( dataTypes[ 0 ] === "*" ) {
7442 if ( ct === undefined ) {
7443 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7447 // Check if we're dealing with a known content-type
7449 for ( type in contents ) {
7450 if ( contents[ type ] && contents[ type ].test( ct ) ) {
7451 dataTypes.unshift( type );
7457 // Check to see if we have a response for the expected dataType
7458 if ( dataTypes[ 0 ] in responses ) {
7459 finalDataType = dataTypes[ 0 ];
7461 // Try convertible dataTypes
7462 for ( type in responses ) {
7463 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7464 finalDataType = type;
7467 if ( !firstDataType ) {
7468 firstDataType = type;
7471 // Or just use first one
7472 finalDataType = finalDataType || firstDataType;
7475 // If we found a dataType
7476 // We add the dataType to the list if needed
7477 // and return the corresponding response
7478 if ( finalDataType ) {
7479 if ( finalDataType !== dataTypes[ 0 ] ) {
7480 dataTypes.unshift( finalDataType );
7482 return responses[ finalDataType ];
7486 // Chain conversions given the request and the original response
7487 function ajaxConvert( s, response ) {
7489 // Apply the dataFilter if provided
7490 if ( s.dataFilter ) {
7491 response = s.dataFilter( response, s.dataType );
7494 var dataTypes = s.dataTypes,
7498 length = dataTypes.length,
7500 // Current and previous dataTypes
7501 current = dataTypes[ 0 ],
7503 // Conversion expression
7505 // Conversion function
7507 // Conversion functions (transitive conversion)
7511 // For each dataType in the chain
7512 for( i = 1; i < length; i++ ) {
7514 // Create converters map
7515 // with lowercased keys
7517 for( key in s.converters ) {
7518 if( typeof key === "string" ) {
7519 converters[ key.toLowerCase() ] = s.converters[ key ];
7524 // Get the dataTypes
7526 current = dataTypes[ i ];
7528 // If current is auto dataType, update it to prev
7529 if( current === "*" ) {
7531 // If no auto and dataTypes are actually different
7532 } else if ( prev !== "*" && prev !== current ) {
7534 // Get the converter
7535 conversion = prev + " " + current;
7536 conv = converters[ conversion ] || converters[ "* " + current ];
7538 // If there is no direct converter, search transitively
7541 for( conv1 in converters ) {
7542 tmp = conv1.split( " " );
7543 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7544 conv2 = converters[ tmp[1] + " " + current ];
7546 conv1 = converters[ conv1 ];
7547 if ( conv1 === true ) {
7549 } else if ( conv2 === true ) {
7557 // If we found no converter, dispatch an error
7558 if ( !( conv || conv2 ) ) {
7559 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7561 // If found converter is not an equivalence
7562 if ( conv !== true ) {
7563 // Convert with 1 or 2 converters accordingly
7564 response = conv ? conv( response ) : conv2( conv1(response) );
7574 var jsc = jQuery.now(),
7575 jsre = /(\=)\?(&|$)|\?\?/i;
7577 // Default jsonp settings
7580 jsonpCallback: function() {
7581 return jQuery.expando + "_" + ( jsc++ );
7585 // Detect, normalize options and install callbacks for jsonp requests
7586 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7588 var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7589 ( typeof s.data === "string" );
7591 if ( s.dataTypes[ 0 ] === "jsonp" ||
7592 s.jsonp !== false && ( jsre.test( s.url ) ||
7593 inspectData && jsre.test( s.data ) ) ) {
7595 var responseContainer,
7596 jsonpCallback = s.jsonpCallback =
7597 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7598 previous = window[ jsonpCallback ],
7601 replace = "$1" + jsonpCallback + "$2";
7603 if ( s.jsonp !== false ) {
7604 url = url.replace( jsre, replace );
7605 if ( s.url === url ) {
7606 if ( inspectData ) {
7607 data = data.replace( jsre, replace );
7609 if ( s.data === data ) {
7610 // Add callback manually
7611 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7620 window[ jsonpCallback ] = function( response ) {
7621 responseContainer = [ response ];
7624 // Clean-up function
7625 jqXHR.always(function() {
7626 // Set callback back to previous value
7627 window[ jsonpCallback ] = previous;
7628 // Call if it was a function and we have a response
7629 if ( responseContainer && jQuery.isFunction( previous ) ) {
7630 window[ jsonpCallback ]( responseContainer[ 0 ] );
7634 // Use data converter to retrieve json after script execution
7635 s.converters["script json"] = function() {
7636 if ( !responseContainer ) {
7637 jQuery.error( jsonpCallback + " was not called" );
7639 return responseContainer[ 0 ];
7642 // force json dataType
7643 s.dataTypes[ 0 ] = "json";
7645 // Delegate to script
7653 // Install script dataType
7656 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7659 script: /javascript|ecmascript/
7662 "text script": function( text ) {
7663 jQuery.globalEval( text );
7669 // Handle cache's special case and global
7670 jQuery.ajaxPrefilter( "script", function( s ) {
7671 if ( s.cache === undefined ) {
7674 if ( s.crossDomain ) {
7680 // Bind script tag hack transport
7681 jQuery.ajaxTransport( "script", function(s) {
7683 // This transport only deals with cross domain requests
7684 if ( s.crossDomain ) {
7687 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7691 send: function( _, callback ) {
7693 script = document.createElement( "script" );
7695 script.async = "async";
7697 if ( s.scriptCharset ) {
7698 script.charset = s.scriptCharset;
7703 // Attach handlers for all browsers
7704 script.onload = script.onreadystatechange = function( _, isAbort ) {
7706 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7708 // Handle memory leak in IE
7709 script.onload = script.onreadystatechange = null;
7711 // Remove the script
7712 if ( head && script.parentNode ) {
7713 head.removeChild( script );
7716 // Dereference the script
7719 // Callback if not abort
7721 callback( 200, "success" );
7725 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
7726 // This arises when a base node is used (#2709 and #4378).
7727 head.insertBefore( script, head.firstChild );
7732 script.onload( 0, 1 );
7742 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7743 xhrOnUnloadAbort = window.ActiveXObject ? function() {
7744 // Abort all pending requests
7745 for ( var key in xhrCallbacks ) {
7746 xhrCallbacks[ key ]( 0, 1 );
7752 // Functions to create xhrs
7753 function createStandardXHR() {
7755 return new window.XMLHttpRequest();
7759 function createActiveXHR() {
7761 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7765 // Create the request object
7766 // (This is still attached to ajaxSettings for backward compatibility)
7767 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7768 /* Microsoft failed to properly
7769 * implement the XMLHttpRequest in IE7 (can't request local files),
7770 * so we use the ActiveXObject when it is available
7771 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7772 * we need a fallback.
7775 return !this.isLocal && createStandardXHR() || createActiveXHR();
7777 // For all other browsers, use the standard XMLHttpRequest object
7780 // Determine support properties
7782 jQuery.extend( jQuery.support, {
7784 cors: !!xhr && ( "withCredentials" in xhr )
7786 })( jQuery.ajaxSettings.xhr() );
7788 // Create transport if the browser can provide an xhr
7789 if ( jQuery.support.ajax ) {
7791 jQuery.ajaxTransport(function( s ) {
7792 // Cross domain only allowed if supported through XMLHttpRequest
7793 if ( !s.crossDomain || jQuery.support.cors ) {
7798 send: function( headers, complete ) {
7806 // Passing null username, generates a login popup on Opera (#2865)
7808 xhr.open( s.type, s.url, s.async, s.username, s.password );
7810 xhr.open( s.type, s.url, s.async );
7813 // Apply custom fields if provided
7814 if ( s.xhrFields ) {
7815 for ( i in s.xhrFields ) {
7816 xhr[ i ] = s.xhrFields[ i ];
7820 // Override mime type if needed
7821 if ( s.mimeType && xhr.overrideMimeType ) {
7822 xhr.overrideMimeType( s.mimeType );
7825 // X-Requested-With header
7826 // For cross-domain requests, seeing as conditions for a preflight are
7827 // akin to a jigsaw puzzle, we simply never set it to be sure.
7828 // (it can always be set on a per-request basis or even using ajaxSetup)
7829 // For same-domain requests, won't change header if already provided.
7830 if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7831 headers[ "X-Requested-With" ] = "XMLHttpRequest";
7834 // Need an extra try/catch for cross domain requests in Firefox 3
7836 for ( i in headers ) {
7837 xhr.setRequestHeader( i, headers[ i ] );
7841 // Do send the request
7842 // This may raise an exception which is actually
7843 // handled in jQuery.ajax (so no try/catch here)
7844 xhr.send( ( s.hasContent && s.data ) || null );
7847 callback = function( _, isAbort ) {
7855 // Firefox throws exceptions when accessing properties
7856 // of an xhr when a network error occured
7857 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7860 // Was never called and is aborted or complete
7861 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7864 callback = undefined;
7866 // Do not keep as active anymore
7868 xhr.onreadystatechange = jQuery.noop;
7869 if ( xhrOnUnloadAbort ) {
7870 delete xhrCallbacks[ handle ];
7876 // Abort it manually if needed
7877 if ( xhr.readyState !== 4 ) {
7881 status = xhr.status;
7882 responseHeaders = xhr.getAllResponseHeaders();
7884 xml = xhr.responseXML;
7886 // Construct response list
7887 if ( xml && xml.documentElement /* #4958 */ ) {
7888 responses.xml = xml;
7890 responses.text = xhr.responseText;
7892 // Firefox throws an exception when accessing
7893 // statusText for faulty cross-domain requests
7895 statusText = xhr.statusText;
7897 // We normalize with Webkit giving an empty statusText
7901 // Filter status for non standard behaviors
7903 // If the request is local and we have data: assume a success
7904 // (success with no data won't get notified, that's the best we
7905 // can do given current implementations)
7906 if ( !status && s.isLocal && !s.crossDomain ) {
7907 status = responses.text ? 200 : 404;
7908 // IE - #1450: sometimes returns 1223 when it should be 204
7909 } else if ( status === 1223 ) {
7914 } catch( firefoxAccessException ) {
7916 complete( -1, firefoxAccessException );
7920 // Call complete if needed
7922 complete( status, statusText, responses, responseHeaders );
7926 // if we're in sync mode or it's in cache
7927 // and has been retrieved directly (IE6 & IE7)
7928 // we need to manually fire the callback
7929 if ( !s.async || xhr.readyState === 4 ) {
7933 if ( xhrOnUnloadAbort ) {
7934 // Create the active xhrs callbacks list if needed
7935 // and attach the unload handler
7936 if ( !xhrCallbacks ) {
7938 jQuery( window ).unload( xhrOnUnloadAbort );
7940 // Add to list of active xhrs callbacks
7941 xhrCallbacks[ handle ] = callback;
7943 xhr.onreadystatechange = callback;
7960 var elemdisplay = {},
7962 rfxtypes = /^(?:toggle|show|hide)$/,
7963 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
7966 // height animations
7967 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
7969 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
7970 // opacity animations
7974 requestAnimationFrame = window.webkitRequestAnimationFrame ||
7975 window.mozRequestAnimationFrame ||
7976 window.oRequestAnimationFrame;
7979 show: function( speed, easing, callback ) {
7982 if ( speed || speed === 0 ) {
7983 return this.animate( genFx("show", 3), speed, easing, callback);
7986 for ( var i = 0, j = this.length; i < j; i++ ) {
7990 display = elem.style.display;
7992 // Reset the inline display of this element to learn if it is
7993 // being hidden by cascaded rules or not
7994 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
7995 display = elem.style.display = "";
7998 // Set elements which have been overridden with display: none
7999 // in a stylesheet to whatever the default browser style is
8000 // for such an element
8001 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
8002 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
8007 // Set the display of most of the elements in a second loop
8008 // to avoid the constant reflow
8009 for ( i = 0; i < j; i++ ) {
8013 display = elem.style.display;
8015 if ( display === "" || display === "none" ) {
8016 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8025 hide: function( speed, easing, callback ) {
8026 if ( speed || speed === 0 ) {
8027 return this.animate( genFx("hide", 3), speed, easing, callback);
8030 for ( var i = 0, j = this.length; i < j; i++ ) {
8031 if ( this[i].style ) {
8032 var display = jQuery.css( this[i], "display" );
8034 if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8035 jQuery._data( this[i], "olddisplay", display );
8040 // Set the display of the elements in a second loop
8041 // to avoid the constant reflow
8042 for ( i = 0; i < j; i++ ) {
8043 if ( this[i].style ) {
8044 this[i].style.display = "none";
8052 // Save the old toggle function
8053 _toggle: jQuery.fn.toggle,
8055 toggle: function( fn, fn2, callback ) {
8056 var bool = typeof fn === "boolean";
8058 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8059 this._toggle.apply( this, arguments );
8061 } else if ( fn == null || bool ) {
8062 this.each(function() {
8063 var state = bool ? fn : jQuery(this).is(":hidden");
8064 jQuery(this)[ state ? "show" : "hide" ]();
8068 this.animate(genFx("toggle", 3), fn, fn2, callback);
8074 fadeTo: function( speed, to, easing, callback ) {
8075 return this.filter(":hidden").css("opacity", 0).show().end()
8076 .animate({opacity: to}, speed, easing, callback);
8079 animate: function( prop, speed, easing, callback ) {
8080 var optall = jQuery.speed(speed, easing, callback);
8082 if ( jQuery.isEmptyObject( prop ) ) {
8083 return this.each( optall.complete, [ false ] );
8086 // Do not change referenced properties as per-property easing will be lost
8087 prop = jQuery.extend( {}, prop );
8089 return this[ optall.queue === false ? "each" : "queue" ](function() {
8090 // XXX 'this' does not always have a nodeName when running the
8093 if ( optall.queue === false ) {
8094 jQuery._mark( this );
8097 var opt = jQuery.extend( {}, optall ),
8098 isElement = this.nodeType === 1,
8099 hidden = isElement && jQuery(this).is(":hidden"),
8102 parts, start, end, unit;
8104 // will store per property easing and be used to determine when an animation is complete
8105 opt.animatedProperties = {};
8109 // property name normalization
8110 name = jQuery.camelCase( p );
8112 prop[ name ] = prop[ p ];
8118 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8119 if ( jQuery.isArray( val ) ) {
8120 opt.animatedProperties[ name ] = val[ 1 ];
8121 val = prop[ name ] = val[ 0 ];
8123 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8126 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8127 return opt.complete.call( this );
8130 if ( isElement && ( name === "height" || name === "width" ) ) {
8131 // Make sure that nothing sneaks out
8132 // Record all 3 overflow attributes because IE does not
8133 // change the overflow attribute when overflowX and
8134 // overflowY are set to the same value
8135 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8137 // Set display property to inline-block for height/width
8138 // animations on inline elements that are having width/height
8140 if ( jQuery.css( this, "display" ) === "inline" &&
8141 jQuery.css( this, "float" ) === "none" ) {
8142 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8143 this.style.display = "inline-block";
8146 display = defaultDisplay( this.nodeName );
8148 // inline-level elements accept inline-block;
8149 // block-level elements need to be inline with layout
8150 if ( display === "inline" ) {
8151 this.style.display = "inline-block";
8154 this.style.display = "inline";
8155 this.style.zoom = 1;
8162 if ( opt.overflow != null ) {
8163 this.style.overflow = "hidden";
8167 e = new jQuery.fx( this, opt, p );
8170 if ( rfxtypes.test(val) ) {
8171 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8174 parts = rfxnum.exec( val );
8178 end = parseFloat( parts[2] );
8179 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8181 // We need to compute starting value
8182 if ( unit !== "px" ) {
8183 jQuery.style( this, p, (end || 1) + unit);
8184 start = ((end || 1) / e.cur()) * start;
8185 jQuery.style( this, p, start + unit);
8188 // If a +=/-= token was provided, we're doing a relative animation
8190 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8193 e.custom( start, end, unit );
8196 e.custom( start, val, "" );
8201 // For JS strict compliance
8206 stop: function( clearQueue, gotoEnd ) {
8211 this.each(function() {
8212 var timers = jQuery.timers,
8214 // clear marker counters if we know they won't be
8216 jQuery._unmark( true, this );
8219 if ( timers[i].elem === this ) {
8221 // force the next step to be the last
8225 timers.splice(i, 1);
8230 // start the next in the queue if the last step wasn't forced
8240 // Animations created synchronously will run synchronously
8241 function createFxNow() {
8242 setTimeout( clearFxNow, 0 );
8243 return ( fxNow = jQuery.now() );
8246 function clearFxNow() {
8250 // Generate parameters to create a standard animation
8251 function genFx( type, num ) {
8254 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8261 // Generate shortcuts for custom animations
8263 slideDown: genFx("show", 1),
8264 slideUp: genFx("hide", 1),
8265 slideToggle: genFx("toggle", 1),
8266 fadeIn: { opacity: "show" },
8267 fadeOut: { opacity: "hide" },
8268 fadeToggle: { opacity: "toggle" }
8269 }, function( name, props ) {
8270 jQuery.fn[ name ] = function( speed, easing, callback ) {
8271 return this.animate( props, speed, easing, callback );
8276 speed: function( speed, easing, fn ) {
8277 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8278 complete: fn || !fn && easing ||
8279 jQuery.isFunction( speed ) && speed,
8281 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8284 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8285 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8288 opt.old = opt.complete;
8289 opt.complete = function( noUnmark ) {
8290 if ( opt.queue !== false ) {
8291 jQuery.dequeue( this );
8292 } else if ( noUnmark !== false ) {
8293 jQuery._unmark( this );
8296 if ( jQuery.isFunction( opt.old ) ) {
8297 opt.old.call( this );
8305 linear: function( p, n, firstNum, diff ) {
8306 return firstNum + diff * p;
8308 swing: function( p, n, firstNum, diff ) {
8309 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8315 fx: function( elem, options, prop ) {
8316 this.options = options;
8320 options.orig = options.orig || {};
8325 jQuery.fx.prototype = {
8326 // Simple function for setting a style value
8327 update: function() {
8328 if ( this.options.step ) {
8329 this.options.step.call( this.elem, this.now, this );
8332 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8335 // Get the current size
8337 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8338 return this.elem[ this.prop ];
8342 r = jQuery.css( this.elem, this.prop );
8343 // Empty strings, null, undefined and "auto" are converted to 0,
8344 // complex values such as "rotate(1rad)" are returned as is,
8345 // simple values such as "10px" are parsed to Float.
8346 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8349 // Start an animation from one number to another
8350 custom: function( from, to, unit ) {
8355 this.startTime = fxNow || createFxNow();
8358 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8359 this.now = this.start;
8360 this.pos = this.state = 0;
8362 function t( gotoEnd ) {
8363 return self.step(gotoEnd);
8368 if ( t() && jQuery.timers.push(t) && !timerId ) {
8369 // Use requestAnimationFrame instead of setInterval if available
8370 if ( requestAnimationFrame ) {
8373 // When timerId gets set to null at any point, this stops
8375 requestAnimationFrame( raf );
8379 requestAnimationFrame( raf );
8381 timerId = setInterval( fx.tick, fx.interval );
8386 // Simple 'show' function
8388 // Remember where we started, so that we can go back to it later
8389 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8390 this.options.show = true;
8392 // Begin the animation
8393 // Make sure that we start at a small width/height to avoid any
8395 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8397 // Start by showing the element
8398 jQuery( this.elem ).show();
8401 // Simple 'hide' function
8403 // Remember where we started, so that we can go back to it later
8404 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8405 this.options.hide = true;
8407 // Begin the animation
8408 this.custom(this.cur(), 0);
8411 // Each step of an animation
8412 step: function( gotoEnd ) {
8413 var t = fxNow || createFxNow(),
8416 options = this.options,
8419 if ( gotoEnd || t >= options.duration + this.startTime ) {
8420 this.now = this.end;
8421 this.pos = this.state = 1;
8424 options.animatedProperties[ this.prop ] = true;
8426 for ( i in options.animatedProperties ) {
8427 if ( options.animatedProperties[i] !== true ) {
8433 // Reset the overflow
8434 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8436 jQuery.each( [ "", "X", "Y" ], function (index, value) {
8437 elem.style[ "overflow" + value ] = options.overflow[index];
8441 // Hide the element if the "hide" operation was done
8442 if ( options.hide ) {
8443 jQuery(elem).hide();
8446 // Reset the properties, if the item has been hidden or shown
8447 if ( options.hide || options.show ) {
8448 for ( var p in options.animatedProperties ) {
8449 jQuery.style( elem, p, options.orig[p] );
8453 // Execute the complete function
8454 options.complete.call( elem );
8460 // classical easing cannot be used with an Infinity duration
8461 if ( options.duration == Infinity ) {
8464 n = t - this.startTime;
8465 this.state = n / options.duration;
8467 // Perform the easing function, defaults to swing
8468 this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8469 this.now = this.start + ((this.end - this.start) * this.pos);
8471 // Perform the next step of the animation
8479 jQuery.extend( jQuery.fx, {
8481 for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8482 if ( !timers[i]() ) {
8483 timers.splice(i--, 1);
8487 if ( !timers.length ) {
8495 clearInterval( timerId );
8507 opacity: function( fx ) {
8508 jQuery.style( fx.elem, "opacity", fx.now );
8511 _default: function( fx ) {
8512 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8513 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8515 fx.elem[ fx.prop ] = fx.now;
8521 if ( jQuery.expr && jQuery.expr.filters ) {
8522 jQuery.expr.filters.animated = function( elem ) {
8523 return jQuery.grep(jQuery.timers, function( fn ) {
8524 return elem === fn.elem;
8529 // Try to restore the default display value of an element
8530 function defaultDisplay( nodeName ) {
8532 if ( !elemdisplay[ nodeName ] ) {
8534 var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
8535 display = elem.css( "display" );
8539 // If the simple way fails,
8540 // get element's real default display by attaching it to a temp iframe
8541 if ( display === "none" || display === "" ) {
8542 // No iframe to use yet, so create it
8544 iframe = document.createElement( "iframe" );
8545 iframe.frameBorder = iframe.width = iframe.height = 0;
8548 document.body.appendChild( iframe );
8550 // Create a cacheable copy of the iframe document on first call.
8551 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
8552 // document to it, Webkit & Firefox won't allow reusing the iframe document
8553 if ( !iframeDoc || !iframe.createElement ) {
8554 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8555 iframeDoc.write( "<!doctype><html><body></body></html>" );
8558 elem = iframeDoc.createElement( nodeName );
8560 iframeDoc.body.appendChild( elem );
8562 display = jQuery.css( elem, "display" );
8564 document.body.removeChild( iframe );
8567 // Store the correct default display
8568 elemdisplay[ nodeName ] = display;
8571 return elemdisplay[ nodeName ];
8577 var rtable = /^t(?:able|d|h)$/i,
8578 rroot = /^(?:body|html)$/i;
8580 if ( "getBoundingClientRect" in document.documentElement ) {
8581 jQuery.fn.offset = function( options ) {
8582 var elem = this[0], box;
8585 return this.each(function( i ) {
8586 jQuery.offset.setOffset( this, options, i );
8590 if ( !elem || !elem.ownerDocument ) {
8594 if ( elem === elem.ownerDocument.body ) {
8595 return jQuery.offset.bodyOffset( elem );
8599 box = elem.getBoundingClientRect();
8602 var doc = elem.ownerDocument,
8603 docElem = doc.documentElement;
8605 // Make sure we're not dealing with a disconnected DOM node
8606 if ( !box || !jQuery.contains( docElem, elem ) ) {
8607 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8610 var body = doc.body,
8611 win = getWindow(doc),
8612 clientTop = docElem.clientTop || body.clientTop || 0,
8613 clientLeft = docElem.clientLeft || body.clientLeft || 0,
8614 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
8615 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8616 top = box.top + scrollTop - clientTop,
8617 left = box.left + scrollLeft - clientLeft;
8619 return { top: top, left: left };
8623 jQuery.fn.offset = function( options ) {
8627 return this.each(function( i ) {
8628 jQuery.offset.setOffset( this, options, i );
8632 if ( !elem || !elem.ownerDocument ) {
8636 if ( elem === elem.ownerDocument.body ) {
8637 return jQuery.offset.bodyOffset( elem );
8640 jQuery.offset.initialize();
8643 offsetParent = elem.offsetParent,
8644 prevOffsetParent = elem,
8645 doc = elem.ownerDocument,
8646 docElem = doc.documentElement,
8648 defaultView = doc.defaultView,
8649 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8650 top = elem.offsetTop,
8651 left = elem.offsetLeft;
8653 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8654 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8658 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8659 top -= elem.scrollTop;
8660 left -= elem.scrollLeft;
8662 if ( elem === offsetParent ) {
8663 top += elem.offsetTop;
8664 left += elem.offsetLeft;
8666 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8667 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8668 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8671 prevOffsetParent = offsetParent;
8672 offsetParent = elem.offsetParent;
8675 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8676 top += parseFloat( computedStyle.borderTopWidth ) || 0;
8677 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8680 prevComputedStyle = computedStyle;
8683 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8684 top += body.offsetTop;
8685 left += body.offsetLeft;
8688 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8689 top += Math.max( docElem.scrollTop, body.scrollTop );
8690 left += Math.max( docElem.scrollLeft, body.scrollLeft );
8693 return { top: top, left: left };
8698 initialize: function() {
8699 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8700 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>";
8702 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8704 container.innerHTML = html;
8705 body.insertBefore( container, body.firstChild );
8706 innerDiv = container.firstChild;
8707 checkDiv = innerDiv.firstChild;
8708 td = innerDiv.nextSibling.firstChild.firstChild;
8710 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8711 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8713 checkDiv.style.position = "fixed";
8714 checkDiv.style.top = "20px";
8716 // safari subtracts parent border width here which is 5px
8717 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8718 checkDiv.style.position = checkDiv.style.top = "";
8720 innerDiv.style.overflow = "hidden";
8721 innerDiv.style.position = "relative";
8723 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8725 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8727 body.removeChild( container );
8728 jQuery.offset.initialize = jQuery.noop;
8731 bodyOffset: function( body ) {
8732 var top = body.offsetTop,
8733 left = body.offsetLeft;
8735 jQuery.offset.initialize();
8737 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8738 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8739 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8742 return { top: top, left: left };
8745 setOffset: function( elem, options, i ) {
8746 var position = jQuery.css( elem, "position" );
8748 // set position first, in-case top/left are set even on static elem
8749 if ( position === "static" ) {
8750 elem.style.position = "relative";
8753 var curElem = jQuery( elem ),
8754 curOffset = curElem.offset(),
8755 curCSSTop = jQuery.css( elem, "top" ),
8756 curCSSLeft = jQuery.css( elem, "left" ),
8757 calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8758 props = {}, curPosition = {}, curTop, curLeft;
8760 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8761 if ( calculatePosition ) {
8762 curPosition = curElem.position();
8763 curTop = curPosition.top;
8764 curLeft = curPosition.left;
8766 curTop = parseFloat( curCSSTop ) || 0;
8767 curLeft = parseFloat( curCSSLeft ) || 0;
8770 if ( jQuery.isFunction( options ) ) {
8771 options = options.call( elem, i, curOffset );
8774 if (options.top != null) {
8775 props.top = (options.top - curOffset.top) + curTop;
8777 if (options.left != null) {
8778 props.left = (options.left - curOffset.left) + curLeft;
8781 if ( "using" in options ) {
8782 options.using.call( elem, props );
8784 curElem.css( props );
8791 position: function() {
8798 // Get *real* offsetParent
8799 offsetParent = this.offsetParent(),
8801 // Get correct offsets
8802 offset = this.offset(),
8803 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8805 // Subtract element margins
8806 // note: when an element has margin: auto the offsetLeft and marginLeft
8807 // are the same in Safari causing offset.left to incorrectly be 0
8808 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8809 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8811 // Add offsetParent borders
8812 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8813 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8815 // Subtract the two offsets
8817 top: offset.top - parentOffset.top,
8818 left: offset.left - parentOffset.left
8822 offsetParent: function() {
8823 return this.map(function() {
8824 var offsetParent = this.offsetParent || document.body;
8825 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8826 offsetParent = offsetParent.offsetParent;
8828 return offsetParent;
8834 // Create scrollLeft and scrollTop methods
8835 jQuery.each( ["Left", "Top"], function( i, name ) {
8836 var method = "scroll" + name;
8838 jQuery.fn[ method ] = function( val ) {
8841 if ( val === undefined ) {
8848 win = getWindow( elem );
8850 // Return the scroll offset
8851 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8852 jQuery.support.boxModel && win.document.documentElement[ method ] ||
8853 win.document.body[ method ] :
8857 // Set the scroll offset
8858 return this.each(function() {
8859 win = getWindow( this );
8863 !i ? val : jQuery( win ).scrollLeft(),
8864 i ? val : jQuery( win ).scrollTop()
8868 this[ method ] = val;
8874 function getWindow( elem ) {
8875 return jQuery.isWindow( elem ) ?
8877 elem.nodeType === 9 ?
8878 elem.defaultView || elem.parentWindow :
8885 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
8886 jQuery.each([ "Height", "Width" ], function( i, name ) {
8888 var type = name.toLowerCase();
8890 // innerHeight and innerWidth
8891 jQuery.fn["inner" + name] = function() {
8893 parseFloat( jQuery.css( this[0], type, "padding" ) ) :
8897 // outerHeight and outerWidth
8898 jQuery.fn["outer" + name] = function( margin ) {
8900 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
8904 jQuery.fn[ type ] = function( size ) {
8905 // Get window width or height
8908 return size == null ? null : this;
8911 if ( jQuery.isFunction( size ) ) {
8912 return this.each(function( i ) {
8913 var self = jQuery( this );
8914 self[ type ]( size.call( this, i, self[ type ]() ) );
8918 if ( jQuery.isWindow( elem ) ) {
8919 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
8920 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
8921 var docElemProp = elem.document.documentElement[ "client" + name ];
8922 return elem.document.compatMode === "CSS1Compat" && docElemProp ||
8923 elem.document.body[ "client" + name ] || docElemProp;
8925 // Get document width or height
8926 } else if ( elem.nodeType === 9 ) {
8927 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
8929 elem.documentElement["client" + name],
8930 elem.body["scroll" + name], elem.documentElement["scroll" + name],
8931 elem.body["offset" + name], elem.documentElement["offset" + name]
8934 // Get or set width or height on the element
8935 } else if ( size === undefined ) {
8936 var orig = jQuery.css( elem, type ),
8937 ret = parseFloat( orig );
8939 return jQuery.isNaN( ret ) ? orig : ret;
8941 // Set the width or height on the element (default to pixels if value is unitless)
8943 return this.css( type, typeof size === "string" ? size : size + "px" );
8950 window.jQuery = window.$ = jQuery;