@@ -3,12 +3,9 @@ define( [
33 "./var/rnotwhite"
44] , function ( jQuery , rnotwhite ) {
55
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
107function createOptions ( options ) {
11- var object = optionsCache [ options ] = { } ;
8+ var object = { } ;
129 jQuery . each ( options . match ( rnotwhite ) || [ ] , function ( _ , flag ) {
1310 object [ flag ] = true ;
1411 } ) ;
@@ -42,71 +39,71 @@ jQuery.Callbacks = function( options ) {
4239 // Convert options from String-formatted to Object-formatted if needed
4340 // (we check in cache first)
4441 options = typeof options === "string" ?
45- ( optionsCache [ options ] || createOptions ( options ) ) :
42+ createOptions ( options ) :
4643 jQuery . extend ( { } , options ) ;
4744
4845 var // Flag to know if list is currently firing
4946 firing ,
5047
51- // Last fire value ( for non-forgettable lists)
48+ // Last fire value for non-forgettable lists
5249 memory ,
5350
5451 // Flag to know if list was already fired
5552 fired ,
5653
57- // Flag to prevent .fire/.fireWith
54+ // Flag to prevent firing
5855 locked ,
5956
60- // End of the loop when firing
61- firingLength ,
62-
63- // Index of currently firing callback (modified by remove if needed)
64- firingIndex ,
65-
66- // First callback to fire (used internally by add and fireWith)
67- firingStart ,
68-
6957 // Actual callback list
7058 list = [ ] ,
7159
72- // Stack of fire calls for repeatable lists
73- stack = ! options . once && [ ] ,
60+ // Queue of execution data for repeatable lists
61+ queue = [ ] ,
62+
63+ // Index of currently firing callback (modified by add/remove as needed)
64+ firingIndex = - 1 ,
7465
7566 // Fire callbacks
76- fire = function ( data ) {
67+ fire = function ( ) {
68+
69+ // Enforce single-firing
7770 locked = options . once ;
78- memory = options . memory && data ;
79- fired = true ;
80- firingIndex = firingStart || 0 ;
81- firingStart = 0 ;
82- firingLength = list . length ;
83- firing = true ;
84- for ( ; list && firingIndex < firingLength ; firingIndex ++ ) {
85- if ( list [ firingIndex ] . apply ( data [ 0 ] , data [ 1 ] ) === false &&
86- options . stopOnFalse ) {
87-
88- memory = false ; // To prevent further calls using add
89- break ;
71+
72+ // Execute callbacks for all pending executions,
73+ // respecting firingIndex overrides and runtime changes
74+ fired = firing = true ;
75+ for ( ; queue . length ; firingIndex = - 1 ) {
76+ memory = queue . shift ( ) ;
77+ while ( ++ firingIndex < list . length ) {
78+
79+ // Run callback and check for early termination
80+ if ( list [ firingIndex ] . apply ( memory [ 0 ] , memory [ 1 ] ) === false &&
81+ options . stopOnFalse ) {
82+
83+ // Jump to end and forget the data so .add doesn't re-fire
84+ firingIndex = list . length ;
85+ memory = false ;
86+ }
9087 }
9188 }
92- firing = false ;
9389
94- // If not disabled,
95- if ( list ) {
90+ // Forget the data if we're done with it
91+ if ( ! options . memory ) {
92+ memory = false ;
93+ }
94+
95+ firing = false ;
9696
97- // If repeatable, check for pending execution
98- if ( stack ) {
99- if ( stack . length ) {
100- fire ( stack . shift ( ) ) ;
101- }
97+ // Clean up if we're done firing for good
98+ if ( locked ) {
10299
103- // If not repeatable but with memory, clear out spent callbacks
104- } else if ( memory ) {
100+ // Keep an empty list if we have data for future add calls
101+ if ( memory ) {
105102 list = [ ] ;
106103
107- // Else, disable
104+ // Otherwise, this object is spent
108105 } else {
109- self . disable ( ) ;
106+ list = "" ;
110107 }
111108 }
112109 } ,
@@ -118,72 +115,61 @@ jQuery.Callbacks = function( options ) {
118115 add : function ( ) {
119116 if ( list ) {
120117
121- // First, we save the current length
122- var start = list . length ;
118+ // If we have memory from a past run, we should fire after adding
119+ if ( memory && ! firing ) {
120+ firingIndex = list . length - 1 ;
121+ queue . push ( memory ) ;
122+ }
123+
123124 ( function add ( args ) {
124125 jQuery . each ( args , function ( _ , arg ) {
125- var type = jQuery . type ( arg ) ;
126- if ( type === "function" ) {
126+ if ( jQuery . isFunction ( arg ) ) {
127127 if ( ! options . unique || ! self . has ( arg ) ) {
128128 list . push ( arg ) ;
129129 }
130- } else if ( arg && arg . length && type !== "string" ) {
130+ } else if ( arg && arg . length && jQuery . type ( arg ) !== "string" ) {
131131
132132 // Inspect recursively
133133 add ( arg ) ;
134134 }
135135 } ) ;
136136 } ) ( arguments ) ;
137137
138- // Do we need to add the callbacks to the
139- // current firing batch?
140- if ( firing ) {
141- firingLength = list . length ;
142-
143- // With memory, if we're not firing then
144- // we should call right away
145- } else if ( memory ) {
146- firingStart = start ;
147- fire ( memory ) ;
138+ if ( memory && ! firing ) {
139+ fire ( ) ;
148140 }
149141 }
150142 return this ;
151143 } ,
152144
153145 // Remove a callback from the list
154146 remove : function ( ) {
155- if ( list ) {
156- jQuery . each ( arguments , function ( _ , arg ) {
157- var index ;
158- while ( ( index = jQuery . inArray ( arg , list , index ) ) > - 1 ) {
159- list . splice ( index , 1 ) ;
160-
161- // Handle firing indexes
162- if ( firing ) {
163- if ( index <= firingLength ) {
164- firingLength -- ;
165- }
166- if ( index <= firingIndex ) {
167- firingIndex -- ;
168- }
169- }
147+ jQuery . each ( arguments , function ( _ , arg ) {
148+ var index ;
149+ while ( ( index = jQuery . inArray ( arg , list , index ) ) > - 1 ) {
150+ list . splice ( index , 1 ) ;
151+
152+ // Handle firing indexes
153+ if ( index <= firingIndex ) {
154+ firingIndex -- ;
170155 }
171- } ) ;
172- }
156+ }
157+ } ) ;
173158 return this ;
174159 } ,
175160
176161 // Check if a given callback is in the list.
177162 // If no argument is given, return whether or not list has callbacks attached.
178163 has : function ( fn ) {
179- return fn ? jQuery . inArray ( fn , list ) > - 1 : ! ! ( list && list . length ) ;
164+ return fn ?
165+ jQuery . inArray ( fn , list ) > - 1 :
166+ list . length > 0 ;
180167 } ,
181168
182169 // Remove all callbacks from the list
183170 empty : function ( ) {
184171 if ( list ) {
185172 list = [ ] ;
186- firingLength = 0 ;
187173 }
188174 return this ;
189175 } ,
@@ -192,8 +178,8 @@ jQuery.Callbacks = function( options ) {
192178 // Abort any current/pending executions
193179 // Clear all callbacks and values
194180 disable : function ( ) {
195- list = stack = memory = undefined ;
196- locked = true ;
181+ locked = queue = [ ] ;
182+ list = memory = "" ;
197183 return this ;
198184 } ,
199185 disabled : function ( ) {
@@ -204,10 +190,9 @@ jQuery.Callbacks = function( options ) {
204190 // Also disable .add unless we have memory (since it would have no effect)
205191 // Abort any pending executions
206192 lock : function ( ) {
207- stack = undefined ;
208- locked = true ;
193+ locked = queue = [ ] ;
209194 if ( ! memory ) {
210- self . disable ( ) ;
195+ list = memory = "" ;
211196 }
212197 return this ;
213198 } ,
@@ -220,10 +205,9 @@ jQuery.Callbacks = function( options ) {
220205 if ( ! locked ) {
221206 args = args || [ ] ;
222207 args = [ context , args . slice ? args . slice ( ) : args ] ;
223- if ( firing ) {
224- stack . push ( args ) ;
225- } else {
226- fire ( args ) ;
208+ queue . push ( args ) ;
209+ if ( ! firing ) {
210+ fire ( ) ;
227211 }
228212 }
229213 return this ;
0 commit comments