mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Added deferred to core. Used internally for DOM readyness and ajax callbacks.
This commit is contained in:
parent
1f92edee20
commit
116c82b027
198
src/core.js
198
src/core.js
@ -60,8 +60,8 @@ var jQuery = function( selector, context ) {
|
||||
// Has the ready events already been bound?
|
||||
readyBound = false,
|
||||
|
||||
// The functions to execute on DOM ready
|
||||
readyList = [],
|
||||
// The deferred used on DOM ready
|
||||
readyList,
|
||||
|
||||
// The ready event handler
|
||||
DOMContentLoaded,
|
||||
@ -75,7 +75,10 @@ var jQuery = function( selector, context ) {
|
||||
indexOf = Array.prototype.indexOf,
|
||||
|
||||
// [[Class]] -> type pairs
|
||||
class2type = {};
|
||||
class2type = {},
|
||||
|
||||
// Marker for deferred
|
||||
deferredMarker = [];
|
||||
|
||||
jQuery.fn = jQuery.prototype = {
|
||||
init: function( selector, context ) {
|
||||
@ -253,22 +256,12 @@ jQuery.fn = jQuery.prototype = {
|
||||
return jQuery.each( this, callback, args );
|
||||
},
|
||||
|
||||
ready: function( fn ) {
|
||||
ready: function() {
|
||||
// Attach the listeners
|
||||
jQuery.bindReady();
|
||||
|
||||
// If the DOM is already ready
|
||||
if ( jQuery.isReady ) {
|
||||
// Execute the function immediately
|
||||
fn.call( document, jQuery );
|
||||
|
||||
// Otherwise, remember the function for later
|
||||
} else if ( readyList ) {
|
||||
// Add the function to the wait list
|
||||
readyList.push( fn );
|
||||
}
|
||||
|
||||
return this;
|
||||
// Change ready & apply
|
||||
return ( jQuery.fn.ready = readyList.then ).apply( this , arguments );
|
||||
},
|
||||
|
||||
eq: function( i ) {
|
||||
@ -415,25 +408,13 @@ jQuery.extend({
|
||||
}
|
||||
|
||||
// If there are functions bound, to execute
|
||||
if ( readyList ) {
|
||||
// Execute all of them
|
||||
var fn,
|
||||
i = 0,
|
||||
ready = readyList;
|
||||
|
||||
// Reset the list of functions
|
||||
readyList = null;
|
||||
|
||||
while ( (fn = ready[ i++ ]) ) {
|
||||
fn.call( document, jQuery );
|
||||
}
|
||||
readyList.fire( document , [ jQuery ] );
|
||||
|
||||
// Trigger any bound ready events
|
||||
if ( jQuery.fn.trigger ) {
|
||||
jQuery( document ).trigger( "ready" ).unbind( "ready" );
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
bindReady: function() {
|
||||
@ -801,6 +782,160 @@ jQuery.extend({
|
||||
return (new Date()).getTime();
|
||||
},
|
||||
|
||||
// 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;
|
||||
},
|
||||
|
||||
// Use of jQuery.browser is frowned upon.
|
||||
// More details: http://docs.jquery.com/Utilities/jQuery.browser
|
||||
uaMatch: function( ua ) {
|
||||
@ -818,6 +953,11 @@ jQuery.extend({
|
||||
browser: {}
|
||||
});
|
||||
|
||||
// Create readyList deferred
|
||||
// also force $.fn.ready to be recognized as a defer
|
||||
readyList = jQuery._deferred( false );
|
||||
jQuery.fn.ready._ = deferredMarker;
|
||||
|
||||
// Populate the class2type map
|
||||
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
|
||||
class2type[ "[object " + name + "]" ] = name.toLowerCase();
|
||||
|
167
src/xhr.js
167
src/xhr.js
@ -25,11 +25,12 @@ jQuery.xhr = function( _native ) {
|
||||
if ( force || internal ) {
|
||||
|
||||
// Reset callbacks lists
|
||||
callbacksLists = {
|
||||
success: createCBList(),
|
||||
error: createCBList(),
|
||||
complete: createCBList()
|
||||
};
|
||||
deferred = jQuery.deferred();
|
||||
completeDeferred = jQuery._deferred();
|
||||
|
||||
xhr.success = xhr.then = deferred.then;
|
||||
xhr.error = xhr.fail = deferred.fail;
|
||||
xhr.complete = completeDeferred.then;
|
||||
|
||||
// Reset private variables
|
||||
requestHeaders = {};
|
||||
@ -155,8 +156,8 @@ jQuery.xhr = function( _native ) {
|
||||
callbackContext = s.context || s;
|
||||
globalEventContext = s.context ? jQuery(s.context) : jQuery.event;
|
||||
|
||||
for ( i in callbacksLists ) {
|
||||
callbacksLists[i].bind(s[i]);
|
||||
for ( i in { success:1, error:1, complete:1 } ) {
|
||||
xhr[ i ]( s[ i ] );
|
||||
}
|
||||
|
||||
// Watch for a new set of requests
|
||||
@ -355,10 +356,12 @@ jQuery.xhr = function( _native ) {
|
||||
|
||||
// Keep local copies of vars in case callbacks re-use the xhr
|
||||
var _s = s,
|
||||
_callbacksLists = callbacksLists,
|
||||
_deferred = deferred,
|
||||
_completeDeferred = completeDeferred,
|
||||
_callbackContext = callbackContext,
|
||||
_globalEventContext = globalEventContext;
|
||||
|
||||
|
||||
// Set state if the xhr hasn't been re-used
|
||||
function _setState( value ) {
|
||||
if ( xhr.readyState && s === _s ) {
|
||||
@ -375,18 +378,20 @@ jQuery.xhr = function( _native ) {
|
||||
// We're done
|
||||
_setState( 4 );
|
||||
|
||||
// Success
|
||||
_callbacksLists.success.fire( isSuccess , _callbackContext , success, statusText, xhr);
|
||||
if ( isSuccess && _s.global ) {
|
||||
_globalEventContext.trigger( "ajaxSuccess", [xhr, _s, success] );
|
||||
// Success/Error
|
||||
if ( isSuccess ) {
|
||||
_deferred.fire( _callbackContext , [ success , statusText , xhr ] );
|
||||
} else {
|
||||
_deferred.fireReject( _callbackContext , [ xhr , statusText , error ] );
|
||||
}
|
||||
// Error
|
||||
_callbacksLists.error.fire( ! isSuccess , _callbackContext , xhr, statusText, error);
|
||||
if ( !isSuccess && _s.global ) {
|
||||
_globalEventContext.trigger( "ajaxError", [xhr, _s, error] );
|
||||
|
||||
if ( _s.global ) {
|
||||
_globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) , [ xhr , _s , isSuccess ? success : error ] );
|
||||
}
|
||||
|
||||
// Complete
|
||||
_callbacksLists.complete.fire( 1 , _callbackContext, xhr, statusText);
|
||||
_completeDeferred.fire( _callbackContext, [ xhr , statusText ] );
|
||||
|
||||
if ( _s.global ) {
|
||||
_globalEventContext.trigger( "ajaxComplete", [xhr, _s] );
|
||||
// Handle the global AJAX counter
|
||||
@ -419,7 +424,8 @@ jQuery.xhr = function( _native ) {
|
||||
// Callback stuff
|
||||
callbackContext,
|
||||
globalEventContext,
|
||||
callbacksLists,
|
||||
deferred,
|
||||
completeDeferred,
|
||||
// Headers (they are sent all at once)
|
||||
requestHeaders,
|
||||
// Response headers
|
||||
@ -596,135 +602,10 @@ jQuery.xhr = function( _native ) {
|
||||
// Init data (so that we can bind callbacks early
|
||||
reset(1);
|
||||
|
||||
// Install callbacks related methods
|
||||
jQuery.each(callbacksLists, function(name) {
|
||||
var list;
|
||||
xhr[name] = function() {
|
||||
list = callbacksLists[name];
|
||||
if ( list ) {
|
||||
list.bind.apply(list, arguments );
|
||||
}
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
// Return the xhr emulation
|
||||
return xhr;
|
||||
};
|
||||
|
||||
// Create a callback list
|
||||
function createCBList() {
|
||||
|
||||
var functors = [],
|
||||
autoFire = 0,
|
||||
fireArgs,
|
||||
list = {
|
||||
|
||||
fire: function( flag , context ) {
|
||||
|
||||
// Save info for later bindings
|
||||
fireArgs = arguments;
|
||||
|
||||
// Remove autoFire to keep bindings in order
|
||||
autoFire = 0;
|
||||
|
||||
var args = sliceFunc.call( fireArgs , 2 );
|
||||
|
||||
// Execute callbacks
|
||||
while ( flag && functors.length ) {
|
||||
flag = functors.shift().apply( context , args ) !== false;
|
||||
}
|
||||
|
||||
// Clean if asked to stop
|
||||
if ( ! flag ) {
|
||||
clean();
|
||||
}
|
||||
|
||||
// Set autoFire
|
||||
autoFire = 1;
|
||||
},
|
||||
|
||||
bind: function() {
|
||||
|
||||
var args = arguments,
|
||||
i = 0,
|
||||
length = args.length,
|
||||
func;
|
||||
|
||||
for ( ; i < length ; i++ ) {
|
||||
|
||||
func = args[ i ];
|
||||
|
||||
if ( jQuery.isArray(func) ) {
|
||||
|
||||
list.bind.apply( list , func );
|
||||
|
||||
} else if ( isFunction(func) ) {
|
||||
|
||||
// Add if not already in
|
||||
if ( ! pos( func ) ) {
|
||||
functors.push( func );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( autoFire ) {
|
||||
list.fire.apply( list , fireArgs );
|
||||
}
|
||||
},
|
||||
|
||||
unbind: function() {
|
||||
|
||||
var i = 0,
|
||||
args = arguments,
|
||||
length = args.length,
|
||||
func,
|
||||
position;
|
||||
|
||||
if ( length ) {
|
||||
|
||||
for( ; i < length ; i++ ) {
|
||||
func = args[i];
|
||||
if ( jQuery.isArray(func) ) {
|
||||
list.unbind.apply(list,func);
|
||||
} else if ( isFunction(func) ) {
|
||||
position = pos(func);
|
||||
if ( position ) {
|
||||
functors.splice(position-1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
functors = [];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Get the index of the functor in the list (1-based)
|
||||
function pos( func ) {
|
||||
for (var i = 0, length = functors.length; i < length && functors[i] !== func; i++) {
|
||||
}
|
||||
return i < length ? ( i + 1 ) : 0;
|
||||
}
|
||||
|
||||
// Clean the object
|
||||
function clean() {
|
||||
// Empty callbacks list
|
||||
functors = [];
|
||||
// Inhibit methods
|
||||
for (var i in list) {
|
||||
list[i] = jQuery.noop;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
jQuery.extend(jQuery.xhr, {
|
||||
|
||||
// Add new prefilter
|
||||
|
@ -902,3 +902,253 @@ test("jQuery.parseJSON", function(){
|
||||
ok( true, "Test malformed JSON string." );
|
||||
}
|
||||
});
|
||||
|
||||
test("jQuery._deferred()", function() {
|
||||
|
||||
expect( 14 );
|
||||
|
||||
var deferred,
|
||||
object,
|
||||
test;
|
||||
|
||||
deferred = jQuery._deferred();
|
||||
|
||||
test = false;
|
||||
|
||||
deferred.then( function( value ) {
|
||||
equals( value , "value" , "Test pre-resolve callback" );
|
||||
test = true;
|
||||
} );
|
||||
|
||||
deferred.resolve( "value" );
|
||||
|
||||
ok( test , "Test pre-resolve callbacks called right away" );
|
||||
|
||||
test = false;
|
||||
|
||||
deferred.then( function( value ) {
|
||||
equals( value , "value" , "Test post-resolve callback" );
|
||||
test = true;
|
||||
} );
|
||||
|
||||
ok( test , "Test post-resolve callbacks called right away" );
|
||||
|
||||
deferred.cancel();
|
||||
|
||||
test = true;
|
||||
|
||||
deferred.then( function() {
|
||||
ok( false , "Manual cancel was ignored" );
|
||||
test = false;
|
||||
} );
|
||||
|
||||
ok( test , "Test manual cancel" );
|
||||
|
||||
deferred = jQuery._deferred().then( function() {
|
||||
return false;
|
||||
} );
|
||||
|
||||
deferred.resolve();
|
||||
|
||||
test = true;
|
||||
|
||||
deferred.then( function() {
|
||||
test = false;
|
||||
} );
|
||||
|
||||
ok( test , "Test cancel by returning false" );
|
||||
|
||||
try {
|
||||
deferred = jQuery._deferred().resolve().then( function() {
|
||||
throw "Error";
|
||||
} , function() {
|
||||
ok( false , "Test deferred cancel on exception" );
|
||||
} );
|
||||
} catch( e ) {
|
||||
strictEqual( e , "Error" , "Test deferred propagates exceptions");
|
||||
deferred.then();
|
||||
}
|
||||
|
||||
test = "";
|
||||
deferred = jQuery._deferred().then( function() {
|
||||
|
||||
test += "A";
|
||||
|
||||
}, function() {
|
||||
|
||||
test += "B";
|
||||
|
||||
} ).resolve();
|
||||
|
||||
strictEqual( test , "AB" , "Test multiple then parameters" );
|
||||
|
||||
test = "";
|
||||
|
||||
deferred.then( function() {
|
||||
|
||||
deferred.then( function() {
|
||||
|
||||
test += "C";
|
||||
|
||||
} );
|
||||
|
||||
test += "A";
|
||||
|
||||
}, function() {
|
||||
|
||||
test += "B";
|
||||
} );
|
||||
|
||||
strictEqual( test , "ABC" , "Test then callbacks order" );
|
||||
|
||||
deferred = jQuery._deferred( false ).resolve().cancel();
|
||||
|
||||
deferred.then( function() {
|
||||
ok( true , "Test non-cancellable deferred not cancelled manually");
|
||||
return false;
|
||||
} );
|
||||
|
||||
deferred.then( function() {
|
||||
ok( true , "Test non-cancellable deferred not cancelled by returning false");
|
||||
} );
|
||||
|
||||
try {
|
||||
deferred.then( function() {
|
||||
throw "Error";
|
||||
} , function() {
|
||||
ok( true , "Test non-cancellable deferred keeps callbacks after exception" );
|
||||
} );
|
||||
} catch( e ) {
|
||||
strictEqual( e , "Error" , "Test non-cancellable deferred propagates exceptions");
|
||||
deferred.then();
|
||||
}
|
||||
|
||||
deferred = jQuery._deferred();
|
||||
|
||||
deferred.fire( jQuery , [ document ] ).then( function( doc ) {
|
||||
ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" );
|
||||
});
|
||||
});
|
||||
|
||||
test("jQuery.deferred()", function() {
|
||||
|
||||
expect( 8 );
|
||||
|
||||
jQuery.deferred( function( defer ) {
|
||||
strictEqual( this , defer , "Defer passed as this & first argument" );
|
||||
this.resolve( "done" );
|
||||
}).then( function( value ) {
|
||||
strictEqual( value , "done" , "Passed function executed" );
|
||||
});
|
||||
|
||||
jQuery.deferred().resolve().then( function() {
|
||||
ok( true , "Success on resolve" );
|
||||
}).fail( function() {
|
||||
ok( false , "Error on resolve" );
|
||||
});
|
||||
|
||||
jQuery.deferred().reject().then( function() {
|
||||
ok( false , "Success on reject" );
|
||||
}).fail( function() {
|
||||
ok( true , "Error on reject" );
|
||||
});
|
||||
|
||||
var flag = true;
|
||||
|
||||
jQuery.deferred().resolve().cancel().then( function() {
|
||||
ok( flag = false , "Success on resolve/cancel" );
|
||||
}).fail( function() {
|
||||
ok( flag = false , "Error on resolve/cancel" );
|
||||
});
|
||||
|
||||
ok( flag , "Cancel on resolve" );
|
||||
|
||||
flag = true;
|
||||
|
||||
jQuery.deferred().reject().cancel().then( function() {
|
||||
ok( flag = false , "Success on reject/cancel" );
|
||||
}).fail( function() {
|
||||
ok( flag = false , "Error on reject/cancel" );
|
||||
});
|
||||
|
||||
ok( flag , "Cancel on reject" );
|
||||
|
||||
jQuery.deferred( false ).resolve().then( function() {
|
||||
return false;
|
||||
} , function() {
|
||||
ok( true , "Not cancelled on resolve" );
|
||||
});
|
||||
|
||||
jQuery.deferred( false ).reject().fail( function() {
|
||||
return false;
|
||||
} , function() {
|
||||
ok( true , "Not cancelled on reject" );
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test("jQuery.isDeferred()", function() {
|
||||
|
||||
expect( 11 );
|
||||
|
||||
var object1 = { then: function() { return this; } },
|
||||
object2 = { then: function() { return this; } };
|
||||
|
||||
object2.then._ = [];
|
||||
|
||||
// The use case that we want to match
|
||||
ok(jQuery.isDeferred(jQuery._deferred()), "Simple deferred");
|
||||
ok(jQuery.isDeferred(jQuery.deferred()), "Failable deferred");
|
||||
|
||||
// Some other objects
|
||||
ok(!jQuery.isDeferred(object1), "Object with then & no marker");
|
||||
ok(!jQuery.isDeferred(object2), "Object with then & marker");
|
||||
|
||||
// Not objects shouldn't be matched
|
||||
ok(!jQuery.isDeferred(""), "string");
|
||||
ok(!jQuery.isDeferred(0) && !jQuery.isDeferred(1), "number");
|
||||
ok(!jQuery.isDeferred(true) && !jQuery.isDeferred(false), "boolean");
|
||||
ok(!jQuery.isDeferred(null), "null");
|
||||
ok(!jQuery.isDeferred(undefined), "undefined");
|
||||
|
||||
object1 = {custom: jQuery._deferred().then};
|
||||
|
||||
ok(!jQuery.isDeferred(object1) , "custom method name not found automagically");
|
||||
ok(jQuery.isDeferred(object1,"custom") , "custom method name");
|
||||
});
|
||||
|
||||
test("jQuery.when()", function() {
|
||||
|
||||
expect( 5 );
|
||||
|
||||
var cache, i, deferred = { done: jQuery.deferred().resolve( 1 ).then };
|
||||
|
||||
for( i = 1 ; i < 3 ; i++ ) {
|
||||
jQuery.when( cache || jQuery.deferred( function() {
|
||||
this.resolve( i );
|
||||
}) ).then( function( value ) {
|
||||
strictEqual( value , 1 , "Function executed" + ( i > 1 ? " only once" : "" ) );
|
||||
cache = value;
|
||||
}).fail( function() {
|
||||
ok( false , "Fail called" );
|
||||
});
|
||||
}
|
||||
|
||||
cache = 0;
|
||||
|
||||
for( i = 1 ; i < 3 ; i++ ) {
|
||||
jQuery.when( cache || deferred , "done" ).done( function( value ) {
|
||||
strictEqual( value , 1 , "Custom method: resolved" + ( i > 1 ? " only once" : "" ) );
|
||||
cache = value;
|
||||
}).fail( function() {
|
||||
ok( false , "Custom method: fail called" );
|
||||
});
|
||||
}
|
||||
|
||||
stop();
|
||||
|
||||
jQuery.when( jQuery( document ) , "ready" ).then( function( test ) {
|
||||
strictEqual( test , jQuery , "jQuery.fn.ready recognized as a deferred" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user