Tagging the 1.2.2b2 release.
[jquery.git] / src / fx.js
index c45edc1..fb564f0 100644 (file)
--- a/src/fx.js
+++ b/src/fx.js
@@ -6,9 +6,12 @@ jQuery.fn.extend({
                        }, speed, callback) :
                        
                        this.filter(":hidden").each(function(){
-                               this.style.display = this.oldblock ? this.oldblock : "";
-                               if ( jQuery.css(this,"display") == "none" )
-                                       this.style.display = "block";
+                               this.style.display = this.oldblock || "";
+                               if ( jQuery.css(this,"display") == "none" ) {
+                                       var elem = jQuery("<" + this.tagName + " />").appendTo("body");
+                                       this.style.display = elem.css("display");
+                                       elem.remove();
+                               }
                        }).end();
        },
        
@@ -20,8 +23,6 @@ jQuery.fn.extend({
                        
                        this.filter(":visible").each(function(){
                                this.oldblock = this.oldblock || jQuery.css(this,"display");
-                               if ( this.oldblock == "none" )
-                                       this.oldblock = "block";
                                this.style.display = "none";
                        }).end();
        },
@@ -66,10 +67,13 @@ jQuery.fn.extend({
        },
        
        animate: function( prop, speed, easing, callback ) {
-               var opt = jQuery.speed(speed, easing, callback);
+               var optall = jQuery.speed(speed, easing, callback);
+
+               return this[ optall.queue === false ? "each" : "queue" ](function(){
+                       if ( this.nodeType != 1)
+                               return false;
 
-               return this[ opt.queue === false ? "each" : "queue" ](function(){
-                       opt = jQuery.extend({}, opt);
+                       var opt = jQuery.extend({}, optall);
                        var hidden = jQuery(this).is(":hidden"), self = this;
                        
                        for ( var p in prop ) {
@@ -96,23 +100,23 @@ jQuery.fn.extend({
                                if ( /toggle|show|hide/.test(val) )
                                        e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
                                else {
-                                       var parts = val.toString().match(/^([+-]?)([\d.]+)(.*)$/),
+                                       var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
                                                start = e.cur(true) || 0;
 
                                        if ( parts ) {
-                                               end = parseFloat(parts[2]),
-                                               unit = parts[3] || "px";
+                                               var end = parseFloat(parts[2]),
+                                                       unit = parts[3] || "px";
 
                                                // We need to compute starting value
                                                if ( unit != "px" ) {
-                                                       self.style[ name ] = end + unit;
-                                                       start = (end / e.cur(true)) * start;
+                                                       self.style[ name ] = (end || 1) + unit;
+                                                       start = ((end || 1) / e.cur(true)) * start;
                                                        self.style[ name ] = start + unit;
                                                }
 
-                                               // If a +/- token was provided, we're doing a relative animation
+                                               // If a +=/-= token was provided, we're doing a relative animation
                                                if ( parts[1] )
-                                                       end = ((parts[1] == "-" ? -1 : 1) * end) + start;
+                                                       end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
 
                                                e.custom( start, end, unit );
                                        } else
@@ -126,15 +130,18 @@ jQuery.fn.extend({
        },
        
        queue: function(type, fn){
-               if ( !fn ) {
+               if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
                        fn = type;
                        type = "fx";
                }
 
-               if ( !arguments.length )
+               if ( !type || (typeof type == "string" && !fn) )
                        return queue( this[0], type );
 
                return this.each(function(){
+                       if ( this.nodeType != 1)
+                               return;
+
                        if ( fn.constructor == Array )
                                queue(this, type, fn);
                        else {
@@ -146,43 +153,59 @@ jQuery.fn.extend({
                });
        },
 
-       dequeue: function(type){
-               type = type || "fx";
-
-               return this.each(function(){
-                       var q = queue(this, type);
-
-                       q.shift();
+       stop: function(clearQueue, gotoEnd){
+               var timers = jQuery.timers;
 
-                       if ( q.length )
-                               q[0].apply( this );
+               if (clearQueue)
+                       this.queue([]);
+
+               this.each(function(){
+                       // go in reverse order so anything added to the queue during the loop is ignored
+                       for ( var i = timers.length - 1; i >= 0; i-- )
+                               if ( timers[i].elem == this ) {
+                                       if (gotoEnd)
+                                               // force the next step to be the last
+                                               timers[i](true);
+                                       timers.splice(i, 1);
+                               }
                });
-       },
 
-       stop: function(){
-               var timers = jQuery.timers;
+               // start the next in the queue if the last step wasn't forced
+               if (!gotoEnd)
+                       this.dequeue();
 
-               return this.each(function(){
-                       for ( var i = 0; i < timers.length; i++ )
-                               if ( timers[i].elem == this )
-                                       timers.splice(i--, 1);
-               }).dequeue();
+               return this;
        }
 
 });
 
-function queue( elem, type, array ) {
+var queue = function( elem, type, array ) {
        if ( !elem )
-               return;
+               return undefined;
+
+       type = type || "fx";
 
-       var queue = jQuery.data( elem, type + "queue" );
+       var q = jQuery.data( elem, type + "queue" );
 
-       if ( !queue || array )
-               queue = jQuery.data( elem, type + "queue", 
+       if ( !q || array )
+               q = jQuery.data( elem, type + "queue", 
                        array ? jQuery.makeArray(array) : [] );
 
-       return queue;
-}
+       return q;
+};
+
+jQuery.fn.dequeue = function(type){
+       type = type || "fx";
+
+       return this.each(function(){
+               var q = queue(this, type);
+
+               q.shift();
+
+               if ( q.length )
+                       q[0].apply( this );
+       });
+};
 
 jQuery.extend({
        
@@ -201,7 +224,8 @@ jQuery.extend({
                // Queueing
                opt.old = opt.complete;
                opt.complete = function(){
-                       jQuery(this).dequeue();
+                       if ( opt.queue !== false )
+                               jQuery(this).dequeue();
                        if ( jQuery.isFunction( opt.old ) )
                                opt.old.apply( this );
                };
@@ -219,6 +243,7 @@ jQuery.extend({
        },
        
        timers: [],
+       timerId: null,
 
        fx: function( elem, options, prop ){
                this.options = options;
@@ -250,8 +275,8 @@ jQuery.fx.prototype = {
                if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
                        return this.elem[ this.prop ];
 
-               var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force));
-               return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) || 0;
+               var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+               return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
        },
 
        // Start an animation from one number to another
@@ -265,24 +290,26 @@ jQuery.fx.prototype = {
                this.update();
 
                var self = this;
-               function t(){
-                       return self.step();
+               function t(gotoEnd){
+                       return self.step(gotoEnd);
                }
 
                t.elem = this.elem;
 
                jQuery.timers.push(t);
 
-               if ( jQuery.timers.length == 1 ) {
-                       var timer = setInterval(function(){
+               if ( jQuery.timerId == null ) {
+                       jQuery.timerId = setInterval(function(){
                                var timers = jQuery.timers;
                                
                                for ( var i = 0; i < timers.length; i++ )
                                        if ( !timers[i]() )
                                                timers.splice(i--, 1);
 
-                               if ( !timers.length )
-                                       clearInterval( timer );
+                               if ( !timers.length ) {
+                                       clearInterval( jQuery.timerId );
+                                       jQuery.timerId = null;
+                               }
                        }, 13);
                }
        },
@@ -316,10 +343,10 @@ jQuery.fx.prototype = {
        },
 
        // Each step of an animation
-       step: function(){
+       step: function(gotoEnd){
                var t = (new Date()).getTime();
 
-               if ( t > this.options.duration + this.startTime ) {
+               if ( gotoEnd || t > this.options.duration + this.startTime ) {
                        this.now = this.end;
                        this.pos = this.state = 1;
                        this.update();