Landing pull request 520. Unset the complete function just before calling it to avoid an exception creating a loop. Fixes #5684.

More Details:
 - https://github.com/jquery/jquery/pull/520
 - http://bugs.jquery.com/ticket/5684
This commit is contained in:
Corey Frang 2011-09-28 12:00:21 -04:00 committed by timmywil
parent a3b59d7f92
commit 8dda57f82f
2 changed files with 44 additions and 4 deletions

16
src/effects.js vendored
View File

@ -481,11 +481,11 @@ jQuery.fx.prototype = {
// Each step of an animation // Each step of an animation
step: function( gotoEnd ) { step: function( gotoEnd ) {
var t = fxNow || createFxNow(), var p, n, complete,
t = fxNow || createFxNow(),
done = true, done = true,
elem = this.elem, elem = this.elem,
options = this.options, options = this.options;
p, n;
if ( gotoEnd || t >= options.duration + this.startTime ) { if ( gotoEnd || t >= options.duration + this.startTime ) {
this.now = this.end; this.now = this.end;
@ -525,7 +525,15 @@ jQuery.fx.prototype = {
} }
// Execute the complete function // Execute the complete function
options.complete.call( elem ); // in the event that the complete function throws an exception
// we must ensure it won't be called twice. #5684
complete = options.complete;
if ( complete ) {
options.complete = false;
complete.call( elem );
}
} }
return false; return false;

32
test/unit/effects.js vendored
View File

@ -1205,3 +1205,35 @@ test("callbacks should fire in correct order (#9100)", function() {
} }
}); });
}); });
asyncTest( "callbacks that throw exceptions will be removed (#5684)", function() {
expect( 2 );
var foo = jQuery( "#foo" );
function testException() {
}
foo.animate({ height: 1 }, 1, function() {
throw new testException;
});
// this test thoroughly abuses undocumented methods - please feel free to update
// with any changes internally to these functions.
// make sure that the standard timer loop will NOT run.
jQuery.fx.stop();
setTimeout(function() {
// the first call to fx.tick should raise the callback exception
raises( jQuery.fx.tick, testException, "Exception was thrown" );
// the second call shouldn't
jQuery.fx.tick();
ok( true, "Test completed without throwing a second exception" );
start();
}, 1);
});