From a588336a6dcc6f29e870e8fcdd243f96bec5e833 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Wed, 21 Sep 2011 17:00:55 +0200 Subject: [PATCH] Trimmed down $.Callbacks and $.Deferred. --- src/callbacks.js | 49 ++++++++---------------------------------- src/deferred.js | 49 +++++++++++++++++++++--------------------- test/unit/callbacks.js | 14 +----------- 3 files changed, 34 insertions(+), 78 deletions(-) diff --git a/src/callbacks.js b/src/callbacks.js index a1caf91f2..6ae4971fb 100644 --- a/src/callbacks.js +++ b/src/callbacks.js @@ -20,9 +20,6 @@ function createFlags( flags ) { * flags: an optional list of space-separated flags that will change how * the callback list behaves * - * filter: an optional function that will be applied to each added callbacks, - * what filter returns will then be added provided it is not falsy. - * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * @@ -34,26 +31,12 @@ function createFlags( flags ) { * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * - * queue: only first callback in the list is called each time the list is fired - * (cannot be used in conjunction with memory) - * * unique: will ensure a callback can only be added once (no duplicate in the list) * - * relocate: like "unique" but will relocate the callback at the end of the list - * * stopOnFalse: interrupt callings when a callback returns false * - * addAfterFire: if callbacks are added while firing, then they are not executed until after - * the next call to fire/fireWith - * */ -jQuery.Callbacks = function( flags, filter ) { - - // flags are optional - if ( typeof flags !== "string" ) { - filter = flags; - flags = undefined; - } +jQuery.Callbacks = function( flags ) { // Convert flags from String-formatted to Object-formatted // (we check in cache first) @@ -87,18 +70,9 @@ jQuery.Callbacks = function( flags, filter ) { // Inspect recursively add( elem ); } else if ( type === "function" ) { - // If we have to relocate, we remove the callback - // if it already exists - if ( flags.relocate ) { - self.remove( elem ); - // Skip if we're in unique mode and callback is already in - } else if ( flags.unique && self.has( elem ) ) { - continue; - } - // Get the filtered function if needs be - actual = filter ? filter( elem ) : elem; - if ( actual ) { - list.push( [ elem, actual ] ); + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); } } } @@ -112,12 +86,9 @@ jQuery.Callbacks = function( flags, filter ) { firingStart = 0; firingLength = list.length; for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ][ 1 ].apply( context, args ) === false && flags.stopOnFalse ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { memory = true; // Mark as halted break; - } else if ( flags.queue ) { - list.splice( firingIndex, 1 ); - break; } } firing = false; @@ -144,9 +115,7 @@ jQuery.Callbacks = function( flags, filter ) { // Do we need to add the callbacks to the // current firing batch? if ( firing ) { - if ( !flags.addAfterFire ) { - firingLength = list.length; - } + firingLength = list.length; // With memory, if we're not firing then // we should call right away, unless previous // firing was halted (stopOnFalse) @@ -165,7 +134,7 @@ jQuery.Callbacks = function( flags, filter ) { argLength = args.length; for ( ; argIndex < argLength ; argIndex++ ) { for ( var i = 0; i < list.length; i++ ) { - if ( args[ argIndex ] === list[ i ][ 0 ] ) { + if ( args[ argIndex ] === list[ i ] ) { // Handle firingIndex and firingLength if ( firing ) { if ( i <= firingLength ) { @@ -179,7 +148,7 @@ jQuery.Callbacks = function( flags, filter ) { list.splice( i--, 1 ); // If we have some unicity property then // we only need to do this once - if ( flags.unique || flags.relocate ) { + if ( flags.unique ) { break; } } @@ -194,7 +163,7 @@ jQuery.Callbacks = function( flags, filter ) { var i = 0, length = list.length; for ( ; i < length; i++ ) { - if ( fn === list[ i ][ 0 ] ) { + if ( fn === list[ i ] ) { return true; } } diff --git a/src/deferred.js b/src/deferred.js index 57014af3d..2ebf3fa59 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -1,8 +1,6 @@ (function( jQuery ) { -var // Promise methods - promiseMethods = "done removeDone fail removeFail progress removeProgress isResolved isRejected promise then always pipe".split( " " ), - // Static reference to slice +var // Static reference to slice sliceDeferred = [].slice; jQuery.extend({ @@ -11,31 +9,28 @@ jQuery.extend({ var doneList = jQuery.Callbacks( "once memory" ), failList = jQuery.Callbacks( "once memory" ), progressList = jQuery.Callbacks( "memory" ), - promise, - deferred = { - // Copy existing methods from lists + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { done: doneList.add, - removeDone: doneList.remove, fail: failList.add, - removeFail: failList.remove, progress: progressList.add, - removeProgress: progressList.remove, - resolve: doneList.fire, - resolveWith: doneList.fireWith, - reject: failList.fire, - rejectWith: failList.fireWith, - notify: progressList.fire, - notifyWith: progressList.fireWith, + isResolved: doneList.fired, isRejected: failList.fired, + isProgressing: function() { + return !progressList.locked(); + }, - // Create Deferred-specific methods then: function( doneCallbacks, failCallbacks, progressCallbacks ) { deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); return this; }, always: function() { - return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); + return deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); }, pipe: function( fnDone, fnFail, fnProgress ) { return jQuery.Deferred(function( newDefer ) { @@ -66,18 +61,22 @@ jQuery.extend({ // If obj is provided, the promise aspect is added to the object promise: function( obj ) { if ( obj == null ) { - if ( promise ) { - return promise; + obj = promise; + } else { + for( var key in promise ) { + obj[ key ] = promise[ key ]; } - promise = obj = {}; - } - var i = promiseMethods.length; - while( i-- ) { - obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; } return obj; } - }; + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } // Handle lists exclusiveness deferred.done( failList.disable, progressList.lock ) diff --git a/test/unit/callbacks.js b/test/unit/callbacks.js index fcc3ee46b..a1935e743 100644 --- a/test/unit/callbacks.js +++ b/test/unit/callbacks.js @@ -16,25 +16,13 @@ var output, "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", - "relocate": "XABC X XAABC X XBB X XBA X", "stopOnFalse": "XABC X XABCABCC X XBB X XA X", - "addAfterFire": "XAB X XABCAB X XBB X XABA X", - "queue": "XA X XB X XB X XA X", "once memory": "XABC XABC X XA X XA XABA XC", "once unique": "XABC X X X X X XAB X", - "once relocate": "XABC X X X X X XBA X", "once stopOnFalse": "XABC X X X X X XA X", - "once addAfterFire": "XAB X X X X X XABA X", "memory unique": "XABC XA XABCA XA XBB XB XAB XC", - "memory relocate": "XABC XB XAABC XA XBB XB XBA XC", "memory stopOnFalse": "XABC XABC XABCABCCC XA XBB XB XA X", - "memory addAfterFire": "XAB XAB XABCABC XA XBB XB XABA XC", - "unique relocate": "XABC X XAABC X XBB X XBA X", - "unique stopOnFalse": "XABC X XABCA X XBB X XA X", - "unique addAfterFire": "XAB X XABCA X XBB X XAB X", - "relocate stopOnFalse": "XABC X XAABC X XBB X X X", - "relocate addAfterFire": "XAB X XAA X XBB X XBA X", - "stopOnFalse addAfterFire": "XAB X XABCAB X XBB X XA X" + "unique stopOnFalse": "XABC X XABCA X XBB X XA X" }, filters = { "no filter": undefined,