Created
October 9, 2011 01:09
-
-
Save pixelhandler/1273133 to your computer and use it in GitHub Desktop.
Deferred / Promise extracted from jQuery v1.6.4 for use with older version of jQuery 1.4.2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($){ | |
var // Promise methods | |
promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), | |
// Static reference to slice | |
sliceDeferred = [].slice; | |
if (typeof $ !== 'function') { | |
return false; | |
} else { | |
jQuery.each(promiseMethods, function(){ | |
if (typeof jQuery[this] !== 'undefined') { | |
return false; | |
} | |
}); | |
} | |
// dependencies | |
if (typeof jQuery.type === 'undefined') { | |
var class2type = {}; | |
// Populate the class2type map | |
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { | |
class2type[ "[object " + name + "]" ] = name.toLowerCase(); | |
}); | |
jQuery.extend({ | |
type: function( obj ) { | |
return obj == null ? | |
String( obj ) : | |
class2type[ toString.call(obj) ] || "object"; | |
} | |
// redefine isFunction using type method | |
//isFunction: function( obj ) { | |
// return jQuery.type(obj) === "function"; | |
//} | |
}); | |
} | |
jQuery.extend({ | |
// Create a simple deferred (one callbacks list) | |
_Deferred: function() { | |
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 = { | |
// done( f1, f2, ...) | |
done: function() { | |
if ( !cancelled ) { | |
var args = arguments, | |
i, | |
length, | |
elem, | |
type, | |
_fired; | |
if ( fired ) { | |
_fired = fired; | |
fired = 0; | |
} | |
for ( i = 0, length = args.length; i < length; i++ ) { | |
elem = args[ i ]; | |
type = jQuery.type( elem ); | |
if ( type === "array" ) { | |
deferred.done.apply( deferred, elem ); | |
} else if ( type === "function" ) { | |
callbacks.push( elem ); | |
} | |
} | |
if ( _fired ) { | |
deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); | |
} | |
} | |
return this; | |
}, | |
// resolve with given context and args | |
resolveWith: function( context, args ) { | |
if ( !cancelled && !fired && !firing ) { | |
// make sure args are available (#8421) | |
args = args || []; | |
firing = 1; | |
try { | |
while( callbacks[ 0 ] ) { | |
callbacks.shift().apply( context, args ); | |
} | |
} | |
finally { | |
fired = [ context, args ]; | |
firing = 0; | |
} | |
} | |
return this; | |
}, | |
// resolve with this as context and given arguments | |
resolve: function() { | |
deferred.resolveWith( this, arguments ); | |
return this; | |
}, | |
// Has this deferred been resolved? | |
isResolved: function() { | |
return !!( firing || fired ); | |
}, | |
// Cancel | |
cancel: function() { | |
cancelled = 1; | |
callbacks = []; | |
return this; | |
} | |
}; | |
return deferred; | |
}, | |
// Full fledged deferred (two callbacks list) | |
Deferred: function( func ) { | |
var deferred = jQuery._Deferred(), | |
failDeferred = jQuery._Deferred(), | |
promise; | |
// Add errorDeferred methods, then and promise | |
jQuery.extend( deferred, { | |
then: function( doneCallbacks, failCallbacks ) { | |
deferred.done( doneCallbacks ).fail( failCallbacks ); | |
return this; | |
}, | |
always: function() { | |
return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); | |
}, | |
fail: failDeferred.done, | |
rejectWith: failDeferred.resolveWith, | |
reject: failDeferred.resolve, | |
isRejected: failDeferred.isResolved, | |
pipe: function( fnDone, fnFail ) { | |
return jQuery.Deferred(function( newDefer ) { | |
jQuery.each( { | |
done: [ fnDone, "resolve" ], | |
fail: [ fnFail, "reject" ] | |
}, 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 ) ) { | |
returned.promise().then( newDefer.resolve, newDefer.reject ); | |
} else { | |
newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); | |
} | |
}); | |
} else { | |
deferred[ handler ]( newDefer[ action ] ); | |
} | |
}); | |
}).promise(); | |
}, | |
// Get a promise for this deferred | |
// If obj is provided, the promise aspect is added to the object | |
promise: function( obj ) { | |
if ( obj == null ) { | |
if ( promise ) { | |
return promise; | |
} | |
promise = obj = {}; | |
} | |
var i = promiseMethods.length; | |
while( i-- ) { | |
obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; | |
} | |
return obj; | |
} | |
}); | |
// Make sure only one callback list will be used | |
deferred.done( failDeferred.cancel ).fail( deferred.cancel ); | |
// Unexpose cancel | |
delete deferred.cancel; | |
// Call given func if any | |
if ( func ) { | |
func.call( deferred, deferred ); | |
} | |
return deferred; | |
}, | |
// Deferred helper | |
when: function( firstParam ) { | |
var args = arguments, | |
i = 0, | |
length = args.length, | |
count = length, | |
deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? | |
firstParam : | |
jQuery.Deferred(); | |
function resolveFunc( i ) { | |
return function( value ) { | |
args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; | |
if ( !( --count ) ) { | |
// Strange bug in FF4: | |
// Values changed onto the arguments object sometimes end up as undefined values | |
// outside the $.when method. Cloning the object into a fresh array solves the issue | |
deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) ); | |
} | |
}; | |
} | |
if ( length > 1 ) { | |
for( ; i < length; i++ ) { | |
if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) { | |
args[ i ].promise().then( resolveFunc(i), deferred.reject ); | |
} else { | |
--count; | |
} | |
} | |
if ( !count ) { | |
deferred.resolveWith( deferred, args ); | |
} | |
} else if ( deferred !== firstParam ) { | |
deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); | |
} | |
return deferred.promise(); | |
} | |
}); | |
}(jQuery)); |
I used this to get CKEditor 4.3 working on jQuery 1.4.2 (with mentioned IE fix) - Thanks!
planning to use this deferred js. Is this working with older versions of IE? like 6 and 7?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
By changing line 29 to class2type[ Object.prototype.toString.call(obj) ] || "object"; this script can be used in IE8.