Fixed two bugs with togglling.
[jquery.git] / fx / fx.js
index 44633ab..1929388 100644 (file)
--- a/fx/fx.js
+++ b/fx/fx.js
@@ -1,18 +1,34 @@
 jQuery.fn.extend({
 
        // overwrite the old show method
-       _show: jQuery.fn.show,
+       //_show: jQuery.fn.show,
        
        /**
-        * The effects module overloads the show method to now allow 
-        * for a speed to the show operation. What actually happens is 
-        * that the height, width, and opacity to the matched elements 
-        * are changed dynamically. The only three current speeds are 
-        * "slow", "normal", and "fast". For example:
-        *   $("p").show("slow");
-        * Note: You should not run the show method on things 
-        * that are already shown. This can be circumvented by doing this:
-        *   $("p:hidden").show("slow");
+        * Show all matched elements using a graceful animation.
+        * The height, width, and opacity of each of the matched elements 
+        * are changed dynamically according to the specified speed.
+        *
+        * @example $("p").show("slow");
+        *
+        * @name show
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        */
+        
+       /**
+        * Show all matched elements using a graceful animation and firing a callback
+        * function after completion.
+        * The height, width, and opacity of each of the matched elements 
+        * are changed dynamically according to the specified speed.
+        *
+        * @example $("p").show("slow",function(){
+        *   alert("Animation Done.");
+        * });
+        *
+        * @name show
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        * @param Function callback A function to be executed whenever the animation completes.
         */
        show: function(speed,callback){
                return speed ? this.animate({
@@ -21,12 +37,34 @@ jQuery.fn.extend({
        },
        
        // Overwrite the old hide method
-       _hide: jQuery.fn.hide,
+       //_hide: jQuery.fn.hide,
        
        /**
-        * The hide function behaves very similary to the show function, 
-        * but is just the opposite.
-        *   $("p:visible").hide("slow");
+        * Hide all matched elements using a graceful animation.
+        * The height, width, and opacity of each of the matched elements 
+        * are changed dynamically according to the specified speed.
+        *
+        * @example $("p").hide("slow");
+        *
+        * @name hide
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        */
+        
+       /**
+        * Hide all matched elements using a graceful animation and firing a callback
+        * function after completion.
+        * The height, width, and opacity of each of the matched elements 
+        * are changed dynamically according to the specified speed.
+        *
+        * @example $("p").hide("slow",function(){
+        *   alert("Animation Done.");
+        * });
+        *
+        * @name hide
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        * @param Function callback A function to be executed whenever the animation completes.
         */
        hide: function(speed,callback){
                return speed ? this.animate({
@@ -35,49 +73,170 @@ jQuery.fn.extend({
        },
        
        /**
-        * This function increases the height and opacity for all matched 
-        * elements. This is very similar to 'show', but does not change 
-        * the width - creating a neat sliding effect.
-        *   $("p:hidden").slideDown("slow");
+        * Reveal all matched elements by adjusting their height.
+        * Only the height is adjusted for this animation, causing all matched
+        * elements to be revealed in a "sliding" manner.
+        *
+        * @example $("p").slideDown("slow");
+        *
+        * @name slideDown
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        */
+        
+       /**
+        * Reveal all matched elements by adjusting their height and firing a callback
+        * function after completion.
+        * Only the height is adjusted for this animation, causing all matched
+        * elements to be revealed in a "sliding" manner.
+        *
+        * @example $("p").slideDown("slow",function(){
+        *   alert("Animation Done.");
+        * });
+        *
+        * @name slideDown
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        * @param Function callback A function to be executed whenever the animation completes.
         */
        slideDown: function(speed,callback){
                return this.animate({height: "show"}, speed, callback);
        },
        
        /**
-        * Just like slideDown, only it hides all matched elements.
-        *   $("p:visible").slideUp("slow");
+        * Hide all matched elements by adjusting their height.
+        * Only the height is adjusted for this animation, causing all matched
+        * elements to be hidden in a "sliding" manner.
+        *
+        * @example $("p").slideUp("slow");
+        *
+        * @name slideUp
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        */
+        
+       /**
+        * Hide all matched elements by adjusting their height and firing a callback
+        * function after completion.
+        * Only the height is adjusted for this animation, causing all matched
+        * elements to be hidden in a "sliding" manner.
+        *
+        * @example $("p").slideUp("slow",function(){
+        *   alert("Animation Done.");
+        * });
+        *
+        * @name slideUp
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        * @param Function callback A function to be executed whenever the animation completes.
         */
        slideUp: function(speed,callback){
                return this.animate({height: "hide"}, speed, callback);
        },
        
        /**
-        * Adjusts the opacity of all matched elements from a hidden, 
-        * to a fully visible, state.
-        *   $("p:hidden").fadeIn("slow");
+        * Fade in all matched elements by adjusting their opacity.
+        * Only the opacity is adjusted for this animation, meaning that
+        * all of the matched elements should already have some form of height
+        * and width associated with them.
+        *
+        * @example $("p").fadeIn("slow");
+        *
+        * @name fadeIn
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        */
+        
+       /**
+        * Fade in all matched elements by adjusting their opacity and firing a 
+        * callback function after completion.
+        * Only the opacity is adjusted for this animation, meaning that
+        * all of the matched elements should already have some form of height
+        * and width associated with them.
+        *
+        * @example $("p").fadeIn("slow",function(){
+        *   alert("Animation Done.");
+        * });
+        *
+        * @name fadeIn
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        * @param Function callback A function to be executed whenever the animation completes.
         */
        fadeIn: function(speed,callback){
                return this.animate({opacity: "show"}, speed, callback);
        },
        
        /**
-        * Same as fadeIn, but transitions from a visible, to a hidden state.
-        *   $("p:visible").fadeOut("slow");
+        * Fade out all matched elements by adjusting their opacity.
+        * Only the opacity is adjusted for this animation, meaning that
+        * all of the matched elements should already have some form of height
+        * and width associated with them.
+        *
+        * @example $("p").fadeOut("slow");
+        *
+        * @name fadeOut
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        */
+        
+       /**
+        * Fade out all matched elements by adjusting their opacity and firing a 
+        * callback function after completion.
+        * Only the opacity is adjusted for this animation, meaning that
+        * all of the matched elements should already have some form of height
+        * and width associated with them.
+        *
+        * @example $("p").fadeOut("slow",function(){
+        *   alert("Animation Done.");
+        * });
+        *
+        * @name fadeOut
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        * @param Function callback A function to be executed whenever the animation completes.
         */
        fadeOut: function(speed,callback){
                return this.animate({opacity: "hide"}, speed, callback);
        },
        
        /**
-        * ...
+        * Fade the opacity of all matched elements to a specified opacity.
+        * Only the opacity is adjusted for this animation, meaning that
+        * all of the matched elements should already have some form of height
+        * and width associated with them.
+        *
+        * @example $("p").fadeTo("slow", 0.5);
+        *
+        * @name fadeTo
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        * @param Number opacity The opacity to fade to (a number from 0 to 1).
+        */
+        
+       /**
+        * Fade the opacity of all matched elements to a specified opacity and 
+        * firing a callback function after completion.
+        * Only the opacity is adjusted for this animation, meaning that
+        * all of the matched elements should already have some form of height
+        * and width associated with them.
+        *
+        * @example $("p").fadeTo("slow", 0.5, function(){
+        *   alert("Animation Done.");
+        * });
+        *
+        * @name fadeTo
+        * @type jQuery
+        * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
+        * @param Number opacity The opacity to fade to (a number from 0 to 1).
+        * @param Function callback A function to be executed whenever the animation completes.
         */
        fadeTo: function(speed,to,callback){
                return this.animate({opacity: to}, speed, callback);
        },
        
        /**
-        *
+        * @private
         */
        animate: function(prop,speed,callback) {
                return this.queue(function(){
@@ -87,7 +246,7 @@ jQuery.fn.extend({
                                if ( prop[p].constructor == Number )
                                        e.custom( e.cur(), prop[p] );
                                else
-                                       e[ prop[p] ]();
+                                       e[ prop[p] ]( prop );
                        }
                });
        },
@@ -121,12 +280,31 @@ jQuery.fn.extend({
 jQuery.extend({
 
        setAuto: function(e,p) {
+               if ( e.notAuto ) return;
+
+               if ( p == "height" && e.scrollHeight != parseInt(jQuery.curCSS(e,p)) ) return;
+               if ( p == "width" && e.scrollWidth != parseInt(jQuery.curCSS(e,p)) ) return;
+
+               // Remember the original height
                var a = e.style[p];
-               var o = jQuery.css(e,p);
-               e.style[p] = "auto";
-               var n = jQuery.css(e,p);
-               if ( o != n )
+
+               // Figure out the size of the height right now
+               var o = jQuery.curCSS(e,p,1);
+
+               if ( p == "height" && e.scrollHeight != o ||
+                       p == "width" && e.scrollWidth != o ) return;
+
+               // Set the height to auto
+               e.style[p] = e.currentStyle ? "" : "auto";
+
+               // See what the size of "auto" is
+               var n = jQuery.curCSS(e,p,1);
+
+               // Revert back to the original size
+               if ( o != n && n != "auto" ) {
                        e.style[p] = a;
+                       e.notAuto = true;
+               }
        },
        
        speed: function(s,o,i) {
@@ -164,8 +342,7 @@ jQuery.extend({
                        // Get next function
                        var f = elem.queue[type][0];
                
-                       if ( f )
-                               f.apply( elem );
+                       if ( f ) f.apply( elem );
                }
        },
 
@@ -197,9 +374,13 @@ jQuery.extend({
                                if (z.now == 1) z.now = 0.9999;
                                if (window.ActiveXObject)
                                        y.filter = "alpha(opacity=" + z.now*100 + ")";
-                               y.opacity = z.now;
-                       } else
-                               y[prop] = z.now+"px";
+                               else
+                                       y.opacity = z.now;
+
+                       // My hate for IE will never die
+                       } else if ( parseInt(z.now) )
+                               y[prop] = parseInt(z.now) + "px";
+                       y.display = "block";
                };
        
                // Figure out the maximum number to run to
@@ -209,7 +390,7 @@ jQuery.extend({
        
                // Get the current size
                z.cur = function(){
-                       return parseFloat( jQuery.curCSS(z.el,prop) ) || z.max();
+                       return parseFloat( jQuery.curCSS(z.el, prop) ) || z.max();
                };
        
                // Start an animation from one number to another
@@ -224,15 +405,17 @@ jQuery.extend({
                };
        
                // Simple 'show' function
-               z.show = function(){
+               z.show = function( p ){
                        if ( !z.el.orig ) z.el.orig = {};
 
                        // Remember where we started, so that we can go back to it later
                        z.el.orig[prop] = this.cur();
 
-                       if ( !y[prop] ) z.o.auto = true;
-                       z.custom(0,z.max());
-                       y.display = "block";
+                       z.custom( 0, z.el.orig[prop] );
+
+                       // Stupid IE, look what you made me do
+                       if ( prop != "opacity" )
+                               y[prop] = "1px";
                };
        
                // Simple 'hide' function
@@ -242,19 +425,22 @@ jQuery.extend({
                        // Remember where we started, so that we can go back to it later
                        z.el.orig[prop] = this.cur();
 
-                       z.o.hide = true;        
+                       z.o.hide = true;
+
                        // Begin the animation
                        z.custom(z.cur(),0);
                };
        
                // IE has trouble with opacity if it does not have layout
                if ( jQuery.browser.msie && !z.el.currentStyle.hasLayout )
-                       y.zoom = 1;
+                       y.zoom = "1";
        
                // Remember  the overflow of the element
-               z.oldOverflow = y.overflow;
+               if ( !z.el.oldOverlay )
+                       z.el.oldOverflow = jQuery.css( z.el, "overflow" );
        
                // Make sure that nothing sneaks out
+               //if ( z.el.oldOverlay == "visible" )
                y.overflow = "hidden";
        
                // Each step of an animation
@@ -265,33 +451,28 @@ jQuery.extend({
                                // Stop the timer
                                clearInterval(z.timer);
                                z.timer = null;
-       
+
                                z.now = lastNum;
                                z.a();
+
+                               // Hide the element if the "hide" operation was done
+                               if ( z.o.hide ) y.display = 'none';
        
                                // Reset the overflow
-                               y.overflow = z.oldOverflow;
-
-                               // If the element was shown, and not using a custom number,
-                               // set its height and/or width to auto
-                               if ( (prop == "height" || prop == "width") && z.o.auto )
-                                       jQuery.setAuto( z.el, prop );
+                               y.overflow = z.el.oldOverflow;
 
                                // If a callback was provided, execute it
-                               if( z.o.complete && z.o.complete.constructor == Function ) {
-       
-                                       // Yes, this is a weird place for this, but it needs to be executed
-                                       // only once per cluster of effects.
-                                       // If the element is, effectively, hidden - hide it
-                                       if ( z.o.hide ) y.display = "none";
-       
+                               if( z.o.complete && z.o.complete.constructor == Function )
                                        // Execute the complete function
                                        z.o.complete.apply( z.el );
-                               }
 
                                // Reset the property, if the item has been hidden
                                if ( z.o.hide )
-                                       y[ prop ] = z.el.orig[ prop ].constructor == Number && prop != "opacity" ? z.el.orig[prop] + "px" : z.el.orig[prop];
+                                       y[ prop ] = z.el.orig[ prop ].constructor == Number && prop != "opacity" ?
+                                               z.el.orig[prop] + "px" : z.el.orig[prop];
+
+                               // set its height and/or width to auto
+                               jQuery.setAuto( z.el, prop );
                        } else {
                                // Figure out where in the animation we are and set the number
                                var p = (t - this.startTime) / z.o.duration;