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