Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Function.html
index fdc5d6a..636d6ff 100644 (file)
+<!DOCTYPE html>
 <html>
 <head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>The source code</title>
-    <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
-    <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
+  <script type="text/javascript" src="../prettify/prettify.js"></script>
+  <style type="text/css">
+    .highlight { display: block; background-color: #ddd; }
+  </style>
+  <script type="text/javascript">
+    function highlight() {
+      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+    }
+  </script>
 </head>
-<body  onload="prettyPrint();">
-    <pre class="prettyprint lang-js">/*!
- * Ext JS Library 3.3.0
- * Copyright(c) 2006-2010 Ext JS, Inc.
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
-<div id="cls-Ext.util.Functions"></div>/**
- * @class Ext.util.Functions
+<body onload="prettyPrint(); highlight();">
+  <pre class="prettyprint lang-js"><span id='Ext-Function'>/**
+</span> * @class Ext.Function
+ *
+ * A collection of useful static methods to deal with function callbacks
  * @singleton
  */
-Ext.util.Functions = {
-    <div id="method-Ext.util.Functions-createInterceptor"></div>/**
-     * Creates an interceptor function. The passed function is called before the original one. If it returns false,
+Ext.Function = {
+
+<span id='Ext-Function-method-flexSetter'>    /**
+</span>     * A very commonly used method throughout the framework. It acts as a wrapper around another method
+     * which originally accepts 2 arguments for `name` and `value`.
+     * The wrapped function then allows &quot;flexible&quot; value setting of either:
+     *
+     * - `name` and `value` as 2 arguments
+     * - one single object argument with multiple key - value pairs
+     *
+     * For example:
+     *
+     *     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'
+     *     });
+     *
+     * @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;
+        };
+    },
+
+<span id='Ext-Function-method-bind'>    /**
+</span>     * Create a new function from the provided `fn`, change `this` to the provided scope, optionally
+     * overrides arguments for the call. (Defaults to the arguments passed by the caller)
+     *
+     * {@link Ext#bind Ext.bind} is alias for {@link Ext.Function#bind Ext.Function.bind}
+     *
+     * @param {Function} fn The function to delegate.
+     * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed.
+     * **If omitted, defaults to the browser window.**
+     * @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,
+            slice = Array.prototype.slice;
+
+        return function() {
+            var callArgs = args || arguments;
+
+            if (appendArgs === true) {
+                callArgs = slice.call(arguments, 0);
+                callArgs = callArgs.concat(args);
+            }
+            else if (Ext.isNumber(appendArgs)) {
+                callArgs = slice.call(arguments, 0); // copy arguments first
+                Ext.Array.insert(callArgs, appendArgs, args);
+            }
+
+            return method.apply(scope || window, callArgs);
+        };
+    },
+
+<span id='Ext-Function-method-pass'>    /**
+</span>     * Create a new function from the provided `fn`, 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'
+     *
+     * {@link Ext#pass Ext.pass} is alias for {@link Ext.Function#pass Ext.Function.pass}
+     *
+     * @param {Function} fn The original function
+     * @param {Array} args The arguments to pass to new callback
+     * @param {Object} scope (optional) The scope (`this` 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)));
+        };
+    },
+
+<span id='Ext-Function-method-alias'>    /**
+</span>     * Create an alias to the provided method property with name `methodName` of `object`.
+     * Note that the execution scope will still be bound to the provided `object` itself.
+     *
+     * @param {Object/Function} object
+     * @param {String} methodName
+     * @return {Function} aliasFn
+     */
+    alias: function(object, methodName) {
+        return function() {
+            return object[methodName].apply(object, arguments);
+        };
+    },
+
+<span id='Ext-Function-method-createInterceptor'>    /**
+</span>     * 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.createInterceptor(sayHi, function(name){
-    return name == 'Brian';
-});
-
-sayHiToFriend('Fred');  // no alert
-sayHiToFriend('Brian'); // alerts "Hi, Brian"
-       </code></pre>
+     *
+     *     var sayHi = function(name){
+     *         alert('Hi, ' + name);
+     *     }
+     *
+     *     sayHi('Fred'); // alerts &quot;Hi, Fred&quot;
+     *
+     *     // 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 &quot;Hi, Brian&quot;
+     *
      * @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 {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.**
+     * @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) { 
+    createInterceptor: function(origFn, newFn, scope, returnValue) {
         var method = origFn;
         if (!Ext.isFunction(newFn)) {
             return origFn;
@@ -54,126 +201,95 @@ sayHiToFriend('Brian'); // alerts "Hi, Brian"
                     args = arguments;
                 newFn.target = me;
                 newFn.method = origFn;
-                return (newFn.apply(scope || me || window, args) !== false) ?
-                        origFn.apply(me || window, args) :
-                        null;
+                return (newFn.apply(scope || me || window, args) !== false) ? origFn.apply(me || window, args) : returnValue || null;
             };
         }
     },
 
-    <div id="method-Ext.util.Functions-createDelegate"></div>/**
-     * Creates a delegate (callback) that sets the scope to obj.
-     * Call directly on any function. Example: <code>Ext.createDelegate(this.myFunction, this, [arg1, arg2])</code>
-     * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
-     * callback points to obj. Example usage:
-     * <pre><code>
-var sayHi = function(name){
-    // Note this use of "this.text" here.  This function expects to
-    // execute within a scope that contains a text property.  In this
-    // example, the "this" variable is pointing to the btn object that
-    // was passed in createDelegate below.
-    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
-}
-
-var btn = new Ext.Button({
-    text: 'Say Hi',
-    renderTo: Ext.getBody()
-});
-
-// This callback will execute in the scope of the
-// button instance. Clicking the button alerts
-// "Hi, Fred. You clicked the "Say Hi" button."
-btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
-       </code></pre>
-     * @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)
+<span id='Ext-Function-method-createDelayed'>    /**
+</span>     * 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 (`this` 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} The new function
+     * 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.
      */
-    createDelegate: function(fn, obj, args, appendArgs) {
-        if (!Ext.isFunction(fn)) {
-            return fn;
+    createDelayed: function(fn, delay, scope, args, appendArgs) {
+        if (scope || args) {
+            fn = Ext.Function.bind(fn, scope, args, appendArgs);
         }
         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
-                var applyArgs = [appendArgs, 0].concat(args);
-                // create method call params
-                Array.prototype.splice.apply(callArgs, applyArgs);
-                // splice them in
-            }
-            return fn.apply(obj || window, callArgs);
+            var me = this;
+            setTimeout(function() {
+                fn.apply(me, arguments);
+            }, delay);
         };
     },
 
-    <div id="method-Ext.util.Functions-defer"></div>/**
-     * 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.defer(sayHi, 2000, this, ['Fred']);
-
-// this syntax is sometimes useful for deferring
-// execution of an anonymous function:
-Ext.defer(function(){
-    alert('Anonymous');
-}, 100);
-       </code></pre>
+<span id='Ext-Function-method-defer'>    /**
+</span>     * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
+     *
+     *     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);
+     *
+     * {@link Ext#defer Ext.defer} is alias for {@link Ext.Function#defer Ext.Function.defer}
+     *
      * @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 {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 (`this` reference) in which the function is executed.
+     * **If omitted, defaults to the browser window.**
      * @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.util.Functions.createDelegate(fn, obj, args, appendArgs);
-        if (millis > 0) {
+        fn = Ext.Function.bind(fn, obj, args, appendArgs);
+        if (millis &gt; 0) {
             return setTimeout(fn, millis);
         }
         fn();
         return 0;
     },
 
-
-    <div id="method-Ext.util.Functions-createSequence"></div>/**
-     * Create a combined function call sequence of the original function + the passed function.
+<span id='Ext-Function-method-createSequence'>    /**
+</span>     * 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 fcn is called with the parameters of the original function. Example usage:
-     * 
-
-var sayHi = function(name){
-    alert('Hi, ' + name);
-}
-
-sayHi('Fred'); // alerts "Hi, Fred"
-
-var sayGoodbye = Ext.createSequence(sayHi, function(name){
-    alert('Bye, ' + name);
-});
-
-sayGoodbye('Fred'); // both alerts show
-
+     * The passed function is called with the parameters of the original function. Example usage:
+     *
+     *     var sayHi = function(name){
+     *         alert('Hi, ' + name);
+     *     }
+     *
+     *     sayHi('Fred'); // alerts &quot;Hi, Fred&quot;
+     *
+     *     var sayGoodbye = Ext.Function.createSequence(sayHi, function(name){
+     *         alert('Bye, ' + name);
+     *     });
+     *
+     *     sayGoodbye('Fred'); // both alerts show
+     *
      * @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.
+     * @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
      */
@@ -188,64 +304,93 @@ sayGoodbye('Fred'); // both alerts show
                 return retval;
             };
         }
