1 import { jQuery } from "./core.js";
2 import { toType } from "./core/toType.js";
3 import { rnothtmlwhite } from "./var/rnothtmlwhite.js";
5 // Convert String-formatted options into Object-formatted ones
6 function createOptions( options ) {
8 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
15 * Create a callback list using the following parameters:
17 * options: an optional list of space-separated options that will change how
18 * the callback list behaves or a more traditional option object
20 * By default a callback list will act like an event callback list and can be
21 * "fired" multiple times.
25 * once: will ensure the callback list can only be fired once (like a Deferred)
27 * memory: will keep track of previous values and will call any callback added
28 * after the list has been fired right away with the latest "memorized"
29 * values (like a Deferred)
31 * unique: will ensure a callback can only be added once (no duplicate in the list)
33 * stopOnFalse: interrupt callings when a callback returns false
36 jQuery.Callbacks = function( options ) {
38 // Convert options from String-formatted to Object-formatted if needed
39 // (we check in cache first)
40 options = typeof options === "string" ?
41 createOptions( options ) :
42 jQuery.extend( {}, options );
44 var // Flag to know if list is currently firing
47 // Last fire value for non-forgettable lists
50 // Flag to know if list was already fired
53 // Flag to prevent firing
56 // Actual callback list
59 // Queue of execution data for repeatable lists
62 // Index of currently firing callback (modified by add/remove as needed)
68 // Enforce single-firing
69 locked = locked || options.once;
71 // Execute callbacks for all pending executions,
72 // respecting firingIndex overrides and runtime changes
73 fired = firing = true;
74 for ( ; queue.length; firingIndex = -1 ) {
75 memory = queue.shift();
76 while ( ++firingIndex < list.length ) {
78 // Run callback and check for early termination
79 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
80 options.stopOnFalse ) {
82 // Jump to end and forget the data so .add doesn't re-fire
83 firingIndex = list.length;
89 // Forget the data if we're done with it
90 if ( !options.memory ) {
96 // Clean up if we're done firing for good
99 // Keep an empty list if we have data for future add calls
103 // Otherwise, this object is spent
110 // Actual Callbacks object
113 // Add a callback or a collection of callbacks to the list
117 // If we have memory from a past run, we should fire after adding
118 if ( memory && !firing ) {
119 firingIndex = list.length - 1;
120 queue.push( memory );
123 ( function add( args ) {
124 jQuery.each( args, function( _, arg ) {
125 if ( typeof arg === "function" ) {
126 if ( !options.unique || !self.has( arg ) ) {
129 } else if ( arg && arg.length && toType( arg ) !== "string" ) {
131 // Inspect recursively
137 if ( memory && !firing ) {
144 // Remove a callback from the list
146 jQuery.each( arguments, function( _, arg ) {
148 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
149 list.splice( index, 1 );
151 // Handle firing indexes
152 if ( index <= firingIndex ) {
160 // Check if a given callback is in the list.
161 // If no argument is given, return whether or not list has callbacks attached.
162 has: function( fn ) {
164 jQuery.inArray( fn, list ) > -1 :
168 // Remove all callbacks from the list
176 // Disable .fire and .add
177 // Abort any current/pending executions
178 // Clear all callbacks and values
179 disable: function() {
184 disabled: function() {
189 // Also disable .add unless we have memory (since it would have no effect)
190 // Abort any pending executions
193 if ( !memory && !firing ) {
202 // Call all callbacks with the given context and arguments
203 fireWith: function( context, args ) {
206 args = [ context, args.slice ? args.slice() : args ];
215 // Call all the callbacks with the given arguments
217 self.fireWith( this, arguments );
221 // To know if the callbacks have already been called at least once
230 export { jQuery, jQuery as $ };