X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6e39d509471fe9b4e2660e0d1631b350d0c66f40..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/docs/source/Function.html diff --git a/docs/source/Function.html b/docs/source/Function.html new file mode 100644 index 00000000..985c297d --- /dev/null +++ b/docs/source/Function.html @@ -0,0 +1,374 @@ +
\ No newline at end of file/** + * @class Ext.Function + * + * A collection of useful static methods to deal with function callbacks + * @singleton + */ + +Ext.Function = { + + /** + * A very commonly used method throughout the framework. It acts as a wrapper around another method + * which originally accepts 2 arguments for <code>name</code> and <code>value</code>. + * The wrapped function then allows "flexible" value setting of either: + * + * <ul> + * <li><code>name</code> and <code>value</code> as 2 arguments</li> + * <li>one single object argument with multiple key - value pairs</li> + * </ul> + * + * For example: + * <pre><code> +var setValue = Ext.Function.flexSetter(function(name, value) { + this[name] = value; +}); + +// Afterwards +// Setting a single name - value +setValue('name1', 'value1'); + +// Settings multiple name - value pairs +setValue({ + name1: 'value1', + name2: 'value2', + name3: 'value3' +}); + * </code></pre> + * @param {Function} setter + * @returns {Function} flexSetter + */ + flexSetter: function(fn) { + return function(a, b) { + var k, i; + + if (a === null) { + return this; + } + + if (typeof a !== 'string') { + for (k in a) { + if (a.hasOwnProperty(k)) { + fn.call(this, k, a[k]); + } + } + + if (Ext.enumerables) { + for (i = Ext.enumerables.length; i--;) { + k = Ext.enumerables[i]; + if (a.hasOwnProperty(k)) { + fn.call(this, k, a[k]); + } + } + } + } else { + fn.call(this, a, b); + } + + return this; + }; + }, + + /** + * Create a new function from the provided <code>fn</code>, change <code>this</code> to the provided scope, optionally + * overrides arguments for the call. (Defaults to the arguments passed by the caller) + * + * @param {Function} fn The function to delegate. + * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed. + * <b>If omitted, defaults to the browser window.</b> + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Function} The new function + */ + bind: function(fn, scope, args, appendArgs) { + var method = fn, + applyArgs; + + return function() { + var callArgs = args || arguments; + + if (appendArgs === true) { + callArgs = Array.prototype.slice.call(arguments, 0); + callArgs = callArgs.concat(args); + } + else if (Ext.isNumber(appendArgs)) { + callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first + applyArgs = [appendArgs, 0].concat(args); // create method call params + Array.prototype.splice.apply(callArgs, applyArgs); // splice them in + } + + return method.apply(scope || window, callArgs); + }; + }, + + /** + * Create a new function from the provided <code>fn</code>, the arguments of which are pre-set to `args`. + * New arguments passed to the newly created callback when it's invoked are appended after the pre-set ones. + * This is especially useful when creating callbacks. + * For example: + * + var originalFunction = function(){ + alert(Ext.Array.from(arguments).join(' ')); + }; + + var callback = Ext.Function.pass(originalFunction, ['Hello', 'World']); + + callback(); // alerts 'Hello World' + callback('by Me'); // alerts 'Hello World by Me' + + * @param {Function} fn The original function + * @param {Array} args The arguments to pass to new callback + * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed. + * @return {Function} The new callback function + */ + pass: function(fn, args, scope) { + if (args) { + args = Ext.Array.from(args); + } + + return function() { + return fn.apply(scope, args.concat(Ext.Array.toArray(arguments))); + }; + }, + + /** + * Create an alias to the provided method property with name <code>methodName</code> of <code>object</code>. + * Note that the execution scope will still be bound to the provided <code>object</code> itself. + * + * @param {Object/Function} object + * @param {String} methodName + * @return {Function} aliasFn + */ + alias: function(object, methodName) { + return function() { + return object[methodName].apply(object, arguments); + }; + }, + + /** + * Creates an interceptor function. The passed function is called before the original one. If it returns false, + * the original one is not called. The resulting function returns the results of the original function. + * The passed function is called with the parameters of the original function. Example usage: + * <pre><code> +var sayHi = function(name){ + alert('Hi, ' + name); +} + +sayHi('Fred'); // alerts "Hi, Fred" + +// create a new function that validates input without +// directly modifying the original function: +var sayHiToFriend = Ext.Function.createInterceptor(sayHi, function(name){ + return name == 'Brian'; +}); + +sayHiToFriend('Fred'); // no alert +sayHiToFriend('Brian'); // alerts "Hi, Brian" + </code></pre> + * @param {Function} origFn The original function. + * @param {Function} newFn The function to call before the original + * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed. + * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b> + * @param {Mixed} returnValue (optional) The value to return if the passed function return false (defaults to null). + * @return {Function} The new function + */ + createInterceptor: function(origFn, newFn, scope, returnValue) { + var method = origFn; + if (!Ext.isFunction(newFn)) { + return origFn; + } + else { + return function() { + var me = this, + args = arguments; + newFn.target = me; + newFn.method = origFn; + return (newFn.apply(scope || me || window, args) !== false) ? origFn.apply(me || window, args) : returnValue || null; + }; + } + }, + + /** + * Creates a delegate (callback) which, when called, executes after a specific delay. + * @param {Function} fn The function which will be called on a delay when the returned function is called. + * Optionally, a replacement (or additional) argument list may be specified. + * @param {Number} delay The number of milliseconds to defer execution by whenever called. + * @param {Object} scope (optional) The scope (<code>this</code> reference) used by the function at execution time. + * @param {Array} args (optional) Override arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position. + * @return {Function} A function which, when called, executes the original function after the specified delay. + */ + createDelayed: function(fn, delay, scope, args, appendArgs) { + if (scope || args) { + fn = Ext.Function.bind(fn, scope, args, appendArgs); + } + return function() { + var me = this; + setTimeout(function() { + fn.apply(me, arguments); + }, delay); + }; + }, + + /** + * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage: + * <pre><code> +var sayHi = function(name){ + alert('Hi, ' + name); +} + +// executes immediately: +sayHi('Fred'); + +// executes after 2 seconds: +Ext.Function.defer(sayHi, 2000, this, ['Fred']); + +// this syntax is sometimes useful for deferring +// execution of an anonymous function: +Ext.Function.defer(function(){ + alert('Anonymous'); +}, 100); + </code></pre> + * @param {Function} fn The function to defer. + * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately) + * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed. + * <b>If omitted, defaults to the browser window.</b> + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Number} The timeout id that can be used with clearTimeout + */ + defer: function(fn, millis, obj, args, appendArgs) { + fn = Ext.Function.bind(fn, obj, args, appendArgs); + if (millis > 0) { + return setTimeout(fn, millis); + } + fn(); + return 0; + }, + + /** + * Create a combined function call sequence of the original function + the passed function. + * The resulting function returns the results of the original function. + * The passed function is called with the parameters of the original function. Example usage: + * + * <pre><code> +var sayHi = function(name){ + alert('Hi, ' + name); +} + +sayHi('Fred'); // alerts "Hi, Fred" + +var sayGoodbye = Ext.Function.createSequence(sayHi, function(name){ + alert('Bye, ' + name); +}); + +sayGoodbye('Fred'); // both alerts show + * </code></pre> + * + * @param {Function} origFn The original function. + * @param {Function} newFn The function to sequence + * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. + * If omitted, defaults to the scope in which the original function is called or the browser window. + * @return {Function} The new function + */ + createSequence: function(origFn, newFn, scope) { + if (!Ext.isFunction(newFn)) { + return origFn; + } + else { + return function() { + var retval = origFn.apply(this || window, arguments); + newFn.apply(scope || this || window, arguments); + return retval; + }; + } + }, + + /** + * <p>Creates a delegate function, optionally with a bound scope which, when called, buffers + * the execution of the passed function for the configured number of milliseconds. + * If called again within that period, the impending invocation will be canceled, and the + * timeout period will begin again.</p> + * + * @param {Function} fn The function to invoke on a buffered timer. + * @param {Number} buffer The number of milliseconds by which to buffer the invocation of the + * function. + * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which + * the passed function is executed. If omitted, defaults to the scope specified by the caller. + * @param {Array} args (optional) Override arguments for the call. Defaults to the arguments + * passed by the caller. + * @return {Function} A function which invokes the passed function after buffering for the specified time. + */ + createBuffered: function(fn, buffer, scope, args) { + return function(){ + var timerId; + return function() { + var me = this; + if (timerId) { + clearInterval(timerId); + timerId = null; + } + timerId = setTimeout(function(){ + fn.apply(scope || me, args || arguments); + }, buffer); + }; + }(); + }, + + /** + * <p>Creates a throttled version of the passed function which, when called repeatedly and + * rapidly, invokes the passed function only after a certain interval has elapsed since the + * previous invocation.</p> + * + * <p>This is useful for wrapping functions which may be called repeatedly, such as + * a handler of a mouse move event when the processing is expensive.</p> + * + * @param fn {Function} The function to execute at a regular time interval. + * @param interval {Number} The interval <b>in milliseconds</b> on which the passed function is executed. + * @param scope (optional) The scope (<code><b>this</b></code> reference) in which + * the passed function is executed. If omitted, defaults to the scope specified by the caller. + * @returns {Function} A function which invokes the passed function at the specified interval. + */ + createThrottled: function(fn, interval, scope) { + var lastCallTime, elapsed, lastArgs, timer, execute = function() { + fn.apply(scope || this, lastArgs); + lastCallTime = new Date().getTime(); + }; + + return function() { + elapsed = new Date().getTime() - lastCallTime; + lastArgs = arguments; + + clearTimeout(timer); + if (!lastCallTime || (elapsed >= interval)) { + execute(); + } else { + timer = setTimeout(execute, interval - elapsed); + } + }; + } +}; + +/** + * Shorthand for {@link Ext.Function#defer} + * @member Ext + * @method defer + */ +Ext.defer = Ext.Function.alias(Ext.Function, 'defer'); + +/** + * Shorthand for {@link Ext.Function#pass} + * @member Ext + * @method pass + */ +Ext.pass = Ext.Function.alias(Ext.Function, 'pass'); + +/** + * Shorthand for {@link Ext.Function#bind} + * @member Ext + * @method bind + */ +Ext.bind = Ext.Function.alias(Ext.Function, 'bind'); +