From: Corey Frang Date: Wed, 28 Sep 2011 16:00:21 +0000 (-0400) Subject: Landing pull request 520. Unset the complete function just before calling it to avoid... X-Git-Tag: 1.7b1~2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=8dda57f82f1c366f10c591da099f8e9495eaa01b;p=jquery.git 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 --- diff --git a/src/effects.js b/src/effects.js index ee535e3cd..e14235bc4 100644 --- a/src/effects.js +++ b/src/effects.js @@ -481,11 +481,11 @@ jQuery.fx.prototype = { // Each step of an animation step: function( gotoEnd ) { - var t = fxNow || createFxNow(), + var p, n, complete, + t = fxNow || createFxNow(), done = true, elem = this.elem, - options = this.options, - p, n; + options = this.options; if ( gotoEnd || t >= options.duration + this.startTime ) { this.now = this.end; @@ -525,7 +525,15 @@ jQuery.fx.prototype = { } // 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; diff --git a/test/unit/effects.js b/test/unit/effects.js index da1dd0a62..24f1b53f9 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -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); +});