4 ], function( jQuery, rnotwhite ) {
6 // String to Object options format cache
9 // Convert String-formatted options into Object-formatted ones and store in cache
10 function createOptions( options ) {
11 var object = optionsCache[ options ] = {};
12 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
13 object[ flag ] = true;
19 * Create a callback list using the following parameters:
21 * options: an optional list of space-separated options that will change how
22 * the callback list behaves or a more traditional option object
24 * By default a callback list will act like an event callback list and can be
25 * "fired" multiple times.
29 * once: will ensure the callback list can only be fired once (like a Deferred)
31 * memory: will keep track of previous values and will call any callback added
32 * after the list has been fired right away with the latest "memorized"
33 * values (like a Deferred)
35 * unique: will ensure a callback can only be added once (no duplicate in the list)
37 * stopOnFalse: interrupt callings when a callback returns false
40 jQuery.Callbacks = function( options ) {
42 // Convert options from String-formatted to Object-formatted if needed
43 // (we check in cache first)
44 options = typeof options === "string" ?
45 ( optionsCache[ options ] || createOptions( options ) ) :
46 jQuery.extend( {}, options );
48 var // Last fire value (for non-forgettable lists)
50 // Flag to know if list was already fired
52 // Flag to know if list is currently firing
54 // First callback to fire (used internally by add and fireWith)
56 // End of the loop when firing
58 // Index of currently firing callback (modified by remove if needed)
60 // Actual callback list
62 // Stack of fire calls for repeatable lists
63 stack = !options.once && [],
65 fire = function( data ) {
66 memory = options.memory && data;
68 firingIndex = firingStart || 0;
70 firingLength = list.length;
72 for ( ; list && firingIndex < firingLength; firingIndex++ ) {
73 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
74 memory = false; // To prevent further calls using add
82 fire( stack.shift() );
84 } else if ( memory ) {
91 // Actual Callbacks object
93 // Add a callback or a collection of callbacks to the list
96 // First, we save the current length
97 var start = list.length;
98 (function add( args ) {
99 jQuery.each( args, function( _, arg ) {
100 var type = jQuery.type( arg );
101 if ( type === "function" ) {
102 if ( !options.unique || !self.has( arg ) ) {
105 } else if ( arg && arg.length && type !== "string" ) {
106 // Inspect recursively
111 // Do we need to add the callbacks to the
112 // current firing batch?
114 firingLength = list.length;
115 // With memory, if we're not firing then
116 // we should call right away
117 } else if ( memory ) {
124 // Remove a callback from the list
127 jQuery.each( arguments, function( _, arg ) {
129 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
130 list.splice( index, 1 );
131 // Handle firing indexes
133 if ( index <= firingLength ) {
136 if ( index <= firingIndex ) {
145 // Check if a given callback is in the list.
146 // If no argument is given, return whether or not list has callbacks attached.
147 has: function( fn ) {
148 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
150 // Remove all callbacks from the list
156 // Have the list do nothing anymore
157 disable: function() {
158 list = stack = memory = undefined;
162 disabled: function() {
165 // Lock the list in its current state
177 // Call all callbacks with the given context and arguments
178 fireWith: function( context, args ) {
179 if ( list && ( !fired || stack ) ) {
181 args = [ context, args.slice ? args.slice() : args ];
190 // Call all the callbacks with the given arguments
192 self.fireWith( this, arguments );
195 // To know if the callbacks have already been called at least once