@@ -56,11 +56,13 @@ jQuery.Callbacks = function( flags, filter ) {
56
56
var // Actual callback list
57
57
list = [ ] ,
58
58
// Stack of fire calls for repeatable lists
59
- stack = ! flags . once && [ ] ,
59
+ stack = [ ] ,
60
60
// Last fire value (for non-forgettable lists)
61
61
memory ,
62
62
// Flag to know if list is currently firing
63
63
firing ,
64
+ // Index of cells to remove in the list after firing
65
+ deleteAfterFire ,
64
66
// Add a list of callbacks to the list
65
67
add = function ( args ) {
66
68
var i ,
@@ -79,15 +81,13 @@ jQuery.Callbacks = function( flags, filter ) {
79
81
// if it already exists
80
82
if ( flags . relocate ) {
81
83
object . remove ( elem ) ;
84
+ } else if ( flags . unique && object . has ( elem ) ) {
85
+ continue ;
82
86
}
83
- // Unless we have a list with unicity and the
84
- // function is already there, add it
85
- if ( ! ( flags . unique && object . has ( elem ) ) ) {
86
- // Get the filtered function if needs be
87
- actual = filter ? filter ( elem ) : elem ;
88
- if ( actual ) {
89
- list . push ( [ elem , actual ] ) ;
90
- }
87
+ // Get the filtered function if needs be
88
+ actual = filter ? filter ( elem ) : elem ;
89
+ if ( actual ) {
90
+ list . push ( [ elem , actual ] ) ;
91
91
}
92
92
}
93
93
}
@@ -96,13 +96,15 @@ jQuery.Callbacks = function( flags, filter ) {
96
96
// Add a callback or a collection of callbacks to the list
97
97
add : function ( ) {
98
98
if ( list ) {
99
+ var length = list . length ;
99
100
add ( arguments ) ;
100
- // If we're not firing and we should call right away
101
+ // With memory, if we're not firing then
102
+ // we should call right away
101
103
if ( ! firing && flags . memory && memory ) {
102
104
// Trick the list into thinking it needs to be fired
103
105
var tmp = memory ;
104
106
memory = undefined ;
105
- object . fireWith ( tmp [ 0 ] , tmp [ 1 ] ) ;
107
+ object . fireWith ( tmp [ 0 ] , tmp [ 1 ] , length ) ;
106
108
}
107
109
}
108
110
return this ;
@@ -113,9 +115,14 @@ jQuery.Callbacks = function( flags, filter ) {
113
115
var i = 0 ,
114
116
length = list . length ;
115
117
for ( ; i < length ; i ++ ) {
116
- if ( fn === list [ i ] [ 0 ] ) {
117
- list . splice ( i , 1 ) ;
118
- i -- ;
118
+ if ( list [ i ] && fn === list [ i ] [ 0 ] ) {
119
+ if ( firing ) {
120
+ list [ i ] = undefined ;
121
+ deleteAfterFire . push ( i ) ;
122
+ } else {
123
+ list . splice ( i , 1 ) ;
124
+ i -- ;
125
+ }
119
126
// If we have some unicity property then
120
127
// we only need to do this once
121
128
if ( flags . unique || flags . relocate ) {
@@ -132,7 +139,7 @@ jQuery.Callbacks = function( flags, filter ) {
132
139
var i = 0 ,
133
140
length = list . length ;
134
141
for ( ; i < length ; i ++ ) {
135
- if ( fn === list [ i ] [ 0 ] ) {
142
+ if ( list [ i ] && fn === list [ i ] [ 0 ] ) {
136
143
return true ;
137
144
}
138
145
}
@@ -158,30 +165,39 @@ jQuery.Callbacks = function( flags, filter ) {
158
165
return this ;
159
166
} ,
160
167
// Call all callbacks with the given context and arguments
161
- fireWith : function ( context , args ) {
162
- var i ;
163
- if ( list && ( flags . once ? ! memory && ! firing : stack ) ) {
168
+ fireWith : function ( context , args , start /* internal */ ) {
169
+ var i ,
170
+ done ,
171
+ stoppedOnFalse ;
172
+ if ( list && stack && ( ! flags . once || ! memory && ! firing ) ) {
164
173
if ( firing ) {
165
174
stack . push ( [ context , args ] ) ;
166
175
} else {
167
176
args = args || [ ] ;
168
177
memory = ! flags . memory || [ context , args ] ;
169
178
firing = true ;
179
+ deleteAfterFire = [ ] ;
170
180
try {
171
- for ( i = 0 ; list && i < list . length ; i ++ ) {
172
- if ( list [ i ] [ 1 ] . apply ( context , args ) === false && flags . stopOnFalse ) {
181
+ for ( i = start || 0 ; list && i < list . length ; i ++ ) {
182
+ if ( ( stoppedOnFalse = list [ i ] &&
183
+ list [ i ] [ 1 ] . apply ( context , args ) === false &&
184
+ flags . stopOnFalse ) ) {
173
185
break ;
174
186
}
175
187
}
176
188
} finally {
177
189
firing = false ;
178
190
if ( list ) {
191
+ done = ( stoppedOnFalse || i >= list . length ) ;
192
+ for ( i = 0 ; i < deleteAfterFire . length ; i ++ ) {
193
+ list . splice ( deleteAfterFire [ i ] , 1 ) ;
194
+ }
179
195
if ( ! flags . once ) {
180
- if ( i >= list . length && stack . length ) {
181
- object . fire . apply ( this , stack . shift ( ) ) ;
196
+ if ( done && stack && stack . length ) {
197
+ object . fireWith . apply ( this , stack . shift ( ) ) ;
182
198
}
183
199
} else if ( ! flags . memory ) {
184
- object . destroy ( ) ;
200
+ object . disable ( ) ;
185
201
} else {
186
202
list = [ ] ;
187
203
}
0 commit comments