From 0c5d2fbabb39ef53a798535bc58690d34ea21351 Mon Sep 17 00:00:00 2001 From: nanto Date: Tue, 8 Jan 2013 16:27:13 +0100 Subject: [PATCH] Propagate context of returned deferred object in Deferred.then(). Fixes #13160. --- src/deferred.js | 29 +++++++++++++---------------- test/unit/deferred.js | 18 +++++++++++++++++- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/deferred.js b/src/deferred.js index d84206570..0efc05dc3 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -21,22 +21,19 @@ jQuery.extend({ return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var action = tuple[ 0 ], - fn = fns[ i ]; + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? - function() { - var returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, [ returned ] ); - } - } : - newDefer[ action ] - ); + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); }); fns = null; }).promise(); @@ -72,7 +69,7 @@ jQuery.extend({ // deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( promise, arguments ); + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith; diff --git a/test/unit/deferred.js b/test/unit/deferred.js index 86b0b3411..f9bc13a9c 100644 --- a/test/unit/deferred.js +++ b/test/unit/deferred.js @@ -273,7 +273,7 @@ test( "jQuery.Deferred.then - deferred (progress)", function() { test( "jQuery.Deferred.then - context", function() { - expect( 4 ); + expect( 7 ); var context = {}; @@ -284,6 +284,12 @@ test( "jQuery.Deferred.then - context", function() { strictEqual( value, 6, "proper value received" ); }); + jQuery.Deferred().resolve().then(function() { + return jQuery.Deferred().resolveWith(context); + }).done(function() { + strictEqual( this, context, "custom context of returned deferred correctly propagated" ); + }); + var defer = jQuery.Deferred(), piped = defer.then(function( value ) { return value * 3; @@ -295,6 +301,16 @@ test( "jQuery.Deferred.then - context", function() { strictEqual( this, piped, "default context gets updated to latest promise in the chain" ); strictEqual( value, 6, "proper value received" ); }); + + var defer2 = jQuery.Deferred(), + piped2 = defer2.then(); + + defer2.resolve( 2 ); + + piped2.done(function( value ) { + strictEqual( this, piped2, "default context gets updated to latest promise in the chain (without passing function)" ); + strictEqual( value, 2, "proper value received (without passing function)" ); + }); }); test( "jQuery.when", function() { -- 2.39.5