@@ -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,132 +39,129 @@ 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 ,
50- // Last fire value ( for non-forgettable lists)
47+ // Last fire value for non-forgettable lists
5148 memory ,
5249 // Flag to know if list was already fired
5350 fired ,
54- // Flag to prevent .fire/.fireWith
51+ // Flag to prevent firing
5552 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 ,
6253 // Actual callback list
6354 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 ,
6659 // Fire callbacks
67- fire = function ( data ) {
60+ fire = function ( ) {
61+
62+ // Enforce single-firing
6863 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+ }
8180 }
8281 }
83- firing = false ;
8482
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+ }
8787
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 ) {
9392
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 ) {
9695 list = [ ] ;
9796
98- // Else, disable
97+ // Otherwise, this object is spent
9998 } else {
100- self . disable ( ) ;
99+ list = "" ;
101100 }
102101 }
103102 } ,
103+
104104 // Actual Callbacks object
105105 self = {
106+
106107 // Add a callback or a collection of callbacks to the list
107108 add : function ( ) {
108109 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+
111117 ( function add ( args ) {
112118 jQuery . each ( args , function ( _ , arg ) {
113- var type = jQuery . type ( arg ) ;
114- if ( type === "function" ) {
119+ if ( jQuery . isFunction ( arg ) ) {
115120 if ( ! options . unique || ! self . has ( arg ) ) {
116121 list . push ( arg ) ;
117122 }
118- } else if ( arg && arg . length && type !== "string" ) {
123+ } else if ( arg && arg . length && jQuery . type ( arg ) !== "string" ) {
119124 // Inspect recursively
120125 add ( arg ) ;
121126 }
122127 } ) ;
123128 } ) ( 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 ( ) ;
133132 }
134133 }
135134 return this ;
136135 } ,
137136
138137 // Remove a callback from the list
139138 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 -- ;
154147 }
155- } ) ;
156- }
148+ }
149+ } ) ;
157150 return this ;
158151 } ,
159152
160153 // Check if a given callback is in the list.
161154 // If no argument is given, return whether or not list has callbacks attached.
162155 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 ;
164159 } ,
165160
166161 // Remove all callbacks from the list
167162 empty : function ( ) {
168163 if ( list ) {
169164 list = [ ] ;
170- firingLength = 0 ;
171165 }
172166 return this ;
173167 } ,
@@ -176,8 +170,8 @@ jQuery.Callbacks = function( options ) {
176170 // Abort any current/pending executions
177171 // Clear all callbacks and values
178172 disable : function ( ) {
179- list = stack = memory = undefined ;
180- locked = true ;
173+ locked = queue = [ ] ;
174+ list = memory = "" ;
181175 return this ;
182176 } ,
183177 disabled : function ( ) {
@@ -188,10 +182,9 @@ jQuery.Callbacks = function( options ) {
188182 // Also disable .add unless we have memory (since it would have no effect)
189183 // Abort any pending executions
190184 lock : function ( ) {
191- stack = undefined ;
192- locked = true ;
185+ locked = queue = [ ] ;
193186 if ( ! memory && ! firing ) {
194- self . disable ( ) ;
187+ list = memory = "" ;
195188 }
196189 return this ;
197190 } ,
@@ -204,10 +197,9 @@ jQuery.Callbacks = function( options ) {
204197 if ( ! locked ) {
205198 args = args || [ ] ;
206199 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 ( ) ;
211203 }
212204 }
213205 return this ;
0 commit comments