@@ -3,12 +3,9 @@ define([
3
3
"./var/rnotwhite"
4
4
] , function ( jQuery , rnotwhite ) {
5
5
6
- // String to Object options format cache
7
- var optionsCache = { } ;
8
-
9
- // Convert String-formatted options into Object-formatted ones and store in cache
6
+ // Convert String-formatted options into Object-formatted ones
10
7
function createOptions ( options ) {
11
- var object = optionsCache [ options ] = { } ;
8
+ var object = { } ;
12
9
jQuery . each ( options . match ( rnotwhite ) || [ ] , function ( _ , flag ) {
13
10
object [ flag ] = true ;
14
11
} ) ;
@@ -42,132 +39,129 @@ jQuery.Callbacks = function( options ) {
42
39
// Convert options from String-formatted to Object-formatted if needed
43
40
// (we check in cache first)
44
41
options = typeof options === "string" ?
45
- ( optionsCache [ options ] || createOptions ( options ) ) :
42
+ createOptions ( options ) :
46
43
jQuery . extend ( { } , options ) ;
47
44
48
45
var // Flag to know if list is currently firing
49
46
firing ,
50
- // Last fire value ( for non-forgettable lists)
47
+ // Last fire value for non-forgettable lists
51
48
memory ,
52
49
// Flag to know if list was already fired
53
50
fired ,
54
- // Flag to prevent .fire/.fireWith
51
+ // Flag to prevent firing
55
52
locked ,
56
- // End of the loop when firing
57
- firingLength ,
58
- // Index of currently firing callback (modified by remove if needed)
59
- firingIndex ,
60
- // First callback to fire (used internally by add and fireWith)
61
- firingStart ,
62
53
// Actual callback list
63
54
list = [ ] ,
64
- // Stack of fire calls for repeatable lists
65
- stack = ! options . once && [ ] ,
55
+ // Queue of execution data for repeatable lists
56
+ queue = [ ] ,
57
+ // Index of currently firing callback (modified by add/remove as needed)
58
+ firingIndex = - 1 ,
66
59
// Fire callbacks
67
- fire = function ( data ) {
60
+ fire = function ( ) {
61
+
62
+ // Enforce single-firing
68
63
locked = options . once ;
69
- memory = options . memory && data ;
70
- fired = true ;
71
- firingIndex = firingStart || 0 ;
72
- firingStart = 0 ;
73
- firingLength = list . length ;
74
- firing = true ;
75
- for ( ; list && firingIndex < firingLength ; firingIndex ++ ) {
76
- if ( list [ firingIndex ] . apply ( data [ 0 ] , data [ 1 ] ) === false &&
77
- options . stopOnFalse ) {
78
-
79
- memory = false ; // To prevent further calls using add
80
- break ;
64
+
65
+ // Execute callbacks for all pending executions,
66
+ // respecting firingIndex overrides and runtime changes
67
+ fired = firing = true ;
68
+ for ( ; queue . length ; firingIndex = - 1 ) {
69
+ memory = queue . shift ( ) ;
70
+ while ( ++ firingIndex < list . length ) {
71
+
72
+ // Run callback and check for early termination
73
+ if ( list [ firingIndex ] . apply ( memory [ 0 ] , memory [ 1 ] ) === false &&
74
+ options . stopOnFalse ) {
75
+
76
+ // Jump to end and forget the data so .add doesn't re-fire
77
+ firingIndex = list . length ;
78
+ memory = false ;
79
+ }
81
80
}
82
81
}
83
- firing = false ;
84
82
85
- // If not disabled,
86
- if ( list ) {
83
+ // Forget the data if we're done with it
84
+ if ( ! options . memory ) {
85
+ memory = false ;
86
+ }
87
87
88
- // If repeatable, check for pending execution
89
- if ( stack ) {
90
- if ( stack . length ) {
91
- fire ( stack . shift ( ) ) ;
92
- }
88
+ firing = false ;
89
+
90
+ // Clean up if we're done firing for good
91
+ if ( locked ) {
93
92
94
- // If not repeatable but with memory, clear out spent callbacks
95
- } else if ( memory ) {
93
+ // Keep an empty list if we have data for future add calls
94
+ if ( memory ) {
96
95
list = [ ] ;
97
96
98
- // Else, disable
97
+ // Otherwise, this object is spent
99
98
} else {
100
- self . disable ( ) ;
99
+ list = "" ;
101
100
}
102
101
}
103
102
} ,
103
+
104
104
// Actual Callbacks object
105
105
self = {
106
+
106
107
// Add a callback or a collection of callbacks to the list
107
108
add : function ( ) {
108
109
if ( list ) {
109
- // First, we save the current length
110
- var start = list . length ;
110
+
111
+ // If we have memory from a past run, we should fire after adding
112
+ if ( memory && ! firing ) {
113
+ firingIndex = list . length - 1 ;
114
+ queue . push ( memory ) ;
115
+ }
116
+
111
117
( function add ( args ) {
112
118
jQuery . each ( args , function ( _ , arg ) {
113
- var type = jQuery . type ( arg ) ;
114
- if ( type === "function" ) {
119
+ if ( jQuery . isFunction ( arg ) ) {
115
120
if ( ! options . unique || ! self . has ( arg ) ) {
116
121
list . push ( arg ) ;
117
122
}
118
- } else if ( arg && arg . length && type !== "string" ) {
123
+ } else if ( arg && arg . length && jQuery . type ( arg ) !== "string" ) {
119
124
// Inspect recursively
120
125
add ( arg ) ;
121
126
}
122
127
} ) ;
123
128
} ) ( arguments ) ;
124
- // Do we need to add the callbacks to the
125
- // current firing batch?
126
- if ( firing ) {
127
- firingLength = list . length ;
128
- // With memory, if we're not firing then
129
- // we should call right away
130
- } else if ( memory ) {
131
- firingStart = start ;
132
- fire ( memory ) ;
129
+
130
+ if ( memory && ! firing ) {
131
+ fire ( ) ;
133
132
}
134
133
}
135
134
return this ;
136
135
} ,
137
136
138
137
// Remove a callback from the list
139
138
remove : function ( ) {
140
- if ( list ) {
141
- jQuery . each ( arguments , function ( _ , arg ) {
142
- var index ;
143
- while ( ( index = jQuery . inArray ( arg , list , index ) ) > - 1 ) {
144
- list . splice ( index , 1 ) ;
145
- // Handle firing indexes
146
- if ( firing ) {
147
- if ( index <= firingLength ) {
148
- firingLength -- ;
149
- }
150
- if ( index <= firingIndex ) {
151
- firingIndex -- ;
152
- }
153
- }
139
+ jQuery . each ( arguments , function ( _ , arg ) {
140
+ var index ;
141
+ while ( ( index = jQuery . inArray ( arg , list , index ) ) > - 1 ) {
142
+ list . splice ( index , 1 ) ;
143
+
144
+ // Handle firing indexes
145
+ if ( index <= firingIndex ) {
146
+ firingIndex -- ;
154
147
}
155
- } ) ;
156
- }
148
+ }
149
+ } ) ;
157
150
return this ;
158
151
} ,
159
152
160
153
// Check if a given callback is in the list.
161
154
// If no argument is given, return whether or not list has callbacks attached.
162
155
has : function ( fn ) {
163
- return fn ? jQuery . inArray ( fn , list ) > - 1 : ! ! ( list && list . length ) ;
156
+ return fn ?
157
+ jQuery . inArray ( fn , list ) > - 1 :
158
+ list . length > 0 ;
164
159
} ,
165
160
166
161
// Remove all callbacks from the list
167
162
empty : function ( ) {
168
163
if ( list ) {
169
164
list = [ ] ;
170
- firingLength = 0 ;
171
165
}
172
166
return this ;
173
167
} ,
@@ -176,8 +170,8 @@ jQuery.Callbacks = function( options ) {
176
170
// Abort any current/pending executions
177
171
// Clear all callbacks and values
178
172
disable : function ( ) {
179
- list = stack = memory = undefined ;
180
- locked = true ;
173
+ locked = queue = [ ] ;
174
+ list = memory = "" ;
181
175
return this ;
182
176
} ,
183
177
disabled : function ( ) {
@@ -188,10 +182,9 @@ jQuery.Callbacks = function( options ) {
188
182
// Also disable .add unless we have memory (since it would have no effect)
189
183
// Abort any pending executions
190
184
lock : function ( ) {
191
- stack = undefined ;
192
- locked = true ;
185
+ locked = queue = [ ] ;
193
186
if ( ! memory && ! firing ) {
194
- self . disable ( ) ;
187
+ list = memory = "" ;
195
188
}
196
189
return this ;
197
190
} ,
@@ -204,10 +197,9 @@ jQuery.Callbacks = function( options ) {
204
197
if ( ! locked ) {
205
198
args = args || [ ] ;
206
199
args = [ context , args . slice ? args . slice ( ) : args ] ;
207
- if ( firing ) {
208
- stack . push ( args ) ;
209
- } else {
210
- fire ( args ) ;
200
+ queue . push ( args ) ;
201
+ if ( ! firing ) {
202
+ fire ( ) ;
211
203
}
212
204
}
213
205
return this ;
0 commit comments