3 * jQuery 1.2.6 - New Wave Javascript
5 * Copyright (c) 2008 John Resig (jquery.com)
6 * Dual licensed under the MIT (MIT-LICENSE.txt)
7 * and GPL (GPL-LICENSE.txt) licenses.
9 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
12 /////////////////////////
13 /*Comment by Naama Menda (Feb. 2009):
14 * calling jQeury.noConflict() in jQuery.init() function
15 * so this object will not override the '$' namespace used in Prototype.js
16 * sub classes using jQuery (see thickbox.js) must use the jQuery namespace instead of '$'
18 ///////////////////////
20 // Map over jQuery in case of overwrite
21 var _jQuery = window.jQuery,
22 // Map over the $ in case of overwrite
25 var jQuery = window.jQuery = window.$ = function( selector, context ) {
26 // The jQuery object is actually just the init constructor 'enhanced'
27 return new jQuery.fn.init( selector, context );
30 // A simple way to check for HTML strings or ID strings
31 // (both of which we optimize for)
32 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
34 // Is it a simple selector
35 isSimple = /^.[^:#\[\.]*$/,
37 // Will speed up references to undefined, and allows munging its name.
40 jQuery.fn = jQuery.prototype = {
41 init: function( selector, context ) {
42 // Make sure that a selection was provided
43 selector = selector || document;
45 //don't use the default '$' namespace for this object. Instead use 'jQuery'
48 // Handle $(DOMElement)
49 if ( selector.nodeType ) {
54 // Handle HTML strings
55 if ( typeof selector == "string" ) {
56 // Are we dealing with HTML string or an ID?
57 var match = quickExpr.exec( selector );
59 // Verify a match, and that no context was specified for #id
60 if ( match && (match[1] || !context) ) {
62 // HANDLE: $(html) -> $(array)
64 selector = jQuery.clean( [ match[1] ], context );
68 var elem = document.getElementById( match[3] );
70 // Make sure an element was located
72 // Handle the case where IE and Opera return items
73 // by name instead of ID
74 if ( elem.id != match[3] )
75 return jQuery().find( selector );
77 // Otherwise, we inject the element directly into the jQuery object
78 return jQuery( elem );
83 // HANDLE: $(expr, [context])
84 // (which is just equivalent to: $(content).find(expr)
86 return jQuery( context ).find( selector );
88 // HANDLE: $(function)
89 // Shortcut for document ready
90 } else if ( jQuery.isFunction( selector ) )
91 return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
93 return this.setArray(jQuery.makeArray(selector));
96 // The current version of jQuery being used
99 // The number of elements contained in the matched element set
104 // 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 jQuery.makeArray( 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 ) {
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 // Return the newly-formed element set
132 // Force the current matched set of elements to become
133 // the specified array of elements (destroying the stack in the process)
134 // You should use pushStack() in order to do this, but maintain the stack
135 setArray: function( elems ) {
136 // Resetting the length to 0, then using the native Array push
137 // is a super-fast way to populate an object with array-like properties
139 Array.prototype.push.apply( this, elems );
144 // Execute a callback for every element in the matched set.
145 // (You can seed the arguments with an array of args, but this is
146 // only used internally.)
147 each: function( callback, args ) {
148 return jQuery.each( this, callback, args );
151 // Determine the position of an element within
152 // the matched set of elements
153 index: function( elem ) {
156 // Locate the position of the desired element
157 return jQuery.inArray(
158 // If it receives a jQuery object, the first element is used
159 elem && elem.jquery ? elem[0] : elem
163 attr: function( name, value, type ) {
166 // Look for the case where we're accessing a style value
167 if ( name.constructor == String )
168 if ( value === undefined )
169 return this[0] && jQuery[ type || "attr" ]( this[0], name );
173 options[ name ] = value;
176 // Check to see if we're setting style values
177 return this.each(function(i){
178 // Set all the styles
179 for ( name in options )
184 name, jQuery.prop( this, options[ name ], type, i, name )
189 css: function( key, value ) {
190 // ignore negative width and height values
191 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
193 return this.attr( key, value, "curCSS" );
196 text: function( text ) {
197 if ( typeof text != "object" && text != null )
198 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
202 jQuery.each( text || this, function(){
203 jQuery.each( this.childNodes, function(){
204 if ( this.nodeType != 8 )
205 ret += this.nodeType != 1 ?
207 jQuery.fn.text( [ this ] );
214 wrapAll: function( html ) {
216 // The elements to wrap the target around
217 jQuery( html, this[0].ownerDocument )
219 .insertBefore( this[0] )
223 while ( elem.firstChild )
224 elem = elem.firstChild;
233 wrapInner: function( html ) {
234 return this.each(function(){
235 jQuery( this ).contents().wrapAll( html );
239 wrap: function( html ) {
240 return this.each(function(){
241 jQuery( this ).wrapAll( html );
246 return this.domManip(arguments, true, false, function(elem){
247 if (this.nodeType == 1)
248 this.appendChild( elem );
252 prepend: function() {
253 return this.domManip(arguments, true, true, function(elem){
254 if (this.nodeType == 1)
255 this.insertBefore( elem, this.firstChild );
260 return this.domManip(arguments, false, false, function(elem){
261 this.parentNode.insertBefore( elem, this );
266 return this.domManip(arguments, false, true, function(elem){
267 this.parentNode.insertBefore( elem, this.nextSibling );
272 return this.prevObject || jQuery( [] );
275 find: function( selector ) {
276 var elems = jQuery.map(this, function(elem){
277 return jQuery.find( selector, elem );
280 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
281 jQuery.unique( elems ) :
285 clone: function( events ) {
287 var ret = this.map(function(){
288 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
289 // IE copies events bound via attachEvent when
290 // using cloneNode. Calling detachEvent on the
291 // clone will also remove the events from the orignal
292 // In order to get around this, we use innerHTML.
293 // Unfortunately, this means some modifications to
294 // attributes in IE that are actually only stored
295 // as properties will not be copied (such as the
296 // the name attribute on an input).
297 var clone = this.cloneNode(true),
298 container = document.createElement("div");
299 container.appendChild(clone);
300 return jQuery.clean([container.innerHTML])[0];
302 return this.cloneNode(true);
305 // Need to set the expando to null on the cloned set if it exists
306 // removeData doesn't work here, IE removes it from the original as well
307 // this is primarily for IE but the data expando shouldn't be copied over in any browser
308 var clone = ret.find("*").andSelf().each(function(){
309 if ( this[ expando ] != undefined )
310 this[ expando ] = null;
313 // Copy the events from the original to the clone
314 if ( events === true )
315 this.find("*").andSelf().each(function(i){
316 if (this.nodeType == 3)
318 var events = jQuery.data( this, "events" );
320 for ( var type in events )
321 for ( var handler in events[ type ] )
322 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
325 // Return the cloned set
329 filter: function( selector ) {
330 return this.pushStack(
331 jQuery.isFunction( selector ) &&
332 jQuery.grep(this, function(elem, i){
333 return selector.call( elem, i );
336 jQuery.multiFilter( selector, this ) );
339 not: function( selector ) {
340 if ( selector.constructor == String )
341 // test special case where just one selector is passed in
342 if ( isSimple.test( selector ) )
343 return this.pushStack( jQuery.multiFilter( selector, this, true ) );
345 selector = jQuery.multiFilter( selector, this );
347 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
348 return this.filter(function() {
349 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
353 add: function( selector ) {
354 return this.pushStack( jQuery.unique( jQuery.merge(
356 typeof selector == 'string' ?
358 jQuery.makeArray( selector )
362 is: function( selector ) {
363 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
366 hasClass: function( selector ) {
367 return this.is( "." + selector );
370 val: function( value ) {
371 if ( value == undefined ) {
376 // We need to handle select boxes special
377 if ( jQuery.nodeName( elem, "select" ) ) {
378 var index = elem.selectedIndex,
380 options = elem.options,
381 one = elem.type == "select-one";
383 // Nothing was selected
387 // Loop through all the selected options
388 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
389 var option = options[ i ];
391 if ( option.selected ) {
392 // Get the specifc value for the option
393 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
395 // We don't need an array for one selects
399 // Multi-Selects return an array
400 values.push( value );
406 // Everything else, we just grab the value
408 return (this[0].value || "").replace(/\r/g, "");
415 if( value.constructor == Number )
418 return this.each(function(){
419 if ( this.nodeType != 1 )
422 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
423 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
424 jQuery.inArray(this.name, value) >= 0);
426 else if ( jQuery.nodeName( this, "select" ) ) {
427 var values = jQuery.makeArray(value);
429 jQuery( "option", this ).each(function(){
430 this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
431 jQuery.inArray( this.text, values ) >= 0);
434 if ( !values.length )
435 this.selectedIndex = -1;
442 html: function( value ) {
443 return value == undefined ?
447 this.empty().append( value );
450 replaceWith: function( value ) {
451 return this.after( value ).remove();
455 return this.slice( i, i + 1 );
459 return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
462 map: function( callback ) {
463 return this.pushStack( jQuery.map(this, function(elem, i){
464 return callback.call( elem, i, elem );
468 andSelf: function() {
469 return this.add( this.prevObject );
472 data: function( key, value ){
473 var parts = key.split(".");
474 parts[1] = parts[1] ? "." + parts[1] : "";
476 if ( value === undefined ) {
477 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
479 if ( data === undefined && this.length )
480 data = jQuery.data( this[0], key );
482 return data === undefined && parts[1] ?
483 this.data( parts[0] ) :
486 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
487 jQuery.data( this, key, value );
491 removeData: function( key ){
492 return this.each(function(){
493 jQuery.removeData( this, key );
497 domManip: function( args, table, reverse, callback ) {
498 var clone = this.length > 1, elems;
500 return this.each(function(){
502 elems = jQuery.clean( args, this.ownerDocument );
510 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
511 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
513 var scripts = jQuery( [] );
515 jQuery.each(elems, function(){
517 jQuery( this ).clone( true )[0] :
520 // execute all scripts after the elements have been injected
521 if ( jQuery.nodeName( elem, "script" ) )
522 scripts = scripts.add( elem );
524 // Remove any inner scripts for later evaluation
525 if ( elem.nodeType == 1 )
526 scripts = scripts.add( jQuery( "script", elem ).remove() );
528 // Inject the elements into the document
529 callback.call( obj, elem );
533 scripts.each( evalScript );
538 // Give the init function the jQuery prototype for later instantiation
539 jQuery.fn.init.prototype = jQuery.fn;
541 function evalScript( i, elem ) {
550 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
552 if ( elem.parentNode )
553 elem.parentNode.removeChild( elem );
560 jQuery.extend = jQuery.fn.extend = function() {
561 // copy reference to target object
562 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
564 // Handle a deep copy situation
565 if ( target.constructor == Boolean ) {
567 target = arguments[1] || {};
568 // skip the boolean and the target
572 // Handle case when target is a string or something (possible in deep copy)
573 if ( typeof target != "object" && typeof target != "function" )
576 // extend jQuery itself if only one argument is passed
582 for ( ; i < length; i++ )
583 // Only deal with non-null/undefined values
584 if ( (options = arguments[ i ]) != null )
585 // Extend the base object
586 for ( var name in options ) {
587 var src = target[ name ], copy = options[ name ];
589 // Prevent never-ending loop
590 if ( target === copy )
593 // Recurse if we're merging object values
594 if ( deep && copy && typeof copy == "object" && !copy.nodeType )
595 target[ name ] = jQuery.extend( deep,
596 // Never move original objects, clone them
597 src || ( copy.length != null ? [ ] : { } )
600 // Don't bring in undefined values
601 else if ( copy !== undefined )
602 target[ name ] = copy;
606 // Return the modified object
610 var expando = "jQuery" + now(), uuid = 0, windowData = {},
611 // exclude the following css properties to add px
612 exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
614 defaultView = document.defaultView || {};
617 noConflict: function( deep ) {
621 window.jQuery = _jQuery;
626 // See test/unit/core.js for details concerning this function.
627 isFunction: function( fn ) {
628 return !!fn && typeof fn != "string" && !fn.nodeName &&
629 fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
632 // check if an element is in a (or is an) XML document
633 isXMLDoc: function( elem ) {
634 return elem.documentElement && !elem.body ||
635 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
638 // Evalulates a script in a global context
639 globalEval: function( data ) {
640 data = jQuery.trim( data );
643 // Inspired by code by Andrea Giammarchi
644 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
645 var head = document.getElementsByTagName("head")[0] || document.documentElement,
646 script = document.createElement("script");
648 script.type = "text/javascript";
649 if ( jQuery.browser.msie )
652 script.appendChild( document.createTextNode( data ) );
654 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
655 // This arises when a base node is used (#2709).
656 head.insertBefore( script, head.firstChild );
657 head.removeChild( script );
661 nodeName: function( elem, name ) {
662 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
667 data: function( elem, name, data ) {
668 elem = elem == window ?
672 var id = elem[ expando ];
674 // Compute a unique ID for the element
676 id = elem[ expando ] = ++uuid;
678 // Only generate the data cache if we're
679 // trying to access or manipulate it
680 if ( name && !jQuery.cache[ id ] )
681 jQuery.cache[ id ] = {};
683 // Prevent overriding the named cache with undefined values
684 if ( data !== undefined )
685 jQuery.cache[ id ][ name ] = data;
687 // Return the named cache data, or the ID for the element
689 jQuery.cache[ id ][ name ] :
693 removeData: function( elem, name ) {
694 elem = elem == window ?
698 var id = elem[ expando ];
700 // If we want to remove a specific section of the element's data
702 if ( jQuery.cache[ id ] ) {
703 // Remove the section of cache data
704 delete jQuery.cache[ id ][ name ];
706 // If we've removed all the data, remove the element's cache
709 for ( name in jQuery.cache[ id ] )
713 jQuery.removeData( elem );
716 // Otherwise, we want to remove all of the element's data
718 // Clean up the element expando
720 delete elem[ expando ];
722 // IE has trouble directly removing the expando
723 // but it's ok with using removeAttribute
724 if ( elem.removeAttribute )
725 elem.removeAttribute( expando );
728 // Completely remove the data cache
729 delete jQuery.cache[ id ];
733 // args is for internal usage only
734 each: function( object, callback, args ) {
735 var name, i = 0, length = object.length;
738 if ( length == undefined ) {
739 for ( name in object )
740 if ( callback.apply( object[ name ], args ) === false )
743 for ( ; i < length; )
744 if ( callback.apply( object[ i++ ], args ) === false )
747 // A special, fast, case for the most common use of each
749 if ( length == undefined ) {
750 for ( name in object )
751 if ( callback.call( object[ name ], name, object[ name ] ) === false )
754 for ( var value = object[0];
755 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
761 prop: function( elem, value, type, i, name ) {
762 // Handle executable functions
763 if ( jQuery.isFunction( value ) )
764 value = value.call( elem, i );
766 // Handle passing in a number to a CSS property
767 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
773 // internal only, use addClass("class")
774 add: function( elem, classNames ) {
775 jQuery.each((classNames || "").split(/\s+/), function(i, className){
776 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
777 elem.className += (elem.className ? " " : "") + className;
781 // internal only, use removeClass("class")
782 remove: function( elem, classNames ) {
783 if (elem.nodeType == 1)
784 elem.className = classNames != undefined ?
785 jQuery.grep(elem.className.split(/\s+/), function(className){
786 return !jQuery.className.has( classNames, className );
791 // internal only, use hasClass("class")
792 has: function( elem, className ) {
793 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
797 // A method for quickly swapping in/out CSS properties to get correct calculations
798 swap: function( elem, options, callback ) {
800 // Remember the old values, and insert the new ones
801 for ( var name in options ) {
802 old[ name ] = elem.style[ name ];
803 elem.style[ name ] = options[ name ];
806 callback.call( elem );
808 // Revert the old values
809 for ( var name in options )
810 elem.style[ name ] = old[ name ];
813 css: function( elem, name, force ) {
814 if ( name == "width" || name == "height" ) {
815 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
818 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
819 var padding = 0, border = 0;
820 jQuery.each( which, function() {
821 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
822 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
824 val -= Math.round(padding + border);
827 if ( jQuery(elem).is(":visible") )
830 jQuery.swap( elem, props, getWH );
832 return Math.max(0, val);
835 return jQuery.curCSS( elem, name, force );
838 curCSS: function( elem, name, force ) {
839 var ret, style = elem.style;
841 // A helper method for determining if an element's values are broken
842 function color( elem ) {
843 if ( !jQuery.browser.safari )
846 // defaultView is cached
847 var ret = defaultView.getComputedStyle( elem, null );
848 return !ret || ret.getPropertyValue("color") == "";
851 // We need to handle opacity special in IE
852 if ( name == "opacity" && jQuery.browser.msie ) {
853 ret = jQuery.attr( style, "opacity" );
859 // Opera sometimes will give the wrong display answer, this fixes it, see #2037
860 if ( jQuery.browser.opera && name == "display" ) {
861 var save = style.outline;
862 style.outline = "0 solid black";
863 style.outline = save;
866 // Make sure we're using the right name for getting the float value
867 if ( name.match( /float/i ) )
870 if ( !force && style && style[ name ] )
873 else if ( defaultView.getComputedStyle ) {
875 // Only "float" is needed here
876 if ( name.match( /float/i ) )
879 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
881 var computedStyle = defaultView.getComputedStyle( elem, null );
883 if ( computedStyle && !color( elem ) )
884 ret = computedStyle.getPropertyValue( name );
886 // If the element isn't reporting its values properly in Safari
887 // then some display: none elements are involved
889 var swap = [], stack = [], a = elem, i = 0;
891 // Locate all of the parent display: none elements
892 for ( ; a && color(a); a = a.parentNode )
895 // Go through and make them visible, but in reverse
896 // (It would be better if we knew the exact display type that they had)
897 for ( ; i < stack.length; i++ )
898 if ( color( stack[ i ] ) ) {
899 swap[ i ] = stack[ i ].style.display;
900 stack[ i ].style.display = "block";
903 // Since we flip the display style, we have to handle that
904 // one special, otherwise get the value
905 ret = name == "display" && swap[ stack.length - 1 ] != null ?
907 ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
909 // Finally, revert the display styles back
910 for ( i = 0; i < swap.length; i++ )
911 if ( swap[ i ] != null )
912 stack[ i ].style.display = swap[ i ];
915 // We should always get a number back from opacity
916 if ( name == "opacity" && ret == "" )
919 } else if ( elem.currentStyle ) {
920 var camelCase = name.replace(/\-(\w)/g, function(all, letter){
921 return letter.toUpperCase();
924 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
926 // From the awesome hack by Dean Edwards
927 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
929 // If we're not dealing with a regular pixel number
930 // but a number that has a weird ending, we need to convert it to pixels
931 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
932 // Remember the original values
933 var left = style.left, rsLeft = elem.runtimeStyle.left;
935 // Put in the new values to get a computed value out
936 elem.runtimeStyle.left = elem.currentStyle.left;
937 style.left = ret || 0;
938 ret = style.pixelLeft + "px";
940 // Revert the changed values
942 elem.runtimeStyle.left = rsLeft;
949 clean: function( elems, context ) {
951 context = context || document;
952 // !context.createElement fails in IE with an error but returns typeof 'object'
953 if (typeof context.createElement == 'undefined')
954 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
956 jQuery.each(elems, function(i, elem){
960 if ( elem.constructor == Number )
963 // Convert html string into DOM nodes
964 if ( typeof elem == "string" ) {
965 // Fix "XHTML"-style tags in all browsers
966 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
967 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
969 front + "></" + tag + ">";
972 // Trim whitespace, otherwise indexOf won't work as expected
973 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
976 // option or optgroup
977 !tags.indexOf("<opt") &&
978 [ 1, "<select multiple='multiple'>", "</select>" ] ||
980 !tags.indexOf("<leg") &&
981 [ 1, "<fieldset>", "</fieldset>" ] ||
983 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
984 [ 1, "<table>", "</table>" ] ||
986 !tags.indexOf("<tr") &&
987 [ 2, "<table><tbody>", "</tbody></table>" ] ||
989 // <thead> matched above
990 (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
991 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
993 !tags.indexOf("<col") &&
994 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
996 // IE can't serialize <link> and <script> tags normally
997 jQuery.browser.msie &&
998 [ 1, "div<div>", "</div>" ] ||
1002 // Go to html and back, then peel off extra wrappers
1003 div.innerHTML = wrap[1] + elem + wrap[2];
1005 // Move to the right depth
1007 div = div.lastChild;
1009 // Remove IE's autoinserted <tbody> from table fragments
1010 if ( jQuery.browser.msie ) {
1012 // String was a <table>, *may* have spurious <tbody>
1013 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
1014 div.firstChild && div.firstChild.childNodes :
1016 // String was a bare <thead> or <tfoot>
1017 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
1021 for ( var j = tbody.length - 1; j >= 0 ; --j )
1022 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
1023 tbody[ j ].parentNode.removeChild( tbody[ j ] );
1025 // IE completely kills leading whitespace when innerHTML is used
1026 if ( /^\s/.test( elem ) )
1027 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
1031 elem = jQuery.makeArray( div.childNodes );
1034 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
1037 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
1041 ret = jQuery.merge( ret, elem );
1048 attr: function( elem, name, value ) {
1049 // don't set attributes on text and comment nodes
1050 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
1053 var notxml = !jQuery.isXMLDoc( elem ),
1054 // Whether we are setting (or getting)
1055 set = value !== undefined,
1056 msie = jQuery.browser.msie;
1058 // Try to normalize/fix the name
1059 name = notxml && jQuery.props[ name ] || name;
1061 // Only do all the following if this is a node (faster for style)
1062 // IE elem.getAttribute passes even for style
1063 if ( elem.tagName ) {
1065 // These attributes require special treatment
1066 var special = /href|src|style/.test( name );
1068 // Safari mis-reports the default selected property of a hidden option
1069 // Accessing the parent's selectedIndex property fixes it
1070 if ( name == "selected" && jQuery.browser.safari )
1071 elem.parentNode.selectedIndex;
1073 // If applicable, access the attribute via the DOM 0 way
1074 if ( name in elem && notxml && !special ) {
1076 // We can't allow the type property to be changed (since it causes problems in IE)
1077 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
1078 throw "type property can't be changed";
1080 elem[ name ] = value;
1083 // browsers index elements by id/name on forms, give priority to attributes.
1084 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1085 return elem.getAttributeNode( name ).nodeValue;
1087 return elem[ name ];
1090 if ( msie && notxml && name == "style" )
1091 return jQuery.attr( elem.style, "cssText", value );
1094 // convert the value to a string (all browsers do this but IE) see #1070
1095 elem.setAttribute( name, "" + value );
1097 var attr = msie && notxml && special
1098 // Some attributes require a special call on IE
1099 ? elem.getAttribute( name, 2 )
1100 : elem.getAttribute( name );
1102 // Non-existent attributes return null, we normalize to undefined
1103 return attr === null ? undefined : attr;
1106 // elem is actually elem.style ... set the style
1108 // IE uses filters for opacity
1109 if ( msie && name == "opacity" ) {
1111 // IE has trouble with opacity if it does not have layout
1112 // Force it by setting the zoom level
1115 // Set the alpha filter to set the opacity
1116 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1117 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1120 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1121 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1125 name = name.replace(/-([a-z])/ig, function(all, letter){
1126 return letter.toUpperCase();
1130 elem[ name ] = value;
1132 return elem[ name ];
1135 trim: function( text ) {
1136 return (text || "").replace( /^\s+|\s+$/g, "" );
1139 makeArray: function( array ) {
1142 if( array != null ){
1143 var i = array.length;
1144 //the window, strings and functions also have 'length'
1145 if( i == null || array.split || array.setInterval || array.call )
1149 ret[--i] = array[i];
1155 inArray: function( elem, array ) {
1156 for ( var i = 0, length = array.length; i < length; i++ )
1157 // Use === because on IE, window == document
1158 if ( array[ i ] === elem )
1164 merge: function( first, second ) {
1165 // We have to loop this way because IE & Opera overwrite the length
1166 // expando of getElementsByTagName
1167 var i = 0, elem, pos = first.length;
1168 // Also, we need to make sure that the correct elements are being returned
1169 // (IE returns comment nodes in a '*' query)
1170 if ( jQuery.browser.msie ) {
1171 while ( elem = second[ i++ ] )
1172 if ( elem.nodeType != 8 )
1173 first[ pos++ ] = elem;
1176 while ( elem = second[ i++ ] )
1177 first[ pos++ ] = elem;
1182 unique: function( array ) {
1183 var ret = [], done = {};
1187 for ( var i = 0, length = array.length; i < length; i++ ) {
1188 var id = jQuery.data( array[ i ] );
1190 if ( !done[ id ] ) {
1192 ret.push( array[ i ] );
1203 grep: function( elems, callback, inv ) {
1206 // Go through the array, only saving the items
1207 // that pass the validator function
1208 for ( var i = 0, length = elems.length; i < length; i++ )
1209 if ( !inv != !callback( elems[ i ], i ) )
1210 ret.push( elems[ i ] );
1215 map: function( elems, callback ) {
1218 // Go through the array, translating each of the items to their
1219 // new value (or values).
1220 for ( var i = 0, length = elems.length; i < length; i++ ) {
1221 var value = callback( elems[ i ], i );
1223 if ( value != null )
1224 ret[ ret.length ] = value;
1227 return ret.concat.apply( [], ret );
1231 var userAgent = navigator.userAgent.toLowerCase();
1233 // Figure out what browser is being used
1235 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
1236 safari: /webkit/.test( userAgent ),
1237 opera: /opera/.test( userAgent ),
1238 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1239 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1242 var styleFloat = jQuery.browser.msie ?
1247 // Check to see if the W3C box model is being used
1248 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
1252 "class": "className",
1253 "float": styleFloat,
1254 cssFloat: styleFloat,
1255 styleFloat: styleFloat,
1256 readonly: "readOnly",
1257 maxlength: "maxLength",
1258 cellspacing: "cellSpacing"
1263 parent: function(elem){return elem.parentNode;},
1264 parents: function(elem){return jQuery.dir(elem,"parentNode");},
1265 next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1266 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1267 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1268 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1269 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1270 children: function(elem){return jQuery.sibling(elem.firstChild);},
1271 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1272 }, function(name, fn){
1273 jQuery.fn[ name ] = function( selector ) {
1274 var ret = jQuery.map( this, fn );
1276 if ( selector && typeof selector == "string" )
1277 ret = jQuery.multiFilter( selector, ret );
1279 return this.pushStack( jQuery.unique( ret ) );
1285 prependTo: "prepend",
1286 insertBefore: "before",
1287 insertAfter: "after",
1288 replaceAll: "replaceWith"
1289 }, function(name, original){
1290 jQuery.fn[ name ] = function() {
1291 var args = arguments;
1293 return this.each(function(){
1294 for ( var i = 0, length = args.length; i < length; i++ )
1295 jQuery( args[ i ] )[ original ]( this );
1301 removeAttr: function( name ) {
1302 jQuery.attr( this, name, "" );
1303 if (this.nodeType == 1)
1304 this.removeAttribute( name );
1307 addClass: function( classNames ) {
1308 jQuery.className.add( this, classNames );
1311 removeClass: function( classNames ) {
1312 jQuery.className.remove( this, classNames );
1315 toggleClass: function( classNames ) {
1316 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
1319 remove: function( selector ) {
1320 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
1321 // Prevent memory leaks
1322 jQuery( "*", this ).add(this).each(function(){
1323 jQuery.event.remove(this);
1324 jQuery.removeData(this);
1326 if (this.parentNode)
1327 this.parentNode.removeChild( this );
1332 // Remove element nodes and prevent memory leaks
1333 jQuery( ">*", this ).remove();
1335 // Remove any remaining nodes
1336 while ( this.firstChild )
1337 this.removeChild( this.firstChild );
1339 }, function(name, fn){
1340 jQuery.fn[ name ] = function(){
1341 return this.each( fn, arguments );
1345 jQuery.each([ "Height", "Width" ], function(i, name){
1346 var type = name.toLowerCase();
1348 jQuery.fn[ type ] = function( size ) {
1349 // Get window width or height
1350 return this[0] == window ?
1351 // Opera reports document.body.client[Width/Height] properly in both quirks and standards
1352 jQuery.browser.opera && document.body[ "client" + name ] ||
1354 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
1355 jQuery.browser.safari && window[ "inner" + name ] ||
1357 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
1358 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
1360 // Get document width or height
1361 this[0] == document ?
1362 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
1364 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
1365 Math.max(document.body["offset" + name], document.documentElement["offset" + name])
1368 // Get or set width or height on the element
1370 // Get width or height on the element
1371 (this.length ? jQuery.css( this[0], type ) : null) :
1373 // Set the width or height on the element (default to pixels if value is unitless)
1374 this.css( type, size.constructor == String ? size : size + "px" );
1378 // Helper function used by the dimensions and offset modules
1379 function num(elem, prop) {
1380 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1381 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
1382 "(?:[\\w*_-]|\\\\.)" :
1383 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
1384 quickChild = new RegExp("^>\\s*(" + chars + "+)"),
1385 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
1386 quickClass = new RegExp("^([#.]?)(" + chars + "*)");
1390 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
1391 "#": function(a,i,m){return a.getAttribute("id")==m[2];},
1394 lt: function(a,i,m){return i<m[3]-0;},
1395 gt: function(a,i,m){return i>m[3]-0;},
1396 nth: function(a,i,m){return m[3]-0==i;},
1397 eq: function(a,i,m){return m[3]-0==i;},
1398 first: function(a,i){return i==0;},
1399 last: function(a,i,m,r){return i==r.length-1;},
1400 even: function(a,i){return i%2==0;},
1401 odd: function(a,i){return i%2;},
1404 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
1405 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
1406 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
1409 parent: function(a){return a.firstChild;},
1410 empty: function(a){return !a.firstChild;},
1413 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
1416 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
1417 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
1420 enabled: function(a){return !a.disabled;},
1421 disabled: function(a){return a.disabled;},
1422 checked: function(a){return a.checked;},
1423 selected: function(a){return a.selected||jQuery.attr(a,"selected");},
1426 text: function(a){return "text"==a.type;},
1427 radio: function(a){return "radio"==a.type;},
1428 checkbox: function(a){return "checkbox"==a.type;},
1429 file: function(a){return "file"==a.type;},
1430 password: function(a){return "password"==a.type;},
1431 submit: function(a){return "submit"==a.type;},
1432 image: function(a){return "image"==a.type;},
1433 reset: function(a){return "reset"==a.type;},
1434 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
1435 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
1438 has: function(a,i,m){return jQuery.find(m[3],a).length;},
1441 header: function(a){return /h\d/i.test(a.nodeName);},
1444 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
1448 // The regular expressions that power the parsing engine
1450 // Match: [@value='test'], [@foo]
1451 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
1453 // Match: :contains('foo')
1454 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
1456 // Match: :even, :last-child, #id, .class
1457 new RegExp("^([:.#]*)(" + chars + "+)")
1460 multiFilter: function( expr, elems, not ) {
1463 while ( expr && expr != old ) {
1465 var f = jQuery.filter( expr, elems, not );
1466 expr = f.t.replace(/^\s*,\s*/, "" );
1467 cur = not ? elems = f.r : jQuery.merge( cur, f.r );
1473 find: function( t, context ) {
1474 // Quickly handle non-string expressions
1475 if ( typeof t != "string" )
1478 // check to make sure context is a DOM element or a document
1479 if ( context && context.nodeType != 1 && context.nodeType != 9)
1482 // Set the correct context (if none is provided)
1483 context = context || document;
1485 // Initialize the search
1486 var ret = [context], done = [], last, nodeName;
1488 // Continue while a selector expression exists, and while
1489 // we're no longer looping upon ourselves
1490 while ( t && last != t ) {
1496 var foundToken = false,
1498 // An attempt at speeding up child selectors that
1499 // point to a specific element tag
1505 nodeName = m[1].toUpperCase();
1507 // Perform our own iteration and filter
1508 for ( var i = 0; ret[i]; i++ )
1509 for ( var c = ret[i].firstChild; c; c = c.nextSibling )
1510 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
1514 t = t.replace( re, "" );
1515 if ( t.indexOf(" ") == 0 ) continue;
1518 re = /^([>+~])\s*(\w*)/i;
1520 if ( (m = re.exec(t)) != null ) {
1524 nodeName = m[2].toUpperCase();
1527 for ( var j = 0, rl = ret.length; j < rl; j++ ) {
1528 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
1529 for ( ; n; n = n.nextSibling )
1530 if ( n.nodeType == 1 ) {
1531 var id = jQuery.data(n);
1533 if ( m == "~" && merge[id] ) break;
1535 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
1536 if ( m == "~" ) merge[id] = true;
1540 if ( m == "+" ) break;
1546 // And remove the token
1547 t = jQuery.trim( t.replace( re, "" ) );
1552 // See if there's still an expression, and that we haven't already
1554 if ( t && !foundToken ) {
1555 // Handle multiple expressions
1556 if ( !t.indexOf(",") ) {
1557 // Clean the result set
1558 if ( context == ret[0] ) ret.shift();
1560 // Merge the result sets
1561 done = jQuery.merge( done, ret );
1563 // Reset the context
1564 r = ret = [context];
1566 // Touch up the selector string
1567 t = " " + t.substr(1,t.length);
1570 // Optimize for the case nodeName#idName
1572 var m = re2.exec(t);
1574 // Re-organize the results, so that they're consistent
1576 m = [ 0, m[2], m[3], m[1] ];
1579 // Otherwise, do a traditional filter check for
1580 // ID, class, and element selectors
1585 m[2] = m[2].replace(/\\/g, "");
1587 var elem = ret[ret.length-1];
1589 // Try to do a global search by ID, where we can
1590 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
1591 // Optimization for HTML document case
1592 var oid = elem.getElementById(m[2]);
1594 // Do a quick check for the existence of the actual ID attribute
1595 // to avoid selecting by the name attribute in IE
1596 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
1597 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
1598 oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
1600 // Do a quick check for node name (where applicable) so
1601 // that div#foo searches will be really fast
1602 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
1604 // We need to find all descendant elements
1605 for ( var i = 0; ret[i]; i++ ) {
1606 // Grab the tag name being searched for
1607 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
1609 // Handle IE7 being really dumb about <object>s
1610 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
1613 r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
1616 // It's faster to filter by class and be done with it
1618 r = jQuery.classFilter( r, m[2] );
1620 // Same with ID filtering
1621 if ( m[1] == "#" ) {
1624 // Try to find the element with the ID
1625 for ( var i = 0; r[i]; i++ )
1626 if ( r[i].getAttribute("id") == m[2] ) {
1637 t = t.replace( re2, "" );
1642 // If a selector string still exists
1644 // Attempt to filter it
1645 var val = jQuery.filter(t,r);
1647 t = jQuery.trim(val.t);
1651 // An error occurred with the selector;
1652 // just return an empty set instead
1656 // Remove the root context
1657 if ( ret && context == ret[0] )
1660 // And combine the results
1661 done = jQuery.merge( done, ret );
1666 classFilter: function(r,m,not){
1669 for ( var i = 0; r[i]; i++ ) {
1670 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
1671 if ( !not && pass || not && !pass )
1677 filter: function(t,r,not) {
1680 // Look for common filter expressions
1681 while ( t && t != last ) {
1684 var p = jQuery.parse, m;
1686 for ( var i = 0; p[i]; i++ ) {
1690 // Remove what we just matched
1691 t = t.substring( m[0].length );
1693 m[2] = m[2].replace(/\\/g, "");
1701 // :not() is a special case that can be optimized by
1702 // keeping it out of the expression list
1703 if ( m[1] == ":" && m[2] == "not" )
1704 // optimize if only one selector found (most common case)
1705 r = isSimple.test( m[3] ) ?
1706 jQuery.filter(m[3], r, true).r :
1707 jQuery( r ).not( m[3] );
1709 // We can get a big speed boost by filtering by class here
1710 else if ( m[1] == "." )
1711 r = jQuery.classFilter(r, m[2], not);
1713 else if ( m[1] == "[" ) {
1714 var tmp = [], type = m[3];
1716 for ( var i = 0, rl = r.length; i < rl; i++ ) {
1717 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
1719 if ( z == null || /href|src|selected/.test(m[2]) )
1720 z = jQuery.attr(a,m[2]) || '';
1722 if ( (type == "" && !!z ||
1723 type == "=" && z == m[5] ||
1724 type == "!=" && z != m[5] ||
1725 type == "^=" && z && !z.indexOf(m[5]) ||
1726 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
1727 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
1733 // We can get a speed boost by handling nth-child here
1734 } else if ( m[1] == ":" && m[2] == "nth-child" ) {
1735 var merge = {}, tmp = [],
1736 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1737 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1738 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
1739 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
1740 // calculate the numbers (first)n+(last) including if they are negative
1741 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
1743 // loop through all the elements left in the jQuery object
1744 for ( var i = 0, rl = r.length; i < rl; i++ ) {
1745 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
1750 for ( var n = parentNode.firstChild; n; n = n.nextSibling )
1751 if ( n.nodeType == 1 )
1760 if ( node.nodeIndex == last )
1762 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
1771 // Otherwise, find the expression to execute
1773 var fn = jQuery.expr[ m[1] ];
1774 if ( typeof fn == "object" )
1777 if ( typeof fn == "string" )
1778 fn = eval("false||function(a,i){return " + fn + ";}");
1780 // Execute it against the current filter
1781 r = jQuery.grep( r, function(elem, i){
1782 return fn(elem, i, m, r);
1787 // Return an array of filtered elements (r)
1788 // and the modified expression string (t)
1789 return { r: r, t: t };
1792 dir: function( elem, dir ){
1795 while ( cur && cur != document ) {
1796 if ( cur.nodeType == 1 )
1797 matched.push( cur );
1803 nth: function(cur,result,dir,elem){
1804 result = result || 1;
1807 for ( ; cur; cur = cur[dir] )
1808 if ( cur.nodeType == 1 && ++num == result )
1814 sibling: function( n, elem ) {
1817 for ( ; n; n = n.nextSibling ) {
1818 if ( n.nodeType == 1 && n != elem )
1826 * A number of helper functions used for managing events.
1827 * Many of the ideas behind this code orignated from
1828 * Dean Edwards' addEvent library.
1832 // Bind an event to an element
1833 // Original by Dean Edwards
1834 add: function(elem, types, handler, data) {
1835 if ( elem.nodeType == 3 || elem.nodeType == 8 )
1838 // For whatever reason, IE has trouble passing the window object
1839 // around, causing it to be cloned in the process
1840 if ( jQuery.browser.msie && elem.setInterval )
1843 // Make sure that the function being executed has a unique ID
1844 if ( !handler.guid )
1845 handler.guid = this.guid++;
1847 // if data is passed, bind to handler
1848 if( data != undefined ) {
1849 // Create temporary function pointer to original handler
1852 // Create unique handler function, wrapped around original handler
1853 handler = this.proxy( fn, function() {
1854 // Pass arguments and context to original handler
1855 return fn.apply(this, arguments);
1858 // Store data in unique handler
1859 handler.data = data;
1862 // Init the element's event structure
1863 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
1864 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
1865 // Handle the second event of a trigger and when
1866 // an event is called after a page has unloaded
1867 if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
1868 return jQuery.event.handle.apply(arguments.callee.elem, arguments);
1870 // Add elem as a property of the handle function
1871 // This is to prevent a memory leak with non-native
1875 // Handle multiple events separated by a space
1876 // jQuery(...).bind("mouseover mouseout", fn);
1877 jQuery.each(types.split(/\s+/), function(index, type) {
1878 // Namespaced event handlers
1879 var parts = type.split(".");
1881 handler.type = parts[1];
1883 // Get the current list of functions bound to this event
1884 var handlers = events[type];
1886 // Init the event handler queue
1888 handlers = events[type] = {};
1890 // Check for a special event handler
1891 // Only use addEventListener/attachEvent if the special
1892 // events handler returns false
1893 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
1894 // Bind the global event handler to the element
1895 if (elem.addEventListener)
1896 elem.addEventListener(type, handle, false);
1897 else if (elem.attachEvent)
1898 elem.attachEvent("on" + type, handle);
1902 // Add the function to the element's handler list
1903 handlers[handler.guid] = handler;
1905 // Keep track of which events have been used, for global triggering
1906 jQuery.event.global[type] = true;
1909 // Nullify elem to prevent memory leaks in IE
1916 // Detach an event or set of events from an element
1917 remove: function(elem, types, handler) {
1918 // don't do events on text and comment nodes
1919 if ( elem.nodeType == 3 || elem.nodeType == 8 )
1922 var events = jQuery.data(elem, "events"), ret, index;
1925 // Unbind all events for the element
1926 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
1927 for ( var type in events )
1928 this.remove( elem, type + (types || "") );
1930 // types is actually an event object here
1932 handler = types.handler;
1936 // Handle multiple events seperated by a space
1937 // jQuery(...).unbind("mouseover mouseout", fn);
1938 jQuery.each(types.split(/\s+/), function(index, type){
1939 // Namespaced event handlers
1940 var parts = type.split(".");
1943 if ( events[type] ) {
1944 // remove the given handler for the given type
1946 delete events[type][handler.guid];
1948 // remove all handlers for the given type
1950 for ( handler in events[type] )
1951 // Handle the removal of namespaced events
1952 if ( !parts[1] || events[type][handler].type == parts[1] )
1953 delete events[type][handler];
1955 // remove generic event handler if no more handlers exist
1956 for ( ret in events[type] ) break;
1958 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
1959 if (elem.removeEventListener)
1960 elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
1961 else if (elem.detachEvent)
1962 elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
1965 delete events[type];
1971 // Remove the expando if it's no longer used
1972 for ( ret in events ) break;
1974 var handle = jQuery.data( elem, "handle" );
1975 if ( handle ) handle.elem = null;
1976 jQuery.removeData( elem, "events" );
1977 jQuery.removeData( elem, "handle" );
1982 trigger: function(type, data, elem, donative, extra) {
1983 // Clone the incoming data, if any
1984 data = jQuery.makeArray(data);
1986 if ( type.indexOf("!") >= 0 ) {
1987 type = type.slice(0, -1);
1988 var exclusive = true;
1991 // Handle a global trigger
1993 // Only trigger if we've ever bound an event for it
1994 if ( this.global[type] )
1995 jQuery("*").add([window, document]).trigger(type, data);
1997 // Handle triggering a single element
1999 // don't do events on text and comment nodes
2000 if ( elem.nodeType == 3 || elem.nodeType == 8 )
2003 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
2004 // Check to see if we need to provide a fake event, or not
2005 event = !data[0] || !data[0].preventDefault;
2007 // Pass along a fake event
2012 preventDefault: function(){},
2013 stopPropagation: function(){},
2016 data[0][expando] = true; // no need to fix fake event
2019 // Enforce the right trigger type
2020 data[0].type = type;
2022 data[0].exclusive = true;
2024 // Trigger the event, it is assumed that "handle" is a function
2025 var handle = jQuery.data(elem, "handle");
2027 val = handle.apply( elem, data );
2029 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2030 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2033 // Extra functions don't get the custom event object
2037 // Handle triggering of extra function
2038 if ( extra && jQuery.isFunction( extra ) ) {
2039 // call the extra function and tack the current return value on the end for possible inspection
2040 ret = extra.apply( elem, val == null ? data : data.concat( val ) );
2041 // if anything is returned, give it precedence and have it overwrite the previous value
2042 if (ret !== undefined)
2046 // Trigger the native events (except for clicks on links)
2047 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2048 this.triggered = true;
2051 // prevent IE from throwing an error for some hidden elements
2055 this.triggered = false;
2061 handle: function(event) {
2062 // returned undefined or false
2063 var val, ret, namespace, all, handlers;
2065 event = arguments[0] = jQuery.event.fix( event || window.event );
2067 // Namespaced event handlers
2068 namespace = event.type.split(".");
2069 event.type = namespace[0];
2070 namespace = namespace[1];
2071 // Cache this now, all = true means, any handler
2072 all = !namespace && !event.exclusive;
2074 handlers = ( jQuery.data(this, "events") || {} )[event.type];
2076 for ( var j in handlers ) {
2077 var handler = handlers[j];
2079 // Filter the functions by class
2080 if ( all || handler.type == namespace ) {
2081 // Pass in a reference to the handler function itself
2082 // So that we can later remove it
2083 event.handler = handler;
2084 event.data = handler.data;
2086 ret = handler.apply( this, arguments );
2088 if ( val !== false )
2091 if ( ret === false ) {
2092 event.preventDefault();
2093 event.stopPropagation();
2101 fix: function(event) {
2102 if ( event[expando] == true )
2105 // store a copy of the original event object
2106 // and "clone" to set read-only properties
2107 var originalEvent = event;
2108 event = { originalEvent: originalEvent };
2109 var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
2110 for ( var i=props.length; i; i-- )
2111 event[ props[i] ] = originalEvent[ props[i] ];
2114 event[expando] = true;
2116 // add preventDefault and stopPropagation since
2117 // they will not work on the clone
2118 event.preventDefault = function() {
2119 // if preventDefault exists run it on the original event
2120 if (originalEvent.preventDefault)
2121 originalEvent.preventDefault();
2122 // otherwise set the returnValue property of the original event to false (IE)
2123 originalEvent.returnValue = false;
2125 event.stopPropagation = function() {
2126 // if stopPropagation exists run it on the original event
2127 if (originalEvent.stopPropagation)
2128 originalEvent.stopPropagation();
2129 // otherwise set the cancelBubble property of the original event to true (IE)
2130 originalEvent.cancelBubble = true;
2134 event.timeStamp = event.timeStamp || now();
2136 // Fix target property, if necessary
2137 if ( !event.target )
2138 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2140 // check if target is a textnode (safari)
2141 if ( event.target.nodeType == 3 )
2142 event.target = event.target.parentNode;
2144 // Add relatedTarget, if necessary
2145 if ( !event.relatedTarget && event.fromElement )
2146 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2148 // Calculate pageX/Y if missing and clientX/Y available
2149 if ( event.pageX == null && event.clientX != null ) {
2150 var doc = document.documentElement, body = document.body;
2151 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2152 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2155 // Add which for key events
2156 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2157 event.which = event.charCode || event.keyCode;
2159 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2160 if ( !event.metaKey && event.ctrlKey )
2161 event.metaKey = event.ctrlKey;
2163 // Add which for click: 1 == left; 2 == middle; 3 == right
2164 // Note: button is not normalized, so don't use it
2165 if ( !event.which && event.button )
2166 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2171 proxy: function( fn, proxy ){
2172 // Set the guid of unique handler to the same of original handler, so it can be removed
2173 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2174 // So proxy can be declared as an argument
2181 // Make sure the ready event is setup
2186 teardown: function() { return; }
2191 if ( jQuery.browser.msie ) return false;
2192 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
2196 teardown: function() {
2197 if ( jQuery.browser.msie ) return false;
2198 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
2202 handler: function(event) {
2203 // If we actually just moused on to a sub-element, ignore it
2204 if ( withinElement(event, this) ) return true;
2205 // Execute the right handlers by setting the event type to mouseenter
2206 event.type = "mouseenter";
2207 return jQuery.event.handle.apply(this, arguments);
2213 if ( jQuery.browser.msie ) return false;
2214 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
2218 teardown: function() {
2219 if ( jQuery.browser.msie ) return false;
2220 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
2224 handler: function(event) {
2225 // If we actually just moused on to a sub-element, ignore it
2226 if ( withinElement(event, this) ) return true;
2227 // Execute the right handlers by setting the event type to mouseleave
2228 event.type = "mouseleave";
2229 return jQuery.event.handle.apply(this, arguments);
2236 bind: function( type, data, fn ) {
2237 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2238 jQuery.event.add( this, type, fn || data, fn && data );
2242 one: function( type, data, fn ) {
2243 var one = jQuery.event.proxy( fn || data, function(event) {
2244 jQuery(this).unbind(event, one);
2245 return (fn || data).apply( this, arguments );
2247 return this.each(function(){
2248 jQuery.event.add( this, type, one, fn && data);
2252 unbind: function( type, fn ) {
2253 return this.each(function(){
2254 jQuery.event.remove( this, type, fn );
2258 trigger: function( type, data, fn ) {
2259 return this.each(function(){
2260 jQuery.event.trigger( type, data, this, true, fn );
2264 triggerHandler: function( type, data, fn ) {
2265 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
2268 toggle: function( fn ) {
2269 // Save reference to arguments for access in closure
2270 var args = arguments, i = 1;
2272 // link all the functions, so any of them can unbind this click handler
2273 while( i < args.length )
2274 jQuery.event.proxy( fn, args[i++] );
2276 return this.click( jQuery.event.proxy( fn, function(event) {
2277 // Figure out which function to execute
2278 this.lastToggle = ( this.lastToggle || 0 ) % i;
2280 // Make sure that clicks stop
2281 event.preventDefault();
2283 // and execute the function
2284 return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2288 hover: function(fnOver, fnOut) {
2289 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
2292 ready: function(fn) {
2293 // Attach the listeners
2296 // If the DOM is already ready
2297 if ( jQuery.isReady )
2298 // Execute the function immediately
2299 fn.call( document, jQuery );
2301 // Otherwise, remember the function for later
2303 // Add the function to the wait list
2304 jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
2313 // Handle when the DOM is ready
2315 // Make sure that the DOM is not already loaded
2316 if ( !jQuery.isReady ) {
2317 // Remember that the DOM is ready
2318 jQuery.isReady = true;
2320 // If there are functions bound, to execute
2321 if ( jQuery.readyList ) {
2322 // Execute all of them
2323 jQuery.each( jQuery.readyList, function(){
2324 this.call( document );
2327 // Reset the list of functions
2328 jQuery.readyList = null;
2331 // Trigger any bound ready events
2332 jQuery(document).triggerHandler("ready");
2337 var readyBound = false;
2339 function bindReady(){
2340 if ( readyBound ) return;
2343 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
2344 if ( document.addEventListener && !jQuery.browser.opera)
2345 // Use the handy event callback
2346 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
2348 // If IE is used and is not in a frame
2349 // Continually check to see if the document is ready
2350 if ( jQuery.browser.msie && window == top ) (function(){
2351 if (jQuery.isReady) return;
2353 // If IE is used, use the trick by Diego Perini
2354 // http://javascript.nwbox.com/IEContentLoaded/
2355 document.documentElement.doScroll("left");
2357 setTimeout( arguments.callee, 0 );
2360 // and execute any waiting functions
2364 if ( jQuery.browser.opera )
2365 document.addEventListener( "DOMContentLoaded", function () {
2366 if (jQuery.isReady) return;
2367 for (var i = 0; i < document.styleSheets.length; i++)
2368 if (document.styleSheets[i].disabled) {
2369 setTimeout( arguments.callee, 0 );
2372 // and execute any waiting functions
2376 if ( jQuery.browser.safari ) {
2379 if (jQuery.isReady) return;
2380 if ( document.readyState != "loaded" && document.readyState != "complete" ) {
2381 setTimeout( arguments.callee, 0 );
2384 if ( numStyles === undefined )
2385 numStyles = jQuery("style, link[rel=stylesheet]").length;
2386 if ( document.styleSheets.length != numStyles ) {
2387 setTimeout( arguments.callee, 0 );
2390 // and execute any waiting functions
2395 // A fallback to window.onload, that will always work
2396 jQuery.event.add( window, "load", jQuery.ready );
2399 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2400 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
2401 "submit,keydown,keypress,keyup,error").split(","), function(i, name){
2403 // Handle event binding
2404 jQuery.fn[name] = function(fn){
2405 return fn ? this.bind(name, fn) : this.trigger(name);
2409 // Checks if an event happened on an element within another element
2410 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2411 var withinElement = function(event, elem) {
2412 // Check if mouse(over|out) are still within the same parent element
2413 var parent = event.relatedTarget;
2414 // Traverse up the tree
2415 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
2416 // Return true if we actually just moused on to a sub-element
2417 return parent == elem;
2420 // Prevent memory leaks in IE
2421 // And prevent errors on refresh with events like mouseover in other browsers
2422 // Window isn't included so as not to unbind existing unload events
2423 jQuery(window).bind("unload", function() {
2424 jQuery("*").add(document).unbind();
2427 // Keep a copy of the old load
2428 _load: jQuery.fn.load,
2430 load: function( url, params, callback ) {
2431 if ( typeof url != 'string' )
2432 return this._load( url );
2434 var off = url.indexOf(" ");
2436 var selector = url.slice(off, url.length);
2437 url = url.slice(0, off);
2440 callback = callback || function(){};
2442 // Default to a GET request
2445 // If the second parameter was provided
2447 // If it's a function
2448 if ( jQuery.isFunction( params ) ) {
2449 // We assume that it's the callback
2453 // Otherwise, build a param string
2455 params = jQuery.param( params );
2461 // Request the remote document
2467 complete: function(res, status){
2468 // If successful, inject the HTML into all the matched elements
2469 if ( status == "success" || status == "notmodified" )
2470 // See if a selector was specified
2471 self.html( selector ?
2472 // Create a dummy div to hold the results
2474 // inject the contents of the document in, removing the scripts
2475 // to avoid any 'Permission Denied' errors in IE
2476 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
2478 // Locate the specified elements
2481 // If not, just inject the full result
2484 self.each( callback, [res.responseText, status, res] );
2490 serialize: function() {
2491 return jQuery.param(this.serializeArray());
2493 serializeArray: function() {
2494 return this.map(function(){
2495 return jQuery.nodeName(this, "form") ?
2496 jQuery.makeArray(this.elements) : this;
2499 return this.name && !this.disabled &&
2500 (this.checked || /select|textarea/i.test(this.nodeName) ||
2501 /text|hidden|password/i.test(this.type));
2503 .map(function(i, elem){
2504 var val = jQuery(this).val();
2505 return val == null ? null :
2506 val.constructor == Array ?
2507 jQuery.map( val, function(val, i){
2508 return {name: elem.name, value: val};
2510 {name: elem.name, value: val};
2515 // Attach a bunch of functions for handling common AJAX events
2516 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
2517 jQuery.fn[o] = function(f){
2518 return this.bind(o, f);
2525 get: function( url, data, callback, type ) {
2526 // shift arguments if data argument was ommited
2527 if ( jQuery.isFunction( data ) ) {
2532 return jQuery.ajax({
2541 getScript: function( url, callback ) {
2542 return jQuery.get(url, null, callback, "script");
2545 getJSON: function( url, data, callback ) {
2546 return jQuery.get(url, data, callback, "json");
2549 post: function( url, data, callback, type ) {
2550 if ( jQuery.isFunction( data ) ) {
2555 return jQuery.ajax({
2564 ajaxSetup: function( settings ) {
2565 jQuery.extend( jQuery.ajaxSettings, settings );
2573 contentType: "application/x-www-form-urlencoded",
2580 xml: "application/xml, text/xml",
2582 script: "text/javascript, application/javascript",
2583 json: "application/json, text/javascript",
2589 // Last-Modified header cache for next request
2592 ajax: function( s ) {
2593 // Extend the settings, but re-extend 's' so that it can be
2594 // checked again later (in the test suite, specifically)
2595 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
2597 var jsonp, jsre = /=\?(&|$)/g, status, data,
2598 type = s.type.toUpperCase();
2600 // convert data if not already a string
2601 if ( s.data && s.processData && typeof s.data != "string" )
2602 s.data = jQuery.param(s.data);
2604 // Handle JSONP Parameter Callbacks
2605 if ( s.dataType == "jsonp" ) {
2606 if ( type == "GET" ) {
2607 if ( !s.url.match(jsre) )
2608 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
2609 } else if ( !s.data || !s.data.match(jsre) )
2610 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
2611 s.dataType = "json";
2614 // Build temporary JSONP function
2615 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
2616 jsonp = "jsonp" + jsc++;
2618 // Replace the =? sequence both in the query string and the data
2620 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
2621 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
2623 // We need to make sure
2624 // that a JSONP style response is executed properly
2625 s.dataType = "script";
2627 // Handle JSONP-style loading
2628 window[ jsonp ] = function(tmp){
2633 window[ jsonp ] = undefined;
2634 try{ delete window[ jsonp ]; } catch(e){}
2636 head.removeChild( script );
2640 if ( s.dataType == "script" && s.cache == null )
2643 if ( s.cache === false && type == "GET" ) {
2645 // try replacing _= if it is there
2646 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
2647 // if nothing was replaced, add timestamp to the end
2648 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
2651 // If data is available, append data to url for get requests
2652 if ( s.data && type == "GET" ) {
2653 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
2655 // IE likes to send both get and post data, prevent this
2659 // Watch for a new set of requests
2660 if ( s.global && ! jQuery.active++ )
2661 jQuery.event.trigger( "ajaxStart" );
2663 // Matches an absolute URL, and saves the domain
2664 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
2666 // If we're requesting a remote document
2667 // and trying to load JSON or Script with a GET
2668 if ( s.dataType == "script" && type == "GET"
2669 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
2670 var head = document.getElementsByTagName("head")[0];
2671 var script = document.createElement("script");
2673 if (s.scriptCharset)
2674 script.charset = s.scriptCharset;
2676 // Handle Script loading
2680 // Attach handlers for all browsers
2681 script.onload = script.onreadystatechange = function(){
2682 if ( !done && (!this.readyState ||
2683 this.readyState == "loaded" || this.readyState == "complete") ) {
2687 head.removeChild( script );
2692 head.appendChild(script);
2694 // We handle everything using the script element injection
2698 var requestDone = false;
2700 // Create the request object; Microsoft failed to properly
2701 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
2702 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
2705 // Passing null username, generates a login popup on Opera (#2865)
2707 xhr.open(type, s.url, s.async, s.username, s.password);
2709 xhr.open(type, s.url, s.async);
2711 // Need an extra try/catch for cross domain requests in Firefox 3
2713 // Set the correct header, if data is being sent
2715 xhr.setRequestHeader("Content-Type", s.contentType);
2717 // Set the If-Modified-Since header, if ifModified mode.
2719 xhr.setRequestHeader("If-Modified-Since",
2720 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
2722 // Set header so the called script knows that it's an XMLHttpRequest
2723 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
2725 // Set the Accepts header for the server, depending on the dataType
2726 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
2727 s.accepts[ s.dataType ] + ", */*" :
2728 s.accepts._default );
2731 // Allow custom headers/mimetypes
2732 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
2733 // cleanup active request counter
2734 s.global && jQuery.active--;
2735 // close opended socket
2741 jQuery.event.trigger("ajaxSend", [xhr, s]);
2743 // Wait for a response to come back
2744 var onreadystatechange = function(isTimeout){
2745 // The transfer is complete and the data is available, or the request timed out
2746 if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
2749 // clear poll interval
2751 clearInterval(ival);
2755 status = isTimeout == "timeout" && "timeout" ||
2756 !jQuery.httpSuccess( xhr ) && "error" ||
2757 s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
2760 if ( status == "success" ) {
2761 // Watch for, and catch, XML document parse errors
2763 // process the data (runs the xml through httpData regardless of callback)
2764 data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
2766 status = "parsererror";
2770 // Make sure that the request was successful or notmodified
2771 if ( status == "success" ) {
2772 // Cache Last-Modified header, if ifModified mode.
2775 modRes = xhr.getResponseHeader("Last-Modified");
2776 } catch(e) {} // swallow exception thrown by FF if header is not available
2778 if ( s.ifModified && modRes )
2779 jQuery.lastModified[s.url] = modRes;
2781 // JSONP handles its own success callback
2785 jQuery.handleError(s, xhr, status);
2787 // Fire the complete handlers
2790 // Stop memory leaks
2797 // don't attach the handler to the request, just poll it instead
2798 var ival = setInterval(onreadystatechange, 13);
2801 if ( s.timeout > 0 )
2802 setTimeout(function(){
2803 // Check to see if the request is still happening
2805 // Cancel the request
2809 onreadystatechange( "timeout" );
2818 jQuery.handleError(s, xhr, null, e);
2821 // firefox 1.5 doesn't fire statechange for sync requests
2823 onreadystatechange();
2826 // If a local callback was specified, fire it and pass it the data
2828 s.success( data, status );
2830 // Fire the global callback
2832 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
2835 function complete(){
2838 s.complete(xhr, status);
2840 // The request was completed
2842 jQuery.event.trigger( "ajaxComplete", [xhr, s] );
2844 // Handle the global AJAX counter
2845 if ( s.global && ! --jQuery.active )
2846 jQuery.event.trigger( "ajaxStop" );
2849 // return XMLHttpRequest to allow aborting the request etc.
2853 handleError: function( s, xhr, status, e ) {
2854 // If a local callback was specified, fire it
2855 if ( s.error ) s.error( xhr, status, e );
2857 // Fire the global callback
2859 jQuery.event.trigger( "ajaxError", [xhr, s, e] );
2862 // Counter for holding the number of active queries
2865 // Determines if an XMLHttpRequest was successful or not
2866 httpSuccess: function( xhr ) {
2868 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
2869 return !xhr.status && location.protocol == "file:" ||
2870 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
2871 jQuery.browser.safari && xhr.status == undefined;
2876 // Determines if an XMLHttpRequest returns NotModified
2877 httpNotModified: function( xhr, url ) {
2879 var xhrRes = xhr.getResponseHeader("Last-Modified");
2881 // Firefox always returns 200. check Last-Modified date
2882 return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
2883 jQuery.browser.safari && xhr.status == undefined;
2888 httpData: function( xhr, type, filter ) {
2889 var ct = xhr.getResponseHeader("content-type"),
2890 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
2891 data = xml ? xhr.responseXML : xhr.responseText;
2893 if ( xml && data.documentElement.tagName == "parsererror" )
2894 throw "parsererror";
2896 // Allow a pre-filtering function to sanitize the response
2898 data = filter( data, type );
2900 // If the type is "script", eval it in global context
2901 if ( type == "script" )
2902 jQuery.globalEval( data );
2904 // Get the JavaScript object, if JSON is used.
2905 if ( type == "json" )
2906 data = eval("(" + data + ")");
2911 // Serialize an array of form elements or a set of
2912 // key/values into a query string
2913 param: function( a ) {
2916 // If an array was passed in, assume that it is an array
2918 if ( a.constructor == Array || a.jquery )
2919 // Serialize the form elements
2920 jQuery.each( a, function(){
2921 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
2924 // Otherwise, assume that it's an object of key/value pairs
2926 // Serialize the key/values
2928 // If the value is an array then the key names need to be repeated
2929 if ( a[j] && a[j].constructor == Array )
2930 jQuery.each( a[j], function(){
2931 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
2934 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
2936 // Return the resulting serialization
2937 return s.join("&").replace(/%20/g, "+");
2942 show: function(speed,callback){
2945 height: "show", width: "show", opacity: "show"
2946 }, speed, callback) :
2948 this.filter(":hidden").each(function(){
2949 this.style.display = this.oldblock || "";
2950 if ( jQuery.css(this,"display") == "none" ) {
2951 var elem = jQuery("<" + this.tagName + " />").appendTo("body");
2952 this.style.display = elem.css("display");
2953 // handle an edge condition where css is - div { display:none; } or similar
2954 if (this.style.display == "none")
2955 this.style.display = "block";
2961 hide: function(speed,callback){
2964 height: "hide", width: "hide", opacity: "hide"
2965 }, speed, callback) :
2967 this.filter(":visible").each(function(){
2968 this.oldblock = this.oldblock || jQuery.css(this,"display");
2969 this.style.display = "none";
2973 // Save the old toggle function
2974 _toggle: jQuery.fn.toggle,
2976 toggle: function( fn, fn2 ){
2977 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
2978 this._toggle.apply( this, arguments ) :
2981 height: "toggle", width: "toggle", opacity: "toggle"
2983 this.each(function(){
2984 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
2988 slideDown: function(speed,callback){
2989 return this.animate({height: "show"}, speed, callback);
2992 slideUp: function(speed,callback){
2993 return this.animate({height: "hide"}, speed, callback);
2996 slideToggle: function(speed, callback){
2997 return this.animate({height: "toggle"}, speed, callback);
3000 fadeIn: function(speed, callback){
3001 return this.animate({opacity: "show"}, speed, callback);
3004 fadeOut: function(speed, callback){
3005 return this.animate({opacity: "hide"}, speed, callback);
3008 fadeTo: function(speed,to,callback){
3009 return this.animate({opacity: to}, speed, callback);
3012 animate: function( prop, speed, easing, callback ) {
3013 var optall = jQuery.speed(speed, easing, callback);
3015 return this[ optall.queue === false ? "each" : "queue" ](function(){
3016 if ( this.nodeType != 1)
3019 var opt = jQuery.extend({}, optall), p,
3020 hidden = jQuery(this).is(":hidden"), self = this;
3023 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3024 return opt.complete.call(this);
3026 if ( p == "height" || p == "width" ) {
3027 // Store display property
3028 opt.display = jQuery.css(this, "display");
3030 // Make sure that nothing sneaks out
3031 opt.overflow = this.style.overflow;
3035 if ( opt.overflow != null )
3036 this.style.overflow = "hidden";
3038 opt.curAnim = jQuery.extend({}, prop);
3040 jQuery.each( prop, function(name, val){
3041 var e = new jQuery.fx( self, opt, name );
3043 if ( /toggle|show|hide/.test(val) )
3044 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3046 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3047 start = e.cur(true) || 0;
3050 var end = parseFloat(parts[2]),
3051 unit = parts[3] || "px";
3053 // We need to compute starting value
3054 if ( unit != "px" ) {
3055 self.style[ name ] = (end || 1) + unit;
3056 start = ((end || 1) / e.cur(true)) * start;
3057 self.style[ name ] = start + unit;
3060 // If a +=/-= token was provided, we're doing a relative animation
3062 end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3064 e.custom( start, end, unit );
3066 e.custom( start, val, "" );
3070 // For JS strict compliance
3075 queue: function(type, fn){
3076 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
3081 if ( !type || (typeof type == "string" && !fn) )
3082 return queue( this[0], type );
3084 return this.each(function(){
3085 if ( fn.constructor == Array )
3086 queue(this, type, fn);
3088 queue(this, type).push( fn );
3090 if ( queue(this, type).length == 1 )
3096 stop: function(clearQueue, gotoEnd){
3097 var timers = jQuery.timers;
3102 this.each(function(){
3103 // go in reverse order so anything added to the queue during the loop is ignored
3104 for ( var i = timers.length - 1; i >= 0; i-- )
3105 if ( timers[i].elem == this ) {
3107 // force the next step to be the last
3109 timers.splice(i, 1);
3113 // start the next in the queue if the last step wasn't forced
3122 var queue = function( elem, type, array ) {
3125 type = type || "fx";
3127 var q = jQuery.data( elem, type + "queue" );
3130 q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
3136 jQuery.fn.dequeue = function(type){
3137 type = type || "fx";
3139 return this.each(function(){
3140 var q = queue(this, type);
3151 speed: function(speed, easing, fn) {
3152 var opt = speed && speed.constructor == Object ? speed : {
3153 complete: fn || !fn && easing ||
3154 jQuery.isFunction( speed ) && speed,
3156 easing: fn && easing || easing && easing.constructor != Function && easing
3159 opt.duration = (opt.duration && opt.duration.constructor == Number ?
3161 jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
3164 opt.old = opt.complete;
3165 opt.complete = function(){
3166 if ( opt.queue !== false )
3167 jQuery(this).dequeue();
3168 if ( jQuery.isFunction( opt.old ) )
3169 opt.old.call( this );
3176 linear: function( p, n, firstNum, diff ) {
3177 return firstNum + diff * p;
3179 swing: function( p, n, firstNum, diff ) {
3180 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3187 fx: function( elem, options, prop ){
3188 this.options = options;
3192 if ( !options.orig )
3198 jQuery.fx.prototype = {
3200 // Simple function for setting a style value
3202 if ( this.options.step )
3203 this.options.step.call( this.elem, this.now, this );
3205 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
3207 // Set display property to block for height/width animations
3208 if ( this.prop == "height" || this.prop == "width" )
3209 this.elem.style.display = "block";
3212 // Get the current size
3213 cur: function(force){
3214 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
3215 return this.elem[ this.prop ];
3217 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
3218 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
3221 // Start an animation from one number to another
3222 custom: function(from, to, unit){
3223 this.startTime = now();
3226 this.unit = unit || this.unit || "px";
3227 this.now = this.start;
3228 this.pos = this.state = 0;
3232 function t(gotoEnd){
3233 return self.step(gotoEnd);
3238 jQuery.timers.push(t);
3240 if ( jQuery.timerId == null ) {
3241 jQuery.timerId = setInterval(function(){
3242 var timers = jQuery.timers;
3244 for ( var i = 0; i < timers.length; i++ )
3246 timers.splice(i--, 1);
3248 if ( !timers.length ) {
3249 clearInterval( jQuery.timerId );
3250 jQuery.timerId = null;
3256 // Simple 'show' function
3258 // Remember where we started, so that we can go back to it later
3259 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3260 this.options.show = true;
3262 // Begin the animation
3263 this.custom(0, this.cur());
3265 // Make sure that we start at a small width/height to avoid any
3267 if ( this.prop == "width" || this.prop == "height" )
3268 this.elem.style[this.prop] = "1px";
3270 // Start by showing the element
3271 jQuery(this.elem).show();
3274 // Simple 'hide' function
3276 // Remember where we started, so that we can go back to it later
3277 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3278 this.options.hide = true;
3280 // Begin the animation
3281 this.custom(this.cur(), 0);
3284 // Each step of an animation
3285 step: function(gotoEnd){
3288 if ( gotoEnd || t > this.options.duration + this.startTime ) {
3289 this.now = this.end;
3290 this.pos = this.state = 1;
3293 this.options.curAnim[ this.prop ] = true;
3296 for ( var i in this.options.curAnim )
3297 if ( this.options.curAnim[i] !== true )
3301 if ( this.options.display != null ) {
3302 // Reset the overflow
3303 this.elem.style.overflow = this.options.overflow;
3305 // Reset the display
3306 this.elem.style.display = this.options.display;
3307 if ( jQuery.css(this.elem, "display") == "none" )
3308 this.elem.style.display = "block";
3311 // Hide the element if the "hide" operation was done
3312 if ( this.options.hide )
3313 this.elem.style.display = "none";
3315 // Reset the properties, if the item has been hidden or shown
3316 if ( this.options.hide || this.options.show )
3317 for ( var p in this.options.curAnim )
3318 jQuery.attr(this.elem.style, p, this.options.orig[p]);
3322 // Execute the complete function
3323 this.options.complete.call( this.elem );
3327 var n = t - this.startTime;
3328 this.state = n / this.options.duration;
3330 // Perform the easing function, defaults to swing
3331 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
3332 this.now = this.start + ((this.end - this.start) * this.pos);
3334 // Perform the next step of the animation
3343 jQuery.extend( jQuery.fx, {
3351 scrollLeft: function(fx){
3352 fx.elem.scrollLeft = fx.now;
3355 scrollTop: function(fx){
3356 fx.elem.scrollTop = fx.now;
3359 opacity: function(fx){
3360 jQuery.attr(fx.elem.style, "opacity", fx.now);
3363 _default: function(fx){
3364 fx.elem.style[ fx.prop ] = fx.now + fx.unit;
3368 // The Offset Method
3369 // Originally By Brandon Aaron, part of the Dimension Plugin
3370 // http://jquery.com/plugins/project/dimensions
3371 jQuery.fn.offset = function() {
3372 var left = 0, top = 0, elem = this[0], results;
3374 if ( elem ) with ( jQuery.browser ) {
3375 var parent = elem.parentNode,
3377 offsetParent = elem.offsetParent,
3378 doc = elem.ownerDocument,
3379 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
3380 css = jQuery.curCSS,
3381 fixed = css(elem, "position") == "fixed";
3383 // Use getBoundingClientRect if available
3384 if ( elem.getBoundingClientRect ) {
3385 var box = elem.getBoundingClientRect();
3387 // Add the document scroll offsets
3388 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3389 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
3391 // IE adds the HTML element's border, by default it is medium which is 2px
3392 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
3393 // IE 7 standards mode, the border is always 2px
3394 // This border/offset is typically represented by the clientLeft and clientTop properties
3395 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
3396 // Therefore this method will be off by 2px in IE while in quirksmode
3397 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
3399 // Otherwise loop through the offsetParents and parentNodes
3402 // Initial element offsets
3403 add( elem.offsetLeft, elem.offsetTop );
3405 // Get parent offsets
3406 while ( offsetParent ) {
3407 // Add offsetParent offsets
3408 add( offsetParent.offsetLeft, offsetParent.offsetTop );
3410 // Mozilla and Safari > 2 does not include the border on offset parents
3411 // However Mozilla adds the border for table or table cells
3412 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
3413 border( offsetParent );
3415 // Add the document scroll offsets if position is fixed on any offsetParent
3416 if ( !fixed && css(offsetParent, "position") == "fixed" )
3419 // Set offsetChild to previous offsetParent unless it is the body element
3420 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
3421 // Get next offsetParent
3422 offsetParent = offsetParent.offsetParent;
3425 // Get parent scroll offsets
3426 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
3427 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
3428 if ( !/^inline|table.*$/i.test(css(parent, "display")) )
3429 // Subtract parent scroll offsets
3430 add( -parent.scrollLeft, -parent.scrollTop );
3432 // Mozilla does not add the border for a parent that has overflow != visible
3433 if ( mozilla && css(parent, "overflow") != "visible" )
3437 parent = parent.parentNode;
3440 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
3441 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
3442 if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
3443 (mozilla && css(offsetChild, "position") != "absolute") )
3444 add( -doc.body.offsetLeft, -doc.body.offsetTop );
3446 // Add the document scroll offsets if position is fixed
3448 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3449 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
3452 // Return an object with top and left properties
3453 results = { top: top, left: left };
3456 function border(elem) {
3457 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
3460 function add(l, t) {
3461 left += parseInt(l, 10) || 0;
3462 top += parseInt(t, 10) || 0;
3470 position: function() {
3471 var left = 0, top = 0, results;
3474 // Get *real* offsetParent
3475 var offsetParent = this.offsetParent(),
3477 // Get correct offsets
3478 offset = this.offset(),
3479 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
3481 // Subtract element margins
3482 // note: when an element has margin: auto the offsetLeft and marginLeft
3483 // are the same in Safari causing offset.left to incorrectly be 0
3484 offset.top -= num( this, 'marginTop' );
3485 offset.left -= num( this, 'marginLeft' );
3487 // Add offsetParent borders
3488 parentOffset.top += num( offsetParent, 'borderTopWidth' );
3489 parentOffset.left += num( offsetParent, 'borderLeftWidth' );
3491 // Subtract the two offsets
3493 top: offset.top - parentOffset.top,
3494 left: offset.left - parentOffset.left
3501 offsetParent: function() {
3502 var offsetParent = this[0].offsetParent;
3503 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
3504 offsetParent = offsetParent.offsetParent;
3505 return jQuery(offsetParent);
3510 // Create scrollLeft and scrollTop methods
3511 jQuery.each( ['Left', 'Top'], function(i, name) {
3512 var method = 'scroll' + name;
3514 jQuery.fn[ method ] = function(val) {
3515 if (!this[0]) return;
3517 return val != undefined ?
3519 // Set the scroll offset
3520 this.each(function() {
3521 this == window || this == document ?
3523 !i ? val : jQuery(window).scrollLeft(),
3524 i ? val : jQuery(window).scrollTop()
3526 this[ method ] = val;
3529 // Return the scroll offset
3530 this[0] == window || this[0] == document ?
3531 self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
3532 jQuery.boxModel && document.documentElement[ method ] ||
3533 document.body[ method ] :
3537 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
3538 jQuery.each([ "Height", "Width" ], function(i, name){
3540 var tl = i ? "Left" : "Top", // top or left
3541 br = i ? "Right" : "Bottom"; // bottom or right
3543 // innerHeight and innerWidth
3544 jQuery.fn["inner" + name] = function(){
3545 return this[ name.toLowerCase() ]() +
3546 num(this, "padding" + tl) +
3547 num(this, "padding" + br);
3550 // outerHeight and outerWidth
3551 jQuery.fn["outer" + name] = function(margin) {
3552 return this["inner" + name]() +
3553 num(this, "border" + tl + "Width") +
3554 num(this, "border" + br + "Width") +
3556 num(this, "margin" + tl) + num(this, "margin" + br) : 0);