3
* jQuery 1.2.6 - New Wave Javascript
5
* Copyright (c) 2008 John Resig (jquery.com)
6
* Dual licensed under the MIT (MIT-LICENSE.txt)
7
* and GPL (GPL-LICENSE.txt) licenses.
9
* $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
13
// Map over jQuery in case of overwrite
14
var _jQuery = window.jQuery,
15
// Map over the $ in case of overwrite
18
var jQuery = window.jQuery = window.$ = function( selector, context ) {
19
// The jQuery object is actually just the init constructor 'enhanced'
20
return new jQuery.fn.init( selector, context );
23
// A simple way to check for HTML strings or ID strings
24
// (both of which we optimize for)
25
var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
27
// Is it a simple selector
28
isSimple = /^.[^:#\[\.]*$/,
30
// Will speed up references to undefined, and allows munging its name.
33
jQuery.fn = jQuery.prototype = {
34
init: function( selector, context ) {
35
// Make sure that a selection was provided
36
selector = selector || document;
38
// Handle $(DOMElement)
39
if ( selector.nodeType ) {
44
// Handle HTML strings
45
if ( typeof selector == "string" ) {
46
// Are we dealing with HTML string or an ID?
47
var match = quickExpr.exec( selector );
49
// Verify a match, and that no context was specified for #id
50
if ( match && (match[1] || !context) ) {
52
// HANDLE: $(html) -> $(array)
54
selector = jQuery.clean( [ match[1] ], context );
58
var elem = document.getElementById( match[3] );
60
// Make sure an element was located
62
// Handle the case where IE and Opera return items
63
// by name instead of ID
64
if ( elem.id != match[3] )
65
return jQuery().find( selector );
67
// Otherwise, we inject the element directly into the jQuery object
68
return jQuery( elem );
73
// HANDLE: $(expr, [context])
74
// (which is just equivalent to: $(content).find(expr)
76
return jQuery( context ).find( selector );
78
// HANDLE: $(function)
79
// Shortcut for document ready
80
} else if ( jQuery.isFunction( selector ) )
81
return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
83
return this.setArray(jQuery.makeArray(selector));
86
// The current version of jQuery being used
89
// The number of elements contained in the matched element set
94
// The number of elements contained in the matched element set
97
// Get the Nth element in the matched element set OR
98
// Get the whole matched element set as a clean array
99
get: function( num ) {
100
return num == undefined ?
102
// Return a 'clean' array
103
jQuery.makeArray( this ) :
105
// Return just the object
109
// Take an array of elements and push it onto the stack
110
// (returning the new matched element set)
111
pushStack: function( elems ) {
112
// Build a new jQuery matched element set
113
var ret = jQuery( elems );
115
// Add the old object onto the stack (as a reference)
116
ret.prevObject = this;
118
// Return the newly-formed element set
122
// Force the current matched set of elements to become
123
// the specified array of elements (destroying the stack in the process)
124
// You should use pushStack() in order to do this, but maintain the stack
125
setArray: function( elems ) {
126
// Resetting the length to 0, then using the native Array push
127
// is a super-fast way to populate an object with array-like properties
129
Array.prototype.push.apply( this, elems );
134
// Execute a callback for every element in the matched set.
135
// (You can seed the arguments with an array of args, but this is
136
// only used internally.)
137
each: function( callback, args ) {
138
return jQuery.each( this, callback, args );
141
// Determine the position of an element within
142
// the matched set of elements
143
index: function( elem ) {
146
// Locate the position of the desired element
147
return jQuery.inArray(
148
// If it receives a jQuery object, the first element is used
149
elem && elem.jquery ? elem[0] : elem
153
attr: function( name, value, type ) {
156
// Look for the case where we're accessing a style value
157
if ( name.constructor == String )
158
if ( value === undefined )
159
return this[0] && jQuery[ type || "attr" ]( this[0], name );
163
options[ name ] = value;
166
// Check to see if we're setting style values
167
return this.each(function(i){
168
// Set all the styles
169
for ( name in options )
174
name, jQuery.prop( this, options[ name ], type, i, name )
179
css: function( key, value ) {
180
// ignore negative width and height values
181
if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
183
return this.attr( key, value, "curCSS" );
186
text: function( text ) {
187
if ( typeof text != "object" && text != null )
188
return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
192
jQuery.each( text || this, function(){
193
jQuery.each( this.childNodes, function(){
194
if ( this.nodeType != 8 )
195
ret += this.nodeType != 1 ?
197
jQuery.fn.text( [ this ] );
204
wrapAll: function( html ) {
206
// The elements to wrap the target around
207
jQuery( html, this[0].ownerDocument )
209
.insertBefore( this[0] )
213
while ( elem.firstChild )
214
elem = elem.firstChild;
223
wrapInner: function( html ) {
224
return this.each(function(){
225
jQuery( this ).contents().wrapAll( html );
229
wrap: function( html ) {
230
return this.each(function(){
231
jQuery( this ).wrapAll( html );
236
return this.domManip(arguments, true, false, function(elem){
237
if (this.nodeType == 1)
238
this.appendChild( elem );
242
prepend: function() {
243
return this.domManip(arguments, true, true, function(elem){
244
if (this.nodeType == 1)
245
this.insertBefore( elem, this.firstChild );
250
return this.domManip(arguments, false, false, function(elem){
251
this.parentNode.insertBefore( elem, this );
256
return this.domManip(arguments, false, true, function(elem){
257
this.parentNode.insertBefore( elem, this.nextSibling );
262
return this.prevObject || jQuery( [] );
265
find: function( selector ) {
266
var elems = jQuery.map(this, function(elem){
267
return jQuery.find( selector, elem );
270
return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
271
jQuery.unique( elems ) :
275
clone: function( events ) {
277
var ret = this.map(function(){
278
if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
279
// IE copies events bound via attachEvent when
280
// using cloneNode. Calling detachEvent on the
281
// clone will also remove the events from the orignal
282
// In order to get around this, we use innerHTML.
283
// Unfortunately, this means some modifications to
284
// attributes in IE that are actually only stored
285
// as properties will not be copied (such as the
286
// the name attribute on an input).
287
var clone = this.cloneNode(true),
288
container = document.createElement("div");
289
container.appendChild(clone);
290
return jQuery.clean([container.innerHTML])[0];
292
return this.cloneNode(true);
295
// Need to set the expando to null on the cloned set if it exists
296
// removeData doesn't work here, IE removes it from the original as well
297
// this is primarily for IE but the data expando shouldn't be copied over in any browser
298
var clone = ret.find("*").andSelf().each(function(){
299
if ( this[ expando ] != undefined )
300
this[ expando ] = null;
303
// Copy the events from the original to the clone
304
if ( events === true )
305
this.find("*").andSelf().each(function(i){
306
if (this.nodeType == 3)
308
var events = jQuery.data( this, "events" );
310
for ( var type in events )
311
for ( var handler in events[ type ] )
312
jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
315
// Return the cloned set
319
filter: function( selector ) {
320
return this.pushStack(
321
jQuery.isFunction( selector ) &&
322
jQuery.grep(this, function(elem, i){
323
return selector.call( elem, i );
326
jQuery.multiFilter( selector, this ) );
329
not: function( selector ) {
330
if ( selector.constructor == String )
331
// test special case where just one selector is passed in
332
if ( isSimple.test( selector ) )
333
return this.pushStack( jQuery.multiFilter( selector, this, true ) );
335
selector = jQuery.multiFilter( selector, this );
337
var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
338
return this.filter(function() {
339
return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
343
add: function( selector ) {
344
return this.pushStack( jQuery.unique( jQuery.merge(
346
typeof selector == 'string' ?
348
jQuery.makeArray( selector )
352
is: function( selector ) {
353
return !!selector && jQuery.multiFilter( selector, this ).length > 0;
356
hasClass: function( selector ) {
357
return this.is( "." + selector );
360
val: function( value ) {
361
if ( value == undefined ) {
366
// We need to handle select boxes special
367
if ( jQuery.nodeName( elem, "select" ) ) {
368
var index = elem.selectedIndex,
370
options = elem.options,
371
one = elem.type == "select-one";
373
// Nothing was selected
377
// Loop through all the selected options
378
for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
379
var option = options[ i ];
381
if ( option.selected ) {
382
// Get the specifc value for the option
383
value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
385
// We don't need an array for one selects
389
// Multi-Selects return an array
390
values.push( value );
396
// Everything else, we just grab the value
398
return (this[0].value || "").replace(/\r/g, "");
405
if( value.constructor == Number )
408
return this.each(function(){
409
if ( this.nodeType != 1 )
412
if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
413
this.checked = (jQuery.inArray(this.value, value) >= 0 ||
414
jQuery.inArray(this.name, value) >= 0);
416
else if ( jQuery.nodeName( this, "select" ) ) {
417
var values = jQuery.makeArray(value);
419
jQuery( "option", this ).each(function(){
420
this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
421
jQuery.inArray( this.text, values ) >= 0);
424
if ( !values.length )
425
this.selectedIndex = -1;
432
html: function( value ) {
433
return value == undefined ?
437
this.empty().append( value );
440
replaceWith: function( value ) {
441
return this.after( value ).remove();
445
return this.slice( i, i + 1 );
449
return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
452
map: function( callback ) {
453
return this.pushStack( jQuery.map(this, function(elem, i){
454
return callback.call( elem, i, elem );
458
andSelf: function() {
459
return this.add( this.prevObject );
462
data: function( key, value ){
463
var parts = key.split(".");
464
parts[1] = parts[1] ? "." + parts[1] : "";
466
if ( value === undefined ) {
467
var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
469
if ( data === undefined && this.length )
470
data = jQuery.data( this[0], key );
472
return data === undefined && parts[1] ?
473
this.data( parts[0] ) :
476
return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
477
jQuery.data( this, key, value );
481
removeData: function( key ){
482
return this.each(function(){
483
jQuery.removeData( this, key );
487
domManip: function( args, table, reverse, callback ) {
488
var clone = this.length > 1, elems;
490
return this.each(function(){
492
elems = jQuery.clean( args, this.ownerDocument );
500
if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
501
obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
503
var scripts = jQuery( [] );
505
jQuery.each(elems, function(){
507
jQuery( this ).clone( true )[0] :
510
// execute all scripts after the elements have been injected
511
if ( jQuery.nodeName( elem, "script" ) )
512
scripts = scripts.add( elem );
514
// Remove any inner scripts for later evaluation
515
if ( elem.nodeType == 1 )
516
scripts = scripts.add( jQuery( "script", elem ).remove() );
518
// Inject the elements into the document
519
callback.call( obj, elem );
523
scripts.each( evalScript );
528
// Give the init function the jQuery prototype for later instantiation
529
jQuery.fn.init.prototype = jQuery.fn;
531
function evalScript( i, elem ) {
540
jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
542
if ( elem.parentNode )
543
elem.parentNode.removeChild( elem );
550
jQuery.extend = jQuery.fn.extend = function() {
551
// copy reference to target object
552
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
554
// Handle a deep copy situation
555
if ( target.constructor == Boolean ) {
557
target = arguments[1] || {};
558
// skip the boolean and the target
562
// Handle case when target is a string or something (possible in deep copy)
563
if ( typeof target != "object" && typeof target != "function" )
566
// extend jQuery itself if only one argument is passed
572
for ( ; i < length; i++ )
573
// Only deal with non-null/undefined values
574
if ( (options = arguments[ i ]) != null )
575
// Extend the base object
576
for ( var name in options ) {
577
var src = target[ name ], copy = options[ name ];
579
// Prevent never-ending loop
580
if ( target === copy )
583
// Recurse if we're merging object values
584
if ( deep && copy && typeof copy == "object" && !copy.nodeType )
585
target[ name ] = jQuery.extend( deep,
586
// Never move original objects, clone them
587
src || ( copy.length != null ? [ ] : { } )
590
// Don't bring in undefined values
591
else if ( copy !== undefined )
592
target[ name ] = copy;
596
// Return the modified object
600
var expando = "jQuery" + now(), uuid = 0, windowData = {},
601
// exclude the following css properties to add px
602
exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
604
defaultView = document.defaultView || {};
607
noConflict: function( deep ) {
611
window.jQuery = _jQuery;
616
// See test/unit/core.js for details concerning this function.
617
isFunction: function( fn ) {
618
return !!fn && typeof fn != "string" && !fn.nodeName &&
619
fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
622
// check if an element is in a (or is an) XML document
623
isXMLDoc: function( elem ) {
624
return elem.documentElement && !elem.body ||
625
elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
628
// Evalulates a script in a global context
629
globalEval: function( data ) {
630
data = jQuery.trim( data );
633
// Inspired by code by Andrea Giammarchi
634
// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
635
var head = document.getElementsByTagName("head")[0] || document.documentElement,
636
script = document.createElement("script");
638
script.type = "text/javascript";
639
if ( jQuery.browser.msie )
642
script.appendChild( document.createTextNode( data ) );
644
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
645
// This arises when a base node is used (#2709).
646
head.insertBefore( script, head.firstChild );
647
head.removeChild( script );
651
nodeName: function( elem, name ) {
652
return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
657
data: function( elem, name, data ) {
658
elem = elem == window ?
662
var id = elem[ expando ];
664
// Compute a unique ID for the element
666
id = elem[ expando ] = ++uuid;
668
// Only generate the data cache if we're
669
// trying to access or manipulate it
670
if ( name && !jQuery.cache[ id ] )
671
jQuery.cache[ id ] = {};
673
// Prevent overriding the named cache with undefined values
674
if ( data !== undefined )
675
jQuery.cache[ id ][ name ] = data;
677
// Return the named cache data, or the ID for the element
679
jQuery.cache[ id ][ name ] :
683
removeData: function( elem, name ) {
684
elem = elem == window ?
688
var id = elem[ expando ];
690
// If we want to remove a specific section of the element's data
692
if ( jQuery.cache[ id ] ) {
693
// Remove the section of cache data
694
delete jQuery.cache[ id ][ name ];
696
// If we've removed all the data, remove the element's cache
699
for ( name in jQuery.cache[ id ] )
703
jQuery.removeData( elem );
706
// Otherwise, we want to remove all of the element's data
708
// Clean up the element expando
710
delete elem[ expando ];
712
// IE has trouble directly removing the expando
713
// but it's ok with using removeAttribute
714
if ( elem.removeAttribute )
715
elem.removeAttribute( expando );
718
// Completely remove the data cache
719
delete jQuery.cache[ id ];
723
// args is for internal usage only
724
each: function( object, callback, args ) {
725
var name, i = 0, length = object.length;
728
if ( length == undefined ) {
729
for ( name in object )
730
if ( callback.apply( object[ name ], args ) === false )
733
for ( ; i < length; )
734
if ( callback.apply( object[ i++ ], args ) === false )
737
// A special, fast, case for the most common use of each
739
if ( length == undefined ) {
740
for ( name in object )
741
if ( callback.call( object[ name ], name, object[ name ] ) === false )
744
for ( var value = object[0];
745
i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
751
prop: function( elem, value, type, i, name ) {
752
// Handle executable functions
753
if ( jQuery.isFunction( value ) )
754
value = value.call( elem, i );
756
// Handle passing in a number to a CSS property
757
return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
763
// internal only, use addClass("class")
764
add: function( elem, classNames ) {
765
jQuery.each((classNames || "").split(/\s+/), function(i, className){
766
if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
767
elem.className += (elem.className ? " " : "") + className;
771
// internal only, use removeClass("class")
772
remove: function( elem, classNames ) {
773
if (elem.nodeType == 1)
774
elem.className = classNames != undefined ?
775
jQuery.grep(elem.className.split(/\s+/), function(className){
776
return !jQuery.className.has( classNames, className );
781
// internal only, use hasClass("class")
782
has: function( elem, className ) {
783
return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
787
// A method for quickly swapping in/out CSS properties to get correct calculations
788
swap: function( elem, options, callback ) {
790
// Remember the old values, and insert the new ones
791
for ( var name in options ) {
792
old[ name ] = elem.style[ name ];
793
elem.style[ name ] = options[ name ];
796
callback.call( elem );
798
// Revert the old values
799
for ( var name in options )
800
elem.style[ name ] = old[ name ];
803
css: function( elem, name, force ) {
804
if ( name == "width" || name == "height" ) {
805
var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
808
val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
809
var padding = 0, border = 0;
810
jQuery.each( which, function() {
811
padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
812
border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
814
val -= Math.round(padding + border);
817
if ( jQuery(elem).is(":visible") )
820
jQuery.swap( elem, props, getWH );
822
return Math.max(0, val);
825
return jQuery.curCSS( elem, name, force );
828
curCSS: function( elem, name, force ) {
829
var ret, style = elem.style;
831
// A helper method for determining if an element's values are broken
832
function color( elem ) {
833
if ( !jQuery.browser.safari )
836
// defaultView is cached
837
var ret = defaultView.getComputedStyle( elem, null );
838
return !ret || ret.getPropertyValue("color") == "";
841
// We need to handle opacity special in IE
842
if ( name == "opacity" && jQuery.browser.msie ) {
843
ret = jQuery.attr( style, "opacity" );
849
// Opera sometimes will give the wrong display answer, this fixes it, see #2037
850
if ( jQuery.browser.opera && name == "display" ) {
851
var save = style.outline;
852
style.outline = "0 solid black";
853
style.outline = save;
856
// Make sure we're using the right name for getting the float value
857
if ( name.match( /float/i ) )
860
if ( !force && style && style[ name ] )
863
else if ( defaultView.getComputedStyle ) {
865
// Only "float" is needed here
866
if ( name.match( /float/i ) )
869
name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
871
var computedStyle = defaultView.getComputedStyle( elem, null );
873
if ( computedStyle && !color( elem ) )
874
ret = computedStyle.getPropertyValue( name );
876
// If the element isn't reporting its values properly in Safari
877
// then some display: none elements are involved
879
var swap = [], stack = [], a = elem, i = 0;
881
// Locate all of the parent display: none elements
882
for ( ; a && color(a); a = a.parentNode )
885
// Go through and make them visible, but in reverse
886
// (It would be better if we knew the exact display type that they had)
887
for ( ; i < stack.length; i++ )
888
if ( color( stack[ i ] ) ) {
889
swap[ i ] = stack[ i ].style.display;
890
stack[ i ].style.display = "block";
893
// Since we flip the display style, we have to handle that
894
// one special, otherwise get the value
895
ret = name == "display" && swap[ stack.length - 1 ] != null ?
897
( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
899
// Finally, revert the display styles back
900
for ( i = 0; i < swap.length; i++ )
901
if ( swap[ i ] != null )
902
stack[ i ].style.display = swap[ i ];
905
// We should always get a number back from opacity
906
if ( name == "opacity" && ret == "" )
909
} else if ( elem.currentStyle ) {
910
var camelCase = name.replace(/\-(\w)/g, function(all, letter){
911
return letter.toUpperCase();
914
ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
916
// From the awesome hack by Dean Edwards
917
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
919
// If we're not dealing with a regular pixel number
920
// but a number that has a weird ending, we need to convert it to pixels
921
if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
922
// Remember the original values
923
var left = style.left, rsLeft = elem.runtimeStyle.left;
925
// Put in the new values to get a computed value out
926
elem.runtimeStyle.left = elem.currentStyle.left;
927
style.left = ret || 0;
928
ret = style.pixelLeft + "px";
930
// Revert the changed values
932
elem.runtimeStyle.left = rsLeft;
939
clean: function( elems, context ) {
941
context = context || document;
942
// !context.createElement fails in IE with an error but returns typeof 'object'
943
if (typeof context.createElement == 'undefined')
944
context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
946
jQuery.each(elems, function(i, elem){
950
if ( elem.constructor == Number )
953
// Convert html string into DOM nodes
954
if ( typeof elem == "string" ) {
955
// Fix "XHTML"-style tags in all browsers
956
elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
957
return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
959
front + "></" + tag + ">";
962
// Trim whitespace, otherwise indexOf won't work as expected
963
var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
966
// option or optgroup
967
!tags.indexOf("<opt") &&
968
[ 1, "<select multiple='multiple'>", "</select>" ] ||
970
!tags.indexOf("<leg") &&
971
[ 1, "<fieldset>", "</fieldset>" ] ||
973
tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
974
[ 1, "<table>", "</table>" ] ||
976
!tags.indexOf("<tr") &&
977
[ 2, "<table><tbody>", "</tbody></table>" ] ||
979
// <thead> matched above
980
(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
981
[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
983
!tags.indexOf("<col") &&
984
[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
986
// IE can't serialize <link> and <script> tags normally
987
jQuery.browser.msie &&
988
[ 1, "div<div>", "</div>" ] ||
992
// Go to html and back, then peel off extra wrappers
993
div.innerHTML = wrap[1] + elem + wrap[2];
995
// Move to the right depth
999
// Remove IE's autoinserted <tbody> from table fragments
1000
if ( jQuery.browser.msie ) {
1002
// String was a <table>, *may* have spurious <tbody>
1003
var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
1004
div.firstChild && div.firstChild.childNodes :
1006
// String was a bare <thead> or <tfoot>
1007
wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
1011
for ( var j = tbody.length - 1; j >= 0 ; --j )
1012
if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
1013
tbody[ j ].parentNode.removeChild( tbody[ j ] );
1015
// IE completely kills leading whitespace when innerHTML is used
1016
if ( /^\s/.test( elem ) )
1017
div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
1021
elem = jQuery.makeArray( div.childNodes );
1024
if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
1027
if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
1031
ret = jQuery.merge( ret, elem );
1038
attr: function( elem, name, value ) {
1039
// don't set attributes on text and comment nodes
1040
if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
1043
var notxml = !jQuery.isXMLDoc( elem ),
1044
// Whether we are setting (or getting)
1045
set = value !== undefined,
1046
msie = jQuery.browser.msie;
1048
// Try to normalize/fix the name
1049
name = notxml && jQuery.props[ name ] || name;
1051
// Only do all the following if this is a node (faster for style)
1052
// IE elem.getAttribute passes even for style
1053
if ( elem.tagName ) {
1055
// These attributes require special treatment
1056
var special = /href|src|style/.test( name );
1058
// Safari mis-reports the default selected property of a hidden option
1059
// Accessing the parent's selectedIndex property fixes it
1060
if ( name == "selected" && jQuery.browser.safari )
1061
elem.parentNode.selectedIndex;
1063
// If applicable, access the attribute via the DOM 0 way
1064
if ( name in elem && notxml && !special ) {
1066
// We can't allow the type property to be changed (since it causes problems in IE)
1067
if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
1068
throw "type property can't be changed";
1070
elem[ name ] = value;
1073
// browsers index elements by id/name on forms, give priority to attributes.
1074
if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1075
return elem.getAttributeNode( name ).nodeValue;
1077
return elem[ name ];
1080
if ( msie && notxml && name == "style" )
1081
return jQuery.attr( elem.style, "cssText", value );
1084
// convert the value to a string (all browsers do this but IE) see #1070
1085
elem.setAttribute( name, "" + value );
1087
var attr = msie && notxml && special
1088
// Some attributes require a special call on IE
1089
? elem.getAttribute( name, 2 )
1090
: elem.getAttribute( name );
1092
// Non-existent attributes return null, we normalize to undefined
1093
return attr === null ? undefined : attr;
1096
// elem is actually elem.style ... set the style
1098
// IE uses filters for opacity
1099
if ( msie && name == "opacity" ) {
1101
// IE has trouble with opacity if it does not have layout
1102
// Force it by setting the zoom level
1105
// Set the alpha filter to set the opacity
1106
elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1107
(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1110
return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1111
(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1115
name = name.replace(/-([a-z])/ig, function(all, letter){
1116
return letter.toUpperCase();
1120
elem[ name ] = value;
1122
return elem[ name ];
1125
trim: function( text ) {
1126
return (text || "").replace( /^\s+|\s+$/g, "" );
1129
makeArray: function( array ) {
1132
if( array != null ){
1133
var i = array.length;
1134
//the window, strings and functions also have 'length'
1135
if( i == null || array.split || array.setInterval || array.call )
1139
ret[--i] = array[i];
1145
inArray: function( elem, array ) {
1146
for ( var i = 0, length = array.length; i < length; i++ )
1147
// Use === because on IE, window == document
1148
if ( array[ i ] === elem )
1154
merge: function( first, second ) {
1155
// We have to loop this way because IE & Opera overwrite the length
1156
// expando of getElementsByTagName
1157
var i = 0, elem, pos = first.length;
1158
// Also, we need to make sure that the correct elements are being returned
1159
// (IE returns comment nodes in a '*' query)
1160
if ( jQuery.browser.msie ) {
1161
while ( elem = second[ i++ ] )
1162
if ( elem.nodeType != 8 )
1163
first[ pos++ ] = elem;
1166
while ( elem = second[ i++ ] )
1167
first[ pos++ ] = elem;
1172
unique: function( array ) {
1173
var ret = [], done = {};
1177
for ( var i = 0, length = array.length; i < length; i++ ) {
1178
var id = jQuery.data( array[ i ] );
1180
if ( !done[ id ] ) {
1182
ret.push( array[ i ] );
1193
grep: function( elems, callback, inv ) {
1196
// Go through the array, only saving the items
1197
// that pass the validator function
1198
for ( var i = 0, length = elems.length; i < length; i++ )
1199
if ( !inv != !callback( elems[ i ], i ) )
1200
ret.push( elems[ i ] );
1205
map: function( elems, callback ) {
1208
// Go through the array, translating each of the items to their
1209
// new value (or values).
1210
for ( var i = 0, length = elems.length; i < length; i++ ) {
1211
var value = callback( elems[ i ], i );
1213
if ( value != null )
1214
ret[ ret.length ] = value;
1217
return ret.concat.apply( [], ret );
1221
var userAgent = navigator.userAgent.toLowerCase();
1223
// Figure out what browser is being used
1225
version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
1226
safari: /webkit/.test( userAgent ),
1227
opera: /opera/.test( userAgent ),
1228
msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1229
mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1232
var styleFloat = jQuery.browser.msie ?
1237
// Check to see if the W3C box model is being used
1238
boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
1242
"class": "className",
1243
"float": styleFloat,
1244
cssFloat: styleFloat,
1245
styleFloat: styleFloat,
1246
readonly: "readOnly",
1247
maxlength: "maxLength",
1248
cellspacing: "cellSpacing"
1253
parent: function(elem){return elem.parentNode;},
1254
parents: function(elem){return jQuery.dir(elem,"parentNode");},
1255
next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1256
prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1257
nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1258
prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1259
siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1260
children: function(elem){return jQuery.sibling(elem.firstChild);},
1261
contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1262
}, function(name, fn){
1263
jQuery.fn[ name ] = function( selector ) {
1264
var ret = jQuery.map( this, fn );
1266
if ( selector && typeof selector == "string" )
1267
ret = jQuery.multiFilter( selector, ret );
1269
return this.pushStack( jQuery.unique( ret ) );
1275
prependTo: "prepend",
1276
insertBefore: "before",
1277
insertAfter: "after",
1278
replaceAll: "replaceWith"
1279
}, function(name, original){
1280
jQuery.fn[ name ] = function() {
1281
var args = arguments;
1283
return this.each(function(){
1284
for ( var i = 0, length = args.length; i < length; i++ )
1285
jQuery( args[ i ] )[ original ]( this );
1291
removeAttr: function( name ) {
1292
jQuery.attr( this, name, "" );
1293
if (this.nodeType == 1)
1294
this.removeAttribute( name );
1297
addClass: function( classNames ) {
1298
jQuery.className.add( this, classNames );
1301
removeClass: function( classNames ) {
1302
jQuery.className.remove( this, classNames );
1305
toggleClass: function( classNames ) {
1306
jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
1309
remove: function( selector ) {
1310
if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
1311
// Prevent memory leaks
1312
jQuery( "*", this ).add(this).each(function(){
1313
jQuery.event.remove(this);
1314
jQuery.removeData(this);
1316
if (this.parentNode)
1317
this.parentNode.removeChild( this );
1322
// Remove element nodes and prevent memory leaks
1323
jQuery( ">*", this ).remove();
1325
// Remove any remaining nodes
1326
while ( this.firstChild )
1327
this.removeChild( this.firstChild );
1329
}, function(name, fn){
1330
jQuery.fn[ name ] = function(){
1331
return this.each( fn, arguments );
1335
jQuery.each([ "Height", "Width" ], function(i, name){
1336
var type = name.toLowerCase();
1338
jQuery.fn[ type ] = function( size ) {
1339
// Get window width or height
1340
return this[0] == window ?
1341
// Opera reports document.body.client[Width/Height] properly in both quirks and standards
1342
jQuery.browser.opera && document.body[ "client" + name ] ||
1344
// Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
1345
jQuery.browser.safari && window[ "inner" + name ] ||
1347
// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
1348
document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
1350
// Get document width or height
1351
this[0] == document ?
1352
// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
1354
Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
1355
Math.max(document.body["offset" + name], document.documentElement["offset" + name])
1358
// Get or set width or height on the element
1360
// Get width or height on the element
1361
(this.length ? jQuery.css( this[0], type ) : null) :
1363
// Set the width or height on the element (default to pixels if value is unitless)
1364
this.css( type, size.constructor == String ? size : size + "px" );
1368
// Helper function used by the dimensions and offset modules
1369
function num(elem, prop) {
1370
return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1371
}var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
1372
"(?:[\\w*_-]|\\\\.)" :
1373
"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
1374
quickChild = new RegExp("^>\\s*(" + chars + "+)"),
1375
quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
1376
quickClass = new RegExp("^([#.]?)(" + chars + "*)");
1380
"": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
1381
"#": function(a,i,m){return a.getAttribute("id")==m[2];},
1384
lt: function(a,i,m){return i<m[3]-0;},
1385
gt: function(a,i,m){return i>m[3]-0;},
1386
nth: function(a,i,m){return m[3]-0==i;},
1387
eq: function(a,i,m){return m[3]-0==i;},
1388
first: function(a,i){return i==0;},
1389
last: function(a,i,m,r){return i==r.length-1;},
1390
even: function(a,i){return i%2==0;},
1391
odd: function(a,i){return i%2;},
1394
"first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
1395
"last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
1396
"only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
1399
parent: function(a){return a.firstChild;},
1400
empty: function(a){return !a.firstChild;},
1403
contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
1406
visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
1407
hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
1410
enabled: function(a){return !a.disabled;},
1411
disabled: function(a){return a.disabled;},
1412
checked: function(a){return a.checked;},
1413
selected: function(a){return a.selected||jQuery.attr(a,"selected");},
1416
text: function(a){return "text"==a.type;},
1417
radio: function(a){return "radio"==a.type;},
1418
checkbox: function(a){return "checkbox"==a.type;},
1419
file: function(a){return "file"==a.type;},
1420
password: function(a){return "password"==a.type;},
1421
submit: function(a){return "submit"==a.type;},
1422
image: function(a){return "image"==a.type;},
1423
reset: function(a){return "reset"==a.type;},
1424
button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
1425
input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
1428
has: function(a,i,m){return jQuery.find(m[3],a).length;},
1431
header: function(a){return /h\d/i.test(a.nodeName);},
1434
animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
1438
// The regular expressions that power the parsing engine
1440
// Match: [@value='test'], [@foo]
1441
/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
1443
// Match: :contains('foo')
1444
/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
1446
// Match: :even, :last-child, #id, .class
1447
new RegExp("^([:.#]*)(" + chars + "+)")
1450
multiFilter: function( expr, elems, not ) {
1453
while ( expr && expr != old ) {
1455
var f = jQuery.filter( expr, elems, not );
1456
expr = f.t.replace(/^\s*,\s*/, "" );
1457
cur = not ? elems = f.r : jQuery.merge( cur, f.r );
1463
find: function( t, context ) {
1464
// Quickly handle non-string expressions
1465
if ( typeof t != "string" )
1468
// check to make sure context is a DOM element or a document
1469
if ( context && context.nodeType != 1 && context.nodeType != 9)
1472
// Set the correct context (if none is provided)
1473
context = context || document;
1475
// Initialize the search
1476
var ret = [context], done = [], last, nodeName;
1478
// Continue while a selector expression exists, and while
1479
// we're no longer looping upon ourselves
1480
while ( t && last != t ) {
1486
var foundToken = false,
1488
// An attempt at speeding up child selectors that
1489
// point to a specific element tag
1495
nodeName = m[1].toUpperCase();
1497
// Perform our own iteration and filter
1498
for ( var i = 0; ret[i]; i++ )
1499
for ( var c = ret[i].firstChild; c; c = c.nextSibling )
1500
if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
1504
t = t.replace( re, "" );
1505
if ( t.indexOf(" ") == 0 ) continue;
1508
re = /^([>+~])\s*(\w*)/i;
1510
if ( (m = re.exec(t)) != null ) {
1514
nodeName = m[2].toUpperCase();
1517
for ( var j = 0, rl = ret.length; j < rl; j++ ) {
1518
var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
1519
for ( ; n; n = n.nextSibling )
1520
if ( n.nodeType == 1 ) {
1521
var id = jQuery.data(n);
1523
if ( m == "~" && merge[id] ) break;
1525
if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
1526
if ( m == "~" ) merge[id] = true;
1530
if ( m == "+" ) break;
1536
// And remove the token
1537
t = jQuery.trim( t.replace( re, "" ) );
1542
// See if there's still an expression, and that we haven't already
1544
if ( t && !foundToken ) {
1545
// Handle multiple expressions
1546
if ( !t.indexOf(",") ) {
1547
// Clean the result set
1548
if ( context == ret[0] ) ret.shift();
1550
// Merge the result sets
1551
done = jQuery.merge( done, ret );
1553
// Reset the context
1554
r = ret = [context];
1556
// Touch up the selector string
1557
t = " " + t.substr(1,t.length);
1560
// Optimize for the case nodeName#idName
1562
var m = re2.exec(t);
1564
// Re-organize the results, so that they're consistent
1566
m = [ 0, m[2], m[3], m[1] ];
1569
// Otherwise, do a traditional filter check for
1570
// ID, class, and element selectors
1575
m[2] = m[2].replace(/\\/g, "");
1577
var elem = ret[ret.length-1];
1579
// Try to do a global search by ID, where we can
1580
if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
1581
// Optimization for HTML document case
1582
var oid = elem.getElementById(m[2]);
1584
// Do a quick check for the existence of the actual ID attribute
1585
// to avoid selecting by the name attribute in IE
1586
// also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
1587
if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
1588
oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
1590
// Do a quick check for node name (where applicable) so
1591
// that div#foo searches will be really fast
1592
ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
1594
// We need to find all descendant elements
1595
for ( var i = 0; ret[i]; i++ ) {
1596
// Grab the tag name being searched for
1597
var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
1599
// Handle IE7 being really dumb about <object>s
1600
if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
1603
r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
1606
// It's faster to filter by class and be done with it
1608
r = jQuery.classFilter( r, m[2] );
1610
// Same with ID filtering
1611
if ( m[1] == "#" ) {
1614
// Try to find the element with the ID
1615
for ( var i = 0; r[i]; i++ )
1616
if ( r[i].getAttribute("id") == m[2] ) {
1627
t = t.replace( re2, "" );
1632
// If a selector string still exists
1634
// Attempt to filter it
1635
var val = jQuery.filter(t,r);
1637
t = jQuery.trim(val.t);
1641
// An error occurred with the selector;
1642
// just return an empty set instead
1646
// Remove the root context
1647
if ( ret && context == ret[0] )
1650
// And combine the results
1651
done = jQuery.merge( done, ret );
1656
classFilter: function(r,m,not){
1659
for ( var i = 0; r[i]; i++ ) {
1660
var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
1661
if ( !not && pass || not && !pass )
1667
filter: function(t,r,not) {
1670
// Look for common filter expressions
1671
while ( t && t != last ) {
1674
var p = jQuery.parse, m;
1676
for ( var i = 0; p[i]; i++ ) {
1680
// Remove what we just matched
1681
t = t.substring( m[0].length );
1683
m[2] = m[2].replace(/\\/g, "");
1691
// :not() is a special case that can be optimized by
1692
// keeping it out of the expression list
1693
if ( m[1] == ":" && m[2] == "not" )
1694
// optimize if only one selector found (most common case)
1695
r = isSimple.test( m[3] ) ?
1696
jQuery.filter(m[3], r, true).r :
1697
jQuery( r ).not( m[3] );
1699
// We can get a big speed boost by filtering by class here
1700
else if ( m[1] == "." )
1701
r = jQuery.classFilter(r, m[2], not);
1703
else if ( m[1] == "[" ) {
1704
var tmp = [], type = m[3];
1706
for ( var i = 0, rl = r.length; i < rl; i++ ) {
1707
var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
1709
if ( z == null || /href|src|selected/.test(m[2]) )
1710
z = jQuery.attr(a,m[2]) || '';
1712
if ( (type == "" && !!z ||
1713
type == "=" && z == m[5] ||
1714
type == "!=" && z != m[5] ||
1715
type == "^=" && z && !z.indexOf(m[5]) ||
1716
type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
1717
(type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
1723
// We can get a speed boost by handling nth-child here
1724
} else if ( m[1] == ":" && m[2] == "nth-child" ) {
1725
var merge = {}, tmp = [],
1726
// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1727
test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1728
m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
1729
!/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
1730
// calculate the numbers (first)n+(last) including if they are negative
1731
first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
1733
// loop through all the elements left in the jQuery object
1734
for ( var i = 0, rl = r.length; i < rl; i++ ) {
1735
var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
1740
for ( var n = parentNode.firstChild; n; n = n.nextSibling )
1741
if ( n.nodeType == 1 )
1750
if ( node.nodeIndex == last )
1752
} else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
1761
// Otherwise, find the expression to execute
1763
var fn = jQuery.expr[ m[1] ];
1764
if ( typeof fn == "object" )
1767
if ( typeof fn == "string" )
1768
fn = eval("false||function(a,i){return " + fn + ";}");
1770
// Execute it against the current filter
1771
r = jQuery.grep( r, function(elem, i){
1772
return fn(elem, i, m, r);
1777
// Return an array of filtered elements (r)
1778
// and the modified expression string (t)
1779
return { r: r, t: t };
1782
dir: function( elem, dir ){
1785
while ( cur && cur != document ) {
1786
if ( cur.nodeType == 1 )
1787
matched.push( cur );
1793
nth: function(cur,result,dir,elem){
1794
result = result || 1;
1797
for ( ; cur; cur = cur[dir] )
1798
if ( cur.nodeType == 1 && ++num == result )
1804
sibling: function( n, elem ) {
1807
for ( ; n; n = n.nextSibling ) {
1808
if ( n.nodeType == 1 && n != elem )
1816
* A number of helper functions used for managing events.
1817
* Many of the ideas behind this code orignated from
1818
* Dean Edwards' addEvent library.
1822
// Bind an event to an element
1823
// Original by Dean Edwards
1824
add: function(elem, types, handler, data) {
1825
if ( elem.nodeType == 3 || elem.nodeType == 8 )
1828
// For whatever reason, IE has trouble passing the window object
1829
// around, causing it to be cloned in the process
1830
if ( jQuery.browser.msie && elem.setInterval )
1833
// Make sure that the function being executed has a unique ID
1834
if ( !handler.guid )
1835
handler.guid = this.guid++;
1837
// if data is passed, bind to handler
1838
if( data != undefined ) {
1839
// Create temporary function pointer to original handler
1842
// Create unique handler function, wrapped around original handler
1843
handler = this.proxy( fn, function() {
1844
// Pass arguments and context to original handler
1845
return fn.apply(this, arguments);
1848
// Store data in unique handler
1849
handler.data = data;
1852
// Init the element's event structure
1853
var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
1854
handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
1855
// Handle the second event of a trigger and when
1856
// an event is called after a page has unloaded
1857
if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
1858
return jQuery.event.handle.apply(arguments.callee.elem, arguments);
1860
// Add elem as a property of the handle function
1861
// This is to prevent a memory leak with non-native
1865
// Handle multiple events separated by a space
1866
// jQuery(...).bind("mouseover mouseout", fn);
1867
jQuery.each(types.split(/\s+/), function(index, type) {
1868
// Namespaced event handlers
1869
var parts = type.split(".");
1871
handler.type = parts[1];
1873
// Get the current list of functions bound to this event
1874
var handlers = events[type];
1876
// Init the event handler queue
1878
handlers = events[type] = {};
1880
// Check for a special event handler
1881
// Only use addEventListener/attachEvent if the special
1882
// events handler returns false
1883
if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
1884
// Bind the global event handler to the element
1885
if (elem.addEventListener)
1886
elem.addEventListener(type, handle, false);
1887
else if (elem.attachEvent)
1888
elem.attachEvent("on" + type, handle);
1892
// Add the function to the element's handler list
1893
handlers[handler.guid] = handler;
1895
// Keep track of which events have been used, for global triggering
1896
jQuery.event.global[type] = true;
1899
// Nullify elem to prevent memory leaks in IE
1906
// Detach an event or set of events from an element
1907
remove: function(elem, types, handler) {
1908
// don't do events on text and comment nodes
1909
if ( elem.nodeType == 3 || elem.nodeType == 8 )
1912
var events = jQuery.data(elem, "events"), ret, index;
1915
// Unbind all events for the element
1916
if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
1917
for ( var type in events )
1918
this.remove( elem, type + (types || "") );
1920
// types is actually an event object here
1922
handler = types.handler;
1926
// Handle multiple events seperated by a space
1927
// jQuery(...).unbind("mouseover mouseout", fn);
1928
jQuery.each(types.split(/\s+/), function(index, type){
1929
// Namespaced event handlers
1930
var parts = type.split(".");
1933
if ( events[type] ) {
1934
// remove the given handler for the given type
1936
delete events[type][handler.guid];
1938
// remove all handlers for the given type
1940
for ( handler in events[type] )
1941
// Handle the removal of namespaced events
1942
if ( !parts[1] || events[type][handler].type == parts[1] )
1943
delete events[type][handler];
1945
// remove generic event handler if no more handlers exist
1946
for ( ret in events[type] ) break;
1948
if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
1949
if (elem.removeEventListener)
1950
elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
1951
else if (elem.detachEvent)
1952
elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
1955
delete events[type];
1961
// Remove the expando if it's no longer used
1962
for ( ret in events ) break;
1964
var handle = jQuery.data( elem, "handle" );
1965
if ( handle ) handle.elem = null;
1966
jQuery.removeData( elem, "events" );
1967
jQuery.removeData( elem, "handle" );
1972
trigger: function(type, data, elem, donative, extra) {
1973
// Clone the incoming data, if any
1974
data = jQuery.makeArray(data);
1976
if ( type.indexOf("!") >= 0 ) {
1977
type = type.slice(0, -1);
1978
var exclusive = true;
1981
// Handle a global trigger
1983
// Only trigger if we've ever bound an event for it
1984
if ( this.global[type] )
1985
jQuery("*").add([window, document]).trigger(type, data);
1987
// Handle triggering a single element
1989
// don't do events on text and comment nodes
1990
if ( elem.nodeType == 3 || elem.nodeType == 8 )
1993
var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
1994
// Check to see if we need to provide a fake event, or not
1995
event = !data[0] || !data[0].preventDefault;
1997
// Pass along a fake event
2002
preventDefault: function(){},
2003
stopPropagation: function(){},
2006
data[0][expando] = true; // no need to fix fake event
2009
// Enforce the right trigger type
2010
data[0].type = type;
2012
data[0].exclusive = true;
2014
// Trigger the event, it is assumed that "handle" is a function
2015
var handle = jQuery.data(elem, "handle");
2017
val = handle.apply( elem, data );
2019
// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2020
if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2023
// Extra functions don't get the custom event object
2027
// Handle triggering of extra function
2028
if ( extra && jQuery.isFunction( extra ) ) {
2029
// call the extra function and tack the current return value on the end for possible inspection
2030
ret = extra.apply( elem, val == null ? data : data.concat( val ) );
2031
// if anything is returned, give it precedence and have it overwrite the previous value
2032
if (ret !== undefined)
2036
// Trigger the native events (except for clicks on links)
2037
if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2038
this.triggered = true;
2041
// prevent IE from throwing an error for some hidden elements
2045
this.triggered = false;
2051
handle: function(event) {
2052
// returned undefined or false
2053
var val, ret, namespace, all, handlers;
2055
event = arguments[0] = jQuery.event.fix( event || window.event );
2057
// Namespaced event handlers
2058
namespace = event.type.split(".");
2059
event.type = namespace[0];
2060
namespace = namespace[1];
2061
// Cache this now, all = true means, any handler
2062
all = !namespace && !event.exclusive;
2064
handlers = ( jQuery.data(this, "events") || {} )[event.type];
2066
for ( var j in handlers ) {
2067
var handler = handlers[j];
2069
// Filter the functions by class
2070
if ( all || handler.type == namespace ) {
2071
// Pass in a reference to the handler function itself
2072
// So that we can later remove it
2073
event.handler = handler;
2074
event.data = handler.data;
2076
ret = handler.apply( this, arguments );
2078
if ( val !== false )
2081
if ( ret === false ) {
2082
event.preventDefault();
2083
event.stopPropagation();
2091
fix: function(event) {
2092
if ( event[expando] == true )
2095
// store a copy of the original event object
2096
// and "clone" to set read-only properties
2097
var originalEvent = event;
2098
event = { originalEvent: originalEvent };
2099
var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
2100
for ( var i=props.length; i; i-- )
2101
event[ props[i] ] = originalEvent[ props[i] ];
2104
event[expando] = true;
2106
// add preventDefault and stopPropagation since
2107
// they will not work on the clone
2108
event.preventDefault = function() {
2109
// if preventDefault exists run it on the original event
2110
if (originalEvent.preventDefault)
2111
originalEvent.preventDefault();
2112
// otherwise set the returnValue property of the original event to false (IE)
2113
originalEvent.returnValue = false;
2115
event.stopPropagation = function() {
2116
// if stopPropagation exists run it on the original event
2117
if (originalEvent.stopPropagation)
2118
originalEvent.stopPropagation();
2119
// otherwise set the cancelBubble property of the original event to true (IE)
2120
originalEvent.cancelBubble = true;
2124
event.timeStamp = event.timeStamp || now();
2126
// Fix target property, if necessary
2127
if ( !event.target )
2128
event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2130
// check if target is a textnode (safari)
2131
if ( event.target.nodeType == 3 )
2132
event.target = event.target.parentNode;
2134
// Add relatedTarget, if necessary
2135
if ( !event.relatedTarget && event.fromElement )
2136
event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2138
// Calculate pageX/Y if missing and clientX/Y available
2139
if ( event.pageX == null && event.clientX != null ) {
2140
var doc = document.documentElement, body = document.body;
2141
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2142
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2145
// Add which for key events
2146
if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2147
event.which = event.charCode || event.keyCode;
2149
// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2150
if ( !event.metaKey && event.ctrlKey )
2151
event.metaKey = event.ctrlKey;
2153
// Add which for click: 1 == left; 2 == middle; 3 == right
2154
// Note: button is not normalized, so don't use it
2155
if ( !event.which && event.button )
2156
event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2161
proxy: function( fn, proxy ){
2162
// Set the guid of unique handler to the same of original handler, so it can be removed
2163
proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2164
// So proxy can be declared as an argument
2171
// Make sure the ready event is setup
2176
teardown: function() { return; }
2181
if ( jQuery.browser.msie ) return false;
2182
jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
2186
teardown: function() {
2187
if ( jQuery.browser.msie ) return false;
2188
jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
2192
handler: function(event) {
2193
// If we actually just moused on to a sub-element, ignore it
2194
if ( withinElement(event, this) ) return true;
2195
// Execute the right handlers by setting the event type to mouseenter
2196
event.type = "mouseenter";
2197
return jQuery.event.handle.apply(this, arguments);
2203
if ( jQuery.browser.msie ) return false;
2204
jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
2208
teardown: function() {
2209
if ( jQuery.browser.msie ) return false;
2210
jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
2214
handler: function(event) {
2215
// If we actually just moused on to a sub-element, ignore it
2216
if ( withinElement(event, this) ) return true;
2217
// Execute the right handlers by setting the event type to mouseleave
2218
event.type = "mouseleave";
2219
return jQuery.event.handle.apply(this, arguments);
2226
bind: function( type, data, fn ) {
2227
return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2228
jQuery.event.add( this, type, fn || data, fn && data );
2232
one: function( type, data, fn ) {
2233
var one = jQuery.event.proxy( fn || data, function(event) {
2234
jQuery(this).unbind(event, one);
2235
return (fn || data).apply( this, arguments );
2237
return this.each(function(){
2238
jQuery.event.add( this, type, one, fn && data);
2242
unbind: function( type, fn ) {
2243
return this.each(function(){
2244
jQuery.event.remove( this, type, fn );
2248
trigger: function( type, data, fn ) {
2249
return this.each(function(){
2250
jQuery.event.trigger( type, data, this, true, fn );
2254
triggerHandler: function( type, data, fn ) {
2255
return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
2258
toggle: function( fn ) {
2259
// Save reference to arguments for access in closure
2260
var args = arguments, i = 1;
2262
// link all the functions, so any of them can unbind this click handler
2263
while( i < args.length )
2264
jQuery.event.proxy( fn, args[i++] );
2266
return this.click( jQuery.event.proxy( fn, function(event) {
2267
// Figure out which function to execute
2268
this.lastToggle = ( this.lastToggle || 0 ) % i;
2270
// Make sure that clicks stop
2271
event.preventDefault();
2273
// and execute the function
2274
return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2278
hover: function(fnOver, fnOut) {
2279
return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
2282
ready: function(fn) {
2283
// Attach the listeners
2286
// If the DOM is already ready
2287
if ( jQuery.isReady )
2288
// Execute the function immediately
2289
fn.call( document, jQuery );
2291
// Otherwise, remember the function for later
2293
// Add the function to the wait list
2294
jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
2303
// Handle when the DOM is ready
2305
// Make sure that the DOM is not already loaded
2306
if ( !jQuery.isReady ) {
2307
// Remember that the DOM is ready
2308
jQuery.isReady = true;
2310
// If there are functions bound, to execute
2311
if ( jQuery.readyList ) {
2312
// Execute all of them
2313
jQuery.each( jQuery.readyList, function(){
2314
this.call( document );
2317
// Reset the list of functions
2318
jQuery.readyList = null;
2321
// Trigger any bound ready events
2322
jQuery(document).triggerHandler("ready");
2327
var readyBound = false;
2329
function bindReady(){
2330
if ( readyBound ) return;
2333
// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
2334
if ( document.addEventListener && !jQuery.browser.opera)
2335
// Use the handy event callback
2336
document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
2338
// If IE is used and is not in a frame
2339
// Continually check to see if the document is ready
2340
if ( jQuery.browser.msie && window == top ) (function(){
2341
if (jQuery.isReady) return;
2343
// If IE is used, use the trick by Diego Perini
2344
// http://javascript.nwbox.com/IEContentLoaded/
2345
document.documentElement.doScroll("left");
2347
setTimeout( arguments.callee, 0 );
2350
// and execute any waiting functions
2354
if ( jQuery.browser.opera )
2355
document.addEventListener( "DOMContentLoaded", function () {
2356
if (jQuery.isReady) return;
2357
for (var i = 0; i < document.styleSheets.length; i++)
2358
if (document.styleSheets[i].disabled) {
2359
setTimeout( arguments.callee, 0 );
2362
// and execute any waiting functions
2366
if ( jQuery.browser.safari ) {
2369
if (jQuery.isReady) return;
2370
if ( document.readyState != "loaded" && document.readyState != "complete" ) {
2371
setTimeout( arguments.callee, 0 );
2374
if ( numStyles === undefined )
2375
numStyles = jQuery("style, link[rel=stylesheet]").length;
2376
if ( document.styleSheets.length != numStyles ) {
2377
setTimeout( arguments.callee, 0 );
2380
// and execute any waiting functions
2385
// A fallback to window.onload, that will always work
2386
jQuery.event.add( window, "load", jQuery.ready );
2389
jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2390
"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
2391
"submit,keydown,keypress,keyup,error").split(","), function(i, name){
2393
// Handle event binding
2394
jQuery.fn[name] = function(fn){
2395
return fn ? this.bind(name, fn) : this.trigger(name);
2399
// Checks if an event happened on an element within another element
2400
// Used in jQuery.event.special.mouseenter and mouseleave handlers
2401
var withinElement = function(event, elem) {
2402
// Check if mouse(over|out) are still within the same parent element
2403
var parent = event.relatedTarget;
2404
// Traverse up the tree
2405
while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
2406
// Return true if we actually just moused on to a sub-element
2407
return parent == elem;
2410
// Prevent memory leaks in IE
2411
// And prevent errors on refresh with events like mouseover in other browsers
2412
// Window isn't included so as not to unbind existing unload events
2413
jQuery(window).bind("unload", function() {
2414
jQuery("*").add(document).unbind();
2417
// Keep a copy of the old load
2418
_load: jQuery.fn.load,
2420
load: function( url, params, callback ) {
2421
if ( typeof url != 'string' )
2422
return this._load( url );
2424
var off = url.indexOf(" ");
2426
var selector = url.slice(off, url.length);
2427
url = url.slice(0, off);
2430
callback = callback || function(){};
2432
// Default to a GET request
2435
// If the second parameter was provided
2437
// If it's a function
2438
if ( jQuery.isFunction( params ) ) {
2439
// We assume that it's the callback
2443
// Otherwise, build a param string
2445
params = jQuery.param( params );
2451
// Request the remote document
2457
complete: function(res, status){
2458
// If successful, inject the HTML into all the matched elements
2459
if ( status == "success" || status == "notmodified" )
2460
// See if a selector was specified
2461
self.html( selector ?
2462
// Create a dummy div to hold the results
2464
// inject the contents of the document in, removing the scripts
2465
// to avoid any 'Permission Denied' errors in IE
2466
.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
2468
// Locate the specified elements
2471
// If not, just inject the full result
2474
self.each( callback, [res.responseText, status, res] );
2480
serialize: function() {
2481
return jQuery.param(this.serializeArray());
2483
serializeArray: function() {
2484
return this.map(function(){
2485
return jQuery.nodeName(this, "form") ?
2486
jQuery.makeArray(this.elements) : this;
2489
return this.name && !this.disabled &&
2490
(this.checked || /select|textarea/i.test(this.nodeName) ||
2491
/text|hidden|password/i.test(this.type));
2493
.map(function(i, elem){
2494
var val = jQuery(this).val();
2495
return val == null ? null :
2496
val.constructor == Array ?
2497
jQuery.map( val, function(val, i){
2498
return {name: elem.name, value: val};
2500
{name: elem.name, value: val};
2505
// Attach a bunch of functions for handling common AJAX events
2506
jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
2507
jQuery.fn[o] = function(f){
2508
return this.bind(o, f);
2515
get: function( url, data, callback, type ) {
2516
// shift arguments if data argument was ommited
2517
if ( jQuery.isFunction( data ) ) {
2522
return jQuery.ajax({
2531
getScript: function( url, callback ) {
2532
return jQuery.get(url, null, callback, "script");
2535
getJSON: function( url, data, callback ) {
2536
return jQuery.get(url, data, callback, "json");
2539
post: function( url, data, callback, type ) {
2540
if ( jQuery.isFunction( data ) ) {
2545
return jQuery.ajax({
2554
ajaxSetup: function( settings ) {
2555
jQuery.extend( jQuery.ajaxSettings, settings );
2563
contentType: "application/x-www-form-urlencoded",
2570
xml: "application/xml, text/xml",
2572
script: "text/javascript, application/javascript",
2573
json: "application/json, text/javascript",
2579
// Last-Modified header cache for next request
2582
ajax: function( s ) {
2583
// Extend the settings, but re-extend 's' so that it can be
2584
// checked again later (in the test suite, specifically)
2585
s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
2587
var jsonp, jsre = /=\?(&|$)/g, status, data,
2588
type = s.type.toUpperCase();
2590
// convert data if not already a string
2591
if ( s.data && s.processData && typeof s.data != "string" )
2592
s.data = jQuery.param(s.data);
2594
// Handle JSONP Parameter Callbacks
2595
if ( s.dataType == "jsonp" ) {
2596
if ( type == "GET" ) {
2597
if ( !s.url.match(jsre) )
2598
s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
2599
} else if ( !s.data || !s.data.match(jsre) )
2600
s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
2601
s.dataType = "json";
2604
// Build temporary JSONP function
2605
if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
2606
jsonp = "jsonp" + jsc++;
2608
// Replace the =? sequence both in the query string and the data
2610
s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
2611
s.url = s.url.replace(jsre, "=" + jsonp + "$1");
2613
// We need to make sure
2614
// that a JSONP style response is executed properly
2615
s.dataType = "script";
2617
// Handle JSONP-style loading
2618
window[ jsonp ] = function(tmp){
2623
window[ jsonp ] = undefined;
2624
try{ delete window[ jsonp ]; } catch(e){}
2626
head.removeChild( script );
2630
if ( s.dataType == "script" && s.cache == null )
2633
if ( s.cache === false && type == "GET" ) {
2635
// try replacing _= if it is there
2636
var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
2637
// if nothing was replaced, add timestamp to the end
2638
s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
2641
// If data is available, append data to url for get requests
2642
if ( s.data && type == "GET" ) {
2643
s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
2645
// IE likes to send both get and post data, prevent this
2649
// Watch for a new set of requests
2650
if ( s.global && ! jQuery.active++ )
2651
jQuery.event.trigger( "ajaxStart" );
2653
// Matches an absolute URL, and saves the domain
2654
var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
2656
// If we're requesting a remote document
2657
// and trying to load JSON or Script with a GET
2658
if ( s.dataType == "script" && type == "GET"
2659
&& remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
2660
var head = document.getElementsByTagName("head")[0];
2661
var script = document.createElement("script");
2663
if (s.scriptCharset)
2664
script.charset = s.scriptCharset;
2666
// Handle Script loading
2670
// Attach handlers for all browsers
2671
script.onload = script.onreadystatechange = function(){
2672
if ( !done && (!this.readyState ||
2673
this.readyState == "loaded" || this.readyState == "complete") ) {
2677
head.removeChild( script );
2682
head.appendChild(script);
2684
// We handle everything using the script element injection
2688
var requestDone = false;
2690
// Create the request object; Microsoft failed to properly
2691
// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
2692
var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
2695
// Passing null username, generates a login popup on Opera (#2865)
2697
xhr.open(type, s.url, s.async, s.username, s.password);
2699
xhr.open(type, s.url, s.async);
2701
// Need an extra try/catch for cross domain requests in Firefox 3
2703
// Set the correct header, if data is being sent
2705
xhr.setRequestHeader("Content-Type", s.contentType);
2707
// Set the If-Modified-Since header, if ifModified mode.
2709
xhr.setRequestHeader("If-Modified-Since",
2710
jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
2712
// Set header so the called script knows that it's an XMLHttpRequest
2713
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
2715
// Set the Accepts header for the server, depending on the dataType
2716
xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
2717
s.accepts[ s.dataType ] + ", */*" :
2718
s.accepts._default );
2721
// Allow custom headers/mimetypes
2722
if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
2723
// cleanup active request counter
2724
s.global && jQuery.active--;
2725
// close opended socket
2731
jQuery.event.trigger("ajaxSend", [xhr, s]);
2733
// Wait for a response to come back
2734
var onreadystatechange = function(isTimeout){
2735
// The transfer is complete and the data is available, or the request timed out
2736
if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
2739
// clear poll interval
2741
clearInterval(ival);
2745
status = isTimeout == "timeout" && "timeout" ||
2746
!jQuery.httpSuccess( xhr ) && "error" ||
2747
s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
2750
if ( status == "success" ) {
2751
// Watch for, and catch, XML document parse errors
2753
// process the data (runs the xml through httpData regardless of callback)
2754
data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
2756
status = "parsererror";
2760
// Make sure that the request was successful or notmodified
2761
if ( status == "success" ) {
2762
// Cache Last-Modified header, if ifModified mode.
2765
modRes = xhr.getResponseHeader("Last-Modified");
2766
} catch(e) {} // swallow exception thrown by FF if header is not available
2768
if ( s.ifModified && modRes )
2769
jQuery.lastModified[s.url] = modRes;
2771
// JSONP handles its own success callback
2775
jQuery.handleError(s, xhr, status);
2777
// Fire the complete handlers
2780
// Stop memory leaks
2787
// don't attach the handler to the request, just poll it instead
2788
var ival = setInterval(onreadystatechange, 13);
2791
if ( s.timeout > 0 )
2792
setTimeout(function(){
2793
// Check to see if the request is still happening
2795
// Cancel the request
2799
onreadystatechange( "timeout" );
2808
jQuery.handleError(s, xhr, null, e);
2811
// firefox 1.5 doesn't fire statechange for sync requests
2813
onreadystatechange();
2816
// If a local callback was specified, fire it and pass it the data
2818
s.success( data, status );
2820
// Fire the global callback
2822
jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
2825
function complete(){
2828
s.complete(xhr, status);
2830
// The request was completed
2832
jQuery.event.trigger( "ajaxComplete", [xhr, s] );
2834
// Handle the global AJAX counter
2835
if ( s.global && ! --jQuery.active )
2836
jQuery.event.trigger( "ajaxStop" );
2839
// return XMLHttpRequest to allow aborting the request etc.
2843
handleError: function( s, xhr, status, e ) {
2844
// If a local callback was specified, fire it
2845
if ( s.error ) s.error( xhr, status, e );
2847
// Fire the global callback
2849
jQuery.event.trigger( "ajaxError", [xhr, s, e] );
2852
// Counter for holding the number of active queries
2855
// Determines if an XMLHttpRequest was successful or not
2856
httpSuccess: function( xhr ) {
2858
// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
2859
return !xhr.status && location.protocol == "file:" ||
2860
( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
2861
jQuery.browser.safari && xhr.status == undefined;
2866
// Determines if an XMLHttpRequest returns NotModified
2867
httpNotModified: function( xhr, url ) {
2869
var xhrRes = xhr.getResponseHeader("Last-Modified");
2871
// Firefox always returns 200. check Last-Modified date
2872
return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
2873
jQuery.browser.safari && xhr.status == undefined;
2878
httpData: function( xhr, type, filter ) {
2879
var ct = xhr.getResponseHeader("content-type"),
2880
xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
2881
data = xml ? xhr.responseXML : xhr.responseText;
2883
if ( xml && data.documentElement.tagName == "parsererror" )
2884
throw "parsererror";
2886
// Allow a pre-filtering function to sanitize the response
2888
data = filter( data, type );
2890
// If the type is "script", eval it in global context
2891
if ( type == "script" )
2892
jQuery.globalEval( data );
2894
// Get the JavaScript object, if JSON is used.
2895
if ( type == "json" )
2896
data = eval("(" + data + ")");
2901
// Serialize an array of form elements or a set of
2902
// key/values into a query string
2903
param: function( a ) {
2906
// If an array was passed in, assume that it is an array
2908
if ( a.constructor == Array || a.jquery )
2909
// Serialize the form elements
2910
jQuery.each( a, function(){
2911
s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
2914
// Otherwise, assume that it's an object of key/value pairs
2916
// Serialize the key/values
2918
// If the value is an array then the key names need to be repeated
2919
if ( a[j] && a[j].constructor == Array )
2920
jQuery.each( a[j], function(){
2921
s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
2924
s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
2926
// Return the resulting serialization
2927
return s.join("&").replace(/%20/g, "+");
2932
show: function(speed,callback){
2935
height: "show", width: "show", opacity: "show"
2936
}, speed, callback) :
2938
this.filter(":hidden").each(function(){
2939
this.style.display = this.oldblock || "";
2940
if ( jQuery.css(this,"display") == "none" ) {
2941
var elem = jQuery("<" + this.tagName + " />").appendTo("body");
2942
this.style.display = elem.css("display");
2943
// handle an edge condition where css is - div { display:none; } or similar
2944
if (this.style.display == "none")
2945
this.style.display = "block";
2951
hide: function(speed,callback){
2954
height: "hide", width: "hide", opacity: "hide"
2955
}, speed, callback) :
2957
this.filter(":visible").each(function(){
2958
this.oldblock = this.oldblock || jQuery.css(this,"display");
2959
this.style.display = "none";
2963
// Save the old toggle function
2964
_toggle: jQuery.fn.toggle,
2966
toggle: function( fn, fn2 ){
2967
return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
2968
this._toggle.apply( this, arguments ) :
2971
height: "toggle", width: "toggle", opacity: "toggle"
2973
this.each(function(){
2974
jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
2978
slideDown: function(speed,callback){
2979
return this.animate({height: "show"}, speed, callback);
2982
slideUp: function(speed,callback){
2983
return this.animate({height: "hide"}, speed, callback);
2986
slideToggle: function(speed, callback){
2987
return this.animate({height: "toggle"}, speed, callback);
2990
fadeIn: function(speed, callback){
2991
return this.animate({opacity: "show"}, speed, callback);
2994
fadeOut: function(speed, callback){
2995
return this.animate({opacity: "hide"}, speed, callback);
2998
fadeTo: function(speed,to,callback){
2999
return this.animate({opacity: to}, speed, callback);
3002
animate: function( prop, speed, easing, callback ) {
3003
var optall = jQuery.speed(speed, easing, callback);
3005
return this[ optall.queue === false ? "each" : "queue" ](function(){
3006
if ( this.nodeType != 1)
3009
var opt = jQuery.extend({}, optall), p,
3010
hidden = jQuery(this).is(":hidden"), self = this;
3013
if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3014
return opt.complete.call(this);
3016
if ( p == "height" || p == "width" ) {
3017
// Store display property
3018
opt.display = jQuery.css(this, "display");
3020
// Make sure that nothing sneaks out
3021
opt.overflow = this.style.overflow;
3025
if ( opt.overflow != null )
3026
this.style.overflow = "hidden";
3028
opt.curAnim = jQuery.extend({}, prop);
3030
jQuery.each( prop, function(name, val){
3031
var e = new jQuery.fx( self, opt, name );
3033
if ( /toggle|show|hide/.test(val) )
3034
e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3036
var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3037
start = e.cur(true) || 0;
3040
var end = parseFloat(parts[2]),
3041
unit = parts[3] || "px";
3043
// We need to compute starting value
3044
if ( unit != "px" ) {
3045
self.style[ name ] = (end || 1) + unit;
3046
start = ((end || 1) / e.cur(true)) * start;
3047
self.style[ name ] = start + unit;
3050
// If a +=/-= token was provided, we're doing a relative animation
3052
end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3054
e.custom( start, end, unit );
3056
e.custom( start, val, "" );
3060
// For JS strict compliance
3065
queue: function(type, fn){
3066
if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
3071
if ( !type || (typeof type == "string" && !fn) )
3072
return queue( this[0], type );
3074
return this.each(function(){
3075
if ( fn.constructor == Array )
3076
queue(this, type, fn);
3078
queue(this, type).push( fn );
3080
if ( queue(this, type).length == 1 )
3086
stop: function(clearQueue, gotoEnd){
3087
var timers = jQuery.timers;
3092
this.each(function(){
3093
// go in reverse order so anything added to the queue during the loop is ignored
3094
for ( var i = timers.length - 1; i >= 0; i-- )
3095
if ( timers[i].elem == this ) {
3097
// force the next step to be the last
3099
timers.splice(i, 1);
3103
// start the next in the queue if the last step wasn't forced
3112
var queue = function( elem, type, array ) {
3115
type = type || "fx";
3117
var q = jQuery.data( elem, type + "queue" );
3120
q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
3126
jQuery.fn.dequeue = function(type){
3127
type = type || "fx";
3129
return this.each(function(){
3130
var q = queue(this, type);
3141
speed: function(speed, easing, fn) {
3142
var opt = speed && speed.constructor == Object ? speed : {
3143
complete: fn || !fn && easing ||
3144
jQuery.isFunction( speed ) && speed,
3146
easing: fn && easing || easing && easing.constructor != Function && easing
3149
opt.duration = (opt.duration && opt.duration.constructor == Number ?
3151
jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
3154
opt.old = opt.complete;
3155
opt.complete = function(){
3156
if ( opt.queue !== false )
3157
jQuery(this).dequeue();
3158
if ( jQuery.isFunction( opt.old ) )
3159
opt.old.call( this );
3166
linear: function( p, n, firstNum, diff ) {
3167
return firstNum + diff * p;
3169
swing: function( p, n, firstNum, diff ) {
3170
return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3177
fx: function( elem, options, prop ){
3178
this.options = options;
3182
if ( !options.orig )
3188
jQuery.fx.prototype = {
3190
// Simple function for setting a style value
3192
if ( this.options.step )
3193
this.options.step.call( this.elem, this.now, this );
3195
(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
3197
// Set display property to block for height/width animations
3198
if ( this.prop == "height" || this.prop == "width" )
3199
this.elem.style.display = "block";
3202
// Get the current size
3203
cur: function(force){
3204
if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
3205
return this.elem[ this.prop ];
3207
var r = parseFloat(jQuery.css(this.elem, this.prop, force));
3208
return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
3211
// Start an animation from one number to another
3212
custom: function(from, to, unit){
3213
this.startTime = now();
3216
this.unit = unit || this.unit || "px";
3217
this.now = this.start;
3218
this.pos = this.state = 0;
3222
function t(gotoEnd){
3223
return self.step(gotoEnd);
3228
jQuery.timers.push(t);
3230
if ( jQuery.timerId == null ) {
3231
jQuery.timerId = setInterval(function(){
3232
var timers = jQuery.timers;
3234
for ( var i = 0; i < timers.length; i++ )
3236
timers.splice(i--, 1);
3238
if ( !timers.length ) {
3239
clearInterval( jQuery.timerId );
3240
jQuery.timerId = null;
3246
// Simple 'show' function
3248
// Remember where we started, so that we can go back to it later
3249
this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3250
this.options.show = true;
3252
// Begin the animation
3253
this.custom(0, this.cur());
3255
// Make sure that we start at a small width/height to avoid any
3257
if ( this.prop == "width" || this.prop == "height" )
3258
this.elem.style[this.prop] = "1px";
3260
// Start by showing the element
3261
jQuery(this.elem).show();
3264
// Simple 'hide' function
3266
// Remember where we started, so that we can go back to it later
3267
this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3268
this.options.hide = true;
3270
// Begin the animation
3271
this.custom(this.cur(), 0);
3274
// Each step of an animation
3275
step: function(gotoEnd){
3278
if ( gotoEnd || t > this.options.duration + this.startTime ) {
3279
this.now = this.end;
3280
this.pos = this.state = 1;
3283
this.options.curAnim[ this.prop ] = true;
3286
for ( var i in this.options.curAnim )
3287
if ( this.options.curAnim[i] !== true )
3291
if ( this.options.display != null ) {
3292
// Reset the overflow
3293
this.elem.style.overflow = this.options.overflow;
3295
// Reset the display
3296
this.elem.style.display = this.options.display;
3297
if ( jQuery.css(this.elem, "display") == "none" )
3298
this.elem.style.display = "block";
3301
// Hide the element if the "hide" operation was done
3302
if ( this.options.hide )
3303
this.elem.style.display = "none";
3305
// Reset the properties, if the item has been hidden or shown
3306
if ( this.options.hide || this.options.show )
3307
for ( var p in this.options.curAnim )
3308
jQuery.attr(this.elem.style, p, this.options.orig[p]);
3312
// Execute the complete function
3313
this.options.complete.call( this.elem );
3317
var n = t - this.startTime;
3318
this.state = n / this.options.duration;
3320
// Perform the easing function, defaults to swing
3321
this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
3322
this.now = this.start + ((this.end - this.start) * this.pos);
3324
// Perform the next step of the animation
3333
jQuery.extend( jQuery.fx, {
3341
scrollLeft: function(fx){
3342
fx.elem.scrollLeft = fx.now;
3345
scrollTop: function(fx){
3346
fx.elem.scrollTop = fx.now;
3349
opacity: function(fx){
3350
jQuery.attr(fx.elem.style, "opacity", fx.now);
3353
_default: function(fx){
3354
fx.elem.style[ fx.prop ] = fx.now + fx.unit;
3358
// The Offset Method
3359
// Originally By Brandon Aaron, part of the Dimension Plugin
3360
// http://jquery.com/plugins/project/dimensions
3361
jQuery.fn.offset = function() {
3362
var left = 0, top = 0, elem = this[0], results;
3364
if ( elem ) with ( jQuery.browser ) {
3365
var parent = elem.parentNode,
3367
offsetParent = elem.offsetParent,
3368
doc = elem.ownerDocument,
3369
safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
3370
css = jQuery.curCSS,
3371
fixed = css(elem, "position") == "fixed";
3373
// Use getBoundingClientRect if available
3374
if ( elem.getBoundingClientRect ) {
3375
var box = elem.getBoundingClientRect();
3377
// Add the document scroll offsets
3378
add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3379
box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
3381
// IE adds the HTML element's border, by default it is medium which is 2px
3382
// IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
3383
// IE 7 standards mode, the border is always 2px
3384
// This border/offset is typically represented by the clientLeft and clientTop properties
3385
// However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
3386
// Therefore this method will be off by 2px in IE while in quirksmode
3387
add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
3389
// Otherwise loop through the offsetParents and parentNodes
3392
// Initial element offsets
3393
add( elem.offsetLeft, elem.offsetTop );
3395
// Get parent offsets
3396
while ( offsetParent ) {
3397
// Add offsetParent offsets
3398
add( offsetParent.offsetLeft, offsetParent.offsetTop );
3400
// Mozilla and Safari > 2 does not include the border on offset parents
3401
// However Mozilla adds the border for table or table cells
3402
if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
3403
border( offsetParent );
3405
// Add the document scroll offsets if position is fixed on any offsetParent
3406
if ( !fixed && css(offsetParent, "position") == "fixed" )
3409
// Set offsetChild to previous offsetParent unless it is the body element
3410
offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
3411
// Get next offsetParent
3412
offsetParent = offsetParent.offsetParent;
3415
// Get parent scroll offsets
3416
while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
3417
// Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
3418
if ( !/^inline|table.*$/i.test(css(parent, "display")) )
3419
// Subtract parent scroll offsets
3420
add( -parent.scrollLeft, -parent.scrollTop );
3422
// Mozilla does not add the border for a parent that has overflow != visible
3423
if ( mozilla && css(parent, "overflow") != "visible" )
3427
parent = parent.parentNode;
3430
// Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
3431
// Mozilla doubles body offsets with a non-absolutely positioned offsetChild
3432
if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
3433
(mozilla && css(offsetChild, "position") != "absolute") )
3434
add( -doc.body.offsetLeft, -doc.body.offsetTop );
3436
// Add the document scroll offsets if position is fixed
3438
add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3439
Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
3442
// Return an object with top and left properties
3443
results = { top: top, left: left };
3446
function border(elem) {
3447
add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
3450
function add(l, t) {
3451
left += parseInt(l, 10) || 0;
3452
top += parseInt(t, 10) || 0;
3460
position: function() {
3461
var left = 0, top = 0, results;
3464
// Get *real* offsetParent
3465
var offsetParent = this.offsetParent(),
3467
// Get correct offsets
3468
offset = this.offset(),
3469
parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
3471
// Subtract element margins
3472
// note: when an element has margin: auto the offsetLeft and marginLeft
3473
// are the same in Safari causing offset.left to incorrectly be 0
3474
offset.top -= num( this, 'marginTop' );
3475
offset.left -= num( this, 'marginLeft' );
3477
// Add offsetParent borders
3478
parentOffset.top += num( offsetParent, 'borderTopWidth' );
3479
parentOffset.left += num( offsetParent, 'borderLeftWidth' );
3481
// Subtract the two offsets
3483
top: offset.top - parentOffset.top,
3484
left: offset.left - parentOffset.left
3491
offsetParent: function() {
3492
var offsetParent = this[0].offsetParent;
3493
while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
3494
offsetParent = offsetParent.offsetParent;
3495
return jQuery(offsetParent);
3500
// Create scrollLeft and scrollTop methods
3501
jQuery.each( ['Left', 'Top'], function(i, name) {
3502
var method = 'scroll' + name;
3504
jQuery.fn[ method ] = function(val) {
3505
if (!this[0]) return;
3507
return val != undefined ?
3509
// Set the scroll offset
3510
this.each(function() {
3511
this == window || this == document ?
3513
!i ? val : jQuery(window).scrollLeft(),
3514
i ? val : jQuery(window).scrollTop()
3516
this[ method ] = val;
3519
// Return the scroll offset
3520
this[0] == window || this[0] == document ?
3521
self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
3522
jQuery.boxModel && document.documentElement[ method ] ||
3523
document.body[ method ] :
3527
// Create innerHeight, innerWidth, outerHeight and outerWidth methods
3528
jQuery.each([ "Height", "Width" ], function(i, name){
3530
var tl = i ? "Left" : "Top", // top or left
3531
br = i ? "Right" : "Bottom"; // bottom or right
3533
// innerHeight and innerWidth
3534
jQuery.fn["inner" + name] = function(){
3535
return this[ name.toLowerCase() ]() +
3536
num(this, "padding" + tl) +
3537
num(this, "padding" + br);
3540
// outerHeight and outerWidth
3541
jQuery.fn["outer" + name] = function(margin) {
3542
return this["inner" + name]() +
3543
num(this, "border" + tl + "Width") +
3544
num(this, "border" + br + "Width") +
3546
num(this, "margin" + tl) + num(this, "margin" + br) : 0);