X-Git-Url: http://git.asbjorn.biz/?p=jquery.git;a=blobdiff_plain;f=src%2Feffects.js;h=b0675395f45ac8d2ab5eb6d366da3b5d0bf42186;hp=9db341a3b077f491708af2095522ac25b6a9c81d;hb=0cbe4cb8bdce9eacd2b63de6e9ca0b662606b633;hpb=77e310b906112c9e20dfbf0e91249a0b81cf6107 diff --git a/src/effects.js b/src/effects.js index 9db341a..b067539 100644 --- a/src/effects.js +++ b/src/effects.js @@ -1,8 +1,8 @@ (function( jQuery ) { var elemdisplay = {}, - rfxtypes = /toggle|show|hide/, - rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, timerId, fxAttrs = [ // height animations @@ -14,66 +14,63 @@ var elemdisplay = {}, ]; jQuery.fn.extend({ - show: function( speed, callback ) { - if ( speed || speed === 0) { - return this.animate( genFx("show", 3), speed, callback); + show: function( speed, easing, callback ) { + var elem, display; - } 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 nodeName = this[i].nodeName, display; - - if ( elemdisplay[ nodeName ] ) { - display = elemdisplay[ nodeName ]; - - } else { - var elem = jQuery("<" + nodeName + " />").appendTo("body"); - - display = elem.css("display"); - - if ( display === "none" ) { - display = "block"; - } - - elem.remove(); + if ( speed || speed === 0 ) { + return this.animate( genFx("show", 3), speed, easing, callback); - elemdisplay[ nodeName ] = display; - } + } else { + for ( var i = 0, j = this.length; i < j; i++ ) { + elem = this[i]; + display = elem.style.display; + + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { + display = elem.style.display = ""; + } - jQuery.data(this[i], "olddisplay", display); + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { + jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); } } - // Set the display of the elements in a second loop + // Set the display of most of the elements in a second loop // to avoid the constant reflow - for ( var j = 0, k = this.length; j < k; j++ ) { - this[j].style.display = jQuery.data(this[j], "olddisplay") || ""; + for ( i = 0; i < j; i++ ) { + elem = this[i]; + display = elem.style.display; + + if ( display === "" || display === "none" ) { + elem.style.display = jQuery._data(elem, "olddisplay") || ""; + } } return this; } }, - hide: function( speed, callback ) { + hide: function( speed, easing, callback ) { if ( speed || speed === 0 ) { - return this.animate( genFx("hide", 3), speed, callback); + return this.animate( genFx("hide", 3), speed, easing, 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" ) ); + for ( var i = 0, j = this.length; i < j; i++ ) { + var display = jQuery.css( this[i], "display" ); + + if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { + jQuery._data( this[i], "olddisplay", display ); } } // Set the display of the elements in a second loop // to avoid the constant reflow - for ( var j = 0, k = this.length; j < k; j++ ) { - this[j].style.display = "none"; + for ( i = 0; i < j; i++ ) { + this[i].style.display = "none"; } return this; @@ -83,7 +80,7 @@ jQuery.fn.extend({ // Save the old toggle function _toggle: jQuery.fn.toggle, - toggle: function( fn, fn2 ) { + toggle: function( fn, fn2, callback ) { var bool = typeof fn === "boolean"; if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { @@ -96,15 +93,15 @@ jQuery.fn.extend({ }); } else { - this.animate(genFx("toggle", 3), fn, fn2); + this.animate(genFx("toggle", 3), fn, fn2, callback); } return this; }, - fadeTo: function( speed, to, callback ) { + fadeTo: function( speed, to, easing, callback ) { return this.filter(":hidden").css("opacity", 0).show().end() - .animate({opacity: to}, speed, callback); + .animate({opacity: to}, speed, easing, callback); }, animate: function( prop, speed, easing, callback ) { @@ -115,8 +112,12 @@ jQuery.fn.extend({ } return this[ optall.queue === false ? "each" : "queue" ](function() { + // XXX 'this' does not always have a nodeName when running the + // test suite + var opt = jQuery.extend({}, optall), p, - hidden = this.nodeType === 1 && jQuery(this).is(":hidden"), + isElement = this.nodeType === 1, + hidden = isElement && jQuery(this).is(":hidden"), self = this; for ( p in prop ) { @@ -132,12 +133,35 @@ jQuery.fn.extend({ return opt.complete.call(this); } - if ( ( p === "height" || p === "width" ) && this.style ) { - // Store display property - opt.display = this.style.display; - + if ( isElement && ( p === "height" || p === "width" ) ) { // Make sure that nothing sneaks out - opt.overflow = this.style.overflow; + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height + // animated + if ( jQuery.css( this, "display" ) === "inline" && + jQuery.css( this, "float" ) === "none" ) { + if ( !jQuery.support.inlineBlockNeedsLayout ) { + this.style.display = "inline-block"; + + } else { + var display = defaultDisplay(this.nodeName); + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( display === "inline" ) { + this.style.display = "inline-block"; + + } else { + this.style.display = "inline"; + this.style.zoom = 1; + } + } + } } if ( jQuery.isArray( prop[p] ) ) { @@ -161,7 +185,7 @@ jQuery.fn.extend({ } else { var parts = rfxnum.exec(val), - start = e.cur(true) || 0; + start = e.cur() || 0; if ( parts ) { var end = parseFloat( parts[2] ), @@ -169,9 +193,9 @@ jQuery.fn.extend({ // We need to compute starting value if ( unit !== "px" ) { - self.style[ name ] = (end || 1) + unit; - start = ((end || 1) / e.cur(true)) * start; - self.style[ name ] = start + unit; + jQuery.style( self, name, (end || 1) + unit); + start = ((end || 1) / e.cur()) * start; + jQuery.style( self, name, start + unit); } // If a +=/-= token was provided, we're doing a relative animation @@ -239,16 +263,17 @@ jQuery.each({ slideUp: genFx("hide", 1), slideToggle: genFx("toggle", 1), fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" } + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } }, function( name, props ) { - jQuery.fn[ name ] = function( speed, callback ) { - return this.animate( props, speed, callback ); + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); }; }); jQuery.extend({ speed: function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? speed : { + var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { complete: fn || !fn && easing || jQuery.isFunction( speed ) && speed, duration: speed, @@ -256,7 +281,7 @@ jQuery.extend({ }; opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : - jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default; + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default; // Queueing opt.old = opt.complete; @@ -303,11 +328,6 @@ jQuery.fx.prototype = { } (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); - - // Set display property to block for height/width animations - if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) { - this.elem.style.display = "block"; - } }, // Get the current size @@ -316,12 +336,15 @@ jQuery.fx.prototype = { return this.elem[ this.prop ]; } - var r = parseFloat( jQuery.css( this.elem, this.prop ), 10 ); - return r && r > -10000 ? r : 0; + var r = parseFloat( jQuery.css( this.elem, this.prop ) ); + return r || 0; }, // Start an animation from one number to another custom: function( from, to, unit ) { + var self = this, + fx = jQuery.fx; + this.startTime = jQuery.now(); this.start = from; this.end = to; @@ -329,7 +352,6 @@ jQuery.fx.prototype = { this.now = this.start; this.pos = this.state = 0; - var self = this; function t( gotoEnd ) { return self.step(gotoEnd); } @@ -337,7 +359,7 @@ jQuery.fx.prototype = { t.elem = this.elem; if ( t() && jQuery.timers.push(t) && !timerId ) { - timerId = setInterval(jQuery.fx.tick, 13); + timerId = setInterval(fx.tick, fx.interval); } }, @@ -384,17 +406,14 @@ jQuery.fx.prototype = { } if ( done ) { - if ( this.options.display != null ) { - // Reset the overflow - this.elem.style.overflow = this.options.overflow; - - // Reset the display - var old = jQuery.data(this.elem, "olddisplay"); - this.elem.style.display = old ? old : this.options.display; - - if ( jQuery.css( this.elem, "display" ) === "none" ) { - this.elem.style.display = "block"; - } + // Reset the overflow + if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { + var elem = this.elem, + options = this.options; + + jQuery.each( [ "", "X", "Y" ], function (index, value) { + elem.style[ "overflow" + value ] = options.overflow[index]; + } ); } // Hide the element if the "hide" operation was done @@ -447,12 +466,14 @@ jQuery.extend( jQuery.fx, { jQuery.fx.stop(); } }, - + + interval: 13, + stop: function() { clearInterval( timerId ); timerId = null; }, - + speeds: { slow: 600, fast: 200, @@ -483,4 +504,21 @@ if ( jQuery.expr && jQuery.expr.filters ) { }; } +function defaultDisplay( nodeName ) { + if ( !elemdisplay[ nodeName ] ) { + var elem = jQuery("<" + nodeName + ">").appendTo("body"), + display = elem.css("display"); + + elem.remove(); + + if ( display === "none" || display === "" ) { + display = "block"; + } + + elemdisplay[ nodeName ] = display; + } + + return elemdisplay[ nodeName ]; +} + })( jQuery );