Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Function.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-Function'>/**
19 </span> * @class Ext.Function
20  *
21  * A collection of useful static methods to deal with function callbacks
22  * @singleton
23  */
24 Ext.Function = {
25
26 <span id='Ext-Function-method-flexSetter'>    /**
27 </span>     * A very commonly used method throughout the framework. It acts as a wrapper around another method
28      * which originally accepts 2 arguments for `name` and `value`.
29      * The wrapped function then allows &quot;flexible&quot; value setting of either:
30      *
31      * - `name` and `value` as 2 arguments
32      * - one single object argument with multiple key - value pairs
33      *
34      * For example:
35      *
36      *     var setValue = Ext.Function.flexSetter(function(name, value) {
37      *         this[name] = value;
38      *     });
39      *
40      *     // Afterwards
41      *     // Setting a single name - value
42      *     setValue('name1', 'value1');
43      *
44      *     // Settings multiple name - value pairs
45      *     setValue({
46      *         name1: 'value1',
47      *         name2: 'value2',
48      *         name3: 'value3'
49      *     });
50      *
51      * @param {Function} setter
52      * @returns {Function} flexSetter
53      */
54     flexSetter: function(fn) {
55         return function(a, b) {
56             var k, i;
57
58             if (a === null) {
59                 return this;
60             }
61
62             if (typeof a !== 'string') {
63                 for (k in a) {
64                     if (a.hasOwnProperty(k)) {
65                         fn.call(this, k, a[k]);
66                     }
67                 }
68
69                 if (Ext.enumerables) {
70                     for (i = Ext.enumerables.length; i--;) {
71                         k = Ext.enumerables[i];
72                         if (a.hasOwnProperty(k)) {
73                             fn.call(this, k, a[k]);
74                         }
75                     }
76                 }
77             } else {
78                 fn.call(this, a, b);
79             }
80
81             return this;
82         };
83     },
84
85 <span id='Ext-Function-method-bind'>    /**
86 </span>     * Create a new function from the provided `fn`, change `this` to the provided scope, optionally
87      * overrides arguments for the call. (Defaults to the arguments passed by the caller)
88      *
89      * {@link Ext#bind Ext.bind} is alias for {@link Ext.Function#bind Ext.Function.bind}
90      *
91      * @param {Function} fn The function to delegate.
92      * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed.
93      * **If omitted, defaults to the browser window.**
94      * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
95      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
96      * if a number the args are inserted at the specified position
97      * @return {Function} The new function
98      */
99     bind: function(fn, scope, args, appendArgs) {
100         var method = fn,
101             slice = Array.prototype.slice;
102
103         return function() {
104             var callArgs = args || arguments;
105
106             if (appendArgs === true) {
107                 callArgs = slice.call(arguments, 0);
108                 callArgs = callArgs.concat(args);
109             }
110             else if (Ext.isNumber(appendArgs)) {
111                 callArgs = slice.call(arguments, 0); // copy arguments first
112                 Ext.Array.insert(callArgs, appendArgs, args);
113             }
114
115             return method.apply(scope || window, callArgs);
116         };
117     },
118
119 <span id='Ext-Function-method-pass'>    /**
120 </span>     * Create a new function from the provided `fn`, the arguments of which are pre-set to `args`.
121      * New arguments passed to the newly created callback when it's invoked are appended after the pre-set ones.
122      * This is especially useful when creating callbacks.
123      *
124      * For example:
125      *
126      *     var originalFunction = function(){
127      *         alert(Ext.Array.from(arguments).join(' '));
128      *     };
129      *
130      *     var callback = Ext.Function.pass(originalFunction, ['Hello', 'World']);
131      *
132      *     callback(); // alerts 'Hello World'
133      *     callback('by Me'); // alerts 'Hello World by Me'
134      *
135      * {@link Ext#pass Ext.pass} is alias for {@link Ext.Function#pass Ext.Function.pass}
136      *
137      * @param {Function} fn The original function
138      * @param {Array} args The arguments to pass to new callback
139      * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed.
140      * @return {Function} The new callback function
141      */
142     pass: function(fn, args, scope) {
143         if (args) {
144             args = Ext.Array.from(args);
145         }
146
147         return function() {
148             return fn.apply(scope, args.concat(Ext.Array.toArray(arguments)));
149         };
150     },
151
152 <span id='Ext-Function-method-alias'>    /**
153 </span>     * Create an alias to the provided method property with name `methodName` of `object`.
154      * Note that the execution scope will still be bound to the provided `object` itself.
155      *
156      * @param {Object/Function} object
157      * @param {String} methodName
158      * @return {Function} aliasFn
159      */
160     alias: function(object, methodName) {
161         return function() {
162             return object[methodName].apply(object, arguments);
163         };
164     },
165
166 <span id='Ext-Function-method-createInterceptor'>    /**
167 </span>     * Creates an interceptor function. The passed function is called before the original one. If it returns false,
168      * the original one is not called. The resulting function returns the results of the original function.
169      * The passed function is called with the parameters of the original function. Example usage:
170      *
171      *     var sayHi = function(name){
172      *         alert('Hi, ' + name);
173      *     }
174      *
175      *     sayHi('Fred'); // alerts &quot;Hi, Fred&quot;
176      *
177      *     // create a new function that validates input without
178      *     // directly modifying the original function:
179      *     var sayHiToFriend = Ext.Function.createInterceptor(sayHi, function(name){
180      *         return name == 'Brian';
181      *     });
182      *
183      *     sayHiToFriend('Fred');  // no alert
184      *     sayHiToFriend('Brian'); // alerts &quot;Hi, Brian&quot;
185      *
186      * @param {Function} origFn The original function.
187      * @param {Function} newFn The function to call before the original
188      * @param {Object} scope (optional) The scope (`this` reference) in which the passed function is executed.
189      * **If omitted, defaults to the scope in which the original function is called or the browser window.**
190      * @param {Mixed} returnValue (optional) The value to return if the passed function return false (defaults to null).
191      * @return {Function} The new function
192      */
193     createInterceptor: function(origFn, newFn, scope, returnValue) {
194         var method = origFn;
195         if (!Ext.isFunction(newFn)) {
196             return origFn;
197         }
198         else {
199             return function() {
200                 var me = this,
201                     args = arguments;
202                 newFn.target = me;
203                 newFn.method = origFn;
204                 return (newFn.apply(scope || me || window, args) !== false) ? origFn.apply(me || window, args) : returnValue || null;
205             };
206         }
207     },
208
209 <span id='Ext-Function-method-createDelayed'>    /**
210 </span>     * Creates a delegate (callback) which, when called, executes after a specific delay.
211      *
212      * @param {Function} fn The function which will be called on a delay when the returned function is called.
213      * Optionally, a replacement (or additional) argument list may be specified.
214      * @param {Number} delay The number of milliseconds to defer execution by whenever called.
215      * @param {Object} scope (optional) The scope (`this` reference) used by the function at execution time.
216      * @param {Array} args (optional) Override arguments for the call. (Defaults to the arguments passed by the caller)
217      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
218      * if a number the args are inserted at the specified position.
219      * @return {Function} A function which, when called, executes the original function after the specified delay.
220      */
221     createDelayed: function(fn, delay, scope, args, appendArgs) {
222         if (scope || args) {
223             fn = Ext.Function.bind(fn, scope, args, appendArgs);
224         }
225         return function() {
226             var me = this;
227             setTimeout(function() {
228                 fn.apply(me, arguments);
229             }, delay);
230         };
231     },
232
233 <span id='Ext-Function-method-defer'>    /**
234 </span>     * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
235      *
236      *     var sayHi = function(name){
237      *         alert('Hi, ' + name);
238      *     }
239      *
240      *     // executes immediately:
241      *     sayHi('Fred');
242      *
243      *     // executes after 2 seconds:
244      *     Ext.Function.defer(sayHi, 2000, this, ['Fred']);
245      *
246      *     // this syntax is sometimes useful for deferring
247      *     // execution of an anonymous function:
248      *     Ext.Function.defer(function(){
249      *         alert('Anonymous');
250      *     }, 100);
251      *
252      * {@link Ext#defer Ext.defer} is alias for {@link Ext.Function#defer Ext.Function.defer}
253      *
254      * @param {Function} fn The function to defer.
255      * @param {Number} millis The number of milliseconds for the setTimeout call
256      * (if less than or equal to 0 the function is executed immediately)
257      * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed.
258      * **If omitted, defaults to the browser window.**
259      * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
260      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
261      * if a number the args are inserted at the specified position
262      * @return {Number} The timeout id that can be used with clearTimeout
263      */
264     defer: function(fn, millis, obj, args, appendArgs) {
265         fn = Ext.Function.bind(fn, obj, args, appendArgs);
266         if (millis &gt; 0) {
267             return setTimeout(fn, millis);
268         }
269         fn();
270         return 0;
271     },
272
273 <span id='Ext-Function-method-createSequence'>    /**
274 </span>     * Create a combined function call sequence of the original function + the passed function.
275      * The resulting function returns the results of the original function.
276      * The passed function is called with the parameters of the original function. Example usage:
277      *
278      *     var sayHi = function(name){
279      *         alert('Hi, ' + name);
280      *     }
281      *
282      *     sayHi('Fred'); // alerts &quot;Hi, Fred&quot;
283      *
284      *     var sayGoodbye = Ext.Function.createSequence(sayHi, function(name){
285      *         alert('Bye, ' + name);
286      *     });
287      *
288      *     sayGoodbye('Fred'); // both alerts show
289      *
290      * @param {Function} origFn The original function.
291      * @param {Function} newFn The function to sequence
292      * @param {Object} scope (optional) The scope (`this` reference) in which the passed function is executed.
293      * If omitted, defaults to the scope in which the original function is called or the browser window.
294      * @return {Function} The new function
295      */
296     createSequence: function(origFn, newFn, scope) {
297         if (!Ext.isFunction(newFn)) {
298             return origFn;
299         }
300         else {
301             return function() {
302                 var retval = origFn.apply(this || window, arguments);
303                 newFn.apply(scope || this || window, arguments);
304                 return retval;
305             };
306         }
307     },
308
309 <span id='Ext-Function-method-createBuffered'>    /**
310 </span>     * Creates a delegate function, optionally with a bound scope which, when called, buffers
311      * the execution of the passed function for the configured number of milliseconds.
312      * If called again within that period, the impending invocation will be canceled, and the
313      * timeout period will begin again.
314      *
315      * @param {Function} fn The function to invoke on a buffered timer.
316      * @param {Number} buffer The number of milliseconds by which to buffer the invocation of the
317      * function.
318      * @param {Object} scope (optional) The scope (`this` reference) in which
319      * the passed function is executed. If omitted, defaults to the scope specified by the caller.
320      * @param {Array} args (optional) Override arguments for the call. Defaults to the arguments
321      * passed by the caller.
322      * @return {Function} A function which invokes the passed function after buffering for the specified time.
323      */
324     createBuffered: function(fn, buffer, scope, args) {
325         return function(){
326             var timerId;
327             return function() {
328                 var me = this;
329                 if (timerId) {
330                     clearInterval(timerId);
331                     timerId = null;
332                 }
333                 timerId = setTimeout(function(){
334                     fn.apply(scope || me, args || arguments);
335                 }, buffer);
336             };
337         }();
338     },
339
340 <span id='Ext-Function-method-createThrottled'>    /**
341 </span>     * Creates a throttled version of the passed function which, when called repeatedly and
342      * rapidly, invokes the passed function only after a certain interval has elapsed since the
343      * previous invocation.
344      *
345      * This is useful for wrapping functions which may be called repeatedly, such as
346      * a handler of a mouse move event when the processing is expensive.
347      *
348      * @param {Function} fn The function to execute at a regular time interval.
349      * @param {Number} interval The interval **in milliseconds** on which the passed function is executed.
350      * @param {Object} scope (optional) The scope (`this` reference) in which
351      * the passed function is executed. If omitted, defaults to the scope specified by the caller.
352      * @returns {Function} A function which invokes the passed function at the specified interval.
353      */
354     createThrottled: function(fn, interval, scope) {
355         var lastCallTime, elapsed, lastArgs, timer, execute = function() {
356             fn.apply(scope || this, lastArgs);
357             lastCallTime = new Date().getTime();
358         };
359
360         return function() {
361             elapsed = new Date().getTime() - lastCallTime;
362             lastArgs = arguments;
363
364             clearTimeout(timer);
365             if (!lastCallTime || (elapsed &gt;= interval)) {
366                 execute();
367             } else {
368                 timer = setTimeout(execute, interval - elapsed);
369             }
370         };
371     }
372 };
373
374 <span id='Ext-method-defer'>/**
375 </span> * @method
376  * @member Ext
377  * @alias Ext.Function#defer
378  */
379 Ext.defer = Ext.Function.alias(Ext.Function, 'defer');
380
381 <span id='Ext-method-pass'>/**
382 </span> * @method
383  * @member Ext
384  * @alias Ext.Function#pass
385  */
386 Ext.pass = Ext.Function.alias(Ext.Function, 'pass');
387
388 <span id='Ext-method-bind'>/**
389 </span> * @method
390  * @member Ext
391  * @alias Ext.Function#bind
392  */
393 Ext.bind = Ext.Function.alias(Ext.Function, 'bind');
394 </pre>
395 </body>
396 </html>