-    }
-};
+    },
 
-/**
- * Shorthand for {@link Ext.util.Functions#defer}   
- * @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
- * @member Ext
- * @method defer
- */
+<span id='Ext-Function-method-createBuffered'>    /**
+</span>     * 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.
+     *
+     * @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 (`this` 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);
+            };
+        }();
+    },
 
-Ext.defer = Ext.util.Functions.defer;
+<span id='Ext-Function-method-createThrottled'>    /**
+</span>     * 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.
+     *
+     * 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.
+     *
+     * @param {Function} fn The function to execute at a regular time interval.
+     * @param {Number} interval The interval **in milliseconds** on which the passed function is executed.
+     * @param {Object} scope (optional) The scope (`this` 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 &gt;= interval)) {
+                execute();
+            } else {
+                timer = setTimeout(execute, interval - elapsed);
+            }
+        };
+    }
+};
 
-/**
- * Shorthand for {@link Ext.util.Functions#createInterceptor}   
- * @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>
- * @return {Function} The new function
+<span id='Ext-method-defer'>/**
+</span> * @method
  * @member Ext
- * @method defer
+ * @alias Ext.Function#defer
  */
+Ext.defer = Ext.Function.alias(Ext.Function, 'defer');
 
-Ext.createInterceptor = Ext.util.Functions.createInterceptor;
-
-/**
- * Shorthand for {@link Ext.util.Functions#createSequence}
- * @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
+<span id='Ext-method-pass'>/**
+</span> * @method
  * @member Ext
- * @method defer
+ * @alias Ext.Function#pass
  */
+Ext.pass = Ext.Function.alias(Ext.Function, 'pass');
 
-Ext.createSequence = Ext.util.Functions.createSequence;
-
-<div id="method-Ext-defer"></div>/**
- * Shorthand for {@link Ext.util.Functions#createDelegate}
- * @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
+<span id='Ext-method-bind'>/**
+</span> * @method
  * @member Ext
- * @method defer
+ * @alias Ext.Function#bind
  */
-Ext.createDelegate = Ext.util.Functions.createDelegate;
-</pre>    
+Ext.bind = Ext.Function.alias(Ext.Function, 'bind');
+</pre>
 </body>
-</html>
\ No newline at end of file
+</html>