From c45f6095f2d58a9fefd6bc788e50140acc7cf0c4 Mon Sep 17 00:00:00 2001 From: Corey Frang Date: Wed, 7 Nov 2012 19:23:24 -0600 Subject: [PATCH] Keep track of a hiding state for toggle based animations - Fixes #8685 Closes gh-1018 --- src/effects.js | 11 ++++++++++- test/unit/effects.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/effects.js b/src/effects.js index 3c10892a0..4b6b2e4da 100644 --- a/src/effects.js +++ b/src/effects.js @@ -234,7 +234,7 @@ jQuery.Animation = jQuery.extend( Animation, { function defaultPrefilter( elem, props, opts ) { /*jshint validthis:true */ - var index, prop, value, length, dataShow, tween, hooks, oldfire, + var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, anim = this, style = elem.style, orig = {}, @@ -308,6 +308,7 @@ function defaultPrefilter( elem, props, opts ) { value = props[ index ]; if ( rfxtypes.exec( value ) ) { delete props[ index ]; + toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { continue; } @@ -318,6 +319,14 @@ function defaultPrefilter( elem, props, opts ) { length = handled.length; if ( length ) { dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } if ( hidden ) { jQuery( elem ).show(); } else { diff --git a/test/unit/effects.js b/test/unit/effects.js index 519578f82..824afb41b 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -1865,4 +1865,48 @@ test( "Animations with 0 duration don't ease (#12273)", 1, function() { delete jQuery.easing.test; }); +jQuery.map([ "toggle", "slideToggle", "fadeToggle" ], function ( method ) { + // this test would look a lot better if we were using something to override + // the default timers + asyncTest( "toggle state tests: " + method + " (#8685)", function() { + function secondToggle() { + var stopped = parseFloat( element.css( check ) ); + tested = false; + element[ method ]({ + duration: 5000, + step: function( p, fx ) { + if ( fx.pos > 0.1 && fx.prop === check && !tested ) { + tested = true; + equal( fx.start, stopped, check + " starts at " + stopped + " where it stopped" ); + equal( fx.end, original, check + " ending value is " + original ); + element.stop(); + } + }, + always: start + }); + } + + var tested, + original, + check = method === "slideToggle" ? "height" : "opacity", + element = jQuery( "#foo" ); + + expect( 4 ); + + element[ method ]({ + duration: 5000, + step: function( p, fx ) { + if ( fx.pos > 0.1 && fx.prop === check && !tested ) { + tested = true; + original = fx.start; + equal( fx.start !== 0, true, check + " is starting at " + original + " on first toggle" ); + equal( fx.end, 0, check + " is ending at 0 on first toggle" ); + element.stop(); + } + }, + always: secondToggle + }); + }); +}); + } // if ( jQuery.fx ) -- 2.39.5