1 // String to Object options format cache
4 // Convert String-formatted options into Object-formatted ones and store in cache
5 function createOptions( options ) {
6 var object = optionsCache[ options ] = {};
7 jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
14 * Create a callback list using the following parameters:
16 * options: an optional list of space-separated options that will change how
17 * the callback list behaves or a more traditional option object
19 * By default a callback list will act like an event callback list and can be
20 * "fired" multiple times.
24 * once: will ensure the callback list can only be fired once (like a Deferred)
26 * memory: will keep track of previous values and will call any callback added
27 * after the list has been fired right away with the latest "memorized"
28 * values (like a Deferred)
30 * unique: will ensure a callback can only be added once (no duplicate in the list)
32 * stopOnFalse: interrupt callings when a callback returns false
35 jQuery.Callbacks = function( options ) {
37 // Convert options from String-formatted to Object-formatted if needed
38 // (we check in cache first)
39 options = typeof options === "string" ?
40 ( optionsCache[ options ] || createOptions( options ) ) :
41 jQuery.extend( {}, options );
43 var // Flag to know if list is currently firing
45 // Last fire value (for non-forgettable lists)
47 // Flag to know if list was already fired
49 // End of the loop when firing
51 // Index of currently firing callback (modified by remove if needed)
53 // First callback to fire (used internally by add and fireWith)
55 // Actual callback list
57 // Stack of fire calls for repeatable lists
58 stack = !options.once && [],
60 fire = function( data ) {
61 memory = options.memory && data;
63 firingIndex = firingStart || 0;
65 firingLength = list.length;
67 for ( ; list && firingIndex < firingLength; firingIndex++ ) {
68 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
69 memory = false; // To prevent further calls using add
77 fire( stack.shift() );
79 } else if ( memory ) {
86 // Actual Callbacks object
88 // Add a callback or a collection of callbacks to the list
91 // First, we save the current length
92 var start = list.length;
93 (function add( args ) {
94 jQuery.each( args, function( _, arg ) {
95 var type = jQuery.type( arg );
96 if ( type === "function" ) {
97 if ( !options.unique || !self.has( arg ) ) {
100 } else if ( arg && arg.length && type !== "string" ) {
101 // Inspect recursively
106 // Do we need to add the callbacks to the
107 // current firing batch?
109 firingLength = list.length;
110 // With memory, if we're not firing then
111 // we should call right away
112 } else if ( memory ) {
119 // Remove a callback from the list
122 jQuery.each( arguments, function( _, arg ) {
124 while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
125 list.splice( index, 1 );
126 // Handle firing indexes
128 if ( index <= firingLength ) {
131 if ( index <= firingIndex ) {
140 // Check if a given callback is in the list.
141 // If no argument is given, return whether or not list has callbacks attached.
142 has: function( fn ) {
143 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
145 // Remove all callbacks from the list
151 // Have the list do nothing anymore
152 disable: function() {
153 list = stack = memory = undefined;
157 disabled: function() {
160 // Lock the list in its current state
172 // Call all callbacks with the given context and arguments
173 fireWith: function( context, args ) {
175 args = [ context, args.slice ? args.slice() : args ];
176 if ( list && ( !fired || stack ) ) {
185 // Call all the callbacks with the given arguments
187 self.fireWith( this, arguments );
190 // To know if the callbacks have already been called at least once