Commit 97210d4e authored by jaubourg's avatar jaubourg

How about we save 62 bytes? Also ensure that the arguments array given to...

How about we save 62 bytes? Also ensure that the arguments array given to fireWith is copied internally.
parent f3074435
...@@ -5,12 +5,10 @@ var optionsCache = {}; ...@@ -5,12 +5,10 @@ var optionsCache = {};
// Convert String-formatted options into Object-formatted ones and store in cache // Convert String-formatted options into Object-formatted ones and store in cache
function createOptions( options ) { function createOptions( options ) {
var object = optionsCache[ options ] = {}, var object = optionsCache[ options ] = {};
i, length; jQuery.each( options.split( /\s+/ ), function( _, flag ) {
options = options.split( /\s+/ ); object[ flag ] = true;
for ( i = 0, length = options.length; i < length; i++ ) { });
object[ options[i] ] = true;
}
return object; return object;
} }
...@@ -47,7 +45,7 @@ jQuery.Callbacks = function( options ) { ...@@ -47,7 +45,7 @@ jQuery.Callbacks = function( options ) {
var // Actual callback list var // Actual callback list
list = [], list = [],
// Stack of fire calls for repeatable lists // Stack of fire calls for repeatable lists
stack = [], stack = !options.once && [],
// Last fire value (for non-forgettable lists) // Last fire value (for non-forgettable lists)
memory, memory,
// Flag to know if list was already fired // Flag to know if list was already fired
...@@ -60,48 +58,25 @@ jQuery.Callbacks = function( options ) { ...@@ -60,48 +58,25 @@ jQuery.Callbacks = function( options ) {
firingLength, firingLength,
// Index of currently firing callback (modified by remove if needed) // Index of currently firing callback (modified by remove if needed)
firingIndex, 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 = jQuery.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 ( !options.unique || !self.has( elem ) ) {
list.push( elem );
}
}
}
},
// Fire callbacks // Fire callbacks
fire = function( context, args ) { fire = function( data ) {
args = args || []; memory = !options.memory || data;
memory = !options.memory || [ context, args ];
fired = true; fired = true;
firing = true;
firingIndex = firingStart || 0; firingIndex = firingStart || 0;
firingStart = 0; firingStart = 0;
firingLength = list.length; firingLength = list.length;
firing = true;
for ( ; list && firingIndex < firingLength; firingIndex++ ) { for ( ; list && firingIndex < firingLength; firingIndex++ ) {
if ( list[ firingIndex ].apply( context, args ) === false && options.stopOnFalse ) { if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
memory = true; // Mark as halted memory = true; // Mark as halted
break; break;
} }
} }
firing = false; firing = false;
if ( list ) { if ( list ) {
if ( !options.once ) { if ( stack ) {
if ( stack && stack.length ) { if ( stack.length ) {
memory = stack.shift(); fire( stack.shift() );
self.fireWith( memory[ 0 ], memory[ 1 ] );
} }
} else if ( memory === true ) { } else if ( memory === true ) {
self.disable(); self.disable();
...@@ -115,8 +90,18 @@ jQuery.Callbacks = function( options ) { ...@@ -115,8 +90,18 @@ jQuery.Callbacks = function( options ) {
// Add a callback or a collection of callbacks to the list // Add a callback or a collection of callbacks to the list
add: function() { add: function() {
if ( list ) { if ( list ) {
var length = list.length; // First, we save the current length
add( arguments ); var start = list.length;
(function add( args ) {
jQuery.each( args, function( type, arg ) {
if ( ( type = jQuery.type(arg) ) === "array" ) {
// Inspect recursively
add( arg );
} else if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) {
list.push( arg );
}
});
})( arguments );
// Do we need to add the callbacks to the // Do we need to add the callbacks to the
// current firing batch? // current firing batch?
if ( firing ) { if ( firing ) {
...@@ -125,8 +110,8 @@ jQuery.Callbacks = function( options ) { ...@@ -125,8 +110,8 @@ jQuery.Callbacks = function( options ) {
// we should call right away, unless previous // we should call right away, unless previous
// firing was halted (stopOnFalse) // firing was halted (stopOnFalse)
} else if ( memory && memory !== true ) { } else if ( memory && memory !== true ) {
firingStart = length; firingStart = start;
fire( memory[ 0 ], memory[ 1 ] ); fire( memory );
} }
} }
return this; return this;
...@@ -134,46 +119,26 @@ jQuery.Callbacks = function( options ) { ...@@ -134,46 +119,26 @@ jQuery.Callbacks = function( options ) {
// Remove a callback from the list // Remove a callback from the list
remove: function() { remove: function() {
if ( list ) { if ( list ) {
var args = arguments, jQuery.each( arguments, function( index, arg ) {
argIndex = 0, if ( ( index = jQuery.inArray( arg, list ) ) > -1 ) {
argLength = args.length; list.splice( index, 1 );
for ( ; argIndex < argLength ; argIndex++ ) { // Handle firing indexes
for ( var i = 0; i < list.length; i++ ) {
if ( args[ argIndex ] === list[ i ] ) {
// Handle firingIndex and firingLength
if ( firing ) { if ( firing ) {
if ( i <= firingLength ) { if ( index <= firingLength ) {
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 ( options.unique ) {
break;
} }
if ( index <= firingIndex ) {
firingIndex--;
} }
} }
} }
});
} }
return this; return this;
}, },
// Control if a given callback is in the list // Control if a given callback is in the list
has: function( fn ) { has: function( fn ) {
if ( list ) { return jQuery.inArray( fn, list ) > -1;
var i = 0,
length = list.length;
for ( ; i < length; i++ ) {
if ( fn === list[ i ] ) {
return true;
}
}
}
return false;
}, },
// Remove all callbacks from the list // Remove all callbacks from the list
empty: function() { empty: function() {
...@@ -203,13 +168,12 @@ jQuery.Callbacks = function( options ) { ...@@ -203,13 +168,12 @@ jQuery.Callbacks = function( options ) {
}, },
// Call all callbacks with the given context and arguments // Call all callbacks with the given context and arguments
fireWith: function( context, args ) { fireWith: function( context, args ) {
if ( stack ) { args = [ context, jQuery.merge( [], args || [] ) ];
if ( list && ( !fired || stack ) ) {
if ( firing ) { if ( firing ) {
if ( !options.once ) { stack.push( args );
stack.push( [ context, args ] ); } else {
} fire( args );
} else if ( !( options.once && memory ) ) {
fire( context, args );
} }
} }
return this; return this;
......
...@@ -209,15 +209,29 @@ test( "jQuery.Callbacks( options ) - options are copied", function() { ...@@ -209,15 +209,29 @@ test( "jQuery.Callbacks( options ) - options are copied", function() {
expect( 1 ); expect( 1 );
var options = { var options = {
memory: true unique: true
}, },
cb = jQuery.Callbacks( options ); cb = jQuery.Callbacks( options ),
count = 0,
fn = function() {
ok( !( count++ ), "called once" );
};
options.unique = false;
cb.add( fn, fn );
cb.fire();
});
test( "jQuery.Callbacks.fireWith - arguments are copied", function() {
expect( 1 );
options.memory = false; var cb = jQuery.Callbacks( "memory" ),
args = [ "hello" ];
cb.fire( "hello" ); cb.fireWith( null, args );
args[ 0 ] = "world";
cb.add(function( hello ) { cb.add(function( hello ) {
strictEqual( hello, "hello", "options are copied internally" ); strictEqual( hello, "hello", "arguments are copied internally" );
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment