Skip to content

Commit 3c89329

Browse files
authored
Effects: Resolve issues revealed by recent Callbacks fix
Notify full progress before resolving empty animations Register animation callbacks before their ticker Remove the right timer when immediately-done animations spawn more Ref 9d822bc Fixes jquerygh-3502 Fixes jquerygh-3503 Closes jquerygh-3496
1 parent efdb8a4 commit 3c89329

File tree

2 files changed

+36
-20
lines changed

2 files changed

+36
-20
lines changed

src/effects.js

+27-12
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,19 @@ function Animation( elem, properties, options ) {
315315

316316
deferred.notifyWith( elem, [ animation, percent, remaining ] );
317317

318+
// If there's more to do, yield
318319
if ( percent < 1 && length ) {
319320
return remaining;
320-
} else {
321-
deferred.resolveWith( elem, [ animation ] );
322-
return false;
323321
}
322+
323+
// If this was an empty animation, synthesize a final progress notification
324+
if ( !length ) {
325+
deferred.notifyWith( elem, [ animation, 1, 0 ] );
326+
}
327+
328+
// Resolve the animation and report its conclusion
329+
deferred.resolveWith( elem, [ animation ] );
330+
return false;
324331
},
325332
animation = deferred.promise( {
326333
elem: elem,
@@ -385,6 +392,13 @@ function Animation( elem, properties, options ) {
385392
animation.opts.start.call( elem, animation );
386393
}
387394

395+
// Attach callbacks from options
396+
animation
397+
.progress( animation.opts.progress )
398+
.done( animation.opts.done, animation.opts.complete )
399+
.fail( animation.opts.fail )
400+
.always( animation.opts.always );
401+
388402
jQuery.fx.timer(
389403
jQuery.extend( tick, {
390404
elem: elem,
@@ -393,11 +407,7 @@ function Animation( elem, properties, options ) {
393407
} )
394408
);
395409

396-
// attach callbacks from options
397-
return animation.progress( animation.opts.progress )
398-
.done( animation.opts.done, animation.opts.complete )
399-
.fail( animation.opts.fail )
400-
.always( animation.opts.always );
410+
return animation;
401411
}
402412

403413
jQuery.Animation = jQuery.extend( Animation, {
@@ -641,7 +651,7 @@ jQuery.fx.tick = function() {
641651
for ( ; i < timers.length; i++ ) {
642652
timer = timers[ i ];
643653

644-
// Checks the timer has not already been removed
654+
// Run the timer and safely remove it when done (allowing for external removal)
645655
if ( !timer() && timers[ i ] === timer ) {
646656
timers.splice( i--, 1 );
647657
}
@@ -654,11 +664,16 @@ jQuery.fx.tick = function() {
654664
};
655665

656666
jQuery.fx.timer = function( timer ) {
657-
jQuery.timers.push( timer );
667+
var i = jQuery.timers.push( timer ) - 1,
668+
timers = jQuery.timers;
669+
658670
if ( timer() ) {
659671
jQuery.fx.start();
660-
} else {
661-
jQuery.timers.pop();
672+
673+
// If the timer finished immediately, safely remove it (allowing for external removal)
674+
// Use a superfluous post-decrement for better compressibility w.r.t. jQuery.fx.tick above
675+
} else if ( timers[ i ] === timer ) {
676+
timers.splice( i--, 1 );
662677
}
663678
};
664679

test/unit/effects.js

+9-8
Original file line numberDiff line numberDiff line change
@@ -1256,17 +1256,18 @@ QUnit.test( "animate with CSS shorthand properties", function( assert ) {
12561256
} );
12571257

12581258
QUnit.test( "hide hidden elements, with animation (bug #7141)", function( assert ) {
1259-
assert.expect( 3 );
1259+
assert.expect( 4 );
12601260

1261-
var div = jQuery( "<div style='display:none'></div>" ).appendTo( "#qunit-fixture" );
1262-
assert.equal( div.css( "display" ), "none", "Element is hidden by default" );
1263-
div.hide( 1, function() {
1264-
assert.ok( !jQuery._data( div, "olddisplay" ), "olddisplay is undefined after hiding an already-hidden element" );
1265-
div.show( 1, function() {
1266-
assert.equal( div.css( "display" ), "block", "Show a double-hidden element" );
1261+
var div = jQuery( "<div id='bug7141' style='display:none'/>" ).appendTo( "#qunit-fixture" );
1262+
assert.equal( div.css( "display" ), "none", "Element is initially hidden" );
1263+
div.hide( 10, function() {
1264+
assert.equal( div.css( "display" ), "none", "Element is hidden in .hide() callback" );
1265+
div.show( 11, function() {
1266+
assert.equal( div.css( "display" ), "block", "Element is visible in .show() callback" );
12671267
} );
12681268
} );
1269-
this.clock.tick( 10 );
1269+
this.clock.tick( 50 );
1270+
assert.equal( div.css( "display" ), "block", "Element is visible after animations" );
12701271
} );
12711272

12721273
QUnit.test( "animate unit-less properties (#4966)", function( assert ) {

0 commit comments

Comments
 (0)