underscore.deferred
Advanced tools
Comparing version 0.1.2 to 0.1.4
@@ -73,4 +73,2 @@ (function(root){ | ||
var promiseMethods = "done fail isResolved isRejected promise then always pipe".split(" "); | ||
// Internal Deferred namespace | ||
@@ -93,258 +91,261 @@ var _d = {}; | ||
// Convert flags from String-formatted to Object-formatted | ||
// (we check in cache first) | ||
flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; | ||
// Convert flags from String-formatted to Object-formatted | ||
// (we check in cache first) | ||
flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; | ||
var // Actual callback list | ||
list = [], | ||
// Stack of fire calls for repeatable lists | ||
stack = [], | ||
// Last fire value (for non-forgettable lists) | ||
memory, | ||
// Flag to know if list is currently firing | ||
firing, | ||
// First callback to fire (used internally by add and fireWith) | ||
firingStart, | ||
// End of the loop when firing | ||
firingLength, | ||
// Index of currently firing callback (modified by remove if needed) | ||
firingIndex, | ||
// Add one or several callbacks to the list | ||
add = function( args ) { | ||
var i, | ||
length, | ||
elem, | ||
type, | ||
actual; | ||
for ( i = 0, length = args.length; i < length; i++ ) { | ||
elem = args[ i ]; | ||
type = _type( elem ); | ||
if ( type === "array" ) { | ||
// Inspect recursively | ||
add( elem ); | ||
} else if ( type === "function" ) { | ||
// Add if not in unique mode and callback is not in | ||
if ( !flags.unique || !self.has( elem ) ) { | ||
list.push( elem ); | ||
var // Actual callback list | ||
list = [], | ||
// Stack of fire calls for repeatable lists | ||
stack = [], | ||
// Last fire value (for non-forgettable lists) | ||
memory, | ||
// Flag to know if list was already fired | ||
fired, | ||
// Flag to know if list is currently firing | ||
firing, | ||
// First callback to fire (used internally by add and fireWith) | ||
firingStart, | ||
// End of the loop when firing | ||
firingLength, | ||
// Index of currently firing callback (modified by remove if needed) | ||
firingIndex, | ||
// Add one or several callbacks to the list | ||
add = function( args ) { | ||
var i, | ||
length, | ||
elem, | ||
type, | ||
actual; | ||
for ( i = 0, length = args.length; i < length; i++ ) { | ||
elem = args[ i ]; | ||
type = _type( elem ); | ||
if ( type === "array" ) { | ||
// Inspect recursively | ||
add( elem ); | ||
} else if ( type === "function" ) { | ||
// Add if not in unique mode and callback is not in | ||
if ( !flags.unique || !self.has( elem ) ) { | ||
list.push( elem ); | ||
} | ||
} | ||
} | ||
}, | ||
// Fire callbacks | ||
fire = function( context, args ) { | ||
args = args || []; | ||
memory = !flags.memory || [ context, args ]; | ||
fired = true; | ||
firing = true; | ||
firingIndex = firingStart || 0; | ||
firingStart = 0; | ||
firingLength = list.length; | ||
for ( ; list && firingIndex < firingLength; firingIndex++ ) { | ||
if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { | ||
memory = true; // Mark as halted | ||
break; | ||
} | ||
} | ||
firing = false; | ||
if ( list ) { | ||
if ( !flags.once ) { | ||
if ( stack && stack.length ) { | ||
memory = stack.shift(); | ||
self.fireWith( memory[ 0 ], memory[ 1 ] ); | ||
} | ||
} else if ( memory === true ) { | ||
self.disable(); | ||
} else { | ||
list = []; | ||
} | ||
} | ||
}, | ||
// Actual Callbacks object | ||
self = { | ||
// Add a callback or a collection of callbacks to the list | ||
add: function() { | ||
if ( list ) { | ||
var length = list.length; | ||
add( arguments ); | ||
// Do we need to add the callbacks to the | ||
// current firing batch? | ||
if ( firing ) { | ||
firingLength = list.length; | ||
// With memory, if we're not firing then | ||
// we should call right away, unless previous | ||
// firing was halted (stopOnFalse) | ||
} else if ( memory && memory !== true ) { | ||
firingStart = length; | ||
fire( memory[ 0 ], memory[ 1 ] ); | ||
} | ||
} | ||
return this; | ||
}, | ||
// Remove a callback from the list | ||
remove: function() { | ||
if ( list ) { | ||
var args = arguments, | ||
argIndex = 0, | ||
argLength = args.length; | ||
for ( ; argIndex < argLength ; argIndex++ ) { | ||
for ( var i = 0; i < list.length; i++ ) { | ||
if ( args[ argIndex ] === list[ i ] ) { | ||
// Handle firingIndex and firingLength | ||
if ( firing ) { | ||
if ( i <= firingLength ) { | ||
firingLength--; | ||
if ( i <= firingIndex ) { | ||
firingIndex--; | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
// Fire callbacks | ||
fire = function( context, args ) { | ||
args = args || []; | ||
memory = !flags.memory || [ context, args ]; | ||
firing = true; | ||
firingIndex = firingStart || 0; | ||
firingStart = 0; | ||
firingLength = list.length; | ||
for ( ; list && firingIndex < firingLength; firingIndex++ ) { | ||
if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { | ||
memory = true; // Mark as halted | ||
break; | ||
// Remove the element | ||
list.splice( i--, 1 ); | ||
// If we have some unicity property then | ||
// we only need to do this once | ||
if ( flags.unique ) { | ||
break; | ||
} | ||
} | ||
} | ||
firing = false; | ||
if ( list ) { | ||
if ( !flags.once ) { | ||
if ( stack && stack.length ) { | ||
memory = stack.shift(); | ||
self.fireWith( memory[ 0 ], memory[ 1 ] ); | ||
} | ||
} else if ( memory === true ) { | ||
self.disable(); | ||
} else { | ||
list = []; | ||
} | ||
} | ||
} | ||
return this; | ||
}, | ||
// Control if a given callback is in the list | ||
has: function( fn ) { | ||
if ( list ) { | ||
var i = 0, | ||
length = list.length; | ||
for ( ; i < length; i++ ) { | ||
if ( fn === list[ i ] ) { | ||
return true; | ||
} | ||
}, | ||
// Actual Callbacks object | ||
self = { | ||
// Add a callback or a collection of callbacks to the list | ||
add: function() { | ||
if ( list ) { | ||
var length = list.length; | ||
add( arguments ); | ||
// Do we need to add the callbacks to the | ||
// current firing batch? | ||
if ( firing ) { | ||
firingLength = list.length; | ||
// With memory, if we're not firing then | ||
// we should call right away, unless previous | ||
// firing was halted (stopOnFalse) | ||
} else if ( memory && memory !== true ) { | ||
firingStart = length; | ||
fire( memory[ 0 ], memory[ 1 ] ); | ||
} | ||
} | ||
return this; | ||
}, | ||
// Remove a callback from the list | ||
remove: function() { | ||
if ( list ) { | ||
var args = arguments, | ||
argIndex = 0, | ||
argLength = args.length; | ||
for ( ; argIndex < argLength ; argIndex++ ) { | ||
for ( var i = 0; i < list.length; i++ ) { | ||
if ( args[ argIndex ] === list[ i ] ) { | ||
// Handle firingIndex and firingLength | ||
if ( firing ) { | ||
if ( i <= firingLength ) { | ||
firingLength--; | ||
if ( i <= firingIndex ) { | ||
firingIndex--; | ||
} | ||
} | ||
} | ||
// Remove the element | ||
list.splice( i--, 1 ); | ||
// If we have some unicity property then | ||
// we only need to do this once | ||
if ( flags.unique ) { | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return this; | ||
}, | ||
// Control if a given callback is in the list | ||
has: function( fn ) { | ||
if ( list ) { | ||
var i = 0, | ||
length = list.length; | ||
for ( ; i < length; i++ ) { | ||
if ( fn === list[ i ] ) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
}, | ||
// Remove all callbacks from the list | ||
empty: function() { | ||
list = []; | ||
return this; | ||
}, | ||
// Have the list do nothing anymore | ||
disable: function() { | ||
list = stack = memory = undefined; | ||
return this; | ||
}, | ||
// Is it disabled? | ||
disabled: function() { | ||
return !list; | ||
}, | ||
// Lock the list in its current state | ||
lock: function() { | ||
stack = undefined; | ||
if ( !memory || memory === true ) { | ||
self.disable(); | ||
} | ||
return this; | ||
}, | ||
// Is it locked? | ||
locked: function() { | ||
return !stack; | ||
}, | ||
// Call all callbacks with the given context and arguments | ||
fireWith: function( context, args ) { | ||
if ( stack ) { | ||
if ( firing ) { | ||
if ( !flags.once ) { | ||
stack.push( [ context, args ] ); | ||
} | ||
} else if ( !( flags.once && memory ) ) { | ||
fire( context, args ); | ||
} | ||
} | ||
return this; | ||
}, | ||
// Call all the callbacks with the given arguments | ||
fire: function() { | ||
self.fireWith( this, arguments ); | ||
return this; | ||
}, | ||
// To know if the callbacks have already been called at least once | ||
fired: function() { | ||
return !!memory; | ||
} | ||
}; | ||
} | ||
} | ||
return false; | ||
}, | ||
// Remove all callbacks from the list | ||
empty: function() { | ||
list = []; | ||
return this; | ||
}, | ||
// Have the list do nothing anymore | ||
disable: function() { | ||
list = stack = memory = undefined; | ||
return this; | ||
}, | ||
// Is it disabled? | ||
disabled: function() { | ||
return !list; | ||
}, | ||
// Lock the list in its current state | ||
lock: function() { | ||
stack = undefined; | ||
if ( !memory || memory === true ) { | ||
self.disable(); | ||
} | ||
return this; | ||
}, | ||
// Is it locked? | ||
locked: function() { | ||
return !stack; | ||
}, | ||
// Call all callbacks with the given context and arguments | ||
fireWith: function( context, args ) { | ||
if ( stack ) { | ||
if ( firing ) { | ||
if ( !flags.once ) { | ||
stack.push( [ context, args ] ); | ||
} | ||
} else if ( !( flags.once && memory ) ) { | ||
fire( context, args ); | ||
} | ||
} | ||
return this; | ||
}, | ||
// Call all the callbacks with the given arguments | ||
fire: function() { | ||
self.fireWith( this, arguments ); | ||
return this; | ||
}, | ||
// To know if the callbacks have already been called at least once | ||
fired: function() { | ||
return !!fired; | ||
} | ||
}; | ||
return self; | ||
return self; | ||
}; | ||
_d.Deferred = function( func ) { | ||
var doneList = _d.Callbacks( "once memory" ), | ||
failList = _d.Callbacks( "once memory" ), | ||
progressList = _d.Callbacks( "memory" ), | ||
state = "pending", | ||
lists = { | ||
resolve: doneList, | ||
reject: failList, | ||
notify: progressList | ||
var doneList = _d.Callbacks( "once memory" ), | ||
failList = _d.Callbacks( "once memory" ), | ||
progressList = _d.Callbacks( "memory" ), | ||
state = "pending", | ||
lists = { | ||
resolve: doneList, | ||
reject: failList, | ||
notify: progressList | ||
}, | ||
promise = { | ||
done: doneList.add, | ||
fail: failList.add, | ||
progress: progressList.add, | ||
state: function() { | ||
return state; | ||
}, | ||
promise = { | ||
done: doneList.add, | ||
fail: failList.add, | ||
progress: progressList.add, | ||
state: function() { | ||
return state; | ||
}, | ||
// Deprecated | ||
isResolved: doneList.fired, | ||
isRejected: failList.fired, | ||
// Deprecated | ||
isResolved: doneList.fired, | ||
isRejected: failList.fired, | ||
then: function( doneCallbacks, failCallbacks, progressCallbacks ) { | ||
deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); | ||
return this; | ||
}, | ||
always: function() { | ||
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); | ||
return this; | ||
}, | ||
pipe: function( fnDone, fnFail, fnProgress ) { | ||
return _d.Deferred(function( newDefer ) { | ||
_each( { | ||
done: [ fnDone, "resolve" ], | ||
fail: [ fnFail, "reject" ], | ||
progress: [ fnProgress, "notify" ] | ||
}, function( data, handler ) { | ||
var fn = data[ 0 ], | ||
action = data[ 1 ], | ||
returned; | ||
if ( _isFunction( fn ) ) { | ||
deferred[ handler ](function() { | ||
returned = fn.apply( this, arguments ); | ||
if ( returned && _isFunction( returned.promise ) ) { | ||
returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); | ||
} 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 ) { | ||
obj = promise; | ||
} else { | ||
for ( var key in promise ) { | ||
obj[ key ] = promise[ key ]; | ||
then: function( doneCallbacks, failCallbacks, progressCallbacks ) { | ||
deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); | ||
return this; | ||
}, | ||
always: function() { | ||
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); | ||
return this; | ||
}, | ||
pipe: function( fnDone, fnFail, fnProgress ) { | ||
return _d.Deferred(function( newDefer ) { | ||
_each( { | ||
done: [ fnDone, "resolve" ], | ||
fail: [ fnFail, "reject" ], | ||
progress: [ fnProgress, "notify" ] | ||
}, function( data, handler ) { | ||
var fn = data[ 0 ], | ||
action = data[ 1 ], | ||
returned; | ||
if ( _isFunction( fn ) ) { | ||
deferred[ handler ](function() { | ||
returned = fn.apply( this, arguments ); | ||
if ( returned && _isFunction( returned.promise ) ) { | ||
returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); | ||
} 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 ) { | ||
obj = promise; | ||
} else { | ||
for ( var key in promise ) { | ||
obj[ key ] = promise[ key ]; | ||
} | ||
return obj; | ||
} | ||
}, | ||
deferred = promise.promise({}), | ||
key; | ||
return obj; | ||
} | ||
}, | ||
deferred = promise.promise({}), | ||
key; | ||
@@ -358,5 +359,5 @@ for ( key in lists ) { | ||
deferred.done( function() { | ||
state = "resolved"; | ||
state = "resolved"; | ||
}, failList.disable, progressList.lock ).fail( function() { | ||
state = "rejected"; | ||
state = "rejected"; | ||
}, doneList.disable, progressList.lock ); | ||
@@ -366,3 +367,3 @@ | ||
if ( func ) { | ||
func.call( deferred, deferred ); | ||
func.call( deferred, deferred ); | ||
} | ||
@@ -376,41 +377,41 @@ | ||
_d.when = function( firstParam ) { | ||
var args = slice.call( arguments, 0 ), | ||
i = 0, | ||
length = args.length, | ||
pValues = new Array( length ), | ||
count = length, | ||
pCount = length, | ||
deferred = length <= 1 && firstParam && _isFunction( firstParam.promise ) ? | ||
firstParam : | ||
_d.Deferred(), | ||
promise = deferred.promise(); | ||
function resolveFunc( i ) { | ||
return function( value ) { | ||
args[ i ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; | ||
if ( !( --count ) ) { | ||
deferred.resolveWith( deferred, args ); | ||
} | ||
}; | ||
var args = slice.call( arguments, 0 ), | ||
i = 0, | ||
length = args.length, | ||
pValues = new Array( length ), | ||
count = length, | ||
pCount = length, | ||
deferred = length <= 1 && firstParam && _isFunction( firstParam.promise ) ? | ||
firstParam : | ||
_d.Deferred(), | ||
promise = deferred.promise(); | ||
function resolveFunc( i ) { | ||
return function( value ) { | ||
args[ i ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; | ||
if ( !( --count ) ) { | ||
deferred.resolveWith( deferred, args ); | ||
} | ||
}; | ||
} | ||
function progressFunc( i ) { | ||
return function( value ) { | ||
pValues[ i ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; | ||
deferred.notifyWith( promise, pValues ); | ||
}; | ||
} | ||
if ( length > 1 ) { | ||
for ( ; i < length; i++ ) { | ||
if ( args[ i ] && args[ i ].promise && _isFunction( args[ i ].promise ) ) { | ||
args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); | ||
} else { | ||
--count; | ||
} | ||
} | ||
function progressFunc( i ) { | ||
return function( value ) { | ||
pValues[ i ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; | ||
deferred.notifyWith( promise, pValues ); | ||
}; | ||
if ( !count ) { | ||
deferred.resolveWith( deferred, args ); | ||
} | ||
if ( length > 1 ) { | ||
for ( ; i < length; i++ ) { | ||
if ( args[ i ] && args[ i ].promise && _isFunction( args[ i ].promise ) ) { | ||
args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); | ||
} else { | ||
--count; | ||
} | ||
} | ||
if ( !count ) { | ||
deferred.resolveWith( deferred, args ); | ||
} | ||
} else if ( deferred !== firstParam ) { | ||
deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); | ||
} | ||
return promise; | ||
} else if ( deferred !== firstParam ) { | ||
deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); | ||
} | ||
return promise; | ||
}; | ||
@@ -417,0 +418,0 @@ |
{ | ||
"author": "wookiehangover <sam@quickleft.com> (http://quickleft.com)", | ||
"name": "underscore.deferred", | ||
"description": "Underscore style Deferreds", | ||
"version": "0.1.2", | ||
"description": "jQuery style Deferreds", | ||
"version": "0.1.4", | ||
"homepage": "https://github.com/wookiehangover/underscore.Deferred", | ||
"author": { | ||
"name": "Sam Breed", | ||
"email": "sam@quickleft.com" | ||
}, | ||
"repository": { | ||
@@ -11,16 +14,30 @@ "type": "git", | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/wookiehangover/underscore.Deferred/issues" | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "https://github.com/wookiehangover/underscore.Deferred/blob/master/LICENSE-MIT" | ||
} | ||
], | ||
"main": "lib/underscore.deferred.js", | ||
"ender": "lib/ender.js", | ||
"engines": { | ||
"node": "~v0.6.0" | ||
"node": "*" | ||
}, | ||
"scripts": { | ||
"test": "grunt qunit" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"grunt": "~0.2.15", | ||
"grunt": "~0.3.9", | ||
"rimraf": "~2.0.1", | ||
"underscore": "*" | ||
"underscore": "*", | ||
"mocha": "*" | ||
}, | ||
"scripts": { | ||
"test": "mocha -u qunit" | ||
} | ||
"keywords": [ | ||
"deferreds", | ||
"underscore", | ||
"flow-control" | ||
] | ||
} |
# Underscore.Deferred | ||
v0.1.2 | ||
v0.1.3 | ||
This is a port of jQuery.Deferred as an Underscore mixin, but it can be | ||
used without any depencencies. It currently matches the Deferred specifications | ||
and implementation from jQuery 1.7.1, with all the associated helpers. | ||
and implementation from jQuery 1.7.2, with all the associated helpers. | ||
## Contributors | ||
* [rwldrn](https://github.com/rwldrn) | ||
* [tbranyen](https://github.com/tbranyen) | ||
* [taxillian](https://github.com/taxilian) | ||
## Deferred's are great, let's take them everywhere | ||
@@ -24,15 +18,38 @@ | ||
* done | ||
* resolve | ||
* isResolved | ||
* then | ||
* always | ||
* fail | ||
* reject | ||
* isRejected | ||
* pipe | ||
* promise | ||
* [done](http://api.jquery.com/deferred.done/) | ||
* [resolve](http://api.jquery.com/deferred.resolve/) | ||
* [isResolved](http://api.jquery.com/deferred.isresolved/) | ||
* [then](http://api.jquery.com/deferred.then/) | ||
* [always](http://api.jquery.com/deferred.always/) | ||
* [fail](http://api.jquery.com/deferred.fail/) | ||
* [reject](http://api.jquery.com/deferred.reject/) | ||
* [isRejected](http://api.jquery.com/deferred.isrejected/) | ||
* [pipe](http://api.jquery.com/deferred.pipe/) | ||
* [promise](http://api.jquery.com/deferred.promise/) | ||
* [notify](http://api.jquery.com/deferred.notify/) | ||
* [notifyWith](http://api.jquery.com/deferred.notifywith/) | ||
For specific API documentation, look to the [jQuery Docs][jquery-docs]. | ||
## Usage | ||
Underscore.Deferred works on the server and in the browser. | ||
In the browser, just require it like you would any other file. If you're | ||
including Underscore on the page, make sure you include it before | ||
Underscore.Deferred. If you don't have Underscore, the plugin attaches to | ||
`window._`. | ||
Addionally, underscore.Deferred can be used with the [Ender.js build | ||
tool][ender], if you're into that sort of thing. | ||
On the server, simply install via npm and require normally. If you'd like to | ||
use it as an Underscore module, just do this: | ||
var _ = require('underscore')._ | ||
_.mixin( require('underscore.deferred') ); | ||
But keep in mind that Underscore is not a strict requirement, and assigning it | ||
to another namespace will always work. | ||
## Build | ||
@@ -55,27 +72,12 @@ | ||
``` | ||
$ node build test | ||
$ node build qunit | ||
``` | ||
## Contributors | ||
## Usage | ||
* [rwldrn](https://github.com/rwldrn) | ||
* [tbranyen](https://github.com/tbranyen) | ||
* [taxillian](https://github.com/taxilian) | ||
* [danheberden](https://github.com/danheberden) | ||
Underscore.Deferred works on the server and in the browser. | ||
In the browser, just require it like you would any other file. If you're | ||
including Underscore on the page, make sure you include it before | ||
Underscore.Deferred. If you don't have Underscore, the plugin attaches to | ||
`window._`. | ||
Addionally, underscore.Deferred can be used with the [Ender.js build | ||
tool][ender], if you're into that sort of thing. | ||
On the server, simply install via npm and require normally. If you'd like to | ||
use it as an Underscore module, just do this: | ||
var _ = require('underscore')._ | ||
_.mixin( require('underscore.deferred') ); | ||
But keep in mind the Underscore is not a strict requirement, and assigning it | ||
to another namespace will always work. | ||
## Roadmap | ||
@@ -82,0 +84,0 @@ |
@@ -405,1 +405,184 @@ if( typeof module !== "undefined" && module.exports ){ | ||
}); | ||
(function() { | ||
var output, | ||
addToOutput = function( string ) { | ||
return function() { | ||
output += string; | ||
}; | ||
}, | ||
outputA = addToOutput( "A" ), | ||
outputB = addToOutput( "B" ), | ||
outputC = addToOutput( "C" ), | ||
tests = { | ||
"": "XABC X XABCABCC X XBB X XABA X", | ||
"once": "XABC X X X X X XABA X", | ||
"memory": "XABC XABC XABCABCCC XA XBB XB XABA XC", | ||
"unique": "XABC X XABCA X XBB X XAB X", | ||
"stopOnFalse": "XABC X XABCABCC X XBB X XA X", | ||
"once memory": "XABC XABC X XA X XA XABA XC", | ||
"once unique": "XABC X X X X X XAB X", | ||
"once stopOnFalse": "XABC X X X X X XA X", | ||
"memory unique": "XABC XA XABCA XA XBB XB XAB XC", | ||
"memory stopOnFalse": "XABC XABC XABCABCCC XA XBB XB XA X", | ||
"unique stopOnFalse": "XABC X XABCA X XBB X XA X" | ||
}, | ||
filters = { | ||
"no filter": undefined, | ||
"filter": function( fn ) { | ||
return function() { | ||
return fn.apply( this, arguments ); | ||
}; | ||
} | ||
}; | ||
_.each( tests, function( resultString, flags ) { | ||
_.each( filters, function( filter, filterLabel ) { | ||
test( "_.Callbacks( \"" + flags + "\" ) - " + filterLabel, function() { | ||
expect( 20 ); | ||
// Give qunit a little breathing room | ||
stop(); | ||
setTimeout( start, 0 ); | ||
var cblist; | ||
results = resultString.split( /\s+/ ); | ||
// Basic binding and firing | ||
output = "X"; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add(function( str ) { | ||
output += str; | ||
}); | ||
cblist.fire( "A" ); | ||
strictEqual( output, "XA", "Basic binding and firing" ); | ||
strictEqual( cblist.fired(), true, ".fired() detects firing" ); | ||
output = "X"; | ||
cblist.disable(); | ||
cblist.add(function( str ) { | ||
output += str; | ||
}); | ||
strictEqual( output, "X", "Adding a callback after disabling" ); | ||
cblist.fire( "A" ); | ||
strictEqual( output, "X", "Firing after disabling" ); | ||
// Basic binding and firing (context, arguments) | ||
output = "X"; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add(function() { | ||
equal( this, window, "Basic binding and firing (context)" ); | ||
output += Array.prototype.join.call( arguments, "" ); | ||
}); | ||
cblist.fireWith( window, [ "A", "B" ] ); | ||
strictEqual( output, "XAB", "Basic binding and firing (arguments)" ); | ||
// fireWith with no arguments | ||
output = ""; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add(function() { | ||
equal( this, window, "fireWith with no arguments (context is window)" ); | ||
strictEqual( arguments.length, 0, "fireWith with no arguments (no arguments)" ); | ||
}); | ||
cblist.fireWith(); | ||
// Basic binding, removing and firing | ||
output = "X"; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add( outputA, outputB, outputC ); | ||
cblist.remove( outputB, outputC ); | ||
cblist.fire(); | ||
strictEqual( output, "XA", "Basic binding, removing and firing" ); | ||
// Empty | ||
output = "X"; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add( outputA ); | ||
cblist.add( outputB ); | ||
cblist.add( outputC ); | ||
cblist.empty(); | ||
cblist.fire(); | ||
strictEqual( output, "X", "Empty" ); | ||
// Locking | ||
output = "X"; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add( function( str ) { | ||
output += str; | ||
}); | ||
cblist.lock(); | ||
cblist.add( function( str ) { | ||
output += str; | ||
}); | ||
cblist.fire( "A" ); | ||
cblist.add( function( str ) { | ||
output += str; | ||
}); | ||
strictEqual( output, "X", "Lock early" ); | ||
// Ordering | ||
output = "X"; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add( function() { | ||
cblist.add( outputC ); | ||
outputA(); | ||
}, outputB ); | ||
cblist.fire(); | ||
strictEqual( output, results.shift(), "Proper ordering" ); | ||
// Add and fire again | ||
output = "X"; | ||
cblist.add( function() { | ||
cblist.add( outputC ); | ||
outputA(); | ||
}, outputB ); | ||
strictEqual( output, results.shift(), "Add after fire" ); | ||
output = "X"; | ||
cblist.fire(); | ||
strictEqual( output, results.shift(), "Fire again" ); | ||
// Multiple fire | ||
output = "X"; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add( function( str ) { | ||
output += str; | ||
} ); | ||
cblist.fire( "A" ); | ||
strictEqual( output, "XA", "Multiple fire (first fire)" ); | ||
output = "X"; | ||
cblist.add( function( str ) { | ||
output += str; | ||
} ); | ||
strictEqual( output, results.shift(), "Multiple fire (first new callback)" ); | ||
output = "X"; | ||
cblist.fire( "B" ); | ||
strictEqual( output, results.shift(), "Multiple fire (second fire)" ); | ||
output = "X"; | ||
cblist.add( function( str ) { | ||
output += str; | ||
} ); | ||
strictEqual( output, results.shift(), "Multiple fire (second new callback)" ); | ||
// Return false | ||
output = "X"; | ||
cblist = _.Callbacks( flags ); | ||
cblist.add( outputA, function() { return false; }, outputB ); | ||
cblist.add( outputA ); | ||
cblist.fire(); | ||
strictEqual( output, results.shift(), "Callback returning false" ); | ||
// Add another callback (to control lists with memory do not fire anymore) | ||
output = "X"; | ||
cblist.add( outputC ); | ||
strictEqual( output, results.shift(), "Adding a callback after one returned false" ); | ||
}); | ||
}); | ||
}); | ||
})(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
82411
14
0
2526
1
94
4
1