ffffng/app/bower_components/jquery/src/callbacks.js

237 lines
5.4 KiB
JavaScript
Raw Normal View History

2017-05-13 13:25:33 +02:00
define( [
2014-05-12 20:08:19 +02:00
"./core",
2019-03-29 22:00:08 +01:00
"./core/toType",
"./var/isFunction",
2017-05-13 13:25:33 +02:00
"./var/rnothtmlwhite"
2019-03-29 22:00:08 +01:00
], function( jQuery, toType, isFunction, rnothtmlwhite ) {
2014-05-12 20:08:19 +02:00
2017-05-13 13:25:33 +02:00
"use strict";
2014-05-12 20:08:19 +02:00
2017-05-13 13:25:33 +02:00
// Convert String-formatted options into Object-formatted ones
2014-05-12 20:08:19 +02:00
function createOptions( options ) {
2017-05-13 13:25:33 +02:00
var object = {};
jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
2014-05-12 20:08:19 +02:00
object[ flag ] = true;
2017-05-13 13:25:33 +02:00
} );
2014-05-12 20:08:19 +02:00
return object;
}
/*
* Create a callback list using the following parameters:
*
* options: an optional list of space-separated options that will change how
* the callback list behaves or a more traditional option object
*
* By default a callback list will act like an event callback list and can be
* "fired" multiple times.
*
* Possible options:
*
* once: will ensure the callback list can only be fired once (like a Deferred)
*
* memory: will keep track of previous values and will call any callback added
* after the list has been fired right away with the latest "memorized"
* values (like a Deferred)
*
* unique: will ensure a callback can only be added once (no duplicate in the list)
*
* stopOnFalse: interrupt callings when a callback returns false
*
*/
jQuery.Callbacks = function( options ) {
// Convert options from String-formatted to Object-formatted if needed
// (we check in cache first)
options = typeof options === "string" ?
2017-05-13 13:25:33 +02:00
createOptions( options ) :
2014-05-12 20:08:19 +02:00
jQuery.extend( {}, options );
2017-05-13 13:25:33 +02:00
var // Flag to know if list is currently firing
firing,
// Last fire value for non-forgettable lists
2014-05-12 20:08:19 +02:00
memory,
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Flag to know if list was already fired
fired,
2017-05-13 13:25:33 +02:00
// Flag to prevent firing
locked,
2014-05-12 20:08:19 +02:00
// Actual callback list
list = [],
2017-05-13 13:25:33 +02:00
// Queue of execution data for repeatable lists
queue = [],
// Index of currently firing callback (modified by add/remove as needed)
firingIndex = -1,
2014-05-12 20:08:19 +02:00
// Fire callbacks
2017-05-13 13:25:33 +02:00
fire = function() {
// Enforce single-firing
locked = locked || options.once;
// Execute callbacks for all pending executions,
// respecting firingIndex overrides and runtime changes
fired = firing = true;
for ( ; queue.length; firingIndex = -1 ) {
memory = queue.shift();
while ( ++firingIndex < list.length ) {
// Run callback and check for early termination
if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
options.stopOnFalse ) {
// Jump to end and forget the data so .add doesn't re-fire
firingIndex = list.length;
memory = false;
}
2014-05-12 20:08:19 +02:00
}
}
2017-05-13 13:25:33 +02:00
// Forget the data if we're done with it
if ( !options.memory ) {
memory = false;
}
2014-05-12 20:08:19 +02:00
firing = false;
2017-05-13 13:25:33 +02:00
// Clean up if we're done firing for good
if ( locked ) {
// Keep an empty list if we have data for future add calls
if ( memory ) {
2014-05-12 20:08:19 +02:00
list = [];
2017-05-13 13:25:33 +02:00
// Otherwise, this object is spent
2014-05-12 20:08:19 +02:00
} else {
2017-05-13 13:25:33 +02:00
list = "";
2014-05-12 20:08:19 +02:00
}
}
},
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Actual Callbacks object
self = {
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Add a callback or a collection of callbacks to the list
add: function() {
if ( list ) {
2017-05-13 13:25:33 +02:00
// If we have memory from a past run, we should fire after adding
if ( memory && !firing ) {
firingIndex = list.length - 1;
queue.push( memory );
}
( function add( args ) {
2014-05-12 20:08:19 +02:00
jQuery.each( args, function( _, arg ) {
2019-03-29 22:00:08 +01:00
if ( isFunction( arg ) ) {
2014-05-12 20:08:19 +02:00
if ( !options.unique || !self.has( arg ) ) {
list.push( arg );
}
2019-03-29 22:00:08 +01:00
} else if ( arg && arg.length && toType( arg ) !== "string" ) {
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Inspect recursively
add( arg );
}
2017-05-13 13:25:33 +02:00
} );
} )( arguments );
if ( memory && !firing ) {
fire();
2014-05-12 20:08:19 +02:00
}
}
return this;
},
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Remove a callback from the list
remove: function() {
2017-05-13 13:25:33 +02:00
jQuery.each( arguments, function( _, arg ) {
var index;
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
list.splice( index, 1 );
// Handle firing indexes
if ( index <= firingIndex ) {
firingIndex--;
2014-05-12 20:08:19 +02:00
}
2017-05-13 13:25:33 +02:00
}
} );
2014-05-12 20:08:19 +02:00
return this;
},
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Check if a given callback is in the list.
// If no argument is given, return whether or not list has callbacks attached.
has: function( fn ) {
2017-05-13 13:25:33 +02:00
return fn ?
jQuery.inArray( fn, list ) > -1 :
list.length > 0;
2014-05-12 20:08:19 +02:00
},
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Remove all callbacks from the list
empty: function() {
2017-05-13 13:25:33 +02:00
if ( list ) {
list = [];
}
2014-05-12 20:08:19 +02:00
return this;
},
2017-05-13 13:25:33 +02:00
// Disable .fire and .add
// Abort any current/pending executions
// Clear all callbacks and values
2014-05-12 20:08:19 +02:00
disable: function() {
2017-05-13 13:25:33 +02:00
locked = queue = [];
list = memory = "";
2014-05-12 20:08:19 +02:00
return this;
},
disabled: function() {
return !list;
},
2017-05-13 13:25:33 +02:00
// Disable .fire
// Also disable .add unless we have memory (since it would have no effect)
// Abort any pending executions
2014-05-12 20:08:19 +02:00
lock: function() {
2017-05-13 13:25:33 +02:00
locked = queue = [];
if ( !memory && !firing ) {
list = memory = "";
2014-05-12 20:08:19 +02:00
}
return this;
},
locked: function() {
2017-05-13 13:25:33 +02:00
return !!locked;
2014-05-12 20:08:19 +02:00
},
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Call all callbacks with the given context and arguments
fireWith: function( context, args ) {
2017-05-13 13:25:33 +02:00
if ( !locked ) {
2014-05-12 20:08:19 +02:00
args = args || [];
args = [ context, args.slice ? args.slice() : args ];
2017-05-13 13:25:33 +02:00
queue.push( args );
if ( !firing ) {
fire();
2014-05-12 20:08:19 +02:00
}
}
return this;
},
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// Call all the callbacks with the given arguments
fire: function() {
self.fireWith( this, arguments );
return this;
},
2017-05-13 13:25:33 +02:00
2014-05-12 20:08:19 +02:00
// To know if the callbacks have already been called at least once
fired: function() {
return !!fired;
}
};
return self;
};
return jQuery;
2017-05-13 13:25:33 +02:00
} );