jquery fx: Closes #3219. jQuery.fn.toggle can accept a boolean argument indicating...
[jquery.git] / src / fx.js
index 3fe9369..2d6433d 100644 (file)
--- a/src/fx.js
+++ b/src/fx.js
@@ -1,48 +1,74 @@
+var elemdisplay = {};
+
 jQuery.fn.extend({
        show: function(speed,callback){
-               return speed ?
-                       this.animate({
+               if ( speed ) {
+                       return this.animate({
                                height: "show", width: "show", opacity: "show"
-                       }, speed, callback) :
-
-                       this.filter(":hidden").each(function(){
-                               this.style.display = this.oldblock || "";
-                               if ( jQuery.css(this,"display") == "none" ) {
-                                       var elem = jQuery("<" + this.tagName + " />").appendTo("body");
-                                       this.style.display = elem.css("display");
-                                       // handle an edge condition where css is - div { display:none; } or similar
-                                       if (this.style.display == "none")
-                                               this.style.display = "block";
-                                       elem.remove();
+                       }, speed, callback);
+               } else {
+                       for ( var i = 0, l = this.length; i < l; i++ ){
+                               var old = jQuery.data(this[i], "olddisplay");
+                               
+                               this[i].style.display = old || "";
+                               
+                               if ( jQuery.css(this[i], "display") === "none" ) {
+                                       var tagName = this[i].tagName, display;
+                                       
+                                       if ( elemdisplay[ tagName ] ) {
+                                               display = elemdisplay[ tagName ];
+                                       } else {
+                                               var elem = jQuery("<" + this[i].tagName + " />").appendTo("body");
+                                               
+                                               display = elem.css("display");
+                                               if ( display === "none" )
+                                                       display = "block";
+                                               
+                                               elem.remove();
+                                               
+                                               elemdisplay[ this[i].tagName ] = display;
+                                       }
+                                       
+                                       this[i].style.display = jQuery.data(this[i], "olddisplay", display);
                                }
-                       }).end();
+                       }
+                       
+                       return this;
+               }
        },
 
        hide: function(speed,callback){
-               return speed ?
-                       this.animate({
+               if ( speed ) {
+                       return this.animate({
                                height: "hide", width: "hide", opacity: "hide"
-                       }, speed, callback) :
-
-                       this.filter(":visible").each(function(){
-                               this.oldblock = this.oldblock || jQuery.css(this,"display");
-                               this.style.display = "none";
-                       }).end();
+                       }, speed, callback);
+               } else {
+                       for ( var i = 0, l = this.length; i < l; i++ ){
+                               var old = jQuery.data(this[i], "olddisplay");
+                               if ( !old && old !== "none" )
+                                       jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+                               this[i].style.display = "none";
+                       }
+                       return this;
+               }
        },
 
        // Save the old toggle function
        _toggle: jQuery.fn.toggle,
 
        toggle: function( fn, fn2 ){
+               var bool = typeof fn === "boolean";
+
                return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
                        this._toggle.apply( this, arguments ) :
-                       fn ?
+                       fn == null || bool ?
+                               this.each(function(){
+                                       var state = bool ? fn : jQuery(this).is(":hidden");
+                                       jQuery(this)[ state ? "show" : "hide" ]();
+                               }) :
                                this.animate({
                                        height: "toggle", width: "toggle", opacity: "toggle"
-                               }, fn, fn2) :
-                               this.each(function(){
-                                       jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
-                               });
+                               }, fn, fn2);
        },
 
        fadeTo: function(speed,to,callback){
@@ -112,16 +138,16 @@ jQuery.fn.extend({
        },
 
        queue: function(type, fn){
-               if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
+               if ( jQuery.isFunction(type) || jQuery.isArray(type) ) {
                        fn = type;
                        type = "fx";
                }
 
-               if ( !type || (typeof type == "string" && !fn) )
+               if ( !type || (typeof type === "string" && !fn) )
                        return queue( this[0], type );
 
                return this.each(function(){
-                       if ( fn.constructor == Array )
+                       if ( jQuery.isArray(fn) )
                                queue(this, type, fn);
                        else {
                                queue(this, type).push( fn );
@@ -201,14 +227,14 @@ jQuery.fn.dequeue = function(type){
 jQuery.extend({
 
        speed: function(speed, easing, fn) {
-               var opt = speed && speed.constructor == Object ? speed : {
+               var opt = typeof speed === "object" ? speed : {
                        complete: fn || !fn && easing ||
                                jQuery.isFunction( speed ) && speed,
                        duration: speed,
-                       easing: fn && easing || easing && easing.constructor != Function && easing
+                       easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
                };
 
-               opt.duration = jQuery.fx.off ? 0 : typeof opt.duration == 'number' ? opt.duration :
+               opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
                        jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
 
                // Queueing