2 * jQuery JavaScript Library v1.3.2
5 * Copyright (c) 2009 John Resig
6 * Dual licensed under the MIT and GPL licenses.
7 * http://docs.jquery.com/License
9 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
15 // Will speed up references to window, and allows munging its name.
17 // Will speed up references to undefined, and allows munging its name.
19 // Map over jQuery in case of overwrite
20 _jQuery
= window
.jQuery
,
21 // Map over the $ in case of overwrite
24 jQuery
= window
.jQuery
= window
.$ = function( selector
, context
) {
25 // The jQuery object is actually just the init constructor 'enhanced'
26 return new jQuery
.fn
.init( selector
, context
);
29 // A simple way to check for HTML strings or ID strings
30 // (both of which we optimize for)
31 quickExpr
= /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
32 // Is it a simple selector
33 isSimple
= /^.[^:#\[\.,]*$/;
35 jQuery
.fn
= jQuery
.prototype = {
36 init: function( selector
, context
) {
37 // Make sure that a selection was provided
38 selector
= selector
|| document
;
40 // Handle $(DOMElement)
41 if ( selector
.nodeType
) {
44 this.context
= selector
;
47 // Handle HTML strings
48 if ( typeof selector
=== "string" ) {
49 // Are we dealing with HTML string or an ID?
50 var match
= quickExpr
.exec( selector
);
52 // Verify a match, and that no context was specified for #id
53 if ( match
&& (match
[1] || !context
) ) {
55 // HANDLE: $(html) -> $(array)
57 selector
= jQuery
.clean( [ match
[1] ], context
);
61 var elem
= document
.getElementById( match
[3] );
63 // Handle the case where IE and Opera return items
64 // by name instead of ID
65 if ( elem
&& elem
.id
!= match
[3] )
66 return jQuery().find( selector
);
68 // Otherwise, we inject the element directly into the jQuery object
69 var ret
= jQuery( elem
|| [] );
70 ret
.context
= document
;
71 ret
.selector
= selector
;
75 // HANDLE: $(expr, [context])
76 // (which is just equivalent to: $(content).find(expr)
78 return jQuery( context
).find( selector
);
80 // HANDLE: $(function)
81 // Shortcut for document ready
82 } else if ( jQuery
.isFunction( selector
) )
83 return jQuery( document
).ready( selector
);
85 // Make sure that old selector state is passed along
86 if ( selector
.selector
&& selector
.context
) {
87 this.selector
= selector
.selector
;
88 this.context
= selector
.context
;
91 return this.setArray(jQuery
.isArray( selector
) ?
93 jQuery
.makeArray(selector
));
96 // Start with an empty selector
99 // The current version of jQuery being used
102 // The number of elements contained in the matched element set
107 // Get the Nth element in the matched element set OR
108 // Get the whole matched element set as a clean array
109 get: function( num
) {
110 return num
=== undefined ?
112 // Return a 'clean' array
113 Array
.prototype.slice
.call( this ) :
115 // Return just the object
119 // Take an array of elements and push it onto the stack
120 // (returning the new matched element set)
121 pushStack: function( elems
, name
, selector
) {
122 // Build a new jQuery matched element set
123 var ret
= jQuery( elems
);
125 // Add the old object onto the stack (as a reference)
126 ret
.prevObject
= this;
128 ret
.context
= this.context
;
130 if ( name
=== "find" )
131 ret
.selector
= this.selector
+ (this.selector
? " " : "") + selector
;
133 ret
.selector
= this.selector
+ "." + name
+ "(" + selector
+ ")";
135 // Return the newly-formed element set
139 // Force the current matched set of elements to become
140 // the specified array of elements (destroying the stack in the process)
141 // You should use pushStack() in order to do this, but maintain the stack
142 setArray: function( elems
) {
143 // Resetting the length to 0, then using the native Array push
144 // is a super-fast way to populate an object with array-like properties
146 Array
.prototype.push
.apply( this, elems
);
151 // Execute a callback for every element in the matched set.
152 // (You can seed the arguments with an array of args, but this is
153 // only used internally.)
154 each: function( callback
, args
) {
155 return jQuery
.each( this, callback
, args
);
158 // Determine the position of an element within
159 // the matched set of elements
160 index: function( elem
) {
161 // Locate the position of the desired element
162 return jQuery
.inArray(
163 // If it receives a jQuery object, the first element is used
164 elem
&& elem
.jquery
? elem
[0] : elem
168 attr: function( name
, value
, type
) {
171 // Look for the case where we're accessing a style value
172 if ( typeof name
=== "string" )
173 if ( value
=== undefined )
174 return this[0] && jQuery
[ type
|| "attr" ]( this[0], name
);
178 options
[ name
] = value
;
181 // Check to see if we're setting style values
182 return this.each(function(i
){
183 // Set all the styles
184 for ( name
in options
)
189 name
, jQuery
.prop( this, options
[ name
], type
, i
, name
)
194 css: function( key
, value
) {
195 // ignore negative width and height values
196 if ( (key
== 'width' || key
== 'height') && parseFloat(value
) < 0 )
198 return this.attr( key
, value
, "curCSS" );
201 text: function( text
) {
202 if ( typeof text
!== "object" && text
!= null )
203 return this.empty().append( (this[0] && this[0].ownerDocument
|| document
).createTextNode( text
) );
207 jQuery
.each( text
|| this, function(){
208 jQuery
.each( this.childNodes
, function(){
209 if ( this.nodeType
!= 8 )
210 ret
+= this.nodeType
!= 1 ?
212 jQuery
.fn
.text( [ this ] );
219 wrapAll: function( html
) {
221 // The elements to wrap the target around
222 var wrap
= jQuery( html
, this[0].ownerDocument
).clone();
224 if ( this[0].parentNode
)
225 wrap
.insertBefore( this[0] );
230 while ( elem
.firstChild
)
231 elem
= elem
.firstChild
;
240 wrapInner: function( html
) {
241 return this.each(function(){
242 jQuery( this ).contents().wrapAll( html
);
246 wrap: function( html
) {
247 return this.each(function(){
248 jQuery( this ).wrapAll( html
);
253 return this.domManip(arguments
, true, function(elem
){
254 if (this.nodeType
== 1)
255 this.appendChild( elem
);
259 prepend: function() {
260 return this.domManip(arguments
, true, function(elem
){
261 if (this.nodeType
== 1)
262 this.insertBefore( elem
, this.firstChild
);
267 return this.domManip(arguments
, false, function(elem
){
268 this.parentNode
.insertBefore( elem
, this );
273 return this.domManip(arguments
, false, function(elem
){
274 this.parentNode
.insertBefore( elem
, this.nextSibling
);
279 return this.prevObject
|| jQuery( [] );
282 // For internal use only.
283 // Behaves like an Array's method, not like a jQuery method.
288 find: function( selector
) {
289 if ( this.length
=== 1 ) {
290 var ret
= this.pushStack( [], "find", selector
);
292 jQuery
.find( selector
, this[0], ret
);
295 return this.pushStack( jQuery
.unique(jQuery
.map(this, function(elem
){
296 return jQuery
.find( selector
, elem
);
297 })), "find", selector
);
301 clone: function( events
) {
303 var ret
= this.map(function(){
304 if ( !jQuery
.support
.noCloneEvent
&& !jQuery
.isXMLDoc(this) ) {
305 // IE copies events bound via attachEvent when
306 // using cloneNode. Calling detachEvent on the
307 // clone will also remove the events from the orignal
308 // In order to get around this, we use innerHTML.
309 // Unfortunately, this means some modifications to
310 // attributes in IE that are actually only stored
311 // as properties will not be copied (such as the
312 // the name attribute on an input).
313 var html
= this.outerHTML
;
315 var div
= this.ownerDocument
.createElement("div");
316 div
.appendChild( this.cloneNode(true) );
317 html
= div
.innerHTML
;
320 return jQuery
.clean([html
.replace(/ jQuery
\d
+="(?:\d+|null)"/g, "").replace(/^\s*/
, "")])[0];
322 return this.cloneNode(true);
325 // Copy the events from the original to the clone
326 if ( events
=== true ) {
327 var orig
= this.find("*").andSelf(), i
= 0;
329 ret
.find("*").andSelf().each(function(){
330 if ( this.nodeName
!== orig
[i
].nodeName
)
333 var events
= jQuery
.data( orig
[i
], "events" );
335 for ( var type
in events
) {
336 for ( var handler
in events
[ type
] ) {
337 jQuery
.event
.add( this, type
, events
[ type
][ handler
], events
[ type
][ handler
].data
);
345 // Return the cloned set
349 filter: function( selector
) {
350 return this.pushStack(
351 jQuery
.isFunction( selector
) &&
352 jQuery
.grep(this, function(elem
, i
){
353 return selector
.call( elem
, i
);
356 jQuery
.multiFilter( selector
, jQuery
.grep(this, function(elem
){
357 return elem
.nodeType
=== 1;
358 }) ), "filter", selector
);
361 closest: function( selector
) {
362 var pos
= jQuery
.expr
.match
.POS
.test( selector
) ? jQuery(selector
) : null,
365 return this.map(function(){
367 while ( cur
&& cur
.ownerDocument
) {
368 if ( pos
? pos
.index(cur
) > -1 : jQuery(cur
).is(selector
) ) {
369 jQuery
.data(cur
, "closest", closer
);
372 cur
= cur
.parentNode
;
378 not: function( selector
) {
379 if ( typeof selector
=== "string" )
380 // test special case where just one selector is passed in
381 if ( isSimple
.test( selector
) )
382 return this.pushStack( jQuery
.multiFilter( selector
, this, true ), "not", selector
);
384 selector
= jQuery
.multiFilter( selector
, this );
386 var isArrayLike
= selector
.length
&& selector
[selector
.length
- 1] !== undefined && !selector
.nodeType
;
387 return this.filter(function() {
388 return isArrayLike
? jQuery
.inArray( this, selector
) < 0 : this != selector
;
392 add: function( selector
) {
393 return this.pushStack( jQuery
.unique( jQuery
.merge(
395 typeof selector
=== "string" ?
397 jQuery
.makeArray( selector
)
401 is: function( selector
) {
402 return !!selector
&& jQuery
.multiFilter( selector
, this ).length
> 0;
405 hasClass: function( selector
) {
406 return !!selector
&& this.is( "." + selector
);
409 val: function( value
) {
410 if ( value
=== undefined ) {
414 if( jQuery
.nodeName( elem
, 'option' ) )
415 return (elem
.attributes
.value
|| {}).specified
? elem
.value
: elem
.text
;
417 // We need to handle select boxes special
418 if ( jQuery
.nodeName( elem
, "select" ) ) {
419 var index
= elem
.selectedIndex
,
421 options
= elem
.options
,
422 one
= elem
.type
== "select-one";
424 // Nothing was selected
428 // Loop through all the selected options
429 for ( var i
= one
? index
: 0, max
= one
? index
+ 1 : options
.length
; i
< max
; i
++ ) {
430 var option
= options
[ i
];
432 if ( option
.selected
) {
433 // Get the specifc value for the option
434 value
= jQuery(option
).val();
436 // We don't need an array for one selects
440 // Multi-Selects return an array
441 values
.push( value
);
448 // Everything else, we just grab the value
449 return (elem
.value
|| "").replace(/\r/g, "");
456 if ( typeof value
=== "number" )
459 return this.each(function(){
460 if ( this.nodeType
!= 1 )
463 if ( jQuery
.isArray(value
) && /radio|checkbox/.test( this.type
) )
464 this.checked
= (jQuery
.inArray(this.value
, value
) >= 0 ||
465 jQuery
.inArray(this.name
, value
) >= 0);
467 else if ( jQuery
.nodeName( this, "select" ) ) {
468 var values
= jQuery
.makeArray(value
);
470 jQuery( "option", this ).each(function(){
471 this.selected
= (jQuery
.inArray( this.value
, values
) >= 0 ||
472 jQuery
.inArray( this.text
, values
) >= 0);
475 if ( !values
.length
)
476 this.selectedIndex
= -1;
483 html: function( value
) {
484 return value
=== undefined ?
486 this[0].innerHTML
.replace(/ jQuery
\d
+="(?:\d+|null)"/g
, "") :
488 this.empty().append( value
);
491 replaceWith: function( value
) {
492 return this.after( value
).remove();
496 return this.slice( i
, +i
+ 1 );
500 return this.pushStack( Array
.prototype.slice
.apply( this, arguments
),
501 "slice", Array
.prototype.slice
.call(arguments
).join(",") );
504 map: function( callback
) {
505 return this.pushStack( jQuery
.map(this, function(elem
, i
){
506 return callback
.call( elem
, i
, elem
);
510 andSelf: function() {
511 return this.add( this.prevObject
);
514 domManip: function( args
, table
, callback
) {
516 var fragment
= (this[0].ownerDocument
|| this[0]).createDocumentFragment(),
517 scripts
= jQuery
.clean( args
, (this[0].ownerDocument
|| this[0]), fragment
),
518 first
= fragment
.firstChild
;
521 for ( var i
= 0, l
= this.length
; i
< l
; i
++ )
522 callback
.call( root(this[i
], first
), this.length
> 1 || i
> 0 ?
523 fragment
.cloneNode(true) : fragment
);
526 jQuery
.each( scripts
, evalScript
);
531 function root( elem
, cur
) {
532 return table
&& jQuery
.nodeName(elem
, "table") && jQuery
.nodeName(cur
, "tr") ?
533 (elem
.getElementsByTagName("tbody")[0] ||
534 elem
.appendChild(elem
.ownerDocument
.createElement("tbody"))) :
540 // Give the init function the jQuery prototype for later instantiation
541 jQuery
.fn
.init
.prototype = jQuery
.fn
;
543 function evalScript( i
, elem
) {
552 jQuery
.globalEval( elem
.text
|| elem
.textContent
|| elem
.innerHTML
|| "" );
554 if ( elem
.parentNode
)
555 elem
.parentNode
.removeChild( elem
);
562 jQuery
.extend
= jQuery
.fn
.extend = function() {
563 // copy reference to target object
564 var target
= arguments
[0] || {}, i
= 1, length
= arguments
.length
, deep
= false, options
;
566 // Handle a deep copy situation
567 if ( typeof target
=== "boolean" ) {
569 target
= arguments
[1] || {};
570 // skip the boolean and the target
574 // Handle case when target is a string or something (possible in deep copy)
575 if ( typeof target
!== "object" && !jQuery
.isFunction(target
) )
578 // extend jQuery itself if only one argument is passed
584 for ( ; i
< length
; i
++ )
585 // Only deal with non-null/undefined values
586 if ( (options
= arguments
[ i
]) != null )
587 // Extend the base object
588 for ( var name
in options
) {
589 var src
= target
[ name
], copy
= options
[ name
];
591 // Prevent never-ending loop
592 if ( target
=== copy
)
595 // Recurse if we're merging object values
596 if ( deep
&& copy
&& typeof copy
=== "object" && !copy
.nodeType
)
597 target
[ name
] = jQuery
.extend( deep
,
598 // Never move original objects, clone them
599 src
|| ( copy
.length
!= null ? [ ] : { } )
602 // Don't bring in undefined values
603 else if ( copy
!== undefined )
604 target
[ name
] = copy
;
608 // Return the modified object
612 // exclude the following css properties to add px
613 var exclude
= /z-?index|font-?weight|opacity|zoom|line-?height/i,
615 defaultView
= document
.defaultView
|| {},
616 toString
= Object
.prototype.toString
;
619 noConflict: function( deep
) {
623 window
.jQuery
= _jQuery
;
628 // See test/unit/core.js for details concerning isFunction.
629 // Since version 1.3, DOM methods and functions like alert
630 // aren't supported. They return false on IE (#2968).
631 isFunction: function( obj
) {
632 return toString
.call(obj
) === "[object Function]";
635 isArray: function( obj
) {
636 return toString
.call(obj
) === "[object Array]";
639 // check if an element is in a (or is an) XML document
640 isXMLDoc: function( elem
) {
641 return elem
.nodeType
=== 9 && elem
.documentElement
.nodeName
!== "HTML" ||
642 !!elem
.ownerDocument
&& jQuery
.isXMLDoc( elem
.ownerDocument
);
645 // Evalulates a script in a global context
646 globalEval: function( data
) {
647 if ( data
&& /\S/.test(data
) ) {
648 // Inspired by code by Andrea Giammarchi
649 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
650 var head
= document
.getElementsByTagName("head")[0] || document
.documentElement
,
651 script
= document
.createElement("script");
653 script
.type
= "text/javascript";
654 if ( jQuery
.support
.scriptEval
)
655 script
.appendChild( document
.createTextNode( data
) );
659 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
660 // This arises when a base node is used (#2709).
661 head
.insertBefore( script
, head
.firstChild
);
662 head
.removeChild( script
);
666 nodeName: function( elem
, name
) {
667 return elem
.nodeName
&& elem
.nodeName
.toUpperCase() == name
.toUpperCase();
670 // args is for internal usage only
671 each: function( object
, callback
, args
) {
672 var name
, i
= 0, length
= object
.length
;
675 if ( length
=== undefined ) {
676 for ( name
in object
)
677 if ( callback
.apply( object
[ name
], args
) === false )
680 for ( ; i
< length
; )
681 if ( callback
.apply( object
[ i
++ ], args
) === false )
684 // A special, fast, case for the most common use of each
686 if ( length
=== undefined ) {
687 for ( name
in object
)
688 if ( callback
.call( object
[ name
], name
, object
[ name
] ) === false )
691 for ( var value
= object
[0];
692 i
< length
&& callback
.call( value
, i
, value
) !== false; value
= object
[++i
] ){}
698 prop: function( elem
, value
, type
, i
, name
) {
699 // Handle executable functions
700 if ( jQuery
.isFunction( value
) )
701 value
= value
.call( elem
, i
);
703 // Handle passing in a number to a CSS property
704 return typeof value
=== "number" && type
== "curCSS" && !exclude
.test( name
) ?
710 // internal only, use addClass("class")
711 add: function( elem
, classNames
) {
712 jQuery
.each((classNames
|| "").split(/\s+/), function(i
, className
){
713 if ( elem
.nodeType
== 1 && !jQuery
.className
.has( elem
.className
, className
) )
714 elem
.className
+= (elem
.className
? " " : "") + className
;
718 // internal only, use removeClass("class")
719 remove: function( elem
, classNames
) {
720 if (elem
.nodeType
== 1)
721 elem
.className
= classNames
!== undefined ?
722 jQuery
.grep(elem
.className
.split(/\s+/), function(className
){
723 return !jQuery
.className
.has( classNames
, className
);
728 // internal only, use hasClass("class")
729 has: function( elem
, className
) {
730 return elem
&& jQuery
.inArray( className
, (elem
.className
|| elem
).toString().split(/\s+/) ) > -1;
734 // A method for quickly swapping in/out CSS properties to get correct calculations
735 swap: function( elem
, options
, callback
) {
737 // Remember the old values, and insert the new ones
738 for ( var name
in options
) {
739 old
[ name
] = elem
.style
[ name
];
740 elem
.style
[ name
] = options
[ name
];
743 callback
.call( elem
);
745 // Revert the old values
746 for ( var name
in options
)
747 elem
.style
[ name
] = old
[ name
];
750 css: function( elem
, name
, force
, extra
) {
751 if ( name
== "width" || name
== "height" ) {
752 var val
, props
= { position
: "absolute", visibility
: "hidden", display
:"block" }, which
= name
== "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
755 val
= name
== "width" ? elem
.offsetWidth
: elem
.offsetHeight
;
757 if ( extra
=== "border" )
760 jQuery
.each( which
, function() {
762 val
-= parseFloat(jQuery
.curCSS( elem
, "padding" + this, true)) || 0;
763 if ( extra
=== "margin" )
764 val
+= parseFloat(jQuery
.curCSS( elem
, "margin" + this, true)) || 0;
766 val
-= parseFloat(jQuery
.curCSS( elem
, "border" + this + "Width", true)) || 0;
770 if ( elem
.offsetWidth
!== 0 )
773 jQuery
.swap( elem
, props
, getWH
);
775 return Math
.max(0, Math
.round(val
));
778 return jQuery
.curCSS( elem
, name
, force
);
781 curCSS: function( elem
, name
, force
) {
782 var ret
, style
= elem
.style
;
784 // We need to handle opacity special in IE
785 if ( name
== "opacity" && !jQuery
.support
.opacity
) {
786 ret
= jQuery
.attr( style
, "opacity" );
793 // Make sure we're using the right name for getting the float value
794 if ( name
.match( /float/i ) )
797 if ( !force
&& style
&& style
[ name
] )
800 else if ( defaultView
.getComputedStyle
) {
802 // Only "float" is needed here
803 if ( name
.match( /float/i ) )
806 name
= name
.replace( /([A-Z])/g, "-$1" ).toLowerCase();
808 var computedStyle
= defaultView
.getComputedStyle( elem
, null );
810 // Error in getting computedStyle
813 ret
= computedStyle
.getPropertyValue( name
);
815 // We should always get a number back from opacity
816 if ( name
== "opacity" && ret
== "" )
819 } else if ( elem
.currentStyle
) {
820 var camelCase
= name
.replace(/\-(\w)/g, function(all
, letter
){
821 return letter
.toUpperCase();
824 ret
= elem
.currentStyle
[ name
] || elem
.currentStyle
[ camelCase
];
826 // From the awesome hack by Dean Edwards
827 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
829 // If we're not dealing with a regular pixel number
830 // but a number that has a weird ending, we need to convert it to pixels
831 if ( !/^\d+(px)?$/i.test( ret
) && /^\d/.test( ret
) ) {
832 // Remember the original values
833 var left
= style
.left
, rsLeft
= elem
.runtimeStyle
.left
;
835 // Put in the new values to get a computed value out
836 elem
.runtimeStyle
.left
= elem
.currentStyle
.left
;
837 style
.left
= ret
|| 0;
838 ret
= style
.pixelLeft
+ "px";
840 // Revert the changed values
842 elem
.runtimeStyle
.left
= rsLeft
;
849 clean: function( elems
, context
, fragment
) {
850 context
= context
|| document
;
852 // !context.createElement fails in IE with an error but returns typeof 'object'
853 if ( typeof context
.createElement
=== "undefined" )
854 context
= context
.ownerDocument
|| context
[0] && context
[0].ownerDocument
|| document
;
856 // If a single string is passed in and it's a single tag
857 // just do a createElement and skip the rest
858 if ( !fragment
&& elems
.length
=== 1 && typeof elems
[0] === "string" ) {
859 var match
= /^<(\w+)\s*\/?>$/.exec(elems
[0]);
861 return [ context
.createElement( match
[1] ) ];
864 var ret
= [], scripts
= [], div
= context
.createElement("div");
866 jQuery
.each(elems
, function(i
, elem
){
867 if ( typeof elem
=== "number" )
873 // Convert html string into DOM nodes
874 if ( typeof elem
=== "string" ) {
875 // Fix "XHTML"-style tags in all browsers
876 elem
= elem
.replace(/(<(\w+)[^>]*?)\/>/g, function(all
, front
, tag
){
877 return tag
.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
879 front
+ "></" + tag
+ ">";
882 // Trim whitespace, otherwise indexOf won't work as expected
883 var tags
= elem
.replace(/^\s+/, "").substring(0, 10).toLowerCase();
886 // option or optgroup
887 !tags
.indexOf("<opt") &&
888 [ 1, "<select multiple='multiple'>", "</select>" ] ||
890 !tags
.indexOf("<leg") &&
891 [ 1, "<fieldset>", "</fieldset>" ] ||
893 tags
.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
894 [ 1, "<table>", "</table>" ] ||
896 !tags
.indexOf("<tr") &&
897 [ 2, "<table><tbody>", "</tbody></table>" ] ||
899 // <thead> matched above
900 (!tags
.indexOf("<td") || !tags
.indexOf("<th")) &&
901 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
903 !tags
.indexOf("<col") &&
904 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
906 // IE can't serialize <link> and <script> tags normally
907 !jQuery
.support
.htmlSerialize
&&
908 [ 1, "div<div>", "</div>" ] ||
912 // Go to html and back, then peel off extra wrappers
913 div
.innerHTML
= wrap
[1] + elem
+ wrap
[2];
915 // Move to the right depth
919 // Remove IE's autoinserted <tbody> from table fragments
920 if ( !jQuery
.support
.tbody
) {
922 // String was a <table>, *may* have spurious <tbody>
923 var hasBody
= /<tbody/i.test(elem
),
924 tbody
= !tags
.indexOf("<table") && !hasBody
?
925 div
.firstChild
&& div
.firstChild
.childNodes
:
927 // String was a bare <thead> or <tfoot>
928 wrap
[1] == "<table>" && !hasBody
?
932 for ( var j
= tbody
.length
- 1; j
>= 0 ; --j
)
933 if ( jQuery
.nodeName( tbody
[ j
], "tbody" ) && !tbody
[ j
].childNodes
.length
)
934 tbody
[ j
].parentNode
.removeChild( tbody
[ j
] );
938 // IE completely kills leading whitespace when innerHTML is used
939 if ( !jQuery
.support
.leadingWhitespace
&& /^\s/.test( elem
) )
940 div
.insertBefore( context
.createTextNode( elem
.match(/^\s*/)[0] ), div
.firstChild
);
942 elem
= jQuery
.makeArray( div
.childNodes
);
948 ret
= jQuery
.merge( ret
, elem
);
953 for ( var i
= 0; ret
[i
]; i
++ ) {
954 if ( jQuery
.nodeName( ret
[i
], "script" ) && (!ret
[i
].type
|| ret
[i
].type
.toLowerCase() === "text/javascript") ) {
955 scripts
.push( ret
[i
].parentNode
? ret
[i
].parentNode
.removeChild( ret
[i
] ) : ret
[i
] );
957 if ( ret
[i
].nodeType
=== 1 )
958 ret
.splice
.apply( ret
, [i
+ 1, 0].concat(jQuery
.makeArray(ret
[i
].getElementsByTagName("script"))) );
959 fragment
.appendChild( ret
[i
] );
969 attr: function( elem
, name
, value
) {
970 // don't set attributes on text and comment nodes
971 if (!elem
|| elem
.nodeType
== 3 || elem
.nodeType
== 8)
974 var notxml
= !jQuery
.isXMLDoc( elem
),
975 // Whether we are setting (or getting)
976 set = value
!== undefined;
978 // Try to normalize/fix the name
979 name
= notxml
&& jQuery
.props
[ name
] || name
;
981 // Only do all the following if this is a node (faster for style)
982 // IE elem.getAttribute passes even for style
983 if ( elem
.tagName
) {
985 // These attributes require special treatment
986 var special
= /href|src|style/.test( name
);
988 // Safari mis-reports the default selected property of a hidden option
989 // Accessing the parent's selectedIndex property fixes it
990 if ( name
== "selected" && elem
.parentNode
)
991 elem
.parentNode
.selectedIndex
;
993 // If applicable, access the attribute via the DOM 0 way
994 if ( name
in elem
&& notxml
&& !special
) {
996 // We can't allow the type property to be changed (since it causes problems in IE)
997 if ( name
== "type" && jQuery
.nodeName( elem
, "input" ) && elem
.parentNode
)
998 throw "type property can't be changed";
1000 elem
[ name
] = value
;
1003 // browsers index elements by id/name on forms, give priority to attributes.
1004 if( jQuery
.nodeName( elem
, "form" ) && elem
.getAttributeNode(name
) )
1005 return elem
.getAttributeNode( name
).nodeValue
;
1007 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1008 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1009 if ( name
== "tabIndex" ) {
1010 var attributeNode
= elem
.getAttributeNode( "tabIndex" );
1011 return attributeNode
&& attributeNode
.specified
1012 ? attributeNode
.value
1013 : elem
.nodeName
.match(/(button|input|object|select|textarea)/i)
1015 : elem
.nodeName
.match(/^(a|area)$/i) && elem
.href
1020 return elem
[ name
];
1023 if ( !jQuery
.support
.style
&& notxml
&& name
== "style" )
1024 return jQuery
.attr( elem
.style
, "cssText", value
);
1027 // convert the value to a string (all browsers do this but IE) see #1070
1028 elem
.setAttribute( name
, "" + value
);
1030 var attr
= !jQuery
.support
.hrefNormalized
&& notxml
&& special
1031 // Some attributes require a special call on IE
1032 ? elem
.getAttribute( name
, 2 )
1033 : elem
.getAttribute( name
);
1035 // Non-existent attributes return null, we normalize to undefined
1036 return attr
=== null ? undefined : attr
;
1039 // elem is actually elem.style ... set the style
1041 // IE uses filters for opacity
1042 if ( !jQuery
.support
.opacity
&& name
== "opacity" ) {
1044 // IE has trouble with opacity if it does not have layout
1045 // Force it by setting the zoom level
1048 // Set the alpha filter to set the opacity
1049 elem
.filter
= (elem
.filter
|| "").replace( /alpha\([^)]*\)/, "" ) +
1050 (parseInt( value
) + '' == "NaN" ? "" : "alpha(opacity=" + value
* 100 + ")");
1053 return elem
.filter
&& elem
.filter
.indexOf("opacity=") >= 0 ?
1054 (parseFloat( elem
.filter
.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1058 name
= name
.replace(/-([a-z])/ig, function(all
, letter
){
1059 return letter
.toUpperCase();
1062 if ( set && value
!= 'NaNpx' && value
!= 'nullpx' ) // Patched by Trevor, see http://is.gd/5NXiD
1063 elem
[ name
] = value
;
1065 return elem
[ name
];
1068 trim: function( text
) {
1069 return (text
|| "").replace( /^\s+|\s+$/g, "" );
1072 makeArray: function( array
) {
1075 if( array
!= null ){
1076 var i
= array
.length
;
1077 // The window, strings (and functions) also have 'length'
1078 if( i
== null || typeof array
=== "string" || jQuery
.isFunction(array
) || array
.setInterval
)
1082 ret
[--i
] = array
[i
];
1088 inArray: function( elem
, array
) {
1089 for ( var i
= 0, length
= array
.length
; i
< length
; i
++ )
1090 // Use === because on IE, window == document
1091 if ( array
[ i
] === elem
)
1097 merge: function( first
, second
) {
1098 // We have to loop this way because IE & Opera overwrite the length
1099 // expando of getElementsByTagName
1100 var i
= 0, elem
, pos
= first
.length
;
1101 // Also, we need to make sure that the correct elements are being returned
1102 // (IE returns comment nodes in a '*' query)
1103 if ( !jQuery
.support
.getAll
) {
1104 while ( (elem
= second
[ i
++ ]) != null )
1105 if ( elem
.nodeType
!= 8 )
1106 first
[ pos
++ ] = elem
;
1109 while ( (elem
= second
[ i
++ ]) != null )
1110 first
[ pos
++ ] = elem
;
1115 unique: function( array
) {
1116 var ret
= [], done
= {};
1120 for ( var i
= 0, length
= array
.length
; i
< length
; i
++ ) {
1121 var id
= jQuery
.data( array
[ i
] );
1123 if ( !done
[ id
] ) {
1125 ret
.push( array
[ i
] );
1136 grep: function( elems
, callback
, inv
) {
1139 // Go through the array, only saving the items
1140 // that pass the validator function
1141 for ( var i
= 0, length
= elems
.length
; i
< length
; i
++ )
1142 if ( !inv
!= !callback( elems
[ i
], i
) )
1143 ret
.push( elems
[ i
] );
1148 map: function( elems
, callback
) {
1151 // Go through the array, translating each of the items to their
1152 // new value (or values).
1153 for ( var i
= 0, length
= elems
.length
; i
< length
; i
++ ) {
1154 var value
= callback( elems
[ i
], i
);
1156 if ( value
!= null )
1157 ret
[ ret
.length
] = value
;
1160 return ret
.concat
.apply( [], ret
);
1164 // Use of jQuery.browser is deprecated.
1165 // It's included for backwards compatibility and plugins,
1166 // although they should work to migrate away.
1168 var userAgent
= navigator
.userAgent
.toLowerCase();
1170 // Figure out what browser is being used
1172 version
: (userAgent
.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1173 safari
: /webkit/.test( userAgent
),
1174 opera
: /opera/.test( userAgent
),
1175 msie
: /msie/.test( userAgent
) && !/opera/.test( userAgent
),
1176 mozilla
: /mozilla/.test( userAgent
) && !/(compatible|webkit)/.test( userAgent
)
1180 parent: function(elem
){return elem
.parentNode
;},
1181 parents: function(elem
){return jQuery
.dir(elem
,"parentNode");},
1182 next: function(elem
){return jQuery
.nth(elem
,2,"nextSibling");},
1183 prev: function(elem
){return jQuery
.nth(elem
,2,"previousSibling");},
1184 nextAll: function(elem
){return jQuery
.dir(elem
,"nextSibling");},
1185 prevAll: function(elem
){return jQuery
.dir(elem
,"previousSibling");},
1186 siblings: function(elem
){return jQuery
.sibling(elem
.parentNode
.firstChild
,elem
);},
1187 children: function(elem
){return jQuery
.sibling(elem
.firstChild
);},
1188 contents: function(elem
){return jQuery
.nodeName(elem
,"iframe")?elem
.contentDocument
||elem
.contentWindow
.document
:jQuery
.makeArray(elem
.childNodes
);}
1189 }, function(name
, fn
){
1190 jQuery
.fn
[ name
] = function( selector
) {
1191 var ret
= jQuery
.map( this, fn
);
1193 if ( selector
&& typeof selector
== "string" )
1194 ret
= jQuery
.multiFilter( selector
, ret
);
1196 return this.pushStack( jQuery
.unique( ret
), name
, selector
);
1202 prependTo
: "prepend",
1203 insertBefore
: "before",
1204 insertAfter
: "after",
1205 replaceAll
: "replaceWith"
1206 }, function(name
, original
){
1207 jQuery
.fn
[ name
] = function( selector
) {
1208 var ret
= [], insert
= jQuery( selector
);
1210 for ( var i
= 0, l
= insert
.length
; i
< l
; i
++ ) {
1211 var elems
= (i
> 0 ? this.clone(true) : this).get();
1212 jQuery
.fn
[ original
].apply( jQuery(insert
[i
]), elems
);
1213 ret
= ret
.concat( elems
);
1216 return this.pushStack( ret
, name
, selector
);
1221 removeAttr: function( name
) {
1222 jQuery
.attr( this, name
, "" );
1223 if (this.nodeType
== 1)
1224 this.removeAttribute( name
);
1227 addClass: function( classNames
) {
1228 jQuery
.className
.add( this, classNames
);
1231 removeClass: function( classNames
) {
1232 jQuery
.className
.remove( this, classNames
);
1235 toggleClass: function( classNames
, state
) {
1236 if( typeof state
!== "boolean" )
1237 state
= !jQuery
.className
.has( this, classNames
);
1238 jQuery
.className
[ state
? "add" : "remove" ]( this, classNames
);
1241 remove: function( selector
) {
1242 if ( !selector
|| jQuery
.filter( selector
, [ this ] ).length
) {
1243 // Prevent memory leaks
1244 jQuery( "*", this ).add([this]).each(function(){
1245 jQuery
.event
.remove(this);
1246 jQuery
.removeData(this);
1248 if (this.parentNode
)
1249 this.parentNode
.removeChild( this );
1254 // Remove element nodes and prevent memory leaks
1255 jQuery(this).children().remove();
1257 // Remove any remaining nodes
1258 while ( this.firstChild
)
1259 this.removeChild( this.firstChild
);
1261 }, function(name
, fn
){
1262 jQuery
.fn
[ name
] = function(){
1263 return this.each( fn
, arguments
);
1267 // Helper function used by the dimensions and offset modules
1268 function num(elem
, prop
) {
1269 return elem
[0] && parseInt( jQuery
.curCSS(elem
[0], prop
, true), 10 ) || 0;
1271 var expando
= "jQuery" + now(), uuid
= 0, windowData
= {};
1276 data: function( elem
, name
, data
) {
1277 elem
= elem
== window
?
1281 var id
= elem
[ expando
];
1283 // Compute a unique ID for the element
1285 id
= elem
[ expando
] = ++uuid
;
1287 // Only generate the data cache if we're
1288 // trying to access or manipulate it
1289 if ( name
&& !jQuery
.cache
[ id
] )
1290 jQuery
.cache
[ id
] = {};
1292 // Prevent overriding the named cache with undefined values
1293 if ( data
!== undefined )
1294 jQuery
.cache
[ id
][ name
] = data
;
1296 // Return the named cache data, or the ID for the element
1298 jQuery
.cache
[ id
][ name
] :
1302 removeData: function( elem
, name
) {
1303 elem
= elem
== window
?
1307 var id
= elem
[ expando
];
1309 // If we want to remove a specific section of the element's data
1311 if ( jQuery
.cache
[ id
] ) {
1312 // Remove the section of cache data
1313 delete jQuery
.cache
[ id
][ name
];
1315 // If we've removed all the data, remove the element's cache
1318 for ( name
in jQuery
.cache
[ id
] )
1322 jQuery
.removeData( elem
);
1325 // Otherwise, we want to remove all of the element's data
1327 // Clean up the element expando
1329 delete elem
[ expando
];
1331 // IE has trouble directly removing the expando
1332 // but it's ok with using removeAttribute
1333 if ( elem
.removeAttribute
)
1334 elem
.removeAttribute( expando
);
1337 // Completely remove the data cache
1338 delete jQuery
.cache
[ id
];
1341 queue: function( elem
, type
, data
) {
1344 type
= (type
|| "fx") + "queue";
1346 var q
= jQuery
.data( elem
, type
);
1348 if ( !q
|| jQuery
.isArray(data
) )
1349 q
= jQuery
.data( elem
, type
, jQuery
.makeArray(data
) );
1357 dequeue: function( elem
, type
){
1358 var queue
= jQuery
.queue( elem
, type
),
1361 if( !type
|| type
=== "fx" )
1364 if( fn
!== undefined )
1370 data: function( key
, value
){
1371 var parts
= key
.split(".");
1372 parts
[1] = parts
[1] ? "." + parts
[1] : "";
1374 if ( value
=== undefined ) {
1375 var data
= this.triggerHandler("getData" + parts
[1] + "!", [parts
[0]]);
1377 if ( data
=== undefined && this.length
)
1378 data
= jQuery
.data( this[0], key
);
1380 return data
=== undefined && parts
[1] ?
1381 this.data( parts
[0] ) :
1384 return this.trigger("setData" + parts
[1] + "!", [parts
[0], value
]).each(function(){
1385 jQuery
.data( this, key
, value
);
1389 removeData: function( key
){
1390 return this.each(function(){
1391 jQuery
.removeData( this, key
);
1394 queue: function(type
, data
){
1395 if ( typeof type
!== "string" ) {
1400 if ( data
=== undefined )
1401 return jQuery
.queue( this[0], type
);
1403 return this.each(function(){
1404 var queue
= jQuery
.queue( this, type
, data
);
1406 if( type
== "fx" && queue
.length
== 1 )
1407 queue
[0].call(this);
1410 dequeue: function(type
){
1411 return this.each(function(){
1412 jQuery
.dequeue( this, type
);
1416 * Sizzle CSS Selector Engine - v0.9.3
1417 * Copyright 2009, The Dojo Foundation
1418 * Released under the MIT, BSD, and GPL Licenses.
1419 * More information: http://sizzlejs.com/
1423 var chunker
= /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1425 toString
= Object
.prototype.toString
;
1427 var Sizzle = function(selector
, context
, results
, seed
) {
1428 results
= results
|| [];
1429 context
= context
|| document
;
1431 if ( context
.nodeType
!== 1 && context
.nodeType
!== 9 )
1434 if ( !selector
|| typeof selector
!== "string" ) {
1438 var parts
= [], m
, set, checkSet
, check
, mode
, extra
, prune
= true;
1440 // Reset the position of the chunker regexp (start from head)
1441 chunker
.lastIndex
= 0;
1443 while ( (m
= chunker
.exec(selector
)) !== null ) {
1447 extra
= RegExp
.rightContext
;
1452 if ( parts
.length
> 1 && origPOS
.exec( selector
) ) {
1453 if ( parts
.length
=== 2 && Expr
.relative
[ parts
[0] ] ) {
1454 set = posProcess( parts
[0] + parts
[1], context
);
1456 set = Expr
.relative
[ parts
[0] ] ?
1458 Sizzle( parts
.shift(), context
);
1460 while ( parts
.length
) {
1461 selector
= parts
.shift();
1463 if ( Expr
.relative
[ selector
] )
1464 selector
+= parts
.shift();
1466 set = posProcess( selector
, set );
1471 { expr
: parts
.pop(), set: makeArray(seed
) } :
1472 Sizzle
.find( parts
.pop(), parts
.length
=== 1 && context
.parentNode
? context
.parentNode
: context
, isXML(context
) );
1473 set = Sizzle
.filter( ret
.expr
, ret
.set );
1475 if ( parts
.length
> 0 ) {
1476 checkSet
= makeArray(set);
1481 while ( parts
.length
) {
1482 var cur
= parts
.pop(), pop
= cur
;
1484 if ( !Expr
.relative
[ cur
] ) {
1490 if ( pop
== null ) {
1494 Expr
.relative
[ cur
]( checkSet
, pop
, isXML(context
) );
1503 throw "Syntax error, unrecognized expression: " + (cur
|| selector
);
1506 if ( toString
.call(checkSet
) === "[object Array]" ) {
1508 results
.push
.apply( results
, checkSet
);
1509 } else if ( context
.nodeType
=== 1 ) {
1510 for ( var i
= 0; checkSet
[i
] != null; i
++ ) {
1511 if ( checkSet
[i
] && (checkSet
[i
] === true || checkSet
[i
].nodeType
=== 1 && contains(context
, checkSet
[i
])) ) {
1512 results
.push( set[i
] );
1516 for ( var i
= 0; checkSet
[i
] != null; i
++ ) {
1517 if ( checkSet
[i
] && checkSet
[i
].nodeType
=== 1 ) {
1518 results
.push( set[i
] );
1523 makeArray( checkSet
, results
);
1527 Sizzle( extra
, context
, results
, seed
);
1530 hasDuplicate
= false;
1531 results
.sort(sortOrder
);
1533 if ( hasDuplicate
) {
1534 for ( var i
= 1; i
< results
.length
; i
++ ) {
1535 if ( results
[i
] === results
[i
-1] ) {
1536 results
.splice(i
--, 1);
1546 Sizzle
.matches = function(expr
, set){
1547 return Sizzle(expr
, null, null, set);
1550 Sizzle
.find = function(expr
, context
, isXML
){
1557 for ( var i
= 0, l
= Expr
.order
.length
; i
< l
; i
++ ) {
1558 var type
= Expr
.order
[i
], match
;
1560 if ( (match
= Expr
.match
[ type
].exec( expr
)) ) {
1561 var left
= RegExp
.leftContext
;
1563 if ( left
.substr( left
.length
- 1 ) !== "\\" ) {
1564 match
[1] = (match
[1] || "").replace(/\\/g
, "");
1565 set = Expr
.find
[ type
]( match
, context
, isXML
);
1566 if ( set != null ) {
1567 expr
= expr
.replace( Expr
.match
[ type
], "" );
1575 set = context
.getElementsByTagName("*");
1578 return {set: set, expr
: expr
};
1581 Sizzle
.filter = function(expr
, set, inplace
, not
){
1582 var old
= expr
, result
= [], curLoop
= set, match
, anyFound
,
1583 isXMLFilter
= set && set[0] && isXML(set[0]);
1585 while ( expr
&& set.length
) {
1586 for ( var type
in Expr
.filter
) {
1587 if ( (match
= Expr
.match
[ type
].exec( expr
)) != null ) {
1588 var filter
= Expr
.filter
[ type
], found
, item
;
1591 if ( curLoop
== result
) {
1595 if ( Expr
.preFilter
[ type
] ) {
1596 match
= Expr
.preFilter
[ type
]( match
, curLoop
, inplace
, result
, not
, isXMLFilter
);
1599 anyFound
= found
= true;
1600 } else if ( match
=== true ) {
1606 for ( var i
= 0; (item
= curLoop
[i
]) != null; i
++ ) {
1608 found
= filter( item
, match
, i
, curLoop
);
1609 var pass
= not
^ !!found
;
1611 if ( inplace
&& found
!= null ) {
1617 } else if ( pass
) {
1618 result
.push( item
);
1625 if ( found
!== undefined ) {
1630 expr
= expr
.replace( Expr
.match
[ type
], "" );
1641 // Improper expression
1642 if ( expr
== old
) {
1643 if ( anyFound
== null ) {
1644 throw "Syntax error, unrecognized expression: " + expr
;
1656 var Expr
= Sizzle
.selectors
= {
1657 order
: [ "ID", "NAME", "TAG" ],
1659 ID
: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1660 CLASS
: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1661 NAME
: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1662 ATTR
: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1663 TAG
: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1664 CHILD
: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1665 POS
: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1666 PSEUDO
: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1669 "class": "className",
1673 href: function(elem
){
1674 return elem
.getAttribute("href");
1678 "+": function(checkSet
, part
, isXML
){
1679 var isPartStr
= typeof part
=== "string",
1680 isTag
= isPartStr
&& !/\W/.test(part
),
1681 isPartStrNotTag
= isPartStr
&& !isTag
;
1683 if ( isTag
&& !isXML
) {
1684 part
= part
.toUpperCase();
1687 for ( var i
= 0, l
= checkSet
.length
, elem
; i
< l
; i
++ ) {
1688 if ( (elem
= checkSet
[i
]) ) {
1689 while ( (elem
= elem
.previousSibling
) && elem
.nodeType
!== 1 ) {}
1691 checkSet
[i
] = isPartStrNotTag
|| elem
&& elem
.nodeName
=== part
?
1697 if ( isPartStrNotTag
) {
1698 Sizzle
.filter( part
, checkSet
, true );
1701 ">": function(checkSet
, part
, isXML
){
1702 var isPartStr
= typeof part
=== "string";
1704 if ( isPartStr
&& !/\W/.test(part
) ) {
1705 part
= isXML
? part
: part
.toUpperCase();
1707 for ( var i
= 0, l
= checkSet
.length
; i
< l
; i
++ ) {
1708 var elem
= checkSet
[i
];
1710 var parent
= elem
.parentNode
;
1711 checkSet
[i
] = parent
.nodeName
=== part
? parent
: false;
1715 for ( var i
= 0, l
= checkSet
.length
; i
< l
; i
++ ) {
1716 var elem
= checkSet
[i
];
1718 checkSet
[i
] = isPartStr
?
1720 elem
.parentNode
=== part
;
1725 Sizzle
.filter( part
, checkSet
, true );
1729 "": function(checkSet
, part
, isXML
){
1730 var doneName
= done
++, checkFn
= dirCheck
;
1732 if ( !part
.match(/\W/) ) {
1733 var nodeCheck
= part
= isXML
? part
: part
.toUpperCase();
1734 checkFn
= dirNodeCheck
;
1737 checkFn("parentNode", part
, doneName
, checkSet
, nodeCheck
, isXML
);
1739 "~": function(checkSet
, part
, isXML
){
1740 var doneName
= done
++, checkFn
= dirCheck
;
1742 if ( typeof part
=== "string" && !part
.match(/\W/) ) {
1743 var nodeCheck
= part
= isXML
? part
: part
.toUpperCase();
1744 checkFn
= dirNodeCheck
;
1747 checkFn("previousSibling", part
, doneName
, checkSet
, nodeCheck
, isXML
);
1751 ID: function(match
, context
, isXML
){
1752 if ( typeof context
.getElementById
!== "undefined" && !isXML
) {
1753 var m
= context
.getElementById(match
[1]);
1754 return m
? [m
] : [];
1757 NAME: function(match
, context
, isXML
){
1758 if ( typeof context
.getElementsByName
!== "undefined" ) {
1759 var ret
= [], results
= context
.getElementsByName(match
[1]);
1761 for ( var i
= 0, l
= results
.length
; i
< l
; i
++ ) {
1762 if ( results
[i
].getAttribute("name") === match
[1] ) {
1763 ret
.push( results
[i
] );
1767 return ret
.length
=== 0 ? null : ret
;
1770 TAG: function(match
, context
){
1771 return context
.getElementsByTagName(match
[1]);
1775 CLASS: function(match
, curLoop
, inplace
, result
, not
, isXML
){
1776 match
= " " + match
[1].replace(/\\/g
, "") + " ";
1782 for ( var i
= 0, elem
; (elem
= curLoop
[i
]) != null; i
++ ) {
1784 if ( not
^ (elem
.className
&& (" " + elem
.className
+ " ").indexOf(match
) >= 0) ) {
1786 result
.push( elem
);
1787 } else if ( inplace
) {
1795 ID: function(match
){
1796 return match
[1].replace(/\\/g
, "");
1798 TAG: function(match
, curLoop
){
1799 for ( var i
= 0; curLoop
[i
] === false; i
++ ){}
1800 return curLoop
[i
] && isXML(curLoop
[i
]) ? match
[1] : match
[1].toUpperCase();
1802 CHILD: function(match
){
1803 if ( match
[1] == "nth" ) {
1804 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1805 var test
= /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1806 match
[2] == "even" && "2n" || match
[2] == "odd" && "2n+1" ||
1807 !/\D/.test( match
[2] ) && "0n+" + match
[2] || match
[2]);
1809 // calculate the numbers (first)n+(last) including if they are negative
1810 match
[2] = (test
[1] + (test
[2] || 1)) - 0;
1811 match
[3] = test
[3] - 0;
1814 // TODO: Move to normal caching system
1819 ATTR: function(match
, curLoop
, inplace
, result
, not
, isXML
){
1820 var name
= match
[1].replace(/\\/g
, "");
1822 if ( !isXML
&& Expr
.attrMap
[name
] ) {
1823 match
[1] = Expr
.attrMap
[name
];
1826 if ( match
[2] === "~=" ) {
1827 match
[4] = " " + match
[4] + " ";
1832 PSEUDO: function(match
, curLoop
, inplace
, result
, not
){
1833 if ( match
[1] === "not" ) {
1834 // If we're dealing with a complex expression, or a simple one
1835 if ( match
[3].match(chunker
).length
> 1 || /^\w/.test(match
[3]) ) {
1836 match
[3] = Sizzle(match
[3], null, null, curLoop
);
1838 var ret
= Sizzle
.filter(match
[3], curLoop
, inplace
, true ^ not
);
1840 result
.push
.apply( result
, ret
);
1844 } else if ( Expr
.match
.POS
.test( match
[0] ) || Expr
.match
.CHILD
.test( match
[0] ) ) {
1850 POS: function(match
){
1851 match
.unshift( true );
1856 enabled: function(elem
){
1857 return elem
.disabled
=== false && elem
.type
!== "hidden";
1859 disabled: function(elem
){
1860 return elem
.disabled
=== true;
1862 checked: function(elem
){
1863 return elem
.checked
=== true;
1865 selected: function(elem
){
1866 // Accessing this property makes selected-by-default
1867 // options in Safari work properly
1868 elem
.parentNode
.selectedIndex
;
1869 return elem
.selected
=== true;
1871 parent: function(elem
){
1872 return !!elem
.firstChild
;
1874 empty: function(elem
){
1875 return !elem
.firstChild
;
1877 has: function(elem
, i
, match
){
1878 return !!Sizzle( match
[3], elem
).length
;
1880 header: function(elem
){
1881 return /h\d/i.test( elem
.nodeName
);
1883 text: function(elem
){
1884 return "text" === elem
.type
;
1886 radio: function(elem
){
1887 return "radio" === elem
.type
;
1889 checkbox: function(elem
){
1890 return "checkbox" === elem
.type
;
1892 file: function(elem
){
1893 return "file" === elem
.type
;
1895 password: function(elem
){
1896 return "password" === elem
.type
;
1898 submit: function(elem
){
1899 return "submit" === elem
.type
;
1901 image: function(elem
){
1902 return "image" === elem
.type
;
1904 reset: function(elem
){
1905 return "reset" === elem
.type
;
1907 button: function(elem
){
1908 return "button" === elem
.type
|| elem
.nodeName
.toUpperCase() === "BUTTON";
1910 input: function(elem
){
1911 return /input|select|textarea|button/i.test(elem
.nodeName
);
1915 first: function(elem
, i
){
1918 last: function(elem
, i
, match
, array
){
1919 return i
=== array
.length
- 1;
1921 even: function(elem
, i
){
1924 odd: function(elem
, i
){
1927 lt: function(elem
, i
, match
){
1928 return i
< match
[3] - 0;
1930 gt: function(elem
, i
, match
){
1931 return i
> match
[3] - 0;
1933 nth: function(elem
, i
, match
){
1934 return match
[3] - 0 == i
;
1936 eq: function(elem
, i
, match
){
1937 return match
[3] - 0 == i
;
1941 PSEUDO: function(elem
, match
, i
, array
){
1942 var name
= match
[1], filter
= Expr
.filters
[ name
];
1945 return filter( elem
, i
, match
, array
);
1946 } else if ( name
=== "contains" ) {
1947 return (elem
.textContent
|| elem
.innerText
|| "").indexOf(match
[3]) >= 0;
1948 } else if ( name
=== "not" ) {
1951 for ( var i
= 0, l
= not
.length
; i
< l
; i
++ ) {
1952 if ( not
[i
] === elem
) {
1960 CHILD: function(elem
, match
){
1961 var type
= match
[1], node
= elem
;
1965 while (node
= node
.previousSibling
) {
1966 if ( node
.nodeType
=== 1 ) return false;
1968 if ( type
== 'first') return true;
1971 while (node
= node
.nextSibling
) {
1972 if ( node
.nodeType
=== 1 ) return false;
1976 var first
= match
[2], last
= match
[3];
1978 if ( first
== 1 && last
== 0 ) {
1982 var doneName
= match
[0],
1983 parent
= elem
.parentNode
;
1985 if ( parent
&& (parent
.sizcache
!== doneName
|| !elem
.nodeIndex
) ) {
1987 for ( node
= parent
.firstChild
; node
; node
= node
.nextSibling
) {
1988 if ( node
.nodeType
=== 1 ) {
1989 node
.nodeIndex
= ++count
;
1992 parent
.sizcache
= doneName
;
1995 var diff
= elem
.nodeIndex
- last
;
1999 return ( diff
% first
== 0 && diff
/ first
>= 0 );
2003 ID: function(elem
, match
){
2004 return elem
.nodeType
=== 1 && elem
.getAttribute("id") === match
;
2006 TAG: function(elem
, match
){
2007 return (match
=== "*" && elem
.nodeType
=== 1) || elem
.nodeName
=== match
;
2009 CLASS: function(elem
, match
){
2010 return (" " + (elem
.className
|| elem
.getAttribute("class")) + " ")
2011 .indexOf( match
) > -1;
2013 ATTR: function(elem
, match
){
2014 var name
= match
[1],
2015 result
= Expr
.attrHandle
[ name
] ?
2016 Expr
.attrHandle
[ name
]( elem
) :
2017 elem
[ name
] != null ?
2019 elem
.getAttribute( name
),
2020 value
= result
+ "",
2024 return result
== null ?
2029 value
.indexOf(check
) >= 0 :
2031 (" " + value
+ " ").indexOf(check
) >= 0 :
2033 value
&& result
!== false :
2037 value
.indexOf(check
) === 0 :
2039 value
.substr(value
.length
- check
.length
) === check
:
2041 value
=== check
|| value
.substr(0, check
.length
+ 1) === check
+ "-" :
2044 POS: function(elem
, match
, i
, array
){
2045 var name
= match
[2], filter
= Expr
.setFilters
[ name
];
2048 return filter( elem
, i
, match
, array
);
2054 var origPOS
= Expr
.match
.POS
;
2056 for ( var type
in Expr
.match
) {
2057 Expr
.match
[ type
] = RegExp( Expr
.match
[ type
].source
+ /(?![^\[]*\])(?![^\(]*\))/.source
);
2060 var makeArray = function(array
, results
) {
2061 array
= Array
.prototype.slice
.call( array
);
2064 results
.push
.apply( results
, array
);
2071 // Perform a simple check to determine if the browser is capable of
2072 // converting a NodeList to an array using builtin methods.
2074 Array
.prototype.slice
.call( document
.documentElement
.childNodes
);
2076 // Provide a fallback method if it does not work
2078 makeArray = function(array
, results
) {
2079 var ret
= results
|| [];
2081 if ( toString
.call(array
) === "[object Array]" ) {
2082 Array
.prototype.push
.apply( ret
, array
);
2084 if ( typeof array
.length
=== "number" ) {
2085 for ( var i
= 0, l
= array
.length
; i
< l
; i
++ ) {
2086 ret
.push( array
[i
] );
2089 for ( var i
= 0; array
[i
]; i
++ ) {
2090 ret
.push( array
[i
] );
2101 if ( document
.documentElement
.compareDocumentPosition
) {
2102 sortOrder = function( a
, b
) {
2103 var ret
= a
.compareDocumentPosition(b
) & 4 ? -1 : a
=== b
? 0 : 1;
2105 hasDuplicate
= true;
2109 } else if ( "sourceIndex" in document
.documentElement
) {
2110 sortOrder = function( a
, b
) {
2111 var ret
= a
.sourceIndex
- b
.sourceIndex
;
2113 hasDuplicate
= true;
2117 } else if ( document
.createRange
) {
2118 sortOrder = function( a
, b
) {
2119 var aRange
= a
.ownerDocument
.createRange(), bRange
= b
.ownerDocument
.createRange();
2120 aRange
.selectNode(a
);
2121 aRange
.collapse(true);
2122 bRange
.selectNode(b
);
2123 bRange
.collapse(true);
2124 var ret
= aRange
.compareBoundaryPoints(Range
.START_TO_END
, bRange
);
2126 hasDuplicate
= true;
2132 // Check to see if the browser returns elements by name when
2133 // querying by getElementById (and provide a workaround)
2135 // We're going to inject a fake input element with a specified name
2136 var form
= document
.createElement("form"),
2137 id
= "script" + (new Date
).getTime();
2138 form
.innerHTML
= "<input name='" + id
+ "'/>";
2140 // Inject it into the root element, check its status, and remove it quickly
2141 var root
= document
.documentElement
;
2142 root
.insertBefore( form
, root
.firstChild
);
2144 // The workaround has to do additional checks after a getElementById
2145 // Which slows things down for other browsers (hence the branching)
2146 if ( !!document
.getElementById( id
) ) {
2147 Expr
.find
.ID = function(match
, context
, isXML
){
2148 if ( typeof context
.getElementById
!== "undefined" && !isXML
) {
2149 var m
= context
.getElementById(match
[1]);
2150 return m
? m
.id
=== match
[1] || typeof m
.getAttributeNode
!== "undefined" && m
.getAttributeNode("id").nodeValue
=== match
[1] ? [m
] : undefined : [];
2154 Expr
.filter
.ID = function(elem
, match
){
2155 var node
= typeof elem
.getAttributeNode
!== "undefined" && elem
.getAttributeNode("id");
2156 return elem
.nodeType
=== 1 && node
&& node
.nodeValue
=== match
;
2160 root
.removeChild( form
);
2164 // Check to see if the browser returns only elements
2165 // when doing getElementsByTagName("*")
2167 // Create a fake element
2168 var div
= document
.createElement("div");
2169 div
.appendChild( document
.createComment("") );
2171 // Make sure no comments are found
2172 if ( div
.getElementsByTagName("*").length
> 0 ) {
2173 Expr
.find
.TAG = function(match
, context
){
2174 var results
= context
.getElementsByTagName(match
[1]);
2176 // Filter out possible comments
2177 if ( match
[1] === "*" ) {
2180 for ( var i
= 0; results
[i
]; i
++ ) {
2181 if ( results
[i
].nodeType
=== 1 ) {
2182 tmp
.push( results
[i
] );
2193 // Check to see if an attribute returns normalized href attributes
2194 div
.innerHTML
= "<a href='#'></a>";
2195 if ( div
.firstChild
&& typeof div
.firstChild
.getAttribute
!== "undefined" &&
2196 div
.firstChild
.getAttribute("href") !== "#" ) {
2197 Expr
.attrHandle
.href = function(elem
){
2198 return elem
.getAttribute("href", 2);
2203 if ( document
.querySelectorAll
) (function(){
2204 var oldSizzle
= Sizzle
, div
= document
.createElement("div");
2205 div
.innerHTML
= "<p class='TEST'></p>";
2207 // Safari can't handle uppercase or unicode characters when
2209 if ( div
.querySelectorAll
&& div
.querySelectorAll(".TEST").length
=== 0 ) {
2213 Sizzle = function(query
, context
, extra
, seed
){
2214 context
= context
|| document
;
2216 // Only use querySelectorAll on non-XML documents
2217 // (ID selectors don't work in non-HTML documents)
2218 if ( !seed
&& context
.nodeType
=== 9 && !isXML(context
) ) {
2220 return makeArray( context
.querySelectorAll(query
), extra
);
2224 return oldSizzle(query
, context
, extra
, seed
);
2227 Sizzle
.find
= oldSizzle
.find
;
2228 Sizzle
.filter
= oldSizzle
.filter
;
2229 Sizzle
.selectors
= oldSizzle
.selectors
;
2230 Sizzle
.matches
= oldSizzle
.matches
;
2233 if ( document
.getElementsByClassName
&& document
.documentElement
.getElementsByClassName
) (function(){
2234 var div
= document
.createElement("div");
2235 div
.innerHTML
= "<div class='test e'></div><div class='test'></div>";
2237 // Opera can't find a second classname (in 9.6)
2238 if ( div
.getElementsByClassName("e").length
=== 0 )
2241 // Safari caches class attributes, doesn't catch changes (in 3.2)
2242 div
.lastChild
.className
= "e";
2244 if ( div
.getElementsByClassName("e").length
=== 1 )
2247 Expr
.order
.splice(1, 0, "CLASS");
2248 Expr
.find
.CLASS = function(match
, context
, isXML
) {
2249 if ( typeof context
.getElementsByClassName
!== "undefined" && !isXML
) {
2250 return context
.getElementsByClassName(match
[1]);
2255 function dirNodeCheck( dir
, cur
, doneName
, checkSet
, nodeCheck
, isXML
) {
2256 var sibDir
= dir
== "previousSibling" && !isXML
;
2257 for ( var i
= 0, l
= checkSet
.length
; i
< l
; i
++ ) {
2258 var elem
= checkSet
[i
];
2260 if ( sibDir
&& elem
.nodeType
=== 1 ){
2261 elem
.sizcache
= doneName
;
2268 if ( elem
.sizcache
=== doneName
) {
2269 match
= checkSet
[elem
.sizset
];
2273 if ( elem
.nodeType
=== 1 && !isXML
){
2274 elem
.sizcache
= doneName
;
2278 if ( elem
.nodeName
=== cur
) {
2286 checkSet
[i
] = match
;
2291 function dirCheck( dir
, cur
, doneName
, checkSet
, nodeCheck
, isXML
) {
2292 var sibDir
= dir
== "previousSibling" && !isXML
;
2293 for ( var i
= 0, l
= checkSet
.length
; i
< l
; i
++ ) {
2294 var elem
= checkSet
[i
];
2296 if ( sibDir
&& elem
.nodeType
=== 1 ) {
2297 elem
.sizcache
= doneName
;
2304 if ( elem
.sizcache
=== doneName
) {
2305 match
= checkSet
[elem
.sizset
];
2309 if ( elem
.nodeType
=== 1 ) {
2311 elem
.sizcache
= doneName
;
2314 if ( typeof cur
!== "string" ) {
2315 if ( elem
=== cur
) {
2320 } else if ( Sizzle
.filter( cur
, [elem
] ).length
> 0 ) {
2329 checkSet
[i
] = match
;
2334 var contains
= document
.compareDocumentPosition
? function(a
, b
){
2335 return a
.compareDocumentPosition(b
) & 16;
2337 return a
!== b
&& (a
.contains
? a
.contains(b
) : true);
2340 var isXML = function(elem
){
2341 return elem
.nodeType
=== 9 && elem
.documentElement
.nodeName
!== "HTML" ||
2342 !!elem
.ownerDocument
&& isXML( elem
.ownerDocument
);
2345 var posProcess = function(selector
, context
){
2346 var tmpSet
= [], later
= "", match
,
2347 root
= context
.nodeType
? [context
] : context
;
2349 // Position selectors must be done after the filter
2350 // And so must :not(positional) so we move all PSEUDOs to the end
2351 while ( (match
= Expr
.match
.PSEUDO
.exec( selector
)) ) {
2353 selector
= selector
.replace( Expr
.match
.PSEUDO
, "" );
2356 selector
= Expr
.relative
[selector
] ? selector
+ "*" : selector
;
2358 for ( var i
= 0, l
= root
.length
; i
< l
; i
++ ) {
2359 Sizzle( selector
, root
[i
], tmpSet
);
2362 return Sizzle
.filter( later
, tmpSet
);
2366 jQuery
.find
= Sizzle
;
2367 jQuery
.filter
= Sizzle
.filter
;
2368 jQuery
.expr
= Sizzle
.selectors
;
2369 jQuery
.expr
[":"] = jQuery
.expr
.filters
;
2371 Sizzle
.selectors
.filters
.hidden = function(elem
){
2372 return elem
.offsetWidth
=== 0 || elem
.offsetHeight
=== 0;
2375 Sizzle
.selectors
.filters
.visible = function(elem
){
2376 return elem
.offsetWidth
> 0 || elem
.offsetHeight
> 0;
2379 Sizzle
.selectors
.filters
.animated = function(elem
){
2380 return jQuery
.grep(jQuery
.timers
, function(fn
){
2381 return elem
=== fn
.elem
;
2385 jQuery
.multiFilter = function( expr
, elems
, not
) {
2387 expr
= ":not(" + expr
+ ")";
2390 return Sizzle
.matches(expr
, elems
);
2393 jQuery
.dir = function( elem
, dir
){
2394 var matched
= [], cur
= elem
[dir
];
2395 while ( cur
&& cur
!= document
) {
2396 if ( cur
.nodeType
== 1 )
2397 matched
.push( cur
);
2403 jQuery
.nth = function(cur
, result
, dir
, elem
){
2404 result
= result
|| 1;
2407 for ( ; cur
; cur
= cur
[dir
] )
2408 if ( cur
.nodeType
== 1 && ++num
== result
)
2414 jQuery
.sibling = function(n
, elem
){
2417 for ( ; n
; n
= n
.nextSibling
) {
2418 if ( n
.nodeType
== 1 && n
!= elem
)
2427 window
.Sizzle
= Sizzle
;
2431 * A number of helper functions used for managing events.
2432 * Many of the ideas behind this code originated from
2433 * Dean Edwards' addEvent library.
2437 // Bind an event to an element
2438 // Original by Dean Edwards
2439 add: function(elem
, types
, handler
, data
) {
2440 if ( elem
.nodeType
== 3 || elem
.nodeType
== 8 )
2443 // For whatever reason, IE has trouble passing the window object
2444 // around, causing it to be cloned in the process
2445 if ( elem
.setInterval
&& elem
!= window
)
2448 // Make sure that the function being executed has a unique ID
2449 if ( !handler
.guid
)
2450 handler
.guid
= this.guid
++;
2452 // if data is passed, bind to handler
2453 if ( data
!== undefined ) {
2454 // Create temporary function pointer to original handler
2457 // Create unique handler function, wrapped around original handler
2458 handler
= this.proxy( fn
);
2460 // Store data in unique handler
2461 handler
.data
= data
;
2464 // Init the element's event structure
2465 var events
= jQuery
.data(elem
, "events") || jQuery
.data(elem
, "events", {}),
2466 handle
= jQuery
.data(elem
, "handle") || jQuery
.data(elem
, "handle", function(){
2467 // Handle the second event of a trigger and when
2468 // an event is called after a page has unloaded
2469 return typeof jQuery
!== "undefined" && !jQuery
.event
.triggered
?
2470 jQuery
.event
.handle
.apply(arguments
.callee
.elem
, arguments
) :
2473 // Add elem as a property of the handle function
2474 // This is to prevent a memory leak with non-native
2478 // Handle multiple events separated by a space
2479 // jQuery(...).bind("mouseover mouseout", fn);
2480 jQuery
.each(types
.split(/\s+/), function(index
, type
) {
2481 // Namespaced event handlers
2482 var namespaces
= type
.split(".");
2483 type
= namespaces
.shift();
2484 handler
.type
= namespaces
.slice().sort().join(".");
2486 // Get the current list of functions bound to this event
2487 var handlers
= events
[type
];
2489 if ( jQuery
.event
.specialAll
[type
] )
2490 jQuery
.event
.specialAll
[type
].setup
.call(elem
, data
, namespaces
);
2492 // Init the event handler queue
2494 handlers
= events
[type
] = {};
2496 // Check for a special event handler
2497 // Only use addEventListener/attachEvent if the special
2498 // events handler returns false
2499 if ( !jQuery
.event
.special
[type
] || jQuery
.event
.special
[type
].setup
.call(elem
, data
, namespaces
) === false ) {
2500 // Bind the global event handler to the element
2501 if (elem
.addEventListener
)
2502 elem
.addEventListener(type
, handle
, false);
2503 else if (elem
.attachEvent
)
2504 elem
.attachEvent("on" + type
, handle
);
2508 // Add the function to the element's handler list
2509 handlers
[handler
.guid
] = handler
;
2511 // Keep track of which events have been used, for global triggering
2512 jQuery
.event
.global
[type
] = true;
2515 // Nullify elem to prevent memory leaks in IE
2522 // Detach an event or set of events from an element
2523 remove: function(elem
, types
, handler
) {
2524 // don't do events on text and comment nodes
2525 if ( elem
.nodeType
== 3 || elem
.nodeType
== 8 )
2528 var events
= jQuery
.data(elem
, "events"), ret
, index
;
2531 // Unbind all events for the element
2532 if ( types
=== undefined || (typeof types
=== "string" && types
.charAt(0) == ".") )
2533 for ( var type
in events
)
2534 this.remove( elem
, type
+ (types
|| "") );
2536 // types is actually an event object here
2538 handler
= types
.handler
;
2542 // Handle multiple events seperated by a space
2543 // jQuery(...).unbind("mouseover mouseout", fn);
2544 jQuery
.each(types
.split(/\s+/), function(index
, type
){
2545 // Namespaced event handlers
2546 var namespaces
= type
.split(".");
2547 type
= namespaces
.shift();
2548 var namespace = RegExp("(^|\\.)" + namespaces
.slice().sort().join(".*\\.") + "(\\.|$)");
2550 if ( events
[type
] ) {
2551 // remove the given handler for the given type
2553 delete events
[type
][handler
.guid
];
2555 // remove all handlers for the given type
2557 for ( var handle
in events
[type
] )
2558 // Handle the removal of namespaced events
2559 if ( namespace.test(events
[type
][handle
].type
) )
2560 delete events
[type
][handle
];
2562 if ( jQuery
.event
.specialAll
[type
] )
2563 jQuery
.event
.specialAll
[type
].teardown
.call(elem
, namespaces
);
2565 // remove generic event handler if no more handlers exist
2566 for ( ret
in events
[type
] ) break;
2568 if ( !jQuery
.event
.special
[type
] || jQuery
.event
.special
[type
].teardown
.call(elem
, namespaces
) === false ) {
2569 if (elem
.removeEventListener
)
2570 elem
.removeEventListener(type
, jQuery
.data(elem
, "handle"), false);
2571 else if (elem
.detachEvent
)
2572 elem
.detachEvent("on" + type
, jQuery
.data(elem
, "handle"));
2575 delete events
[type
];
2581 // Remove the expando if it's no longer used
2582 for ( ret
in events
) break;
2584 var handle
= jQuery
.data( elem
, "handle" );
2585 if ( handle
) handle
.elem
= null;
2586 jQuery
.removeData( elem
, "events" );
2587 jQuery
.removeData( elem
, "handle" );
2592 // bubbling is internal
2593 trigger: function( event
, data
, elem
, bubbling
) {
2594 // Event object or event type
2595 var type
= event
.type
|| event
;
2598 event
= typeof event
=== "object" ?
2599 // jQuery.Event object
2600 event
[expando
] ? event
:
2602 jQuery
.extend( jQuery
.Event(type
), event
) :
2603 // Just the event type (string)
2606 if ( type
.indexOf("!") >= 0 ) {
2607 event
.type
= type
= type
.slice(0, -1);
2608 event
.exclusive
= true;
2611 // Handle a global trigger
2613 // Don't bubble custom events when global (to avoid too much overhead)
2614 event
.stopPropagation();
2615 // Only trigger if we've ever bound an event for it
2616 if ( this.global
[type
] )
2617 jQuery
.each( jQuery
.cache
, function(){
2618 if ( this.events
&& this.events
[type
] )
2619 jQuery
.event
.trigger( event
, data
, this.handle
.elem
);
2623 // Handle triggering a single element
2625 // don't do events on text and comment nodes
2626 if ( !elem
|| elem
.nodeType
== 3 || elem
.nodeType
== 8 )
2629 // Clean up in case it is reused
2630 event
.result
= undefined;
2631 event
.target
= elem
;
2633 // Clone the incoming data, if any
2634 data
= jQuery
.makeArray(data
);
2635 data
.unshift( event
);
2638 event
.currentTarget
= elem
;
2640 // Trigger the event, it is assumed that "handle" is a function
2641 var handle
= jQuery
.data(elem
, "handle");
2643 handle
.apply( elem
, data
);
2645 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2646 if ( (!elem
[type
] || (jQuery
.nodeName(elem
, 'a') && type
== "click")) && elem
["on"+type
] && elem
["on"+type
].apply( elem
, data
) === false )
2647 event
.result
= false;
2649 // Trigger the native events (except for clicks on links)
2650 if ( !bubbling
&& elem
[type
] && !event
.isDefaultPrevented() && !(jQuery
.nodeName(elem
, 'a') && type
== "click") ) {
2651 this.triggered
= true;
2654 // prevent IE from throwing an error for some hidden elements
2658 this.triggered
= false;
2660 if ( !event
.isPropagationStopped() ) {
2661 var parent
= elem
.parentNode
|| elem
.ownerDocument
;
2663 jQuery
.event
.trigger(event
, data
, parent
, true);
2667 handle: function(event
) {
2668 // returned undefined or false
2671 event
= arguments
[0] = jQuery
.event
.fix( event
|| window
.event
);
2672 event
.currentTarget
= this;
2674 // Namespaced event handlers
2675 var namespaces
= event
.type
.split(".");
2676 event
.type
= namespaces
.shift();
2678 // Cache this now, all = true means, any handler
2679 all
= !namespaces
.length
&& !event
.exclusive
;
2681 var namespace = RegExp("(^|\\.)" + namespaces
.slice().sort().join(".*\\.") + "(\\.|$)");
2683 handlers
= ( jQuery
.data(this, "events") || {} )[event
.type
];
2685 for ( var j
in handlers
) {
2686 var handler
= handlers
[j
];
2688 // Filter the functions by class
2689 if ( all
|| namespace.test(handler
.type
) ) {
2690 // Pass in a reference to the handler function itself
2691 // So that we can later remove it
2692 event
.handler
= handler
;
2693 event
.data
= handler
.data
;
2695 var ret
= handler
.apply(this, arguments
);
2697 if( ret
!== undefined ){
2699 if ( ret
=== false ) {
2700 event
.preventDefault();
2701 event
.stopPropagation();
2705 if( event
.isImmediatePropagationStopped() )
2712 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 toElement view wheelDelta which".split(" "),
2714 fix: function(event
) {
2715 if ( event
[expando
] )
2718 // store a copy of the original event object
2719 // and "clone" to set read-only properties
2720 var originalEvent
= event
;
2721 event
= jQuery
.Event( originalEvent
);
2723 for ( var i
= this.props
.length
, prop
; i
; ){
2724 prop
= this.props
[ --i
];
2725 event
[ prop
] = originalEvent
[ prop
];
2728 // Fix target property, if necessary
2729 if ( !event
.target
)
2730 event
.target
= event
.srcElement
|| document
; // Fixes #1925 where srcElement might not be defined either
2732 // check if target is a textnode (safari)
2733 if ( event
.target
.nodeType
== 3 )
2734 event
.target
= event
.target
.parentNode
;
2736 // Add relatedTarget, if necessary
2737 if ( !event
.relatedTarget
&& event
.fromElement
)
2738 event
.relatedTarget
= event
.fromElement
== event
.target
? event
.toElement
: event
.fromElement
;
2740 // Calculate pageX/Y if missing and clientX/Y available
2741 if ( event
.pageX
== null && event
.clientX
!= null ) {
2742 var doc
= document
.documentElement
, body
= document
.body
;
2743 event
.pageX
= event
.clientX
+ (doc
&& doc
.scrollLeft
|| body
&& body
.scrollLeft
|| 0) - (doc
.clientLeft
|| 0);
2744 event
.pageY
= event
.clientY
+ (doc
&& doc
.scrollTop
|| body
&& body
.scrollTop
|| 0) - (doc
.clientTop
|| 0);
2747 // Add which for key events
2748 if ( !event
.which
&& ((event
.charCode
|| event
.charCode
=== 0) ? event
.charCode
: event
.keyCode
) )
2749 event
.which
= event
.charCode
|| event
.keyCode
;
2751 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2752 if ( !event
.metaKey
&& event
.ctrlKey
)
2753 event
.metaKey
= event
.ctrlKey
;
2755 // Add which for click: 1 == left; 2 == middle; 3 == right
2756 // Note: button is not normalized, so don't use it
2757 if ( !event
.which
&& event
.button
)
2758 event
.which
= (event
.button
& 1 ? 1 : ( event
.button
& 2 ? 3 : ( event
.button
& 4 ? 2 : 0 ) ));
2763 proxy: function( fn
, proxy
){
2764 proxy
= proxy
|| function(){ return fn
.apply(this, arguments
); };
2765 // Set the guid of unique handler to the same of original handler, so it can be removed
2766 proxy
.guid
= fn
.guid
= fn
.guid
|| proxy
.guid
|| this.guid
++;
2767 // So proxy can be declared as an argument
2773 // Make sure the ready event is setup
2775 teardown: function() {}
2781 setup: function( selector
, namespaces
){
2782 jQuery
.event
.add( this, namespaces
[0], liveHandler
);
2784 teardown: function( namespaces
){
2785 if ( namespaces
.length
) {
2786 var remove
= 0, name
= RegExp("(^|\\.)" + namespaces
[0] + "(\\.|$)");
2788 jQuery
.each( (jQuery
.data(this, "events").live
|| {}), function(){
2789 if ( name
.test(this.type
) )
2794 jQuery
.event
.remove( this, namespaces
[0], liveHandler
);
2801 jQuery
.Event = function( src
){
2802 // Allow instantiation without the 'new' keyword
2803 if( !this.preventDefault
)
2804 return new jQuery
.Event(src
);
2807 if( src
&& src
.type
){
2808 this.originalEvent
= src
;
2809 this.type
= src
.type
;
2814 // timeStamp is buggy for some events on Firefox(#3843)
2815 // So we won't rely on the native value
2816 this.timeStamp
= now();
2819 this[expando
] = true;
2822 function returnFalse(){
2825 function returnTrue(){
2829 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2830 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2831 jQuery
.Event
.prototype = {
2832 preventDefault: function() {
2833 this.isDefaultPrevented
= returnTrue
;
2835 var e
= this.originalEvent
;
2838 // if preventDefault exists run it on the original event
2839 if (e
.preventDefault
)
2841 // otherwise set the returnValue property of the original event to false (IE)
2842 e
.returnValue
= false;
2844 stopPropagation: function() {
2845 this.isPropagationStopped
= returnTrue
;
2847 var e
= this.originalEvent
;
2850 // if stopPropagation exists run it on the original event
2851 if (e
.stopPropagation
)
2852 e
.stopPropagation();
2853 // otherwise set the cancelBubble property of the original event to true (IE)
2854 e
.cancelBubble
= true;
2856 stopImmediatePropagation:function(){
2857 this.isImmediatePropagationStopped
= returnTrue
;
2858 this.stopPropagation();
2860 isDefaultPrevented
: returnFalse
,
2861 isPropagationStopped
: returnFalse
,
2862 isImmediatePropagationStopped
: returnFalse
2864 // Checks if an event happened on an element within another element
2865 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2866 var withinElement = function(event
) {
2867 // Check if mouse(over|out) are still within the same parent element
2868 var parent
= event
.relatedTarget
;
2869 // Traverse up the tree
2870 while ( parent
&& parent
!= this )
2871 try { parent
= parent
.parentNode
; }
2872 catch(e
) { parent
= this; }
2874 if( parent
!= this ){
2875 // set the correct event type
2876 event
.type
= event
.data
;
2877 // handle event if we actually just moused on to a non sub-element
2878 jQuery
.event
.handle
.apply( this, arguments
);
2883 mouseover
: 'mouseenter',
2884 mouseout
: 'mouseleave'
2885 }, function( orig
, fix
){
2886 jQuery
.event
.special
[ fix
] = {
2888 jQuery
.event
.add( this, orig
, withinElement
, fix
);
2890 teardown: function(){
2891 jQuery
.event
.remove( this, orig
, withinElement
);
2897 bind: function( type
, data
, fn
) {
2898 return type
== "unload" ? this.one(type
, data
, fn
) : this.each(function(){
2899 jQuery
.event
.add( this, type
, fn
|| data
, fn
&& data
);
2903 one: function( type
, data
, fn
) {
2904 var one
= jQuery
.event
.proxy( fn
|| data
, function(event
) {
2905 jQuery(this).unbind(event
, one
);
2906 return (fn
|| data
).apply( this, arguments
);
2908 return this.each(function(){
2909 jQuery
.event
.add( this, type
, one
, fn
&& data
);
2913 unbind: function( type
, fn
) {
2914 return this.each(function(){
2915 jQuery
.event
.remove( this, type
, fn
);
2919 trigger: function( type
, data
) {
2920 return this.each(function(){
2921 jQuery
.event
.trigger( type
, data
, this );
2925 triggerHandler: function( type
, data
) {
2927 var event
= jQuery
.Event(type
);
2928 event
.preventDefault();
2929 event
.stopPropagation();
2930 jQuery
.event
.trigger( event
, data
, this[0] );
2931 return event
.result
;
2935 toggle: function( fn
) {
2936 // Save reference to arguments for access in closure
2937 var args
= arguments
, i
= 1;
2939 // link all the functions, so any of them can unbind this click handler
2940 while( i
< args
.length
)
2941 jQuery
.event
.proxy( fn
, args
[i
++] );
2943 return this.click( jQuery
.event
.proxy( fn
, function(event
) {
2944 // Figure out which function to execute
2945 this.lastToggle
= ( this.lastToggle
|| 0 ) % i
;
2947 // Make sure that clicks stop
2948 event
.preventDefault();
2950 // and execute the function
2951 return args
[ this.lastToggle
++ ].apply( this, arguments
) || false;
2955 hover: function(fnOver
, fnOut
) {
2956 return this.mouseenter(fnOver
).mouseleave(fnOut
);
2959 ready: function(fn
) {
2960 // Attach the listeners
2963 // If the DOM is already ready
2964 if ( jQuery
.isReady
)
2965 // Execute the function immediately
2966 fn
.call( document
, jQuery
);
2968 // Otherwise, remember the function for later
2970 // Add the function to the wait list
2971 jQuery
.readyList
.push( fn
);
2976 live: function( type
, fn
){
2977 var proxy
= jQuery
.event
.proxy( fn
);
2978 proxy
.guid
+= this.selector
+ type
;
2980 jQuery(document
).bind( liveConvert(type
, this.selector
), this.selector
, proxy
);
2985 die: function( type
, fn
){
2986 jQuery(document
).unbind( liveConvert(type
, this.selector
), fn
? { guid
: fn
.guid
+ this.selector
+ type
} : null );
2991 function liveHandler( event
){
2992 var check
= RegExp("(^|\\.)" + event
.type
+ "(\\.|$)"),
2996 jQuery
.each(jQuery
.data(this, "events").live
|| [], function(i
, fn
){
2997 if ( check
.test(fn
.type
) ) {
2998 var elem
= jQuery(event
.target
).closest(fn
.data
)[0];
3000 elems
.push({ elem
: elem
, fn
: fn
});
3004 elems
.sort(function(a
,b
) {
3005 return jQuery
.data(a
.elem
, "closest") - jQuery
.data(b
.elem
, "closest");
3008 jQuery
.each(elems
, function(){
3009 if ( this.fn
.call(this.elem
, event
, this.fn
.data
) === false )
3010 return (stop
= false);
3016 function liveConvert(type
, selector
){
3017 return ["live", type
, selector
.replace(/\./g, "`").replace(/ /g
, "|")].join(".");
3023 // Handle when the DOM is ready
3025 // Make sure that the DOM is not already loaded
3026 if ( !jQuery
.isReady
) {
3027 // Remember that the DOM is ready
3028 jQuery
.isReady
= true;
3030 // If there are functions bound, to execute
3031 if ( jQuery
.readyList
) {
3032 // Execute all of them
3033 jQuery
.each( jQuery
.readyList
, function(){
3034 this.call( document
, jQuery
);
3037 // Reset the list of functions
3038 jQuery
.readyList
= null;
3041 // Trigger any bound ready events
3042 jQuery(document
).triggerHandler("ready");
3047 var readyBound
= false;
3049 function bindReady(){
3050 if ( readyBound
) return;
3053 // Mozilla, Opera and webkit nightlies currently support this event
3054 if ( document
.addEventListener
) {
3055 // Use the handy event callback
3056 document
.addEventListener( "DOMContentLoaded", function(){
3057 document
.removeEventListener( "DOMContentLoaded", arguments
.callee
, false );
3061 // If IE event model is used
3062 } else if ( document
.attachEvent
) {
3063 // ensure firing before onload,
3064 // maybe late but safe also for iframes
3065 document
.attachEvent("onreadystatechange", function(){
3066 if ( document
.readyState
=== "complete" ) {
3067 document
.detachEvent( "onreadystatechange", arguments
.callee
);
3072 // If IE and not an iframe
3073 // continually check to see if the document is ready
3074 if ( document
.documentElement
.doScroll
&& window
== window
.top
) (function(){
3075 if ( jQuery
.isReady
) return;
3078 // If IE is used, use the trick by Diego Perini
3079 // http://javascript.nwbox.com/IEContentLoaded/
3080 document
.documentElement
.doScroll("left");
3082 setTimeout( arguments
.callee
, 0 );
3086 // and execute any waiting functions
3091 // A fallback to window.onload, that will always work
3092 jQuery
.event
.add( window
, "load", jQuery
.ready
);
3095 jQuery
.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
3096 "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
3097 "change,select,submit,keydown,keypress,keyup,error").split(","), function(i
, name
){
3099 // Handle event binding
3100 jQuery
.fn
[name
] = function(fn
){
3101 return fn
? this.bind(name
, fn
) : this.trigger(name
);
3105 // Prevent memory leaks in IE
3106 // And prevent errors on refresh with events like mouseover in other browsers
3107 // Window isn't included so as not to unbind existing unload events
3108 jQuery( window
).bind( 'unload', function(){
3109 for ( var id
in jQuery
.cache
)
3111 if ( id
!= 1 && jQuery
.cache
[ id
].handle
)
3112 jQuery
.event
.remove( jQuery
.cache
[ id
].handle
.elem
);
3116 jQuery
.support
= {};
3118 var root
= document
.documentElement
,
3119 script
= document
.createElement("script"),
3120 div
= document
.createElement("div"),
3121 id
= "script" + (new Date
).getTime();
3123 div
.style
.display
= "none";
3124 div
.innerHTML
= ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
3126 var all
= div
.getElementsByTagName("*"),
3127 a
= div
.getElementsByTagName("a")[0];
3129 // Can't get basic test support
3130 if ( !all
|| !all
.length
|| !a
) {
3135 // IE strips leading whitespace when .innerHTML is used
3136 leadingWhitespace
: div
.firstChild
.nodeType
== 3,
3138 // Make sure that tbody elements aren't automatically inserted
3139 // IE will insert them into empty tables
3140 tbody
: !div
.getElementsByTagName("tbody").length
,
3142 // Make sure that you can get all elements in an <object> element
3143 // IE 7 always returns no results
3144 objectAll
: !!div
.getElementsByTagName("object")[0]
3145 .getElementsByTagName("*").length
,
3147 // Make sure that link elements get serialized correctly by innerHTML
3148 // This requires a wrapper element in IE
3149 htmlSerialize
: !!div
.getElementsByTagName("link").length
,
3151 // Get the style information from getAttribute
3152 // (IE uses .cssText insted)
3153 style
: /red/.test( a
.getAttribute("style") ),
3155 // Make sure that URLs aren't manipulated
3156 // (IE normalizes it by default)
3157 hrefNormalized
: a
.getAttribute("href") === "/a",
3159 // Make sure that element opacity exists
3160 // (IE uses filter instead)
3161 opacity
: a
.style
.opacity
=== "0.5",
3163 // Verify style float existence
3164 // (IE uses styleFloat instead of cssFloat)
3165 cssFloat
: !!a
.style
.cssFloat
,
3167 // Will be defined later
3173 script
.type
= "text/javascript";
3175 script
.appendChild( document
.createTextNode( "window." + id
+ "=1;" ) );
3178 root
.insertBefore( script
, root
.firstChild
);
3180 // Make sure that the execution of code works by injecting a script
3181 // tag with appendChild/createTextNode
3182 // (IE doesn't support this, fails, and uses .text instead)
3183 if ( window
[ id
] ) {
3184 jQuery
.support
.scriptEval
= true;
3185 delete window
[ id
];
3188 root
.removeChild( script
);
3190 if ( div
.attachEvent
&& div
.fireEvent
) {
3191 div
.attachEvent("onclick", function(){
3192 // Cloning a node shouldn't copy over any
3193 // bound event handlers (IE does this)
3194 jQuery
.support
.noCloneEvent
= false;
3195 div
.detachEvent("onclick", arguments
.callee
);
3197 div
.cloneNode(true).fireEvent("onclick");
3200 // Figure out if the W3C box model works as expected
3201 // document.body must exist before we can do this
3203 var div
= document
.createElement("div");
3204 div
.style
.width
= div
.style
.paddingLeft
= "1px";
3206 document
.body
.appendChild( div
);
3207 jQuery
.boxModel
= jQuery
.support
.boxModel
= div
.offsetWidth
=== 2;
3208 document
.body
.removeChild( div
).style
.display
= 'none';
3212 var styleFloat
= jQuery
.support
.cssFloat
? "cssFloat" : "styleFloat";
3216 "class": "className",
3217 "float": styleFloat
,
3218 cssFloat
: styleFloat
,
3219 styleFloat
: styleFloat
,
3220 readonly
: "readOnly",
3221 maxlength
: "maxLength",
3222 cellspacing
: "cellSpacing",
3224 tabindex
: "tabIndex"
3227 // Keep a copy of the old load
3228 _load
: jQuery
.fn
.load
,
3230 load: function( url
, params
, callback
) {
3231 if ( typeof url
!== "string" )
3232 return this._load( url
);
3234 var off
= url
.indexOf(" ");
3236 var selector
= url
.slice(off
, url
.length
);
3237 url
= url
.slice(0, off
);
3240 // Default to a GET request
3243 // If the second parameter was provided
3245 // If it's a function
3246 if ( jQuery
.isFunction( params
) ) {
3247 // We assume that it's the callback
3251 // Otherwise, build a param string
3252 } else if( typeof params
=== "object" ) {
3253 params
= jQuery
.param( params
);
3259 // Request the remote document
3265 complete: function(res
, status
){
3266 // If successful, inject the HTML into all the matched elements
3267 if ( status
== "success" || status
== "notmodified" )
3268 // See if a selector was specified
3269 self
.html( selector
?
3270 // Create a dummy div to hold the results
3272 // inject the contents of the document in, removing the scripts
3273 // to avoid any 'Permission Denied' errors in IE
3274 .append(res
.responseText
.replace(/<script(.|\s)*?\/script>/g, ""))
3276 // Locate the specified elements
3279 // If not, just inject the full result
3283 self
.each( callback
, [res
.responseText
, status
, res
] );
3289 serialize: function() {
3290 return jQuery
.param(this.serializeArray());
3292 serializeArray: function() {
3293 return this.map(function(){
3294 return this.elements
? jQuery
.makeArray(this.elements
) : this;
3297 return this.name
&& !this.disabled
&&
3298 (this.checked
|| /select|textarea/i.test(this.nodeName
) ||
3299 /text|hidden|password|search/i.test(this.type
));
3301 .map(function(i
, elem
){
3302 var val
= jQuery(this).val();
3303 return val
== null ? null :
3304 jQuery
.isArray(val
) ?
3305 jQuery
.map( val
, function(val
, i
){
3306 return {name
: elem
.name
, value
: val
};
3308 {name
: elem
.name
, value
: val
};
3313 // Attach a bunch of functions for handling common AJAX events
3314 jQuery
.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i
,o
){
3315 jQuery
.fn
[o
] = function(f
){
3316 return this.bind(o
, f
);
3324 get: function( url
, data
, callback
, type
) {
3325 // shift arguments if data argument was ommited
3326 if ( jQuery
.isFunction( data
) ) {
3331 return jQuery
.ajax({
3340 getScript: function( url
, callback
) {
3341 return jQuery
.get(url
, null, callback
, "script");
3344 getJSON: function( url
, data
, callback
) {
3345 return jQuery
.get(url
, data
, callback
, "json");
3348 post: function( url
, data
, callback
, type
) {
3349 if ( jQuery
.isFunction( data
) ) {
3354 return jQuery
.ajax({
3363 ajaxSetup: function( settings
) {
3364 jQuery
.extend( jQuery
.ajaxSettings
, settings
);
3371 contentType
: "application/x-www-form-urlencoded",
3380 // Create the request object; Microsoft failed to properly
3381 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
3382 // This function can be overriden by calling jQuery.ajaxSetup
3384 return window
.ActiveXObject
? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3387 xml
: "application/xml, text/xml",
3389 script
: "text/javascript, application/javascript",
3390 json
: "application/json, text/javascript",
3396 // Last-Modified header cache for next request
3399 ajax: function( s
) {
3400 // Extend the settings, but re-extend 's' so that it can be
3401 // checked again later (in the test suite, specifically)
3402 s
= jQuery
.extend(true, s
, jQuery
.extend(true, {}, jQuery
.ajaxSettings
, s
));
3404 var jsonp
, jsre
= /=\?(&|$)/g, status
, data
,
3405 type
= s
.type
.toUpperCase();
3407 // convert data if not already a string
3408 if ( s
.data
&& s
.processData
&& typeof s
.data
!== "string" )
3409 s
.data
= jQuery
.param(s
.data
);
3411 // Handle JSONP Parameter Callbacks
3412 if ( s
.dataType
== "jsonp" ) {
3413 if ( type
== "GET" ) {
3414 if ( !s
.url
.match(jsre
) )
3415 s
.url
+= (s
.url
.match(/\?/) ? "&" : "?") + (s
.jsonp
|| "callback") + "=?";
3416 } else if ( !s
.data
|| !s
.data
.match(jsre
) )
3417 s
.data
= (s
.data
? s
.data
+ "&" : "") + (s
.jsonp
|| "callback") + "=?";
3418 s
.dataType
= "json";
3421 // Build temporary JSONP function
3422 if ( s
.dataType
== "json" && (s
.data
&& s
.data
.match(jsre
) || s
.url
.match(jsre
)) ) {
3423 jsonp
= "jsonp" + jsc
++;
3425 // Replace the =? sequence both in the query string and the data
3427 s
.data
= (s
.data
+ "").replace(jsre
, "=" + jsonp
+ "$1");
3428 s
.url
= s
.url
.replace(jsre
, "=" + jsonp
+ "$1");
3430 // We need to make sure
3431 // that a JSONP style response is executed properly
3432 s
.dataType
= "script";
3434 // Handle JSONP-style loading
3435 window
[ jsonp
] = function(tmp
){
3440 window
[ jsonp
] = undefined;
3441 try{ delete window
[ jsonp
]; } catch(e
){}
3443 head
.removeChild( script
);
3447 if ( s
.dataType
== "script" && s
.cache
== null )
3450 if ( s
.cache
=== false && type
== "GET" ) {
3452 // try replacing _= if it is there
3453 var ret
= s
.url
.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts
+ "$2");
3454 // if nothing was replaced, add timestamp to the end
3455 s
.url
= ret
+ ((ret
== s
.url
) ? (s
.url
.match(/\?/) ? "&" : "?") + "_=" + ts
: "");
3458 // If data is available, append data to url for get requests
3459 if ( s
.data
&& type
== "GET" ) {
3460 s
.url
+= (s
.url
.match(/\?/) ? "&" : "?") + s
.data
;
3462 // IE likes to send both get and post data, prevent this
3466 // Watch for a new set of requests
3467 if ( s
.global
&& ! jQuery
.active
++ )
3468 jQuery
.event
.trigger( "ajaxStart" );
3470 // Matches an absolute URL, and saves the domain
3471 var parts
= /^(\w+:)?\/\/([^\/?#]+)/.exec( s
.url
);
3473 // If we're requesting a remote document
3474 // and trying to load JSON or Script with a GET
3475 if ( s
.dataType
== "script" && type
== "GET" && parts
3476 && ( parts
[1] && parts
[1] != location
.protocol
|| parts
[2] != location
.host
)){
3478 var head
= document
.getElementsByTagName("head")[0];
3479 var script
= document
.createElement("script");
3481 if (s
.scriptCharset
)
3482 script
.charset
= s
.scriptCharset
;
3484 // Handle Script loading
3488 // Attach handlers for all browsers
3489 script
.onload
= script
.onreadystatechange = function(){
3490 if ( !done
&& (!this.readyState
||
3491 this.readyState
== "loaded" || this.readyState
== "complete") ) {
3496 // Handle memory leak in IE
3497 script
.onload
= script
.onreadystatechange
= null;
3498 head
.removeChild( script
);
3503 head
.appendChild(script
);
3505 // We handle everything using the script element injection
3509 var requestDone
= false;
3511 // Create the request object
3515 // Passing null username, generates a login popup on Opera (#2865)
3517 xhr
.open(type
, s
.url
, s
.async
, s
.username
, s
.password
);
3519 xhr
.open(type
, s
.url
, s
.async
);
3521 // Need an extra try/catch for cross domain requests in Firefox 3
3523 // Set the correct header, if data is being sent
3525 xhr
.setRequestHeader("Content-Type", s
.contentType
);
3527 // Set the If-Modified-Since header, if ifModified mode.
3529 xhr
.setRequestHeader("If-Modified-Since",
3530 jQuery
.lastModified
[s
.url
] || "Thu, 01 Jan 1970 00:00:00 GMT" );
3532 // Set header so the called script knows that it's an XMLHttpRequest
3533 xhr
.setRequestHeader("X-Requested-With", "XMLHttpRequest");
3535 // Set the Accepts header for the server, depending on the dataType
3536 xhr
.setRequestHeader("Accept", s
.dataType
&& s
.accepts
[ s
.dataType
] ?
3537 s
.accepts
[ s
.dataType
] + ", */*" :
3538 s
.accepts
._default
);
3541 // Allow custom headers/mimetypes and early abort
3542 if ( s
.beforeSend
&& s
.beforeSend(xhr
, s
) === false ) {
3543 // Handle the global AJAX counter
3544 if ( s
.global
&& ! --jQuery
.active
)
3545 jQuery
.event
.trigger( "ajaxStop" );
3546 // close opended socket
3552 jQuery
.event
.trigger("ajaxSend", [xhr
, s
]);
3554 // Wait for a response to come back
3555 var onreadystatechange = function(isTimeout
){
3556 // The request was aborted, clear the interval and decrement jQuery.active
3557 if (xhr
.readyState
== 0) {
3559 // clear poll interval
3560 clearInterval(ival
);
3562 // Handle the global AJAX counter
3563 if ( s
.global
&& ! --jQuery
.active
)
3564 jQuery
.event
.trigger( "ajaxStop" );
3566 // The transfer is complete and the data is available, or the request timed out
3567 } else if ( !requestDone
&& xhr
&& (xhr
.readyState
== 4 || isTimeout
== "timeout") ) {
3570 // clear poll interval
3572 clearInterval(ival
);
3576 status
= isTimeout
== "timeout" ? "timeout" :
3577 !jQuery
.httpSuccess( xhr
) ? "error" :
3578 s
.ifModified
&& jQuery
.httpNotModified( xhr
, s
.url
) ? "notmodified" :
3581 if ( status
== "success" ) {
3582 // Watch for, and catch, XML document parse errors
3584 // process the data (runs the xml through httpData regardless of callback)
3585 data
= jQuery
.httpData( xhr
, s
.dataType
, s
);
3587 status
= "parsererror";
3591 // Make sure that the request was successful or notmodified
3592 if ( status
== "success" ) {
3593 // Cache Last-Modified header, if ifModified mode.
3596 modRes
= xhr
.getResponseHeader("Last-Modified");
3597 } catch(e
) {} // swallow exception thrown by FF if header is not available
3599 if ( s
.ifModified
&& modRes
)
3600 jQuery
.lastModified
[s
.url
] = modRes
;
3602 // JSONP handles its own success callback
3606 jQuery
.handleError(s
, xhr
, status
);
3608 // Fire the complete handlers
3614 // Stop memory leaks
3621 // don't attach the handler to the request, just poll it instead
3622 var ival
= setInterval(onreadystatechange
, 13);
3625 if ( s
.timeout
> 0 )
3626 setTimeout(function(){
3627 // Check to see if the request is still happening
3628 if ( xhr
&& !requestDone
)
3629 onreadystatechange( "timeout" );
3637 jQuery
.handleError(s
, xhr
, null, e
);
3640 // firefox 1.5 doesn't fire statechange for sync requests
3642 onreadystatechange();
3645 // If a local callback was specified, fire it and pass it the data
3647 s
.success( data
, status
);
3649 // Fire the global callback
3651 jQuery
.event
.trigger( "ajaxSuccess", [xhr
, s
] );
3654 function complete(){
3657 s
.complete(xhr
, status
);
3659 // The request was completed
3661 jQuery
.event
.trigger( "ajaxComplete", [xhr
, s
] );
3663 // Handle the global AJAX counter
3664 if ( s
.global
&& ! --jQuery
.active
)
3665 jQuery
.event
.trigger( "ajaxStop" );
3668 // return XMLHttpRequest to allow aborting the request etc.
3672 handleError: function( s
, xhr
, status
, e
) {
3673 // If a local callback was specified, fire it
3674 if ( s
.error
) s
.error( xhr
, status
, e
);
3676 // Fire the global callback
3678 jQuery
.event
.trigger( "ajaxError", [xhr
, s
, e
] );
3681 // Counter for holding the number of active queries
3684 // Determines if an XMLHttpRequest was successful or not
3685 httpSuccess: function( xhr
) {
3687 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
3688 return !xhr
.status
&& location
.protocol
== "file:" ||
3689 ( xhr
.status
>= 200 && xhr
.status
< 300 ) || xhr
.status
== 304 || xhr
.status
== 1223;
3694 // Determines if an XMLHttpRequest returns NotModified
3695 httpNotModified: function( xhr
, url
) {
3697 var xhrRes
= xhr
.getResponseHeader("Last-Modified");
3699 // Firefox always returns 200. check Last-Modified date
3700 return xhr
.status
== 304 || xhrRes
== jQuery
.lastModified
[url
];
3705 httpData: function( xhr
, type
, s
) {
3706 var ct
= xhr
.getResponseHeader("content-type"),
3707 xml
= type
== "xml" || !type
&& ct
&& ct
.indexOf("xml") >= 0,
3708 data
= xml
? xhr
.responseXML
: xhr
.responseText
;
3710 if ( xml
&& data
.documentElement
.tagName
== "parsererror" )
3711 throw "parsererror";
3713 // Allow a pre-filtering function to sanitize the response
3714 // s != null is checked to keep backwards compatibility
3715 if( s
&& s
.dataFilter
)
3716 data
= s
.dataFilter( data
, type
);
3718 // The filter can actually parse the response
3719 if( typeof data
=== "string" ){
3721 // If the type is "script", eval it in global context
3722 if ( type
== "script" )
3723 jQuery
.globalEval( data
);
3725 // Get the JavaScript object, if JSON is used.
3726 if ( type
== "json" )
3727 data
= window
["eval"]("(" + data
+ ")");
3733 // Serialize an array of form elements or a set of
3734 // key/values into a query string
3735 param: function( a
) {
3738 function add( key
, value
){
3739 s
[ s
.length
] = encodeURIComponent(key
) + '=' + encodeURIComponent(value
);
3742 // If an array was passed in, assume that it is an array
3744 if ( jQuery
.isArray(a
) || a
.jquery
)
3745 // Serialize the form elements
3746 jQuery
.each( a
, function(){
3747 add( this.name
, this.value
);
3750 // Otherwise, assume that it's an object of key/value pairs
3752 // Serialize the key/values
3754 // If the value is an array then the key names need to be repeated
3755 if ( jQuery
.isArray(a
[j
]) )
3756 jQuery
.each( a
[j
], function(){
3760 add( j
, jQuery
.isFunction(a
[j
]) ? a
[j
]() : a
[j
] );
3762 // Return the resulting serialization
3763 return s
.join("&").replace(/%20/g, "+");
3767 var elemdisplay
= {},
3770 // height animations
3771 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
3773 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
3774 // opacity animations
3778 function genFx( type
, num
){
3780 jQuery
.each( fxAttrs
.concat
.apply([], fxAttrs
.slice(0,num
)), function(){
3787 show: function(speed
,callback
){
3789 return this.animate( genFx("show", 3), speed
, callback
);
3791 for ( var i
= 0, l
= this.length
; i
< l
; i
++ ){
3792 var old
= jQuery
.data(this[i
], "olddisplay");
3794 this[i
].style
.display
= old
|| "";
3796 if ( jQuery
.css(this[i
], "display") === "none" ) {
3797 var tagName
= this[i
].tagName
, display
;
3799 if ( elemdisplay
[ tagName
] ) {
3800 display
= elemdisplay
[ tagName
];
3802 var elem
= jQuery("<" + tagName
+ " />").appendTo("body");
3804 display
= elem
.css("display");
3805 if ( display
=== "none" )
3810 elemdisplay
[ tagName
] = display
;
3813 jQuery
.data(this[i
], "olddisplay", display
);
3817 // Set the display of the elements in a second loop
3818 // to avoid the constant reflow
3819 for ( var i
= 0, l
= this.length
; i
< l
; i
++ ){
3820 this[i
].style
.display
= jQuery
.data(this[i
], "olddisplay") || "";
3827 hide: function(speed
,callback
){
3829 return this.animate( genFx("hide", 3), speed
, callback
);
3831 for ( var i
= 0, l
= this.length
; i
< l
; i
++ ){
3832 var old
= jQuery
.data(this[i
], "olddisplay");
3833 if ( !old
&& old
!== "none" )
3834 jQuery
.data(this[i
], "olddisplay", jQuery
.css(this[i
], "display"));
3837 // Set the display of the elements in a second loop
3838 // to avoid the constant reflow
3839 for ( var i
= 0, l
= this.length
; i
< l
; i
++ ){
3840 this[i
].style
.display
= "none";
3847 // Save the old toggle function
3848 _toggle
: jQuery
.fn
.toggle
,
3850 toggle: function( fn
, fn2
){
3851 var bool
= typeof fn
=== "boolean";
3853 return jQuery
.isFunction(fn
) && jQuery
.isFunction(fn2
) ?
3854 this._toggle
.apply( this, arguments
) :
3855 fn
== null || bool
?
3856 this.each(function(){
3857 var state
= bool
? fn
: jQuery(this).is(":hidden");
3858 jQuery(this)[ state
? "show" : "hide" ]();
3860 this.animate(genFx("toggle", 3), fn
, fn2
);
3863 fadeTo: function(speed
,to
,callback
){
3864 return this.animate({opacity
: to
}, speed
, callback
);
3867 animate: function( prop
, speed
, easing
, callback
) {
3868 var optall
= jQuery
.speed(speed
, easing
, callback
);
3870 return this[ optall
.queue
=== false ? "each" : "queue" ](function(){
3872 var opt
= jQuery
.extend({}, optall
), p
,
3873 hidden
= this.nodeType
== 1 && jQuery(this).is(":hidden"),
3877 if ( prop
[p
] == "hide" && hidden
|| prop
[p
] == "show" && !hidden
)
3878 return opt
.complete
.call(this);
3880 if ( ( p
== "height" || p
== "width" ) && this.style
) {
3881 // Store display property
3882 opt
.display
= jQuery
.css(this, "display");
3884 // Make sure that nothing sneaks out
3885 opt
.overflow
= this.style
.overflow
;
3889 if ( opt
.overflow
!= null )
3890 this.style
.overflow
= "hidden";
3892 opt
.curAnim
= jQuery
.extend({}, prop
);
3894 jQuery
.each( prop
, function(name
, val
){
3895 var e
= new jQuery
.fx( self
, opt
, name
);
3897 if ( /toggle|show|hide/.test(val
) )
3898 e
[ val
== "toggle" ? hidden
? "show" : "hide" : val
]( prop
);
3900 var parts
= val
.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3901 start
= e
.cur(true) || 0;
3904 var end
= parseFloat(parts
[2]),
3905 unit
= parts
[3] || "px";
3907 // We need to compute starting value
3908 if ( unit
!= "px" ) {
3909 self
.style
[ name
] = (end
|| 1) + unit
;
3910 start
= ((end
|| 1) / e
.cur(true)) * start
;
3911 self
.style
[ name
] = start
+ unit
;
3914 // If a +=/-= token was provided, we're doing a relative animation
3916 end
= ((parts
[1] == "-=" ? -1 : 1) * end
) + start
;
3918 e
.custom( start
, end
, unit
);
3920 e
.custom( start
, val
, "" );
3924 // For JS strict compliance
3929 stop: function(clearQueue
, gotoEnd
){
3930 var timers
= jQuery
.timers
;
3935 this.each(function(){
3936 // go in reverse order so anything added to the queue during the loop is ignored
3937 for ( var i
= timers
.length
- 1; i
>= 0; i
-- )
3938 if ( timers
[i
].elem
== this ) {
3940 // force the next step to be the last
3942 timers
.splice(i
, 1);
3946 // start the next in the queue if the last step wasn't forced
3955 // Generate shortcuts for custom animations
3957 slideDown
: genFx("show", 1),
3958 slideUp
: genFx("hide", 1),
3959 slideToggle
: genFx("toggle", 1),
3960 fadeIn
: { opacity
: "show" },
3961 fadeOut
: { opacity
: "hide" }
3962 }, function( name
, props
){
3963 jQuery
.fn
[ name
] = function( speed
, callback
){
3964 return this.animate( props
, speed
, callback
);
3970 speed: function(speed
, easing
, fn
) {
3971 var opt
= typeof speed
=== "object" ? speed
: {
3972 complete
: fn
|| !fn
&& easing
||
3973 jQuery
.isFunction( speed
) && speed
,
3975 easing
: fn
&& easing
|| easing
&& !jQuery
.isFunction(easing
) && easing
3978 opt
.duration
= jQuery
.fx
.off
? 0 : typeof opt
.duration
=== "number" ? opt
.duration
:
3979 jQuery
.fx
.speeds
[opt
.duration
] || jQuery
.fx
.speeds
._default
;
3982 opt
.old
= opt
.complete
;
3983 opt
.complete = function(){
3984 if ( opt
.queue
!== false )
3985 jQuery(this).dequeue();
3986 if ( jQuery
.isFunction( opt
.old
) )
3987 opt
.old
.call( this );
3994 linear: function( p
, n
, firstNum
, diff
) {
3995 return firstNum
+ diff
* p
;
3997 swing: function( p
, n
, firstNum
, diff
) {
3998 return ((-Math
.cos(p
*Math
.PI
)/2) + 0.5) * diff
+ firstNum
;
4004 fx: function( elem
, options
, prop
){
4005 this.options
= options
;
4009 if ( !options
.orig
)
4015 jQuery
.fx
.prototype = {
4017 // Simple function for setting a style value
4019 if ( this.options
.step
)
4020 this.options
.step
.call( this.elem
, this.now
, this );
4022 (jQuery
.fx
.step
[this.prop
] || jQuery
.fx
.step
._default
)( this );
4024 // Set display property to block for height/width animations
4025 if ( ( this.prop
== "height" || this.prop
== "width" ) && this.elem
.style
)
4026 this.elem
.style
.display
= "block";
4029 // Get the current size
4030 cur: function(force
){
4031 if ( this.elem
[this.prop
] != null && (!this.elem
.style
|| this.elem
.style
[this.prop
] == null) )
4032 return this.elem
[ this.prop
];
4034 var r
= parseFloat(jQuery
.css(this.elem
, this.prop
, force
));
4035 return r
&& r
> -10000 ? r
: parseFloat(jQuery
.curCSS(this.elem
, this.prop
)) || 0;
4038 // Start an animation from one number to another
4039 custom: function(from, to
, unit
){
4040 this.startTime
= now();
4043 this.unit
= unit
|| this.unit
|| "px";
4044 this.now
= this.start
;
4045 this.pos
= this.state
= 0;
4048 function t(gotoEnd
){
4049 return self
.step(gotoEnd
);
4054 if ( t() && jQuery
.timers
.push(t
) && !timerId
) {
4055 timerId
= setInterval(function(){
4056 var timers
= jQuery
.timers
;
4058 for ( var i
= 0; i
< timers
.length
; i
++ )
4060 timers
.splice(i
--, 1);
4062 if ( !timers
.length
) {
4063 clearInterval( timerId
);
4064 timerId
= undefined;
4070 // Simple 'show' function
4072 // Remember where we started, so that we can go back to it later
4073 this.options
.orig
[this.prop
] = jQuery
.attr( this.elem
.style
, this.prop
);
4074 this.options
.show
= true;
4076 // Begin the animation
4077 // Make sure that we start at a small width/height to avoid any
4079 this.custom(this.prop
== "width" || this.prop
== "height" ? 1 : 0, this.cur());
4081 // Start by showing the element
4082 jQuery(this.elem
).show();
4085 // Simple 'hide' function
4087 // Remember where we started, so that we can go back to it later
4088 this.options
.orig
[this.prop
] = jQuery
.attr( this.elem
.style
, this.prop
);
4089 this.options
.hide
= true;
4091 // Begin the animation
4092 this.custom(this.cur(), 0);
4095 // Each step of an animation
4096 step: function(gotoEnd
){
4099 if ( gotoEnd
|| t
>= this.options
.duration
+ this.startTime
) {
4100 this.now
= this.end
;
4101 this.pos
= this.state
= 1;
4104 this.options
.curAnim
[ this.prop
] = true;
4107 for ( var i
in this.options
.curAnim
)
4108 if ( this.options
.curAnim
[i
] !== true )
4112 if ( this.options
.display
!= null ) {
4113 // Reset the overflow
4114 this.elem
.style
.overflow
= this.options
.overflow
;
4116 // Reset the display
4117 this.elem
.style
.display
= this.options
.display
;
4118 if ( jQuery
.css(this.elem
, "display") == "none" )
4119 this.elem
.style
.display
= "block";
4122 // Hide the element if the "hide" operation was done
4123 if ( this.options
.hide
)
4124 jQuery(this.elem
).hide();
4126 // Reset the properties, if the item has been hidden or shown
4127 if ( this.options
.hide
|| this.options
.show
)
4128 for ( var p
in this.options
.curAnim
)
4129 jQuery
.attr(this.elem
.style
, p
, this.options
.orig
[p
]);
4131 // Execute the complete function
4132 this.options
.complete
.call( this.elem
);
4137 var n
= t
- this.startTime
;
4138 this.state
= n
/ this.options
.duration
;
4140 // Perform the easing function, defaults to swing
4141 this.pos
= jQuery
.easing
[this.options
.easing
|| (jQuery
.easing
.swing
? "swing" : "linear")](this.state
, n
, 0, 1, this.options
.duration
);
4142 this.now
= this.start
+ ((this.end
- this.start
) * this.pos
);
4144 // Perform the next step of the animation
4153 jQuery
.extend( jQuery
.fx
, {
4162 opacity: function(fx
){
4163 jQuery
.attr(fx
.elem
.style
, "opacity", fx
.now
);
4166 _default: function(fx
){
4167 if ( fx
.elem
.style
&& fx
.elem
.style
[ fx
.prop
] != null )
4168 fx
.elem
.style
[ fx
.prop
] = fx
.now
+ fx
.unit
;
4170 fx
.elem
[ fx
.prop
] = fx
.now
;
4174 if ( document
.documentElement
["getBoundingClientRect"] )
4175 jQuery
.fn
.offset = function() {
4176 if ( !this[0] ) return { top
: 0, left
: 0 };
4177 if ( this[0] === this[0].ownerDocument
.body
) return jQuery
.offset
.bodyOffset( this[0] );
4178 var box
= this[0].getBoundingClientRect(), doc
= this[0].ownerDocument
, body
= doc
.body
, docElem
= doc
.documentElement
,
4179 clientTop
= docElem
.clientTop
|| body
.clientTop
|| 0, clientLeft
= docElem
.clientLeft
|| body
.clientLeft
|| 0,
4180 top
= box
.top
+ (self
.pageYOffset
|| jQuery
.boxModel
&& docElem
.scrollTop
|| body
.scrollTop
) - clientTop
,
4181 left
= box
.left
+ (self
.pageXOffset
|| jQuery
.boxModel
&& docElem
.scrollLeft
|| body
.scrollLeft
) - clientLeft
;
4182 return { top
: top
, left
: left
};
4185 jQuery
.fn
.offset = function() {
4186 if ( !this[0] ) return { top
: 0, left
: 0 };
4187 if ( this[0] === this[0].ownerDocument
.body
) return jQuery
.offset
.bodyOffset( this[0] );
4188 jQuery
.offset
.initialized
|| jQuery
.offset
.initialize();
4190 var elem
= this[0], offsetParent
= elem
.offsetParent
, prevOffsetParent
= elem
,
4191 doc
= elem
.ownerDocument
, computedStyle
, docElem
= doc
.documentElement
,
4192 body
= doc
.body
, defaultView
= doc
.defaultView
,
4193 prevComputedStyle
= defaultView
.getComputedStyle(elem
, null),
4194 top
= elem
.offsetTop
, left
= elem
.offsetLeft
;
4196 while ( (elem
= elem
.parentNode
) && elem
!== body
&& elem
!== docElem
) {
4197 computedStyle
= defaultView
.getComputedStyle(elem
, null);
4198 top
-= elem
.scrollTop
, left
-= elem
.scrollLeft
;
4199 if ( elem
=== offsetParent
) {
4200 top
+= elem
.offsetTop
, left
+= elem
.offsetLeft
;
4201 if ( jQuery
.offset
.doesNotAddBorder
&& !(jQuery
.offset
.doesAddBorderForTableAndCells
&& /^t(able|d|h)$/i.test(elem
.tagName
)) )
4202 top
+= parseInt( computedStyle
.borderTopWidth
, 10) || 0,
4203 left
+= parseInt( computedStyle
.borderLeftWidth
, 10) || 0;
4204 prevOffsetParent
= offsetParent
, offsetParent
= elem
.offsetParent
;
4206 if ( jQuery
.offset
.subtractsBorderForOverflowNotVisible
&& computedStyle
.overflow
!== "visible" )
4207 top
+= parseInt( computedStyle
.borderTopWidth
, 10) || 0,
4208 left
+= parseInt( computedStyle
.borderLeftWidth
, 10) || 0;
4209 prevComputedStyle
= computedStyle
;
4212 if ( prevComputedStyle
.position
=== "relative" || prevComputedStyle
.position
=== "static" )
4213 top
+= body
.offsetTop
,
4214 left
+= body
.offsetLeft
;
4216 if ( prevComputedStyle
.position
=== "fixed" )
4217 top
+= Math
.max(docElem
.scrollTop
, body
.scrollTop
),
4218 left
+= Math
.max(docElem
.scrollLeft
, body
.scrollLeft
);
4220 return { top
: top
, left
: left
};
4224 initialize: function() {
4225 if ( this.initialized
) return;
4226 var body
= document
.body
, container
= document
.createElement('div'), innerDiv
, checkDiv
, table
, td
, rules
, prop
, bodyMarginTop
= body
.style
.marginTop
,
4227 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>';
4229 rules
= { position
: 'absolute', top
: 0, left
: 0, margin
: 0, border
: 0, width
: '1px', height
: '1px', visibility
: 'hidden' };
4230 for ( prop
in rules
) container
.style
[prop
] = rules
[prop
];
4232 container
.innerHTML
= html
;
4233 body
.insertBefore(container
, body
.firstChild
);
4234 innerDiv
= container
.firstChild
, checkDiv
= innerDiv
.firstChild
, td
= innerDiv
.nextSibling
.firstChild
.firstChild
;
4236 this.doesNotAddBorder
= (checkDiv
.offsetTop
!== 5);
4237 this.doesAddBorderForTableAndCells
= (td
.offsetTop
=== 5);
4239 innerDiv
.style
.overflow
= 'hidden', innerDiv
.style
.position
= 'relative';
4240 this.subtractsBorderForOverflowNotVisible
= (checkDiv
.offsetTop
=== -5);
4242 body
.style
.marginTop
= '1px';
4243 this.doesNotIncludeMarginInBodyOffset
= (body
.offsetTop
=== 0);
4244 body
.style
.marginTop
= bodyMarginTop
;
4246 body
.removeChild(container
);
4247 this.initialized
= true;
4250 bodyOffset: function(body
) {
4251 jQuery
.offset
.initialized
|| jQuery
.offset
.initialize();
4252 var top
= body
.offsetTop
, left
= body
.offsetLeft
;
4253 if ( jQuery
.offset
.doesNotIncludeMarginInBodyOffset
)
4254 top
+= parseInt( jQuery
.curCSS(body
, 'marginTop', true), 10 ) || 0,
4255 left
+= parseInt( jQuery
.curCSS(body
, 'marginLeft', true), 10 ) || 0;
4256 return { top
: top
, left
: left
};
4262 position: function() {
4263 var left
= 0, top
= 0, results
;
4266 // Get *real* offsetParent
4267 var offsetParent
= this.offsetParent(),
4269 // Get correct offsets
4270 offset
= this.offset(),
4271 parentOffset
= /^body|html$/i.test(offsetParent
[0].tagName
) ? { top
: 0, left
: 0 } : offsetParent
.offset();
4273 // Subtract element margins
4274 // note: when an element has margin: auto the offsetLeft and marginLeft
4275 // are the same in Safari causing offset.left to incorrectly be 0
4276 offset
.top
-= num( this, 'marginTop' );
4277 offset
.left
-= num( this, 'marginLeft' );
4279 // Add offsetParent borders
4280 parentOffset
.top
+= num( offsetParent
, 'borderTopWidth' );
4281 parentOffset
.left
+= num( offsetParent
, 'borderLeftWidth' );
4283 // Subtract the two offsets
4285 top
: offset
.top
- parentOffset
.top
,
4286 left
: offset
.left
- parentOffset
.left
4293 offsetParent: function() {
4294 var offsetParent
= this[0].offsetParent
|| document
.body
;
4295 while ( offsetParent
&& (!/^body|html$/i.test(offsetParent
.tagName
) && jQuery
.css(offsetParent
, 'position') == 'static') )
4296 offsetParent
= offsetParent
.offsetParent
;
4297 return jQuery(offsetParent
);
4302 // Create scrollLeft and scrollTop methods
4303 jQuery
.each( ['Left', 'Top'], function(i
, name
) {
4304 var method
= 'scroll' + name
;
4306 jQuery
.fn
[ method
] = function(val
) {
4307 if (!this[0]) return null;
4309 return val
!== undefined ?
4311 // Set the scroll offset
4312 this.each(function() {
4313 this == window
|| this == document
?
4315 !i
? val
: jQuery(window
).scrollLeft(),
4316 i
? val
: jQuery(window
).scrollTop()
4318 this[ method
] = val
;
4321 // Return the scroll offset
4322 this[0] == window
|| this[0] == document
?
4323 self
[ i
? 'pageYOffset' : 'pageXOffset' ] ||
4324 jQuery
.boxModel
&& document
.documentElement
[ method
] ||
4325 document
.body
[ method
] :
4329 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
4330 jQuery
.each([ "Height", "Width" ], function(i
, name
){
4332 var tl
= i
? "Left" : "Top", // top or left
4333 br
= i
? "Right" : "Bottom", // bottom or right
4334 lower
= name
.toLowerCase();
4336 // innerHeight and innerWidth
4337 jQuery
.fn
["inner" + name
] = function(){
4339 jQuery
.css( this[0], lower
, false, "padding" ) :
4343 // outerHeight and outerWidth
4344 jQuery
.fn
["outer" + name
] = function(margin
) {
4346 jQuery
.css( this[0], lower
, false, margin
? "margin" : "border" ) :
4350 var type
= name
.toLowerCase();
4352 jQuery
.fn
[ type
] = function( size
) {
4353 // Get window width or height
4354 return this[0] == window
?
4355 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
4356 document
.compatMode
== "CSS1Compat" && document
.documentElement
[ "client" + name
] ||
4357 document
.body
[ "client" + name
] :
4359 // Get document width or height
4360 this[0] == document
?
4361 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
4363 document
.documentElement
["client" + name
],
4364 document
.body
["scroll" + name
], document
.documentElement
["scroll" + name
],
4365 document
.body
["offset" + name
], document
.documentElement
["offset" + name
]
4368 // Get or set width or height on the element
4369 size
=== undefined ?
4370 // Get width or height on the element
4371 (this.length
? jQuery
.css( this[0], type
) : null) :
4373 // Set the width or height on the element (default to pixels if value is unitless)
4374 this.css( type
, typeof size
=== "string" ? size
: size
+ "px" );
4381 * Add a suitable MW-specific alias
4383 $j
= jQuery
.noConflict();