tuiHoneyPot

front and back end of my TUI honeypot
Log | Files | Refs | README

callbacks.js (5552B)


      1 define( [
      2 	"./core",
      3 	"./core/toType",
      4 	"./var/isFunction",
      5 	"./var/rnothtmlwhite"
      6 ], function( jQuery, toType, isFunction, rnothtmlwhite ) {
      7 
      8 "use strict";
      9 
     10 // Convert String-formatted options into Object-formatted ones
     11 function createOptions( options ) {
     12 	var object = {};
     13 	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
     14 		object[ flag ] = true;
     15 	} );
     16 	return object;
     17 }
     18 
     19 /*
     20  * Create a callback list using the following parameters:
     21  *
     22  *	options: an optional list of space-separated options that will change how
     23  *			the callback list behaves or a more traditional option object
     24  *
     25  * By default a callback list will act like an event callback list and can be
     26  * "fired" multiple times.
     27  *
     28  * Possible options:
     29  *
     30  *	once:			will ensure the callback list can only be fired once (like a Deferred)
     31  *
     32  *	memory:			will keep track of previous values and will call any callback added
     33  *					after the list has been fired right away with the latest "memorized"
     34  *					values (like a Deferred)
     35  *
     36  *	unique:			will ensure a callback can only be added once (no duplicate in the list)
     37  *
     38  *	stopOnFalse:	interrupt callings when a callback returns false
     39  *
     40  */
     41 jQuery.Callbacks = function( options ) {
     42 
     43 	// Convert options from String-formatted to Object-formatted if needed
     44 	// (we check in cache first)
     45 	options = typeof options === "string" ?
     46 		createOptions( options ) :
     47 		jQuery.extend( {}, options );
     48 
     49 	var // Flag to know if list is currently firing
     50 		firing,
     51 
     52 		// Last fire value for non-forgettable lists
     53 		memory,
     54 
     55 		// Flag to know if list was already fired
     56 		fired,
     57 
     58 		// Flag to prevent firing
     59 		locked,
     60 
     61 		// Actual callback list
     62 		list = [],
     63 
     64 		// Queue of execution data for repeatable lists
     65 		queue = [],
     66 
     67 		// Index of currently firing callback (modified by add/remove as needed)
     68 		firingIndex = -1,
     69 
     70 		// Fire callbacks
     71 		fire = function() {
     72 
     73 			// Enforce single-firing
     74 			locked = locked || options.once;
     75 
     76 			// Execute callbacks for all pending executions,
     77 			// respecting firingIndex overrides and runtime changes
     78 			fired = firing = true;
     79 			for ( ; queue.length; firingIndex = -1 ) {
     80 				memory = queue.shift();
     81 				while ( ++firingIndex < list.length ) {
     82 
     83 					// Run callback and check for early termination
     84 					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
     85 						options.stopOnFalse ) {
     86 
     87 						// Jump to end and forget the data so .add doesn't re-fire
     88 						firingIndex = list.length;
     89 						memory = false;
     90 					}
     91 				}
     92 			}
     93 
     94 			// Forget the data if we're done with it
     95 			if ( !options.memory ) {
     96 				memory = false;
     97 			}
     98 
     99 			firing = false;
    100 
    101 			// Clean up if we're done firing for good
    102 			if ( locked ) {
    103 
    104 				// Keep an empty list if we have data for future add calls
    105 				if ( memory ) {
    106 					list = [];
    107 
    108 				// Otherwise, this object is spent
    109 				} else {
    110 					list = "";
    111 				}
    112 			}
    113 		},
    114 
    115 		// Actual Callbacks object
    116 		self = {
    117 
    118 			// Add a callback or a collection of callbacks to the list
    119 			add: function() {
    120 				if ( list ) {
    121 
    122 					// If we have memory from a past run, we should fire after adding
    123 					if ( memory && !firing ) {
    124 						firingIndex = list.length - 1;
    125 						queue.push( memory );
    126 					}
    127 
    128 					( function add( args ) {
    129 						jQuery.each( args, function( _, arg ) {
    130 							if ( isFunction( arg ) ) {
    131 								if ( !options.unique || !self.has( arg ) ) {
    132 									list.push( arg );
    133 								}
    134 							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
    135 
    136 								// Inspect recursively
    137 								add( arg );
    138 							}
    139 						} );
    140 					} )( arguments );
    141 
    142 					if ( memory && !firing ) {
    143 						fire();
    144 					}
    145 				}
    146 				return this;
    147 			},
    148 
    149 			// Remove a callback from the list
    150 			remove: function() {
    151 				jQuery.each( arguments, function( _, arg ) {
    152 					var index;
    153 					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
    154 						list.splice( index, 1 );
    155 
    156 						// Handle firing indexes
    157 						if ( index <= firingIndex ) {
    158 							firingIndex--;
    159 						}
    160 					}
    161 				} );
    162 				return this;
    163 			},
    164 
    165 			// Check if a given callback is in the list.
    166 			// If no argument is given, return whether or not list has callbacks attached.
    167 			has: function( fn ) {
    168 				return fn ?
    169 					jQuery.inArray( fn, list ) > -1 :
    170 					list.length > 0;
    171 			},
    172 
    173 			// Remove all callbacks from the list
    174 			empty: function() {
    175 				if ( list ) {
    176 					list = [];
    177 				}
    178 				return this;
    179 			},
    180 
    181 			// Disable .fire and .add
    182 			// Abort any current/pending executions
    183 			// Clear all callbacks and values
    184 			disable: function() {
    185 				locked = queue = [];
    186 				list = memory = "";
    187 				return this;
    188 			},
    189 			disabled: function() {
    190 				return !list;
    191 			},
    192 
    193 			// Disable .fire
    194 			// Also disable .add unless we have memory (since it would have no effect)
    195 			// Abort any pending executions
    196 			lock: function() {
    197 				locked = queue = [];
    198 				if ( !memory && !firing ) {
    199 					list = memory = "";
    200 				}
    201 				return this;
    202 			},
    203 			locked: function() {
    204 				return !!locked;
    205 			},
    206 
    207 			// Call all callbacks with the given context and arguments
    208 			fireWith: function( context, args ) {
    209 				if ( !locked ) {
    210 					args = args || [];
    211 					args = [ context, args.slice ? args.slice() : args ];
    212 					queue.push( args );
    213 					if ( !firing ) {
    214 						fire();
    215 					}
    216 				}
    217 				return this;
    218 			},
    219 
    220 			// Call all the callbacks with the given arguments
    221 			fire: function() {
    222 				self.fireWith( this, arguments );
    223 				return this;
    224 			},
    225 
    226 			// To know if the callbacks have already been called at least once
    227 			fired: function() {
    228 				return !!fired;
    229 			}
    230 		};
    231 
    232 	return self;
    233 };
    234 
    235 return jQuery;
    236 } );