| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 | <!DOCTYPE html><html><head>  <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>  <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(); 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 * @alternateClassName Ext.util.Functions */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 "flexible" 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 default global environment object (usually 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) {        if (arguments.length === 2) {            return function() {                return fn.apply(scope, arguments);            };        }        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 (typeof appendArgs == 'number') {                callArgs = slice.call(arguments, 0); // copy arguments first                Ext.Array.insert(callArgs, appendArgs, args);            }            return method.apply(scope || Ext.global, 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 (!Ext.isArray(args)) {            if (Ext.isIterable(args)) {                args = Ext.Array.clone(args);            } else {                args = args !== undefined ? [args] : [];            }        }        return function() {            var fnArgs = [].concat(args);            fnArgs.push.apply(fnArgs, arguments);            return fn.apply(scope || this, fnArgs);        };    },<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-clone'>    /**</span>     * Create a "clone" of the provided method. The returned method will call the given     * method passing along all arguments and the "this" pointer and return its result.     *     * @param {Function} method     * @return {Function} cloneFn     */    clone: function(method) {        return function() {            return method.apply(this, 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:     *     *     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"     *     * @param {Function} origFn The original function.     * @param {Function} newFn The function to call before the original     * @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 {Object} 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 || Ext.global, args) !== false) ? origFn.apply(me || Ext.global, args) : returnValue || null;            };        }    },<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} 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,                args = Array.prototype.slice.call(arguments);            setTimeout(function() {                fn.apply(me, args);            }, delay);        };    },<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 (`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, scope, args, appendArgs) {        fn = Ext.Function.bind(fn, scope, args, appendArgs);        if (millis > 0) {            return setTimeout(Ext.supports.TimeoutActualLateness ? function () {                fn();            } : fn, millis);        }        fn();        return 0;    },<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 function 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.Function.createSequence(sayHi, function(name){     *         alert('Bye, ' + name);     *     });     *     *     sayGoodbye('Fred'); // both alerts show     *     * @param {Function} originalFn 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 default global environment object (usually the browser window).     * @return {Function} The new function     */    createSequence: function(originalFn, newFn, scope) {        if (!newFn) {            return originalFn;        }        else {            return function() {                var result = originalFn.apply(this, arguments);                newFn.apply(scope || this, arguments);                return result;            };        }    },<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) {        var timerId;        return function() {            var callArgs = args || Array.prototype.slice.call(arguments, 0),                me = scope || this;            if (timerId) {                clearTimeout(timerId);            }            timerId = setTimeout(function(){                fn.apply(me, callArgs);            }, buffer);        };    },<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 >= interval)) {                execute();            } else {                timer = setTimeout(execute, interval - elapsed);            }        };    },<span id='Ext-Function-method-interceptBefore'>    /**</span>     * Adds behavior to an existing method that is executed before the     * original behavior of the function.  For example:     *      *     var soup = {     *         contents: [],     *         add: function(ingredient) {     *             this.contents.push(ingredient);     *         }     *     };     *     Ext.Function.interceptBefore(soup, "add", function(ingredient){     *         if (!this.contents.length && ingredient !== "water") {     *             // Always add water to start with     *             this.contents.push("water");     *         }     *     });     *     soup.add("onions");     *     soup.add("salt");     *     soup.contents; // will contain: water, onions, salt     *      * @param {Object} object The target object     * @param {String} methodName Name of the method to override     * @param {Function} fn Function with the new behavior.  It will     * be called with the same arguments as the original method.  The     * return value of this function will be the return value of the     * new method.     * @param {Object} [scope] The scope to execute the interceptor function. Defaults to the object.     * @return {Function} The new function just created.     */    interceptBefore: function(object, methodName, fn, scope) {        var method = object[methodName] || Ext.emptyFn;        return (object[methodName] = function() {            var ret = fn.apply(scope || this, arguments);            method.apply(this, arguments);            return ret;        });    },<span id='Ext-Function-method-interceptAfter'>    /**</span>     * Adds behavior to an existing method that is executed after the     * original behavior of the function.  For example:     *      *     var soup = {     *         contents: [],     *         add: function(ingredient) {     *             this.contents.push(ingredient);     *         }     *     };     *     Ext.Function.interceptAfter(soup, "add", function(ingredient){     *         // Always add a bit of extra salt     *         this.contents.push("salt");     *     });     *     soup.add("water");     *     soup.add("onions");     *     soup.contents; // will contain: water, salt, onions, salt     *      * @param {Object} object The target object     * @param {String} methodName Name of the method to override     * @param {Function} fn Function with the new behavior.  It will     * be called with the same arguments as the original method.  The     * return value of this function will be the return value of the     * new method.     * @param {Object} [scope] The scope to execute the interceptor function. Defaults to the object.     * @return {Function} The new function just created.     */    interceptAfter: function(object, methodName, fn, scope) {        var method = object[methodName] || Ext.emptyFn;        return (object[methodName] = function() {            method.apply(this, arguments);            return fn.apply(scope || this, arguments);        });    }};<span id='Ext-method-defer'>/**</span> * @method * @member Ext * @inheritdoc Ext.Function#defer */Ext.defer = Ext.Function.alias(Ext.Function, 'defer');<span id='Ext-method-pass'>/**</span> * @method * @member Ext * @inheritdoc Ext.Function#pass */Ext.pass = Ext.Function.alias(Ext.Function, 'pass');<span id='Ext-method-bind'>/**</span> * @method * @member Ext * @inheritdoc Ext.Function#bind */Ext.bind = Ext.Function.alias(Ext.Function, 'bind');</pre></body></html>
 |