4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-Function'>/**
19 </span> * @class Ext.Function
21 * A collection of useful static methods to deal with function callbacks
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 "flexible" value setting of either:
31 * - `name` and `value` as 2 arguments
32 * - one single object argument with multiple key - value pairs
36 * var setValue = Ext.Function.flexSetter(function(name, value) {
41 * // Setting a single name - value
42 * setValue('name1', 'value1');
44 * // Settings multiple name - value pairs
51 * @param {Function} setter
52 * @returns {Function} flexSetter
54 flexSetter: function(fn) {
55 return function(a, b) {
62 if (typeof a !== 'string') {
64 if (a.hasOwnProperty(k)) {
65 fn.call(this, k, a[k]);
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]);
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)
89 * {@link Ext#bind Ext.bind} is alias for {@link Ext.Function#bind Ext.Function.bind}
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
99 bind: function(fn, scope, args, appendArgs) {
100 if (arguments.length === 2) {
102 return fn.apply(scope, arguments);
107 slice = Array.prototype.slice;
110 var callArgs = args || arguments;
112 if (appendArgs === true) {
113 callArgs = slice.call(arguments, 0);
114 callArgs = callArgs.concat(args);
116 else if (typeof appendArgs == 'number') {
117 callArgs = slice.call(arguments, 0); // copy arguments first
118 Ext.Array.insert(callArgs, appendArgs, args);
121 return method.apply(scope || window, callArgs);
125 <span id='Ext-Function-method-pass'> /**
126 </span> * Create a new function from the provided `fn`, the arguments of which are pre-set to `args`.
127 * New arguments passed to the newly created callback when it's invoked are appended after the pre-set ones.
128 * This is especially useful when creating callbacks.
132 * var originalFunction = function(){
133 * alert(Ext.Array.from(arguments).join(' '));
136 * var callback = Ext.Function.pass(originalFunction, ['Hello', 'World']);
138 * callback(); // alerts 'Hello World'
139 * callback('by Me'); // alerts 'Hello World by Me'
141 * {@link Ext#pass Ext.pass} is alias for {@link Ext.Function#pass Ext.Function.pass}
143 * @param {Function} fn The original function
144 * @param {Array} args The arguments to pass to new callback
145 * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed.
146 * @return {Function} The new callback function
148 pass: function(fn, args, scope) {
150 args = Ext.Array.from(args);
154 return fn.apply(scope, args.concat(Ext.Array.toArray(arguments)));
158 <span id='Ext-Function-method-alias'> /**
159 </span> * Create an alias to the provided method property with name `methodName` of `object`.
160 * Note that the execution scope will still be bound to the provided `object` itself.
162 * @param {Object/Function} object
163 * @param {String} methodName
164 * @return {Function} aliasFn
166 alias: function(object, methodName) {
168 return object[methodName].apply(object, arguments);
172 <span id='Ext-Function-method-createInterceptor'> /**
173 </span> * Creates an interceptor function. The passed function is called before the original one. If it returns false,
174 * the original one is not called. The resulting function returns the results of the original function.
175 * The passed function is called with the parameters of the original function. Example usage:
177 * var sayHi = function(name){
178 * alert('Hi, ' + name);
181 * sayHi('Fred'); // alerts "Hi, Fred"
183 * // create a new function that validates input without
184 * // directly modifying the original function:
185 * var sayHiToFriend = Ext.Function.createInterceptor(sayHi, function(name){
186 * return name == 'Brian';
189 * sayHiToFriend('Fred'); // no alert
190 * sayHiToFriend('Brian'); // alerts "Hi, Brian"
192 * @param {Function} origFn The original function.
193 * @param {Function} newFn The function to call before the original
194 * @param {Object} scope (optional) The scope (`this` reference) in which the passed function is executed.
195 * **If omitted, defaults to the scope in which the original function is called or the browser window.**
196 * @param {Object} returnValue (optional) The value to return if the passed function return false (defaults to null).
197 * @return {Function} The new function
199 createInterceptor: function(origFn, newFn, scope, returnValue) {
201 if (!Ext.isFunction(newFn)) {
209 newFn.method = origFn;
210 return (newFn.apply(scope || me || window, args) !== false) ? origFn.apply(me || window, args) : returnValue || null;
215 <span id='Ext-Function-method-createDelayed'> /**
216 </span> * Creates a delegate (callback) which, when called, executes after a specific delay.
218 * @param {Function} fn The function which will be called on a delay when the returned function is called.
219 * Optionally, a replacement (or additional) argument list may be specified.
220 * @param {Number} delay The number of milliseconds to defer execution by whenever called.
221 * @param {Object} scope (optional) The scope (`this` reference) used by the function at execution time.
222 * @param {Array} args (optional) Override arguments for the call. (Defaults to the arguments passed by the caller)
223 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
224 * if a number the args are inserted at the specified position.
225 * @return {Function} A function which, when called, executes the original function after the specified delay.
227 createDelayed: function(fn, delay, scope, args, appendArgs) {
229 fn = Ext.Function.bind(fn, scope, args, appendArgs);
233 setTimeout(function() {
234 fn.apply(me, arguments);
239 <span id='Ext-Function-method-defer'> /**
240 </span> * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
242 * var sayHi = function(name){
243 * alert('Hi, ' + name);
246 * // executes immediately:
249 * // executes after 2 seconds:
250 * Ext.Function.defer(sayHi, 2000, this, ['Fred']);
252 * // this syntax is sometimes useful for deferring
253 * // execution of an anonymous function:
254 * Ext.Function.defer(function(){
255 * alert('Anonymous');
258 * {@link Ext#defer Ext.defer} is alias for {@link Ext.Function#defer Ext.Function.defer}
260 * @param {Function} fn The function to defer.
261 * @param {Number} millis The number of milliseconds for the setTimeout call
262 * (if less than or equal to 0 the function is executed immediately)
263 * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed.
264 * **If omitted, defaults to the browser window.**
265 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
266 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
267 * if a number the args are inserted at the specified position
268 * @return {Number} The timeout id that can be used with clearTimeout
270 defer: function(fn, millis, obj, args, appendArgs) {
271 fn = Ext.Function.bind(fn, obj, args, appendArgs);
273 return setTimeout(fn, millis);
279 <span id='Ext-Function-method-createSequence'> /**
280 </span> * Create a combined function call sequence of the original function + the passed function.
281 * The resulting function returns the results of the original function.
282 * The passed function is called with the parameters of the original function. Example usage:
284 * var sayHi = function(name){
285 * alert('Hi, ' + name);
288 * sayHi('Fred'); // alerts "Hi, Fred"
290 * var sayGoodbye = Ext.Function.createSequence(sayHi, function(name){
291 * alert('Bye, ' + name);
294 * sayGoodbye('Fred'); // both alerts show
296 * @param {Function} origFn The original function.
297 * @param {Function} newFn The function to sequence
298 * @param {Object} scope (optional) The scope (`this` reference) in which the passed function is executed.
299 * If omitted, defaults to the scope in which the original function is called or the browser window.
300 * @return {Function} The new function
302 createSequence: function(origFn, newFn, scope) {
303 if (!Ext.isFunction(newFn)) {
308 var retval = origFn.apply(this || window, arguments);
309 newFn.apply(scope || this || window, arguments);
315 <span id='Ext-Function-method-createBuffered'> /**
316 </span> * Creates a delegate function, optionally with a bound scope which, when called, buffers
317 * the execution of the passed function for the configured number of milliseconds.
318 * If called again within that period, the impending invocation will be canceled, and the
319 * timeout period will begin again.
321 * @param {Function} fn The function to invoke on a buffered timer.
322 * @param {Number} buffer The number of milliseconds by which to buffer the invocation of the
324 * @param {Object} scope (optional) The scope (`this` reference) in which
325 * the passed function is executed. If omitted, defaults to the scope specified by the caller.
326 * @param {Array} args (optional) Override arguments for the call. Defaults to the arguments
327 * passed by the caller.
328 * @return {Function} A function which invokes the passed function after buffering for the specified time.
330 createBuffered: function(fn, buffer, scope, args) {
336 clearTimeout(timerId);
339 timerId = setTimeout(function(){
340 fn.apply(scope || me, args || arguments);
346 <span id='Ext-Function-method-createThrottled'> /**
347 </span> * Creates a throttled version of the passed function which, when called repeatedly and
348 * rapidly, invokes the passed function only after a certain interval has elapsed since the
349 * previous invocation.
351 * This is useful for wrapping functions which may be called repeatedly, such as
352 * a handler of a mouse move event when the processing is expensive.
354 * @param {Function} fn The function to execute at a regular time interval.
355 * @param {Number} interval The interval **in milliseconds** on which the passed function is executed.
356 * @param {Object} scope (optional) The scope (`this` reference) in which
357 * the passed function is executed. If omitted, defaults to the scope specified by the caller.
358 * @returns {Function} A function which invokes the passed function at the specified interval.
360 createThrottled: function(fn, interval, scope) {
361 var lastCallTime, elapsed, lastArgs, timer, execute = function() {
362 fn.apply(scope || this, lastArgs);
363 lastCallTime = new Date().getTime();
367 elapsed = new Date().getTime() - lastCallTime;
368 lastArgs = arguments;
371 if (!lastCallTime || (elapsed >= interval)) {
374 timer = setTimeout(execute, interval - elapsed);
379 <span id='Ext-Function-method-interceptBefore'> /**
380 </span> * Adds behavior to an existing method that is executed before the
381 * original behavior of the function. For example:
385 * add: function(ingredient) {
386 * this.contents.push(ingredient);
389 * Ext.Function.interceptBefore(soup, "add", function(ingredient){
390 * if (!this.contents.length && ingredient !== "water") {
391 * // Always add water to start with
392 * this.contents.push("water");
395 * soup.add("onions");
396 * soup.add("salt");
397 * soup.contents; // will contain: water, onions, salt
399 * @param {Object} object The target object
400 * @param {String} methodName Name of the method to override
401 * @param {Function} fn Function with the new behavior. It will
402 * be called with the same arguments as the original method. The
403 * return value of this function will be the return value of the
405 * @return {Function} The new function just created.
407 interceptBefore: function(object, methodName, fn) {
408 var method = object[methodName] || Ext.emptyFn;
410 return object[methodName] = function() {
411 var ret = fn.apply(this, arguments);
412 method.apply(this, arguments);
418 <span id='Ext-Function-method-interceptAfter'> /**
419 </span> * Adds behavior to an existing method that is executed after the
420 * original behavior of the function. For example:
424 * add: function(ingredient) {
425 * this.contents.push(ingredient);
428 * Ext.Function.interceptAfter(soup, "add", function(ingredient){
429 * // Always add a bit of extra salt
430 * this.contents.push("salt");
432 * soup.add("water");
433 * soup.add("onions");
434 * soup.contents; // will contain: water, salt, onions, salt
436 * @param {Object} object The target object
437 * @param {String} methodName Name of the method to override
438 * @param {Function} fn Function with the new behavior. It will
439 * be called with the same arguments as the original method. The
440 * return value of this function will be the return value of the
442 * @return {Function} The new function just created.
444 interceptAfter: function(object, methodName, fn) {
445 var method = object[methodName] || Ext.emptyFn;
447 return object[methodName] = function() {
448 method.apply(this, arguments);
449 return fn.apply(this, arguments);
454 <span id='Ext-method-defer'>/**
457 * @alias Ext.Function#defer
459 Ext.defer = Ext.Function.alias(Ext.Function, 'defer');
461 <span id='Ext-method-pass'>/**
464 * @alias Ext.Function#pass
466 Ext.pass = Ext.Function.alias(Ext.Function, 'pass');
468 <span id='Ext-method-bind'>/**
471 * @alias Ext.Function#bind
473 Ext.bind = Ext.Function.alias(Ext.Function, 'bind');