+
+ // Create a simple deferred (one callbacks list)
+ _deferred: function( cancellable ) {
+
+ // cancellable by default
+ cancellable = cancellable !== false;
+
+ var // callbacks list
+ callbacks = [],
+ // stored [ context , args ]
+ fired,
+ // to avoid firing when already doing so
+ firing,
+ // flag to know if the deferred has been cancelled
+ cancelled,
+ // the deferred itself
+ deferred = {
+
+ // then( f1, f2, ...)
+ then: function() {
+
+ if ( ! cancelled ) {
+
+ var args = arguments,
+ i,
+ type,
+ _fired;
+
+ if ( fired ) {
+ _fired = fired;
+ fired = 0;
+ }
+
+ for ( i in args ) {
+ i = args[ i ];
+ type = jQuery.type( i );
+ if ( type === "array" ) {
+ this.then.apply( this , i );
+ } else if ( type === "function" ) {
+ callbacks.push( i );
+ }
+ }
+
+ if ( _fired ) {
+ deferred.fire( _fired[ 0 ] , _fired[ 1 ] );
+ }
+ }
+ return this;
+ },
+
+ // resolve with given context and args
+ // (i is used internally)
+ fire: function( context , args , i ) {
+ if ( ! cancelled && ! fired && ! firing ) {
+ firing = 1;
+ try {
+ for( i = 0 ; ! cancelled && callbacks[ i ] ; i++ ) {
+ cancelled = ( callbacks[ i ].apply( context , args ) === false ) && cancellable;
+ }
+ } catch( e ) {
+ cancelled = cancellable;
+ jQuery.error( e );
+ } finally {
+ fired = [ context , args ];
+ callbacks = cancelled ? [] : callbacks.slice( i + 1 );
+ firing = 0;
+ }
+ }
+ return this;
+ },
+
+ // resolve with this as context and given arguments
+ resolve: function() {
+ deferred.fire( this , arguments );
+ return this;
+ },
+
+ // cancelling further callbacks
+ cancel: function() {
+ if ( cancellable ) {
+ callbacks = [];
+ cancelled = 1;
+ }
+ return this;
+ }
+
+ };
+
+ // Add the deferred marker
+ deferred.then._ = deferredMarker;
+
+ return deferred;
+ },
+
+ // Full fledged deferred (two callbacks list)
+ // Typical success/error system
+ deferred: function( func , cancellable ) {
+
+ // Handle varargs
+ if ( arguments.length === 1 ) {
+
+ if ( typeof func === "boolean" ) {
+ cancellable = func;
+ func = 0;
+ }
+ }
+
+ var errorDeferred = jQuery._deferred( cancellable ),
+ deferred = jQuery._deferred( cancellable ),
+ // Keep reference of the cancel method since we'll redefine it
+ cancelThen = deferred.cancel;
+
+ // Add errorDeferred methods and redefine cancel
+ jQuery.extend( deferred , {
+
+ fail: errorDeferred.then,
+ fireReject: errorDeferred.fire,
+ reject: errorDeferred.resolve,
+ cancel: function() {
+ cancelThen();
+ errorDeferred.cancel();
+ return this;
+ }
+
+ } );
+
+ // Make sure only one callback list will be used
+ deferred.then( errorDeferred.cancel ).fail( cancelThen );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred , deferred );
+ }
+
+ return deferred;
+ },
+
+ // Check if an object is a deferred
+ isDeferred: function( object , method ) {
+ method = method || "then";
+ return !!( object && object[ method ] && object[ method ]._ === deferredMarker );
+ },
+
+ // Deferred helper
+ when: function( object , method ) {
+ method = method || "then";
+ object = jQuery.isDeferred( object , method ) ?
+ object :
+ jQuery.deferred().resolve( object );
+ object.fail = object.fail || function() { return this; };
+ object[ method ] = object[ method ] || object.then;
+ object.then = object.then || object[ method ];
+ return object;
+ },