2011-03-03 18:38:06 +00:00
|
|
|
(function( jQuery ) {
|
|
|
|
|
2011-09-21 15:00:55 +00:00
|
|
|
var // Static reference to slice
|
2011-03-03 18:38:06 +00:00
|
|
|
sliceDeferred = [].slice;
|
|
|
|
|
|
|
|
jQuery.extend({
|
|
|
|
|
2011-09-12 15:37:41 +00:00
|
|
|
Deferred: function( func ) {
|
|
|
|
var doneList = jQuery.Callbacks( "once memory" ),
|
|
|
|
failList = jQuery.Callbacks( "once memory" ),
|
|
|
|
progressList = jQuery.Callbacks( "memory" ),
|
2011-10-12 00:23:56 +00:00
|
|
|
state = "pending",
|
2011-09-21 15:00:55 +00:00
|
|
|
lists = {
|
|
|
|
resolve: doneList,
|
|
|
|
reject: failList,
|
|
|
|
notify: progressList
|
|
|
|
},
|
|
|
|
promise = {
|
2011-09-12 15:37:41 +00:00
|
|
|
done: doneList.add,
|
|
|
|
fail: failList.add,
|
|
|
|
progress: progressList.add,
|
2011-09-21 15:00:55 +00:00
|
|
|
|
2011-10-12 00:23:56 +00:00
|
|
|
state: function() {
|
|
|
|
return state;
|
|
|
|
},
|
|
|
|
|
|
|
|
// Deprecated
|
2011-09-12 15:37:41 +00:00
|
|
|
isResolved: doneList.fired,
|
|
|
|
isRejected: failList.fired,
|
2011-03-03 18:38:06 +00:00
|
|
|
|
2011-09-12 15:37:41 +00:00
|
|
|
always: function() {
|
2011-11-09 00:02:29 +00:00
|
|
|
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
|
|
|
|
return this;
|
2011-03-03 18:38:06 +00:00
|
|
|
},
|
2012-04-01 23:29:39 +00:00
|
|
|
then: function( fnDone, fnFail, fnProgress ) {
|
2011-09-12 15:37:41 +00:00
|
|
|
return jQuery.Deferred(function( newDefer ) {
|
|
|
|
jQuery.each( {
|
|
|
|
done: [ fnDone, "resolve" ],
|
|
|
|
fail: [ fnFail, "reject" ],
|
|
|
|
progress: [ fnProgress, "notify" ]
|
|
|
|
}, function( handler, data ) {
|
|
|
|
var fn = data[ 0 ],
|
|
|
|
action = data[ 1 ],
|
|
|
|
returned;
|
|
|
|
if ( jQuery.isFunction( fn ) ) {
|
|
|
|
deferred[ handler ](function() {
|
|
|
|
returned = fn.apply( this, arguments );
|
|
|
|
if ( returned && jQuery.isFunction( returned.promise ) ) {
|
2012-04-01 23:29:39 +00:00
|
|
|
returned.promise().done( newDefer.resolve ).fail( newDefer.reject ).progress( newDefer.notify );
|
2011-09-12 15:37:41 +00:00
|
|
|
} else {
|
|
|
|
newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
deferred[ handler ]( newDefer[ action ] );
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}).promise();
|
2011-03-03 18:38:06 +00:00
|
|
|
},
|
2011-09-12 15:37:41 +00:00
|
|
|
// Get a promise for this deferred
|
|
|
|
// If obj is provided, the promise aspect is added to the object
|
|
|
|
promise: function( obj ) {
|
|
|
|
if ( obj == null ) {
|
2011-09-21 15:00:55 +00:00
|
|
|
obj = promise;
|
|
|
|
} else {
|
2011-10-26 18:58:05 +00:00
|
|
|
for ( var key in promise ) {
|
2011-09-21 15:00:55 +00:00
|
|
|
obj[ key ] = promise[ key ];
|
2011-09-12 15:37:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return obj;
|
2011-03-03 18:38:06 +00:00
|
|
|
}
|
2011-09-21 15:00:55 +00:00
|
|
|
},
|
2012-04-01 23:29:39 +00:00
|
|
|
deferred,
|
2011-09-21 15:00:55 +00:00
|
|
|
key;
|
|
|
|
|
2012-04-01 23:29:39 +00:00
|
|
|
// Keep pipe for back-compat
|
|
|
|
promise.pipe = promise.then;
|
|
|
|
|
|
|
|
// Construct deferred
|
|
|
|
deferred = promise.promise({});
|
|
|
|
|
2011-09-21 15:00:55 +00:00
|
|
|
for ( key in lists ) {
|
|
|
|
deferred[ key ] = lists[ key ].fire;
|
|
|
|
deferred[ key + "With" ] = lists[ key ].fireWith;
|
|
|
|
}
|
2011-03-03 18:38:06 +00:00
|
|
|
|
2011-10-12 00:23:56 +00:00
|
|
|
// Handle state
|
|
|
|
deferred.done( function() {
|
|
|
|
state = "resolved";
|
|
|
|
}, failList.disable, progressList.lock ).fail( function() {
|
|
|
|
state = "rejected";
|
|
|
|
}, doneList.disable, progressList.lock );
|
2011-03-03 18:38:06 +00:00
|
|
|
|
|
|
|
// Call given func if any
|
|
|
|
if ( func ) {
|
|
|
|
func.call( deferred, deferred );
|
|
|
|
}
|
2011-09-12 15:37:41 +00:00
|
|
|
|
|
|
|
// All done!
|
2011-03-03 18:38:06 +00:00
|
|
|
return deferred;
|
|
|
|
},
|
|
|
|
|
|
|
|
// Deferred helper
|
|
|
|
when: function( firstParam ) {
|
2012-03-13 13:39:40 +00:00
|
|
|
var args = sliceDeferred.call( arguments ),
|
2011-03-03 18:38:06 +00:00
|
|
|
i = 0,
|
|
|
|
length = args.length,
|
2011-09-12 15:37:41 +00:00
|
|
|
pValues = new Array( length ),
|
2011-03-03 18:38:06 +00:00
|
|
|
count = length,
|
2011-09-12 15:37:41 +00:00
|
|
|
pCount = length,
|
2011-03-03 18:38:06 +00:00
|
|
|
deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
|
|
|
|
firstParam :
|
2011-09-12 15:37:41 +00:00
|
|
|
jQuery.Deferred(),
|
|
|
|
promise = deferred.promise();
|
2011-03-03 18:38:06 +00:00
|
|
|
function resolveFunc( i ) {
|
|
|
|
return function( value ) {
|
2012-03-13 13:39:40 +00:00
|
|
|
args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments ) : value;
|
2011-03-03 18:38:06 +00:00
|
|
|
if ( !( --count ) ) {
|
2011-09-12 15:37:41 +00:00
|
|
|
deferred.resolveWith( deferred, args );
|
2011-03-03 18:38:06 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2011-09-12 15:37:41 +00:00
|
|
|
function progressFunc( i ) {
|
|
|
|
return function( value ) {
|
2012-03-13 13:39:40 +00:00
|
|
|
pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments ) : value;
|
2011-09-12 15:37:41 +00:00
|
|
|
deferred.notifyWith( promise, pValues );
|
|
|
|
};
|
|
|
|
}
|
2011-03-03 18:38:06 +00:00
|
|
|
if ( length > 1 ) {
|
2011-10-26 18:58:05 +00:00
|
|
|
for ( ; i < length; i++ ) {
|
2011-09-12 15:37:41 +00:00
|
|
|
if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
|
2012-04-01 23:29:39 +00:00
|
|
|
args[ i ].promise().done( resolveFunc(i) ).fail( deferred.reject ).progress( progressFunc(i) );
|
2011-03-03 18:38:06 +00:00
|
|
|
} else {
|
|
|
|
--count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !count ) {
|
|
|
|
deferred.resolveWith( deferred, args );
|
|
|
|
}
|
|
|
|
} else if ( deferred !== firstParam ) {
|
|
|
|
deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
|
|
|
|
}
|
2011-09-12 15:37:41 +00:00
|
|
|
return promise;
|
2011-03-03 18:38:06 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2011-09-12 15:37:41 +00:00
|
|
|
})( jQuery );
|