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