X Tutup
Skip to content

Commit 97210d4

Browse files
committed
How about we save 62 bytes? Also ensure that the arguments array given to fireWith is copied internally.
1 parent f307443 commit 97210d4

File tree

2 files changed

+61
-83
lines changed

2 files changed

+61
-83
lines changed

src/callbacks.js

Lines changed: 42 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ var optionsCache = {};
55

66
// Convert String-formatted options into Object-formatted ones and store in cache
77
function createOptions( options ) {
8-
var object = optionsCache[ options ] = {},
9-
i, length;
10-
options = options.split( /\s+/ );
11-
for ( i = 0, length = options.length; i < length; i++ ) {
12-
object[ options[i] ] = true;
13-
}
8+
var object = optionsCache[ options ] = {};
9+
jQuery.each( options.split( /\s+/ ), function( _, flag ) {
10+
object[ flag ] = true;
11+
});
1412
return object;
1513
}
1614

@@ -47,7 +45,7 @@ jQuery.Callbacks = function( options ) {
4745
var // Actual callback list
4846
list = [],
4947
// Stack of fire calls for repeatable lists
50-
stack = [],
48+
stack = !options.once && [],
5149
// Last fire value (for non-forgettable lists)
5250
memory,
5351
// Flag to know if list was already fired
@@ -60,48 +58,25 @@ jQuery.Callbacks = function( options ) {
6058
firingLength,
6159
// Index of currently firing callback (modified by remove if needed)
6260
firingIndex,
63-
// Add one or several callbacks to the list
64-
add = function( args ) {
65-
var i,
66-
length,
67-
elem,
68-
type,
69-
actual;
70-
for ( i = 0, length = args.length; i < length; i++ ) {
71-
elem = args[ i ];
72-
type = jQuery.type( elem );
73-
if ( type === "array" ) {
74-
// Inspect recursively
75-
add( elem );
76-
} else if ( type === "function" ) {
77-
// Add if not in unique mode and callback is not in
78-
if ( !options.unique || !self.has( elem ) ) {
79-
list.push( elem );
80-
}
81-
}
82-
}
83-
},
8461
// Fire callbacks
85-
fire = function( context, args ) {
86-
args = args || [];
87-
memory = !options.memory || [ context, args ];
62+
fire = function( data ) {
63+
memory = !options.memory || data;
8864
fired = true;
89-
firing = true;
9065
firingIndex = firingStart || 0;
9166
firingStart = 0;
9267
firingLength = list.length;
68+
firing = true;
9369
for ( ; list && firingIndex < firingLength; firingIndex++ ) {
94-
if ( list[ firingIndex ].apply( context, args ) === false && options.stopOnFalse ) {
70+
if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
9571
memory = true; // Mark as halted
9672
break;
9773
}
9874
}
9975
firing = false;
10076
if ( list ) {
101-
if ( !options.once ) {
102-
if ( stack && stack.length ) {
103-
memory = stack.shift();
104-
self.fireWith( memory[ 0 ], memory[ 1 ] );
77+
if ( stack ) {
78+
if ( stack.length ) {
79+
fire( stack.shift() );
10580
}
10681
} else if ( memory === true ) {
10782
self.disable();
@@ -115,8 +90,18 @@ jQuery.Callbacks = function( options ) {
11590
// Add a callback or a collection of callbacks to the list
11691
add: function() {
11792
if ( list ) {
118-
var length = list.length;
119-
add( arguments );
93+
// First, we save the current length
94+
var start = list.length;
95+
(function add( args ) {
96+
jQuery.each( args, function( type, arg ) {
97+
if ( ( type = jQuery.type(arg) ) === "array" ) {
98+
// Inspect recursively
99+
add( arg );
100+
} else if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) {
101+
list.push( arg );
102+
}
103+
});
104+
})( arguments );
120105
// Do we need to add the callbacks to the
121106
// current firing batch?
122107
if ( firing ) {
@@ -125,55 +110,35 @@ jQuery.Callbacks = function( options ) {
125110
// we should call right away, unless previous
126111
// firing was halted (stopOnFalse)
127112
} else if ( memory && memory !== true ) {
128-
firingStart = length;
129-
fire( memory[ 0 ], memory[ 1 ] );
113+
firingStart = start;
114+
fire( memory );
130115
}
131116
}
132117
return this;
133118
},
134119
// Remove a callback from the list
135120
remove: function() {
136121
if ( list ) {
137-
var args = arguments,
138-
argIndex = 0,
139-
argLength = args.length;
140-
for ( ; argIndex < argLength ; argIndex++ ) {
141-
for ( var i = 0; i < list.length; i++ ) {
142-
if ( args[ argIndex ] === list[ i ] ) {
143-
// Handle firingIndex and firingLength
144-
if ( firing ) {
145-
if ( i <= firingLength ) {
146-
firingLength--;
147-
if ( i <= firingIndex ) {
148-
firingIndex--;
149-
}
150-
}
122+
jQuery.each( arguments, function( index, arg ) {
123+
if ( ( index = jQuery.inArray( arg, list ) ) > -1 ) {
124+
list.splice( index, 1 );
125+
// Handle firing indexes
126+
if ( firing ) {
127+
if ( index <= firingLength ) {
128+
firingLength--;
151129
}
152-
// Remove the element
153-
list.splice( i--, 1 );
154-
// If we have some unicity property then
155-
// we only need to do this once
156-
if ( options.unique ) {
157-
break;
130+
if ( index <= firingIndex ) {
131+
firingIndex--;
158132
}
159133
}
160134
}
161-
}
135+
});
162136
}
163137
return this;
164138
},
165139
// Control if a given callback is in the list
166140
has: function( fn ) {
167-
if ( list ) {
168-
var i = 0,
169-
length = list.length;
170-
for ( ; i < length; i++ ) {
171-
if ( fn === list[ i ] ) {
172-
return true;
173-
}
174-
}
175-
}
176-
return false;
141+
return jQuery.inArray( fn, list ) > -1;
177142
},
178143
// Remove all callbacks from the list
179144
empty: function() {
@@ -203,13 +168,12 @@ jQuery.Callbacks = function( options ) {
203168
},
204169
// Call all callbacks with the given context and arguments
205170
fireWith: function( context, args ) {
206-
if ( stack ) {
171+
args = [ context, jQuery.merge( [], args || [] ) ];
172+
if ( list && ( !fired || stack ) ) {
207173
if ( firing ) {
208-
if ( !options.once ) {
209-
stack.push( [ context, args ] );
210-
}
211-
} else if ( !( options.once && memory ) ) {
212-
fire( context, args );
174+
stack.push( args );
175+
} else {
176+
fire( args );
213177
}
214178
}
215179
return this;

test/unit/callbacks.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,15 +209,29 @@ test( "jQuery.Callbacks( options ) - options are copied", function() {
209209
expect( 1 );
210210

211211
var options = {
212-
memory: true
212+
unique: true
213213
},
214-
cb = jQuery.Callbacks( options );
214+
cb = jQuery.Callbacks( options ),
215+
count = 0,
216+
fn = function() {
217+
ok( !( count++ ), "called once" );
218+
};
219+
options.unique = false;
220+
cb.add( fn, fn );
221+
cb.fire();
222+
});
223+
224+
test( "jQuery.Callbacks.fireWith - arguments are copied", function() {
225+
226+
expect( 1 );
215227

216-
options.memory = false;
228+
var cb = jQuery.Callbacks( "memory" ),
229+
args = [ "hello" ];
217230

218-
cb.fire( "hello" );
231+
cb.fireWith( null, args );
232+
args[ 0 ] = "world";
219233

220234
cb.add(function( hello ) {
221-
strictEqual( hello, "hello", "options are copied internally" );
235+
strictEqual( hello, "hello", "arguments are copied internally" );
222236
});
223237
});

0 commit comments

Comments
 (0)
X Tutup