From: jaubourg Date: Wed, 25 Apr 2012 13:50:26 +0000 (+0200) Subject: How about we save 62 bytes? Also ensure that the arguments array given to fireWith... X-Git-Tag: 1.8b1~185 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=97210d4e700aba1b67ac3652303bb685d129aced;p=jquery.git How about we save 62 bytes? Also ensure that the arguments array given to fireWith is copied internally. --- diff --git a/src/callbacks.js b/src/callbacks.js index 5e1f3db0d..a6c504c79 100644 --- a/src/callbacks.js +++ b/src/callbacks.js @@ -5,12 +5,10 @@ var optionsCache = {}; // Convert String-formatted options into Object-formatted ones and store in cache function createOptions( options ) { - var object = optionsCache[ options ] = {}, - i, length; - options = options.split( /\s+/ ); - for ( i = 0, length = options.length; i < length; i++ ) { - object[ options[i] ] = true; - } + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( /\s+/ ), function( _, flag ) { + object[ flag ] = true; + }); return object; } @@ -47,7 +45,7 @@ jQuery.Callbacks = function( options ) { var // Actual callback list list = [], // Stack of fire calls for repeatable lists - stack = [], + stack = !options.once && [], // Last fire value (for non-forgettable lists) memory, // Flag to know if list was already fired @@ -60,48 +58,25 @@ jQuery.Callbacks = function( options ) { 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 = 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 = function( context, args ) { - args = args || []; - memory = !options.memory || [ context, args ]; + fire = function( data ) { + memory = !options.memory || data; fired = true; - firing = true; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; + firing = true; 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 break; } } firing = false; if ( list ) { - if ( !options.once ) { - if ( stack && stack.length ) { - memory = stack.shift(); - self.fireWith( memory[ 0 ], memory[ 1 ] ); + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); } } else if ( memory === true ) { self.disable(); @@ -115,8 +90,18 @@ jQuery.Callbacks = function( options ) { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { - var length = list.length; - add( arguments ); + // First, we save the current length + 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 // current firing batch? if ( firing ) { @@ -125,8 +110,8 @@ jQuery.Callbacks = function( options ) { // we should call right away, unless previous // firing was halted (stopOnFalse) } else if ( memory && memory !== true ) { - firingStart = length; - fire( memory[ 0 ], memory[ 1 ] ); + firingStart = start; + fire( memory ); } } return this; @@ -134,46 +119,26 @@ jQuery.Callbacks = function( options ) { // 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--; - } - } + jQuery.each( arguments, function( index, arg ) { + if ( ( index = jQuery.inArray( arg, list ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; } - // 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; }, // 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; + return jQuery.inArray( fn, list ) > -1; }, // Remove all callbacks from the list empty: function() { @@ -203,13 +168,12 @@ jQuery.Callbacks = function( options ) { }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { - if ( stack ) { + args = [ context, jQuery.merge( [], args || [] ) ]; + if ( list && ( !fired || stack ) ) { if ( firing ) { - if ( !options.once ) { - stack.push( [ context, args ] ); - } - } else if ( !( options.once && memory ) ) { - fire( context, args ); + stack.push( args ); + } else { + fire( args ); } } return this; diff --git a/test/unit/callbacks.js b/test/unit/callbacks.js index d1e8fbd6d..6fca16be9 100644 --- a/test/unit/callbacks.js +++ b/test/unit/callbacks.js @@ -209,15 +209,29 @@ test( "jQuery.Callbacks( options ) - options are copied", function() { expect( 1 ); 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 ) { - strictEqual( hello, "hello", "options are copied internally" ); + strictEqual( hello, "hello", "arguments are copied internally" ); }); });