mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Callbacks: Reduce size
This commit is contained in:
parent
fc7477f492
commit
18baae2efb
134
src/callbacks.js
134
src/callbacks.js
@ -3,12 +3,9 @@ define([
|
|||||||
"./var/rnotwhite"
|
"./var/rnotwhite"
|
||||||
], function( jQuery, rnotwhite ) {
|
], function( jQuery, rnotwhite ) {
|
||||||
|
|
||||||
// String to Object options format cache
|
// Convert String-formatted options into Object-formatted ones
|
||||||
var optionsCache = {};
|
|
||||||
|
|
||||||
// Convert String-formatted options into Object-formatted ones and store in cache
|
|
||||||
function createOptions( options ) {
|
function createOptions( options ) {
|
||||||
var object = optionsCache[ options ] = {};
|
var object = {};
|
||||||
jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
|
jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
|
||||||
object[ flag ] = true;
|
object[ flag ] = true;
|
||||||
});
|
});
|
||||||
@ -42,94 +39,96 @@ jQuery.Callbacks = function( options ) {
|
|||||||
// Convert options from String-formatted to Object-formatted if needed
|
// Convert options from String-formatted to Object-formatted if needed
|
||||||
// (we check in cache first)
|
// (we check in cache first)
|
||||||
options = typeof options === "string" ?
|
options = typeof options === "string" ?
|
||||||
( optionsCache[ options ] || createOptions( options ) ) :
|
createOptions( options ) :
|
||||||
jQuery.extend( {}, options );
|
jQuery.extend( {}, options );
|
||||||
|
|
||||||
var // Flag to know if list is currently firing
|
var // Flag to know if list is currently firing
|
||||||
firing,
|
firing,
|
||||||
// Last fire value (for non-forgettable lists)
|
// Last fire value for non-forgettable lists
|
||||||
memory,
|
memory,
|
||||||
// Flag to know if list was already fired
|
// Flag to know if list was already fired
|
||||||
fired,
|
fired,
|
||||||
// Flag to prevent .fire/.fireWith
|
// Flag to prevent firing
|
||||||
locked,
|
locked,
|
||||||
// End of the loop when firing
|
|
||||||
firingLength,
|
|
||||||
// Index of currently firing callback (modified by remove if needed)
|
|
||||||
firingIndex,
|
|
||||||
// First callback to fire (used internally by add and fireWith)
|
|
||||||
firingStart,
|
|
||||||
// Actual callback list
|
// Actual callback list
|
||||||
list = [],
|
list = [],
|
||||||
// Stack of fire calls for repeatable lists
|
// Queue of execution data for repeatable lists
|
||||||
stack = !options.once && [],
|
queue = [],
|
||||||
|
// Index of currently firing callback (modified by add/remove as needed)
|
||||||
|
firingIndex = -1,
|
||||||
// Fire callbacks
|
// Fire callbacks
|
||||||
fire = function( data ) {
|
fire = function() {
|
||||||
|
|
||||||
|
// Enforce single-firing
|
||||||
locked = options.once;
|
locked = options.once;
|
||||||
memory = options.memory && data;
|
|
||||||
fired = true;
|
// Execute callbacks for all pending executions,
|
||||||
firingIndex = firingStart || 0;
|
// respecting firingIndex overrides and runtime changes
|
||||||
firingStart = 0;
|
fired = firing = true;
|
||||||
firingLength = list.length;
|
for ( ; queue.length; firingIndex = -1 ) {
|
||||||
firing = true;
|
memory = queue.shift();
|
||||||
for ( ; list && firingIndex < firingLength; firingIndex++ ) {
|
while ( ++firingIndex < list.length ) {
|
||||||
if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false &&
|
|
||||||
|
// Run callback and check for early termination
|
||||||
|
if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
|
||||||
options.stopOnFalse ) {
|
options.stopOnFalse ) {
|
||||||
|
|
||||||
memory = false; // To prevent further calls using add
|
// Jump to end and forget the data so .add doesn't re-fire
|
||||||
break;
|
firingIndex = list.length;
|
||||||
|
memory = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forget the data if we're done with it
|
||||||
|
if ( !options.memory ) {
|
||||||
|
memory = false;
|
||||||
|
}
|
||||||
|
|
||||||
firing = false;
|
firing = false;
|
||||||
|
|
||||||
// If not disabled,
|
// Clean up if we're done firing for good
|
||||||
if ( list ) {
|
if ( locked ) {
|
||||||
|
|
||||||
// If repeatable, check for pending execution
|
// Keep an empty list if we have data for future add calls
|
||||||
if ( stack ) {
|
if ( memory ) {
|
||||||
if ( stack.length ) {
|
|
||||||
fire( stack.shift() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not repeatable but with memory, clear out spent callbacks
|
|
||||||
} else if ( memory ) {
|
|
||||||
list = [];
|
list = [];
|
||||||
|
|
||||||
// Else, disable
|
// Otherwise, this object is spent
|
||||||
} else {
|
} else {
|
||||||
self.disable();
|
list = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Actual Callbacks object
|
// Actual Callbacks object
|
||||||
self = {
|
self = {
|
||||||
|
|
||||||
// Add a callback or a collection of callbacks to the list
|
// Add a callback or a collection of callbacks to the list
|
||||||
add: function() {
|
add: function() {
|
||||||
if ( list ) {
|
if ( list ) {
|
||||||
// First, we save the current length
|
|
||||||
var start = list.length;
|
// 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 ) {
|
(function add( args ) {
|
||||||
jQuery.each( args, function( _, arg ) {
|
jQuery.each( args, function( _, arg ) {
|
||||||
var type = jQuery.type( arg );
|
if ( jQuery.isFunction( arg ) ) {
|
||||||
if ( type === "function" ) {
|
|
||||||
if ( !options.unique || !self.has( arg ) ) {
|
if ( !options.unique || !self.has( arg ) ) {
|
||||||
list.push( arg );
|
list.push( arg );
|
||||||
}
|
}
|
||||||
} else if ( arg && arg.length && type !== "string" ) {
|
} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
|
||||||
// Inspect recursively
|
// Inspect recursively
|
||||||
add( arg );
|
add( arg );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})( arguments );
|
})( arguments );
|
||||||
// Do we need to add the callbacks to the
|
|
||||||
// current firing batch?
|
if ( memory && !firing ) {
|
||||||
if ( firing ) {
|
fire();
|
||||||
firingLength = list.length;
|
|
||||||
// With memory, if we're not firing then
|
|
||||||
// we should call right away
|
|
||||||
} else if ( memory ) {
|
|
||||||
firingStart = start;
|
|
||||||
fire( memory );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@ -137,37 +136,32 @@ jQuery.Callbacks = function( options ) {
|
|||||||
|
|
||||||
// Remove a callback from the list
|
// Remove a callback from the list
|
||||||
remove: function() {
|
remove: function() {
|
||||||
if ( list ) {
|
|
||||||
jQuery.each( arguments, function( _, arg ) {
|
jQuery.each( arguments, function( _, arg ) {
|
||||||
var index;
|
var index;
|
||||||
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
|
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
|
||||||
list.splice( index, 1 );
|
list.splice( index, 1 );
|
||||||
|
|
||||||
// Handle firing indexes
|
// Handle firing indexes
|
||||||
if ( firing ) {
|
|
||||||
if ( index <= firingLength ) {
|
|
||||||
firingLength--;
|
|
||||||
}
|
|
||||||
if ( index <= firingIndex ) {
|
if ( index <= firingIndex ) {
|
||||||
firingIndex--;
|
firingIndex--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Check if a given callback is in the list.
|
// Check if a given callback is in the list.
|
||||||
// If no argument is given, return whether or not list has callbacks attached.
|
// If no argument is given, return whether or not list has callbacks attached.
|
||||||
has: function( fn ) {
|
has: function( fn ) {
|
||||||
return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
|
return fn ?
|
||||||
|
jQuery.inArray( fn, list ) > -1 :
|
||||||
|
list.length > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Remove all callbacks from the list
|
// Remove all callbacks from the list
|
||||||
empty: function() {
|
empty: function() {
|
||||||
if ( list ) {
|
if ( list ) {
|
||||||
list = [];
|
list = [];
|
||||||
firingLength = 0;
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
@ -176,8 +170,8 @@ jQuery.Callbacks = function( options ) {
|
|||||||
// Abort any current/pending executions
|
// Abort any current/pending executions
|
||||||
// Clear all callbacks and values
|
// Clear all callbacks and values
|
||||||
disable: function() {
|
disable: function() {
|
||||||
list = stack = memory = undefined;
|
locked = queue = [];
|
||||||
locked = true;
|
list = memory = "";
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
disabled: function() {
|
disabled: function() {
|
||||||
@ -188,10 +182,9 @@ jQuery.Callbacks = function( options ) {
|
|||||||
// Also disable .add unless we have memory (since it would have no effect)
|
// Also disable .add unless we have memory (since it would have no effect)
|
||||||
// Abort any pending executions
|
// Abort any pending executions
|
||||||
lock: function() {
|
lock: function() {
|
||||||
stack = undefined;
|
locked = queue = [];
|
||||||
locked = true;
|
|
||||||
if ( !memory && !firing ) {
|
if ( !memory && !firing ) {
|
||||||
self.disable();
|
list = memory = "";
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
@ -204,10 +197,9 @@ jQuery.Callbacks = function( options ) {
|
|||||||
if ( !locked ) {
|
if ( !locked ) {
|
||||||
args = args || [];
|
args = args || [];
|
||||||
args = [ context, args.slice ? args.slice() : args ];
|
args = [ context, args.slice ? args.slice() : args ];
|
||||||
if ( firing ) {
|
queue.push( args );
|
||||||
stack.push( args );
|
if ( !firing ) {
|
||||||
} else {
|
fire();
|
||||||
fire( args );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
Loading…
Reference in New Issue
Block a user