Make Build.PL less complainy and add manifest
[cxgn-jslib.git] / jQuery.js
blob441847adec070a46f392e0b3e18a3824e75f4c39
1 (function(){
2 /*
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) $
10 * $Rev: 5685 $
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
23 _$ = window.$;
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.
38 undefined;
40 jQuery.fn = jQuery.prototype = {
41 init: function( selector, context ) {
42 // Make sure that a selection was provided
43 selector = selector || document;
44 ///////////////////
45 //don't use the default '$' namespace for this object. Instead use 'jQuery'
46 jQuery.noConflict();
47 /////////////////////
48 // Handle $(DOMElement)
49 if ( selector.nodeType ) {
50 this[0] = selector;
51 this.length = 1;
52 return this;
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)
63 if ( match[1] )
64 selector = jQuery.clean( [ match[1] ], context );
66 // HANDLE: $("#id")
67 else {
68 var elem = document.getElementById( match[3] );
70 // Make sure an element was located
71 if ( elem ){
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 );
80 selector = [];
83 // HANDLE: $(expr, [context])
84 // (which is just equivalent to: $(content).find(expr)
85 } else
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
97 jquery: "1.2.6",
99 // The number of elements contained in the matched element set
100 size: function() {
101 return this.length;
104 // The number of elements contained in the matched element set
105 length: 0,
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
116 this[ num ];
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
129 return ret;
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
138 this.length = 0;
139 Array.prototype.push.apply( this, elems );
141 return this;
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 ) {
154 var ret = -1;
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
160 , this );
163 attr: function( name, value, type ) {
164 var options = name;
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 );
171 else {
172 options = {};
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 )
180 jQuery.attr(
181 type ?
182 this.style :
183 this,
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 )
192 value = undefined;
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 ) );
200 var ret = "";
202 jQuery.each( text || this, function(){
203 jQuery.each( this.childNodes, function(){
204 if ( this.nodeType != 8 )
205 ret += this.nodeType != 1 ?
206 this.nodeValue :
207 jQuery.fn.text( [ this ] );
211 return ret;
214 wrapAll: function( html ) {
215 if ( this[0] )
216 // The elements to wrap the target around
217 jQuery( html, this[0].ownerDocument )
218 .clone()
219 .insertBefore( this[0] )
220 .map(function(){
221 var elem = this;
223 while ( elem.firstChild )
224 elem = elem.firstChild;
226 return elem;
228 .append(this);
230 return this;
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 );
245 append: function() {
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 );
259 before: function() {
260 return this.domManip(arguments, false, false, function(elem){
261 this.parentNode.insertBefore( elem, this );
265 after: function() {
266 return this.domManip(arguments, false, true, function(elem){
267 this.parentNode.insertBefore( elem, this.nextSibling );
271 end: function() {
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 ) :
282 elems );
285 clone: function( events ) {
286 // Do the clone
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];
301 } else
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)
317 return;
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
326 return ret;
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 );
334 }) ||
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 ) );
344 else
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(
355 this.get(),
356 typeof selector == 'string' ?
357 jQuery( selector ) :
358 jQuery.makeArray( selector )
359 )));
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 ) {
373 if ( this.length ) {
374 var elem = this[0];
376 // We need to handle select boxes special
377 if ( jQuery.nodeName( elem, "select" ) ) {
378 var index = elem.selectedIndex,
379 values = [],
380 options = elem.options,
381 one = elem.type == "select-one";
383 // Nothing was selected
384 if ( index < 0 )
385 return null;
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
396 if ( one )
397 return value;
399 // Multi-Selects return an array
400 values.push( value );
404 return values;
406 // Everything else, we just grab the value
407 } else
408 return (this[0].value || "").replace(/\r/g, "");
412 return undefined;
415 if( value.constructor == Number )
416 value += '';
418 return this.each(function(){
419 if ( this.nodeType != 1 )
420 return;
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;
437 } else
438 this.value = value;
442 html: function( value ) {
443 return value == undefined ?
444 (this[0] ?
445 this[0].innerHTML :
446 null) :
447 this.empty().append( value );
450 replaceWith: function( value ) {
451 return this.after( value ).remove();
454 eq: function( i ) {
455 return this.slice( i, i + 1 );
458 slice: function() {
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 );
465 }));
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] ) :
484 data;
485 } else
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(){
501 if ( !elems ) {
502 elems = jQuery.clean( args, this.ownerDocument );
504 if ( reverse )
505 elems.reverse();
508 var obj = this;
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(){
516 var elem = clone ?
517 jQuery( this ).clone( true )[0] :
518 this;
520 // execute all scripts after the elements have been injected
521 if ( jQuery.nodeName( elem, "script" ) )
522 scripts = scripts.add( elem );
523 else {
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 ) {
542 if ( elem.src )
543 jQuery.ajax({
544 url: elem.src,
545 async: false,
546 dataType: "script"
549 else
550 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
552 if ( elem.parentNode )
553 elem.parentNode.removeChild( elem );
556 function now(){
557 return +new Date;
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 ) {
566 deep = target;
567 target = arguments[1] || {};
568 // skip the boolean and the target
569 i = 2;
572 // Handle case when target is a string or something (possible in deep copy)
573 if ( typeof target != "object" && typeof target != "function" )
574 target = {};
576 // extend jQuery itself if only one argument is passed
577 if ( length == i ) {
578 target = this;
579 --i;
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 )
591 continue;
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 ? [ ] : { } )
598 , copy );
600 // Don't bring in undefined values
601 else if ( copy !== undefined )
602 target[ name ] = copy;
606 // Return the modified object
607 return target;
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,
613 // cache defaultView
614 defaultView = document.defaultView || {};
616 jQuery.extend({
617 noConflict: function( deep ) {
618 window.$ = _$;
620 if ( deep )
621 window.jQuery = _jQuery;
623 return 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 );
642 if ( 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 )
650 script.text = data;
651 else
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();
665 cache: {},
667 data: function( elem, name, data ) {
668 elem = elem == window ?
669 windowData :
670 elem;
672 var id = elem[ expando ];
674 // Compute a unique ID for the element
675 if ( !id )
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
688 return name ?
689 jQuery.cache[ id ][ name ] :
693 removeData: function( elem, name ) {
694 elem = elem == window ?
695 windowData :
696 elem;
698 var id = elem[ expando ];
700 // If we want to remove a specific section of the element's data
701 if ( name ) {
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
707 name = "";
709 for ( name in jQuery.cache[ id ] )
710 break;
712 if ( !name )
713 jQuery.removeData( elem );
716 // Otherwise, we want to remove all of the element's data
717 } else {
718 // Clean up the element expando
719 try {
720 delete elem[ expando ];
721 } catch(e){
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;
737 if ( args ) {
738 if ( length == undefined ) {
739 for ( name in object )
740 if ( callback.apply( object[ name ], args ) === false )
741 break;
742 } else
743 for ( ; i < length; )
744 if ( callback.apply( object[ i++ ], args ) === false )
745 break;
747 // A special, fast, case for the most common use of each
748 } else {
749 if ( length == undefined ) {
750 for ( name in object )
751 if ( callback.call( object[ name ], name, object[ name ] ) === false )
752 break;
753 } else
754 for ( var value = object[0];
755 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
758 return object;
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 ) ?
768 value + "px" :
769 value;
772 className: {
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 );
787 }).join(" ") :
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 ) {
799 var old = {};
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" ];
817 function getWH() {
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") )
828 getWH();
829 else
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 )
844 return false;
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" );
855 return ret == "" ?
856 "1" :
857 ret;
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 ) )
868 name = styleFloat;
870 if ( !force && style && style[ name ] )
871 ret = style[ name ];
873 else if ( defaultView.getComputedStyle ) {
875 // Only "float" is needed here
876 if ( name.match( /float/i ) )
877 name = "float";
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
888 else {
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 )
893 stack.unshift(a);
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 ?
906 "none" :
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 == "" )
917 ret = "1";
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
941 style.left = left;
942 elem.runtimeStyle.left = rsLeft;
946 return ret;
949 clean: function( elems, context ) {
950 var ret = [];
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){
957 if ( !elem )
958 return;
960 if ( elem.constructor == Number )
961 elem += '';
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) ?
968 all :
969 front + "></" + tag + ">";
972 // Trim whitespace, otherwise indexOf won't work as expected
973 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
975 var wrap =
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>" ] ||
1000 [ 0, "", "" ];
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
1006 while ( wrap[0]-- )
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 ?
1018 div.childNodes :
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" )) )
1035 return;
1037 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
1038 ret.push( elem );
1040 else
1041 ret = jQuery.merge( ret, elem );
1045 return ret;
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)
1051 return undefined;
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 ) {
1075 if ( set ){
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 );
1093 if ( set )
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" ) {
1110 if ( set ) {
1111 // IE has trouble with opacity if it does not have layout
1112 // Force it by setting the zoom level
1113 elem.zoom = 1;
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();
1129 if ( set )
1130 elem[ name ] = value;
1132 return elem[ name ];
1135 trim: function( text ) {
1136 return (text || "").replace( /^\s+|\s+$/g, "" );
1139 makeArray: function( array ) {
1140 var ret = [];
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 )
1146 ret[0] = array;
1147 else
1148 while( i )
1149 ret[--i] = array[i];
1152 return ret;
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 )
1159 return i;
1161 return -1;
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;
1175 } else
1176 while ( elem = second[ i++ ] )
1177 first[ pos++ ] = elem;
1179 return first;
1182 unique: function( array ) {
1183 var ret = [], done = {};
1185 try {
1187 for ( var i = 0, length = array.length; i < length; i++ ) {
1188 var id = jQuery.data( array[ i ] );
1190 if ( !done[ id ] ) {
1191 done[ id ] = true;
1192 ret.push( array[ i ] );
1196 } catch( e ) {
1197 ret = array;
1200 return ret;
1203 grep: function( elems, callback, inv ) {
1204 var ret = [];
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 ] );
1212 return ret;
1215 map: function( elems, callback ) {
1216 var ret = [];
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
1234 jQuery.browser = {
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 ?
1243 "styleFloat" :
1244 "cssFloat";
1246 jQuery.extend({
1247 // Check to see if the W3C box model is being used
1248 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
1250 props: {
1251 "for": "htmlFor",
1252 "class": "className",
1253 "float": styleFloat,
1254 cssFloat: styleFloat,
1255 styleFloat: styleFloat,
1256 readonly: "readOnly",
1257 maxlength: "maxLength",
1258 cellspacing: "cellSpacing"
1262 jQuery.each({
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 ) );
1283 jQuery.each({
1284 appendTo: "append",
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 );
1300 jQuery.each({
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 );
1331 empty: function() {
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
1363 Math.max(
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
1369 size == undefined ?
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 + "*)");
1388 jQuery.extend({
1389 expr: {
1390 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
1391 "#": function(a,i,m){return a.getAttribute("id")==m[2];},
1392 ":": {
1393 // Position Checks
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;},
1403 // Child Checks
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");},
1408 // Parent Checks
1409 parent: function(a){return a.firstChild;},
1410 empty: function(a){return !a.firstChild;},
1412 // Text Check
1413 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
1415 // Visibility
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";},
1419 // Form attributes
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");},
1425 // Form elements
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);},
1437 // :has()
1438 has: function(a,i,m){return jQuery.find(m[3],a).length;},
1440 // :header
1441 header: function(a){return /h\d/i.test(a.nodeName);},
1443 // :animated
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
1449 parse: [
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 ) {
1461 var old, cur = [];
1463 while ( expr && expr != old ) {
1464 old = expr;
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 );
1470 return cur;
1473 find: function( t, context ) {
1474 // Quickly handle non-string expressions
1475 if ( typeof t != "string" )
1476 return [ t ];
1478 // check to make sure context is a DOM element or a document
1479 if ( context && context.nodeType != 1 && context.nodeType != 9)
1480 return [ ];
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 ) {
1491 var r = [];
1492 last = t;
1494 t = jQuery.trim(t);
1496 var foundToken = false,
1498 // An attempt at speeding up child selectors that
1499 // point to a specific element tag
1500 re = quickChild,
1502 m = re.exec(t);
1504 if ( m ) {
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) )
1511 r.push( c );
1513 ret = r;
1514 t = t.replace( re, "" );
1515 if ( t.indexOf(" ") == 0 ) continue;
1516 foundToken = true;
1517 } else {
1518 re = /^([>+~])\s*(\w*)/i;
1520 if ( (m = re.exec(t)) != null ) {
1521 r = [];
1523 var merge = {};
1524 nodeName = m[2].toUpperCase();
1525 m = m[1];
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;
1537 r.push( n );
1540 if ( m == "+" ) break;
1544 ret = r;
1546 // And remove the token
1547 t = jQuery.trim( t.replace( re, "" ) );
1548 foundToken = true;
1552 // See if there's still an expression, and that we haven't already
1553 // matched a token
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);
1569 } else {
1570 // Optimize for the case nodeName#idName
1571 var re2 = quickID;
1572 var m = re2.exec(t);
1574 // Re-organize the results, so that they're consistent
1575 if ( m ) {
1576 m = [ 0, m[2], m[3], m[1] ];
1578 } else {
1579 // Otherwise, do a traditional filter check for
1580 // ID, class, and element selectors
1581 re2 = quickClass;
1582 m = re2.exec(t);
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] : [];
1603 } else {
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" )
1611 tag = "param";
1613 r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
1616 // It's faster to filter by class and be done with it
1617 if ( m[1] == "." )
1618 r = jQuery.classFilter( r, m[2] );
1620 // Same with ID filtering
1621 if ( m[1] == "#" ) {
1622 var tmp = [];
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] ) {
1627 tmp = [ r[i] ];
1628 break;
1631 r = tmp;
1634 ret = r;
1637 t = t.replace( re2, "" );
1642 // If a selector string still exists
1643 if ( t ) {
1644 // Attempt to filter it
1645 var val = jQuery.filter(t,r);
1646 ret = r = val.r;
1647 t = jQuery.trim(val.t);
1651 // An error occurred with the selector;
1652 // just return an empty set instead
1653 if ( t )
1654 ret = [];
1656 // Remove the root context
1657 if ( ret && context == ret[0] )
1658 ret.shift();
1660 // And combine the results
1661 done = jQuery.merge( done, ret );
1663 return done;
1666 classFilter: function(r,m,not){
1667 m = " " + m + " ";
1668 var tmp = [];
1669 for ( var i = 0; r[i]; i++ ) {
1670 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
1671 if ( !not && pass || not && !pass )
1672 tmp.push( r[i] );
1674 return tmp;
1677 filter: function(t,r,not) {
1678 var last;
1680 // Look for common filter expressions
1681 while ( t && t != last ) {
1682 last = t;
1684 var p = jQuery.parse, m;
1686 for ( var i = 0; p[i]; i++ ) {
1687 m = p[i].exec( t );
1689 if ( m ) {
1690 // Remove what we just matched
1691 t = t.substring( m[0].length );
1693 m[2] = m[2].replace(/\\/g, "");
1694 break;
1698 if ( !m )
1699 break;
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 )
1728 tmp.push( a );
1731 r = tmp;
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);
1747 if ( !merge[id] ) {
1748 var c = 1;
1750 for ( var n = parentNode.firstChild; n; n = n.nextSibling )
1751 if ( n.nodeType == 1 )
1752 n.nodeIndex = c++;
1754 merge[id] = true;
1757 var add = false;
1759 if ( first == 0 ) {
1760 if ( node.nodeIndex == last )
1761 add = true;
1762 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
1763 add = true;
1765 if ( add ^ not )
1766 tmp.push( node );
1769 r = tmp;
1771 // Otherwise, find the expression to execute
1772 } else {
1773 var fn = jQuery.expr[ m[1] ];
1774 if ( typeof fn == "object" )
1775 fn = fn[ m[2] ];
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);
1783 }, not );
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 ){
1793 var matched = [],
1794 cur = elem[dir];
1795 while ( cur && cur != document ) {
1796 if ( cur.nodeType == 1 )
1797 matched.push( cur );
1798 cur = cur[dir];
1800 return matched;
1803 nth: function(cur,result,dir,elem){
1804 result = result || 1;
1805 var num = 0;
1807 for ( ; cur; cur = cur[dir] )
1808 if ( cur.nodeType == 1 && ++num == result )
1809 break;
1811 return cur;
1814 sibling: function( n, elem ) {
1815 var r = [];
1817 for ( ; n; n = n.nextSibling ) {
1818 if ( n.nodeType == 1 && n != elem )
1819 r.push( n );
1822 return r;
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.
1830 jQuery.event = {
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 )
1836 return;
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 )
1841 elem = window;
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
1850 var fn = 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
1872 // event in IE.
1873 handle.elem = elem;
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(".");
1880 type = parts[0];
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
1887 if (!handlers) {
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
1910 elem = null;
1913 guid: 1,
1914 global: {},
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 )
1920 return;
1922 var events = jQuery.data(elem, "events"), ret, index;
1924 if ( events ) {
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 || "") );
1929 else {
1930 // types is actually an event object here
1931 if ( types.type ) {
1932 handler = types.handler;
1933 types = types.type;
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(".");
1941 type = parts[0];
1943 if ( events[type] ) {
1944 // remove the given handler for the given type
1945 if ( handler )
1946 delete events[type][handler.guid];
1948 // remove all handlers for the given type
1949 else
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;
1957 if ( !ret ) {
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"));
1964 ret = null;
1965 delete events[type];
1971 // Remove the expando if it's no longer used
1972 for ( ret in events ) break;
1973 if ( !ret ) {
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
1992 if ( !elem ) {
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
1998 } else {
1999 // don't do events on text and comment nodes
2000 if ( elem.nodeType == 3 || elem.nodeType == 8 )
2001 return undefined;
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
2008 if ( event ) {
2009 data.unshift({
2010 type: type,
2011 target: elem,
2012 preventDefault: function(){},
2013 stopPropagation: function(){},
2014 timeStamp: now()
2016 data[0][expando] = true; // no need to fix fake event
2019 // Enforce the right trigger type
2020 data[0].type = type;
2021 if ( exclusive )
2022 data[0].exclusive = true;
2024 // Trigger the event, it is assumed that "handle" is a function
2025 var handle = jQuery.data(elem, "handle");
2026 if ( 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 )
2031 val = false;
2033 // Extra functions don't get the custom event object
2034 if ( event )
2035 data.shift();
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)
2043 val = ret;
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;
2049 try {
2050 elem[ type ]();
2051 // prevent IE from throwing an error for some hidden elements
2052 } catch (e) {}
2055 this.triggered = false;
2058 return val;
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 )
2089 val = ret;
2091 if ( ret === false ) {
2092 event.preventDefault();
2093 event.stopPropagation();
2098 return val;
2101 fix: function(event) {
2102 if ( event[expando] == true )
2103 return event;
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] ];
2113 // Mark it as fixed
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;
2133 // Fix timeStamp
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 ) ));
2168 return event;
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
2175 return proxy;
2178 special: {
2179 ready: {
2180 setup: function() {
2181 // Make sure the ready event is setup
2182 bindReady();
2183 return;
2186 teardown: function() { return; }
2189 mouseenter: {
2190 setup: function() {
2191 if ( jQuery.browser.msie ) return false;
2192 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
2193 return true;
2196 teardown: function() {
2197 if ( jQuery.browser.msie ) return false;
2198 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
2199 return true;
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);
2211 mouseleave: {
2212 setup: function() {
2213 if ( jQuery.browser.msie ) return false;
2214 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
2215 return true;
2218 teardown: function() {
2219 if ( jQuery.browser.msie ) return false;
2220 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
2221 return true;
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);
2235 jQuery.fn.extend({
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;
2285 }));
2288 hover: function(fnOver, fnOut) {
2289 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
2292 ready: function(fn) {
2293 // Attach the listeners
2294 bindReady();
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
2302 else
2303 // Add the function to the wait list
2304 jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
2306 return this;
2310 jQuery.extend({
2311 isReady: false,
2312 readyList: [],
2313 // Handle when the DOM is ready
2314 ready: function() {
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;
2341 readyBound = true;
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;
2352 try {
2353 // If IE is used, use the trick by Diego Perini
2354 // http://javascript.nwbox.com/IEContentLoaded/
2355 document.documentElement.doScroll("left");
2356 } catch( error ) {
2357 setTimeout( arguments.callee, 0 );
2358 return;
2360 // and execute any waiting functions
2361 jQuery.ready();
2362 })();
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 );
2370 return;
2372 // and execute any waiting functions
2373 jQuery.ready();
2374 }, false);
2376 if ( jQuery.browser.safari ) {
2377 var numStyles;
2378 (function(){
2379 if (jQuery.isReady) return;
2380 if ( document.readyState != "loaded" && document.readyState != "complete" ) {
2381 setTimeout( arguments.callee, 0 );
2382 return;
2384 if ( numStyles === undefined )
2385 numStyles = jQuery("style, link[rel=stylesheet]").length;
2386 if ( document.styleSheets.length != numStyles ) {
2387 setTimeout( arguments.callee, 0 );
2388 return;
2390 // and execute any waiting functions
2391 jQuery.ready();
2392 })();
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();
2426 jQuery.fn.extend({
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(" ");
2435 if ( off >= 0 ) {
2436 var selector = url.slice(off, url.length);
2437 url = url.slice(0, off);
2440 callback = callback || function(){};
2442 // Default to a GET request
2443 var type = "GET";
2445 // If the second parameter was provided
2446 if ( params )
2447 // If it's a function
2448 if ( jQuery.isFunction( params ) ) {
2449 // We assume that it's the callback
2450 callback = params;
2451 params = null;
2453 // Otherwise, build a param string
2454 } else {
2455 params = jQuery.param( params );
2456 type = "POST";
2459 var self = this;
2461 // Request the remote document
2462 jQuery.ajax({
2463 url: url,
2464 type: type,
2465 dataType: "html",
2466 data: params,
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
2473 jQuery("<div/>")
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
2479 .find(selector) :
2481 // If not, just inject the full result
2482 res.responseText );
2484 self.each( callback, [res.responseText, status, res] );
2487 return this;
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;
2498 .filter(function(){
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};
2509 }) :
2510 {name: elem.name, value: val};
2511 }).get();
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);
2522 var jsc = now();
2524 jQuery.extend({
2525 get: function( url, data, callback, type ) {
2526 // shift arguments if data argument was ommited
2527 if ( jQuery.isFunction( data ) ) {
2528 callback = data;
2529 data = null;
2532 return jQuery.ajax({
2533 type: "GET",
2534 url: url,
2535 data: data,
2536 success: callback,
2537 dataType: type
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 ) ) {
2551 callback = data;
2552 data = {};
2555 return jQuery.ajax({
2556 type: "POST",
2557 url: url,
2558 data: data,
2559 success: callback,
2560 dataType: type
2564 ajaxSetup: function( settings ) {
2565 jQuery.extend( jQuery.ajaxSettings, settings );
2568 ajaxSettings: {
2569 url: location.href,
2570 global: true,
2571 type: "GET",
2572 timeout: 0,
2573 contentType: "application/x-www-form-urlencoded",
2574 processData: true,
2575 async: true,
2576 data: null,
2577 username: null,
2578 password: null,
2579 accepts: {
2580 xml: "application/xml, text/xml",
2581 html: "text/html",
2582 script: "text/javascript, application/javascript",
2583 json: "application/json, text/javascript",
2584 text: "text/plain",
2585 _default: "*/*"
2589 // Last-Modified header cache for next request
2590 lastModified: {},
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
2619 if ( s.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){
2629 data = tmp;
2630 success();
2631 complete();
2632 // Garbage collect
2633 window[ jsonp ] = undefined;
2634 try{ delete window[ jsonp ]; } catch(e){}
2635 if ( head )
2636 head.removeChild( script );
2640 if ( s.dataType == "script" && s.cache == null )
2641 s.cache = false;
2643 if ( s.cache === false && type == "GET" ) {
2644 var ts = now();
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
2656 s.data = null;
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");
2672 script.src = s.url;
2673 if (s.scriptCharset)
2674 script.charset = s.scriptCharset;
2676 // Handle Script loading
2677 if ( !jsonp ) {
2678 var done = false;
2680 // Attach handlers for all browsers
2681 script.onload = script.onreadystatechange = function(){
2682 if ( !done && (!this.readyState ||
2683 this.readyState == "loaded" || this.readyState == "complete") ) {
2684 done = true;
2685 success();
2686 complete();
2687 head.removeChild( script );
2692 head.appendChild(script);
2694 // We handle everything using the script element injection
2695 return undefined;
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();
2704 // Open the socket
2705 // Passing null username, generates a login popup on Opera (#2865)
2706 if( s.username )
2707 xhr.open(type, s.url, s.async, s.username, s.password);
2708 else
2709 xhr.open(type, s.url, s.async);
2711 // Need an extra try/catch for cross domain requests in Firefox 3
2712 try {
2713 // Set the correct header, if data is being sent
2714 if ( s.data )
2715 xhr.setRequestHeader("Content-Type", s.contentType);
2717 // Set the If-Modified-Since header, if ifModified mode.
2718 if ( s.ifModified )
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 );
2729 } catch(e){}
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
2736 xhr.abort();
2737 return false;
2740 if ( s.global )
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") ) {
2747 requestDone = true;
2749 // clear poll interval
2750 if (ival) {
2751 clearInterval(ival);
2752 ival = null;
2755 status = isTimeout == "timeout" && "timeout" ||
2756 !jQuery.httpSuccess( xhr ) && "error" ||
2757 s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
2758 "success";
2760 if ( status == "success" ) {
2761 // Watch for, and catch, XML document parse errors
2762 try {
2763 // process the data (runs the xml through httpData regardless of callback)
2764 data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
2765 } catch(e) {
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.
2773 var modRes;
2774 try {
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
2782 if ( !jsonp )
2783 success();
2784 } else
2785 jQuery.handleError(s, xhr, status);
2787 // Fire the complete handlers
2788 complete();
2790 // Stop memory leaks
2791 if ( s.async )
2792 xhr = null;
2796 if ( s.async ) {
2797 // don't attach the handler to the request, just poll it instead
2798 var ival = setInterval(onreadystatechange, 13);
2800 // Timeout checker
2801 if ( s.timeout > 0 )
2802 setTimeout(function(){
2803 // Check to see if the request is still happening
2804 if ( xhr ) {
2805 // Cancel the request
2806 xhr.abort();
2808 if( !requestDone )
2809 onreadystatechange( "timeout" );
2811 }, s.timeout);
2814 // Send the data
2815 try {
2816 xhr.send(s.data);
2817 } catch(e) {
2818 jQuery.handleError(s, xhr, null, e);
2821 // firefox 1.5 doesn't fire statechange for sync requests
2822 if ( !s.async )
2823 onreadystatechange();
2825 function success(){
2826 // If a local callback was specified, fire it and pass it the data
2827 if ( s.success )
2828 s.success( data, status );
2830 // Fire the global callback
2831 if ( s.global )
2832 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
2835 function complete(){
2836 // Process result
2837 if ( s.complete )
2838 s.complete(xhr, status);
2840 // The request was completed
2841 if ( s.global )
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.
2850 return xhr;
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
2858 if ( s.global )
2859 jQuery.event.trigger( "ajaxError", [xhr, s, e] );
2862 // Counter for holding the number of active queries
2863 active: 0,
2865 // Determines if an XMLHttpRequest was successful or not
2866 httpSuccess: function( xhr ) {
2867 try {
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;
2872 } catch(e){}
2873 return false;
2876 // Determines if an XMLHttpRequest returns NotModified
2877 httpNotModified: function( xhr, url ) {
2878 try {
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;
2884 } catch(e){}
2885 return false;
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
2897 if( filter )
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 + ")");
2908 return data;
2911 // Serialize an array of form elements or a set of
2912 // key/values into a query string
2913 param: function( a ) {
2914 var s = [];
2916 // If an array was passed in, assume that it is an array
2917 // of form elements
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
2925 else
2926 // Serialize the key/values
2927 for ( var j in a )
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 ) );
2933 else
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, "+");
2941 jQuery.fn.extend({
2942 show: function(speed,callback){
2943 return speed ?
2944 this.animate({
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";
2956 elem.remove();
2958 }).end();
2961 hide: function(speed,callback){
2962 return speed ?
2963 this.animate({
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";
2970 }).end();
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 ) :
2979 fn ?
2980 this.animate({
2981 height: "toggle", width: "toggle", opacity: "toggle"
2982 }, fn, fn2) :
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)
3017 return false;
3019 var opt = jQuery.extend({}, optall), p,
3020 hidden = jQuery(this).is(":hidden"), self = this;
3022 for ( p in prop ) {
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 );
3045 else {
3046 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3047 start = e.cur(true) || 0;
3049 if ( parts ) {
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
3061 if ( parts[1] )
3062 end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3064 e.custom( start, end, unit );
3065 } else
3066 e.custom( start, val, "" );
3070 // For JS strict compliance
3071 return true;
3075 queue: function(type, fn){
3076 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
3077 fn = type;
3078 type = "fx";
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);
3087 else {
3088 queue(this, type).push( fn );
3090 if ( queue(this, type).length == 1 )
3091 fn.call(this);
3096 stop: function(clearQueue, gotoEnd){
3097 var timers = jQuery.timers;
3099 if (clearQueue)
3100 this.queue([]);
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 ) {
3106 if (gotoEnd)
3107 // force the next step to be the last
3108 timers[i](true);
3109 timers.splice(i, 1);
3113 // start the next in the queue if the last step wasn't forced
3114 if (!gotoEnd)
3115 this.dequeue();
3117 return this;
3122 var queue = function( elem, type, array ) {
3123 if ( elem ){
3125 type = type || "fx";
3127 var q = jQuery.data( elem, type + "queue" );
3129 if ( !q || array )
3130 q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
3133 return q;
3136 jQuery.fn.dequeue = function(type){
3137 type = type || "fx";
3139 return this.each(function(){
3140 var q = queue(this, type);
3142 q.shift();
3144 if ( q.length )
3145 q[0].call( this );
3149 jQuery.extend({
3151 speed: function(speed, easing, fn) {
3152 var opt = speed && speed.constructor == Object ? speed : {
3153 complete: fn || !fn && easing ||
3154 jQuery.isFunction( speed ) && speed,
3155 duration: speed,
3156 easing: fn && easing || easing && easing.constructor != Function && easing
3159 opt.duration = (opt.duration && opt.duration.constructor == Number ?
3160 opt.duration :
3161 jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
3163 // Queueing
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 );
3172 return opt;
3175 easing: {
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;
3184 timers: [],
3185 timerId: null,
3187 fx: function( elem, options, prop ){
3188 this.options = options;
3189 this.elem = elem;
3190 this.prop = prop;
3192 if ( !options.orig )
3193 options.orig = {};
3198 jQuery.fx.prototype = {
3200 // Simple function for setting a style value
3201 update: function(){
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();
3224 this.start = from;
3225 this.end = to;
3226 this.unit = unit || this.unit || "px";
3227 this.now = this.start;
3228 this.pos = this.state = 0;
3229 this.update();
3231 var self = this;
3232 function t(gotoEnd){
3233 return self.step(gotoEnd);
3236 t.elem = this.elem;
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++ )
3245 if ( !timers[i]() )
3246 timers.splice(i--, 1);
3248 if ( !timers.length ) {
3249 clearInterval( jQuery.timerId );
3250 jQuery.timerId = null;
3252 }, 13);
3256 // Simple 'show' function
3257 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
3266 // flash of content
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
3275 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){
3286 var t = now();
3288 if ( gotoEnd || t > this.options.duration + this.startTime ) {
3289 this.now = this.end;
3290 this.pos = this.state = 1;
3291 this.update();
3293 this.options.curAnim[ this.prop ] = true;
3295 var done = true;
3296 for ( var i in this.options.curAnim )
3297 if ( this.options.curAnim[i] !== true )
3298 done = false;
3300 if ( done ) {
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]);
3321 if ( done )
3322 // Execute the complete function
3323 this.options.complete.call( this.elem );
3325 return false;
3326 } else {
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
3335 this.update();
3338 return true;
3343 jQuery.extend( jQuery.fx, {
3344 speeds:{
3345 slow: 600,
3346 fast: 200,
3347 // Default speed
3348 def: 400
3350 step: {
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,
3376 offsetChild = elem,
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
3400 } else {
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" )
3417 fixed = true;
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" )
3434 border( parent );
3436 // Get next parent
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
3447 if ( 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;
3465 return results;
3469 jQuery.fn.extend({
3470 position: function() {
3471 var left = 0, top = 0, results;
3473 if ( this[0] ) {
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
3492 results = {
3493 top: offset.top - parentOffset.top,
3494 left: offset.left - parentOffset.left
3498 return results;
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 ?
3522 window.scrollTo(
3523 !i ? val : jQuery(window).scrollLeft(),
3524 i ? val : jQuery(window).scrollTop()
3526 this[ method ] = val;
3527 }) :
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 ] :
3534 this[0][ 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") +
3555 (margin ?
3556 num(this, "margin" + tl) + num(this, "margin" + br) : 0);
3559 });})();