source: trunk/web/addons/job_monarch/lib/extjs-30/src/core/core/Ext.js @ 625

Last change on this file since 625 was 625, checked in by ramonb, 15 years ago

lib/extjs-30:

  • new ExtJS 3.0
File size: 33.4 KB
Line 
1/*!
2 * Ext JS Library 3.0.0
3 * Copyright(c) 2006-2009 Ext JS, LLC
4 * licensing@extjs.com
5 * http://www.extjs.com/license
6 */
7
8// for old browsers
9window.undefined = window.undefined;
10
11/**
12 * @class Ext
13 * Ext core utilities and functions.
14 * @singleton
15 */
16
17Ext = {
18    /**
19     * The version of the framework
20     * @type String
21     */
22    version : '3.0'
23};
24
25/**
26 * Copies all the properties of config to obj.
27 * @param {Object} obj The receiver of the properties
28 * @param {Object} config The source of the properties
29 * @param {Object} defaults A different object that will also be applied for default values
30 * @return {Object} returns obj
31 * @member Ext apply
32 */
33Ext.apply = function(o, c, defaults){
34    // no "this" reference for friendly out of scope calls
35    if(defaults){
36        Ext.apply(o, defaults);
37    }
38    if(o && c && typeof c == 'object'){
39        for(var p in c){
40            o[p] = c[p];
41        }
42    }
43    return o;
44};
45
46(function(){
47    var idSeed = 0,
48        toString = Object.prototype.toString,
49        //assume it's not null and not an array
50        isIterable = function(v){
51            //check for array or arguments
52            if(Ext.isArray(v) || v.callee){
53                return true;
54            }
55            //check for node list type
56            if(/NodeList|HTMLCollection/.test(toString.call(v))){
57                return true;
58            }
59            //NodeList has an item and length property
60            //IXMLDOMNodeList has nextNode method, needs to be checked first.
61            return ((v.nextNode || v.item) && Ext.isNumber(v.length));
62        },
63        ua = navigator.userAgent.toLowerCase(),
64        check = function(r){
65            return r.test(ua);
66        },
67        DOC = document,
68        isStrict = DOC.compatMode == "CSS1Compat",
69        isOpera = check(/opera/),
70        isChrome = check(/chrome/),
71        isWebKit = check(/webkit/),
72        isSafari = !isChrome && check(/safari/),
73        isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2
74        isSafari3 = isSafari && check(/version\/3/),
75        isSafari4 = isSafari && check(/version\/4/),
76        isIE = !isOpera && check(/msie/),
77        isIE7 = isIE && check(/msie 7/),
78        isIE8 = isIE && check(/msie 8/),
79        isIE6 = isIE && !isIE7 && !isIE8,
80        isGecko = !isWebKit && check(/gecko/),
81        isGecko2 = isGecko && check(/rv:1\.8/),
82        isGecko3 = isGecko && check(/rv:1\.9/),
83        isBorderBox = isIE && !isStrict,
84        isWindows = check(/windows|win32/),
85        isMac = check(/macintosh|mac os x/),
86        isAir = check(/adobeair/),
87        isLinux = check(/linux/),
88        isSecure = /^https/i.test(window.location.protocol);
89
90    // remove css image flicker
91    if(isIE6){
92        try{
93            DOC.execCommand("BackgroundImageCache", false, true);
94        }catch(e){}
95    }
96
97    Ext.apply(Ext, {
98        /**
99         * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
100         * the IE insecure content warning (defaults to javascript:false).
101         * @type String
102         */
103        SSL_SECURE_URL : 'javascript:false',
104        /**
105         * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
106         * @type Boolean
107         */
108        isStrict : isStrict,
109        /**
110         * True if the page is running over SSL
111         * @type Boolean
112         */
113        isSecure : isSecure,
114        /**
115         * True when the document is fully initialized and ready for action
116         * @type Boolean
117         */
118        isReady : false,
119
120        /**
121         * True if the {@link Ext.Fx} Class is available
122         * @type Boolean
123         * @property enableFx
124         */
125
126        /**
127         * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
128         * @type Boolean
129         */
130        enableGarbageCollector : true,
131
132        /**
133         * True to automatically purge event listeners after uncaching an element (defaults to false).
134         * Note: this only happens if {@link #enableGarbageCollector} is true.
135         * @type Boolean
136         */
137        enableListenerCollection : false,
138
139        /**
140         * Indicates whether to use native browser parsing for JSON methods.
141         * This option is ignored if the browser does not support native JSON methods.
142         * <b>Note: Native JSON methods will not work with objects that have functions.
143         * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)
144         * @type Boolean
145         */
146        USE_NATIVE_JSON : false,
147
148        /**
149         * Copies all the properties of config to obj if they don't already exist.
150         * @param {Object} obj The receiver of the properties
151         * @param {Object} config The source of the properties
152         * @return {Object} returns obj
153         */
154        applyIf : function(o, c){
155            if(o){
156                for(var p in c){
157                    if(Ext.isEmpty(o[p])){
158                        o[p] = c[p];
159                    }
160                }
161            }
162            return o;
163        },
164
165        /**
166         * Generates unique ids. If the element already has an id, it is unchanged
167         * @param {Mixed} el (optional) The element to generate an id for
168         * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
169         * @return {String} The generated Id.
170         */
171        id : function(el, prefix){
172            return (el = Ext.getDom(el) || {}).id = el.id || (prefix || "ext-gen") + (++idSeed);
173        },
174
175        /**
176         * Extends one class with another class and optionally overrides members with the passed literal. This class
177         * also adds the function "override()" to the class that can be used to override
178         * members on an instance.
179         * * <p>
180         * This function also supports a 2-argument call in which the subclass's constructor is
181         * not passed as an argument. In this form, the parameters are as follows:</p><p>
182         * <div class="mdetail-params"><ul>
183         * <li><code>superclass</code>
184         * <div class="sub-desc">The class being extended</div></li>
185         * <li><code>overrides</code>
186         * <div class="sub-desc">A literal with members which are copied into the subclass's
187         * prototype, and are therefore shared among all instances of the new class.<p>
188         * This may contain a special member named <tt><b>constructor</b></tt>. This is used
189         * to define the constructor of the new class, and is returned. If this property is
190         * <i>not</i> specified, a constructor is generated and returned which just calls the
191         * superclass's constructor passing on its parameters.</p></div></li>
192         * </ul></div></p><p>
193         * For example, to create a subclass of the Ext GridPanel:
194         * <pre><code>
195MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
196    constructor: function(config) {
197        // Your preprocessing here
198        MyGridPanel.superclass.constructor.apply(this, arguments);
199        // Your postprocessing here
200    },
201
202    yourMethod: function() {
203        // etc.
204    }
205});
206</code></pre>
207         * </p>
208         * @param {Function} subclass The class inheriting the functionality
209         * @param {Function} superclass The class being extended
210         * @param {Object} overrides (optional) A literal with members which are copied into the subclass's
211         * prototype, and are therefore shared between all instances of the new class.
212         * @return {Function} The subclass constructor.
213         * @method extend
214         */
215        extend : function(){
216            // inline overrides
217            var io = function(o){
218                for(var m in o){
219                    this[m] = o[m];
220                }
221            };
222            var oc = Object.prototype.constructor;
223
224            return function(sb, sp, overrides){
225                if(Ext.isObject(sp)){
226                    overrides = sp;
227                    sp = sb;
228                    sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
229                }
230                var F = function(){},
231                    sbp,
232                    spp = sp.prototype;
233
234                F.prototype = spp;
235                sbp = sb.prototype = new F();
236                sbp.constructor=sb;
237                sb.superclass=spp;
238                if(spp.constructor == oc){
239                    spp.constructor=sp;
240                }
241                sb.override = function(o){
242                    Ext.override(sb, o);
243                };
244                sbp.superclass = sbp.supr = (function(){
245                    return spp;
246                });
247                sbp.override = io;
248                Ext.override(sb, overrides);
249                sb.extend = function(o){Ext.extend(sb, o);};
250                return sb;
251            };
252        }(),
253
254        /**
255         * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
256         * Usage:<pre><code>
257Ext.override(MyClass, {
258    newMethod1: function(){
259        // etc.
260    },
261    newMethod2: function(foo){
262        // etc.
263    }
264});
265</code></pre>
266         * @param {Object} origclass The class to override
267         * @param {Object} overrides The list of functions to add to origClass.  This should be specified as an object literal
268         * containing one or more methods.
269         * @method override
270         */
271        override : function(origclass, overrides){
272            if(overrides){
273                var p = origclass.prototype;
274                Ext.apply(p, overrides);
275                if(Ext.isIE && overrides.toString != origclass.toString){
276                    p.toString = overrides.toString;
277                }
278            }
279        },
280
281        /**
282         * Creates namespaces to be used for scoping variables and classes so that they are not global.
283         * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
284         * <pre><code>
285Ext.namespace('Company', 'Company.data');
286Ext.namespace('Company.data'); // equivalent and preferable to above syntax
287Company.Widget = function() { ... }
288Company.data.CustomStore = function(config) { ... }
289</code></pre>
290         * @param {String} namespace1
291         * @param {String} namespace2
292         * @param {String} etc
293         * @method namespace
294         */
295        namespace : function(){
296            var o, d;
297            Ext.each(arguments, function(v) {
298                d = v.split(".");
299                o = window[d[0]] = window[d[0]] || {};
300                Ext.each(d.slice(1), function(v2){
301                    o = o[v2] = o[v2] || {};
302                });
303            });
304            return o;
305        },
306
307        /**
308         * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2".  Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.
309         * @param {Object} o
310         * @param {String} pre (optional) A prefix to add to the url encoded string
311         * @return {String}
312         */
313        urlEncode: function(o, pre){
314            var undef, buf = [], key, e = encodeURIComponent;
315
316            for(key in o){
317                undef = !Ext.isDefined(o[key]);
318                Ext.each(undef ? key : o[key], function(val, i){
319                    buf.push("&", e(key), "=", (val != key || !undef) ? e(val) : "");
320                });
321            }
322            if(!pre){
323                buf.shift();
324                pre = "";
325            }
326            return pre + buf.join('');
327        },
328
329        /**
330         * Takes an encoded URL and and converts it to an object. Example: <pre><code>
331Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}
332Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}
333</code></pre>
334         * @param {String} string
335         * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
336         * @return {Object} A literal with members
337         */
338        urlDecode : function(string, overwrite){
339            var obj = {},
340                pairs = string.split('&'),
341                d = decodeURIComponent,
342                name,
343                value;
344            Ext.each(pairs, function(pair) {
345                pair = pair.split('=');
346                name = d(pair[0]);
347                value = d(pair[1]);
348                obj[name] = overwrite || !obj[name] ? value :
349                            [].concat(obj[name]).concat(value);
350            });
351            return obj;
352        },
353
354        /**
355         * Appends content to the query string of a URL, which handles logic for whether to place
356         * a question mark or ampersand.
357         * @param {String} url The url to append to.
358         * @@param {String} s The content to append to the url.
359         * @return (String) The appended string
360         */
361        urlAppend : function(url, s){
362            if(!Ext.isEmpty(s)){
363                return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
364            }
365            return url;
366        },
367
368        /**
369         * Converts any iterable (numeric indices and a length property) into a true array
370         * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on.
371         * For strings, use this instead: "abc".match(/./g) => [a,b,c];
372         * @param {Iterable} the iterable object to be turned into a true Array.
373         * @return (Array) array
374         */
375        toArray : function(){
376            return isIE ?
377                function(a, i, j, res){
378                    res = [];
379                    Ext.each(a, function(v) {
380                        res.push(v);
381                    });
382                    return res.slice(i || 0, j || res.length);
383                } :
384                function(a, i, j){
385                    return Array.prototype.slice.call(a, i || 0, j || a.length);
386                }
387        }(),
388
389        /**
390         * Iterates an array calling the passed function with each item, stopping if your function returns false. If the
391         * passed array is not really an array, your function is called once with it.
392         * The supplied function is called with (Object item, Number index, Array allItems).
393         * @param {Array/NodeList/Mixed} array
394         * @param {Function} fn
395         * @param {Object} scope
396         */
397        each: function(array, fn, scope){
398            if(Ext.isEmpty(array, true)){
399                return;
400            }
401            if(!isIterable(array) || Ext.isPrimitive(array)){
402                array = [array];
403            }
404            for(var i = 0, len = array.length; i < len; i++){
405                if(fn.call(scope || array[i], array[i], i, array) === false){
406                    return i;
407                };
408            }
409        },
410
411        /**
412         * Iterates either the elements in an array, or each of the properties in an object.
413         * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}.
414         * @param {Object/Array} object The object or array to be iterated
415         * @param {Function} fn The function to be called for each iteration.
416         * The iteration will stop if the supplied function returns false, or
417         * all array elements / object properties have been covered. The signature
418         * varies depending on the type of object being interated:
419         * <div class="mdetail-params"><ul>
420         * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt>
421         * <div class="sub-desc">
422         * When iterating an array, the supplied function is called with each item.</div></li>
423         * <li>Objects : <tt>(String key, Object value)</tt>
424         * <div class="sub-desc">
425         * When iterating an object, the supplied function is called with each key-value pair in
426         * the object.</div></li>
427         * </ul></div>
428         * @param {Object} scope The scope to call the supplied function with, defaults to
429         * the specified <tt>object</tt>
430         */
431        iterate : function(obj, fn, scope){
432            if(isIterable(obj)){
433                Ext.each(obj, fn, scope);
434                return;
435            }else if(Ext.isObject(obj)){
436                for(var prop in obj){
437                    if(obj.hasOwnProperty(prop)){
438                        if(fn.call(scope || obj, prop, obj[prop]) === false){
439                            return;
440                        };
441                    }
442                }
443            }
444        },
445
446        /**
447         * Return the dom node for the passed String (id), dom node, or Ext.Element.
448         * Here are some examples:
449         * <pre><code>
450// gets dom node based on id
451var elDom = Ext.getDom('elId');
452// gets dom node based on the dom node
453var elDom1 = Ext.getDom(elDom);
454
455// If we don&#39;t know if we are working with an
456// Ext.Element or a dom node use Ext.getDom
457function(el){
458    var dom = Ext.getDom(el);
459    // do something with the dom node
460}
461         * </code></pre>
462         * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)
463         * when this method is called to be successful.
464         * @param {Mixed} el
465         * @return HTMLElement
466         */
467        getDom : function(el){
468            if(!el || !DOC){
469                return null;
470            }
471            return el.dom ? el.dom : (Ext.isString(el) ? DOC.getElementById(el) : el);
472        },
473
474        /**
475         * Returns the current document body as an {@link Ext.Element}.
476         * @return Ext.Element The document body
477         */
478        getBody : function(){
479            return Ext.get(DOC.body || DOC.documentElement);
480        },
481
482        /**
483         * Removes a DOM node from the document.  The body node will be ignored if passed in.
484         * @param {HTMLElement} node The node to remove
485         */
486        removeNode : isIE ? function(){
487            var d;
488            return function(n){
489                if(n && n.tagName != 'BODY'){
490                    d = d || DOC.createElement('div');
491                    d.appendChild(n);
492                    d.innerHTML = '';
493                }
494            }
495        }() : function(n){
496            if(n && n.parentNode && n.tagName != 'BODY'){
497                n.parentNode.removeChild(n);
498            }
499        },
500
501        /**
502         * <p>Returns true if the passed value is empty.</p>
503         * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
504         * <li>null</li>
505         * <li>undefined</li>
506         * <li>an empty array</li>
507         * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
508         * </ul></div>
509         * @param {Mixed} value The value to test
510         * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
511         * @return {Boolean}
512         */
513        isEmpty : function(v, allowBlank){
514            return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
515        },
516
517        /**
518         * Returns true if the passed object is a JavaScript array, otherwise false.
519         * @param {Object} object The object to test
520         * @return {Boolean}
521         */
522        isArray : function(v){
523            return toString.apply(v) === '[object Array]';
524        },
525
526        /**
527         * Returns true if the passed object is a JavaScript Object, otherwise false.
528         * @param {Object} object The object to test
529         * @return {Boolean}
530         */
531        isObject : function(v){
532            return v && typeof v == "object";
533        },
534
535        /**
536         * Returns true if the passed object is a JavaScript 'primitive', a string, number or boolean.
537         * @param {Mixed} value The value to test
538         * @return {Boolean}
539         */
540        isPrimitive : function(v){
541            return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
542        },
543
544        /**
545         * Returns true if the passed object is a JavaScript Function, otherwise false.
546         * @param {Object} object The object to test
547         * @return {Boolean}
548         */
549        isFunction : function(v){
550            return toString.apply(v) === '[object Function]';
551        },
552
553        /**
554         * Returns true if the passed object is a number. Returns false for non-finite numbers.
555         * @param {Object} v The object to test
556         * @return {Boolean}
557         */
558        isNumber: function(v){
559            return typeof v === 'number' && isFinite(v);
560        },
561
562        /**
563         * Returns true if the passed object is a string.
564         * @param {Object} v The object to test
565         * @return {Boolean}
566         */
567        isString: function(v){
568            return typeof v === 'string';
569        },
570
571        /**
572         * Returns true if the passed object is a boolean.
573         * @param {Object} v The object to test
574         * @return {Boolean}
575         */
576        isBoolean: function(v){
577            return typeof v === 'boolean';
578        },
579
580        /**
581         * Returns true if the passed object is not undefined.
582         * @param {Object} v The object to test
583         * @return {Boolean}
584         */
585        isDefined: function(v){
586            return typeof v !== 'undefined';
587        },
588
589        /**
590         * True if the detected browser is Opera.
591         * @type Boolean
592         */
593        isOpera : isOpera,
594        /**
595         * True if the detected browser uses WebKit.
596         * @type Boolean
597         */
598        isWebKit: isWebKit,
599        /**
600         * True if the detected browser is Chrome.
601         * @type Boolean
602         */
603        isChrome : isChrome,
604        /**
605         * True if the detected browser is Safari.
606         * @type Boolean
607         */
608        isSafari : isSafari,
609        /**
610         * True if the detected browser is Safari 3.x.
611         * @type Boolean
612         */
613        isSafari3 : isSafari3,
614        /**
615         * True if the detected browser is Safari 4.x.
616         * @type Boolean
617         */
618        isSafari4 : isSafari4,
619        /**
620         * True if the detected browser is Safari 2.x.
621         * @type Boolean
622         */
623        isSafari2 : isSafari2,
624        /**
625         * True if the detected browser is Internet Explorer.
626         * @type Boolean
627         */
628        isIE : isIE,
629        /**
630         * True if the detected browser is Internet Explorer 6.x.
631         * @type Boolean
632         */
633        isIE6 : isIE6,
634        /**
635         * True if the detected browser is Internet Explorer 7.x.
636         * @type Boolean
637         */
638        isIE7 : isIE7,
639        /**
640         * True if the detected browser is Internet Explorer 8.x.
641         * @type Boolean
642         */
643        isIE8 : isIE8,
644        /**
645         * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
646         * @type Boolean
647         */
648        isGecko : isGecko,
649        /**
650         * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
651         * @type Boolean
652         */
653        isGecko2 : isGecko2,
654        /**
655         * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
656         * @type Boolean
657         */
658        isGecko3 : isGecko3,
659        /**
660         * True if the detected browser is Internet Explorer running in non-strict mode.
661         * @type Boolean
662         */
663        isBorderBox : isBorderBox,
664        /**
665         * True if the detected platform is Linux.
666         * @type Boolean
667         */
668        isLinux : isLinux,
669        /**
670         * True if the detected platform is Windows.
671         * @type Boolean
672         */
673        isWindows : isWindows,
674        /**
675         * True if the detected platform is Mac OS.
676         * @type Boolean
677         */
678        isMac : isMac,
679        /**
680         * True if the detected platform is Adobe Air.
681         * @type Boolean
682         */
683        isAir : isAir
684    });
685
686    /**
687     * Creates namespaces to be used for scoping variables and classes so that they are not global.
688     * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
689     * <pre><code>
690Ext.namespace('Company', 'Company.data');
691Ext.namespace('Company.data'); // equivalent and preferable to above syntax
692Company.Widget = function() { ... }
693Company.data.CustomStore = function(config) { ... }
694</code></pre>
695     * @param {String} namespace1
696     * @param {String} namespace2
697     * @param {String} etc
698     * @method namespace
699     */
700    Ext.ns = Ext.namespace;
701})();
702
703Ext.ns("Ext", "Ext.util", "Ext.lib", "Ext.data");
704
705
706/**
707 * @class Function
708 * These functions are available on every Function object (any JavaScript function).
709 */
710Ext.apply(Function.prototype, {
711     /**
712     * Creates an interceptor function. The passed fcn is called before the original one. If it returns false,
713     * the original one is not called. The resulting function returns the results of the original function.
714     * The passed fcn is called with the parameters of the original function. Example usage:
715     * <pre><code>
716var sayHi = function(name){
717    alert('Hi, ' + name);
718}
719
720sayHi('Fred'); // alerts "Hi, Fred"
721
722// create a new function that validates input without
723// directly modifying the original function:
724var sayHiToFriend = sayHi.createInterceptor(function(name){
725    return name == 'Brian';
726});
727
728sayHiToFriend('Fred');  // no alert
729sayHiToFriend('Brian'); // alerts "Hi, Brian"
730</code></pre>
731     * @param {Function} fcn The function to call before the original
732     * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
733     * @return {Function} The new function
734     */
735    createInterceptor : function(fcn, scope){
736        var method = this;
737        return !Ext.isFunction(fcn) ?
738                this :
739                function() {
740                    var me = this,
741                        args = arguments;
742                    fcn.target = me;
743                    fcn.method = method;
744                    return (fcn.apply(scope || me || window, args) !== false) ?
745                            method.apply(me || window, args) :
746                            null;
747                };
748    },
749
750     /**
751     * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
752     * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
753     * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
754     * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
755     * executes in the window scope.
756     * <p>This method is required when you want to pass arguments to a callback function.  If no arguments
757     * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).
758     * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
759     * would simply execute immediately when the code is parsed. Example usage:
760     * <pre><code>
761var sayHi = function(name){
762    alert('Hi, ' + name);
763}
764
765// clicking the button alerts "Hi, Fred"
766new Ext.Button({
767    text: 'Say Hi',
768    renderTo: Ext.getBody(),
769    handler: sayHi.createCallback('Fred')
770});
771</code></pre>
772     * @return {Function} The new function
773    */
774    createCallback : function(/*args...*/){
775        // make args available, in function below
776        var args = arguments,
777            method = this;
778        return function() {
779            return method.apply(window, args);
780        };
781    },
782
783    /**
784     * Creates a delegate (callback) that sets the scope to obj.
785     * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
786     * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
787     * callback points to obj. Example usage:
788     * <pre><code>
789var sayHi = function(name){
790    // Note this use of "this.text" here.  This function expects to
791    // execute within a scope that contains a text property.  In this
792    // example, the "this" variable is pointing to the btn object that
793    // was passed in createDelegate below.
794    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
795}
796
797var btn = new Ext.Button({
798    text: 'Say Hi',
799    renderTo: Ext.getBody()
800});
801
802// This callback will execute in the scope of the
803// button instance. Clicking the button alerts
804// "Hi, Fred. You clicked the "Say Hi" button."
805btn.on('click', sayHi.createDelegate(btn, ['Fred']));
806</code></pre>
807     * @param {Object} obj (optional) The object for which the scope is set
808     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
809     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
810     *                                             if a number the args are inserted at the specified position
811     * @return {Function} The new function
812     */
813    createDelegate : function(obj, args, appendArgs){
814        var method = this;
815        return function() {
816            var callArgs = args || arguments;
817            if (appendArgs === true){
818                callArgs = Array.prototype.slice.call(arguments, 0);
819                callArgs = callArgs.concat(args);
820            }else if (Ext.isNumber(appendArgs)){
821                callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
822                var applyArgs = [appendArgs, 0].concat(args); // create method call params
823                Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
824            }
825            return method.apply(obj || window, callArgs);
826        };
827    },
828
829    /**
830     * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
831     * <pre><code>
832var sayHi = function(name){
833    alert('Hi, ' + name);
834}
835
836// executes immediately:
837sayHi('Fred');
838
839// executes after 2 seconds:
840sayHi.defer(2000, this, ['Fred']);
841
842// this syntax is sometimes useful for deferring
843// execution of an anonymous function:
844(function(){
845    alert('Anonymous');
846}).defer(100);
847</code></pre>
848     * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
849     * @param {Object} obj (optional) The object for which the scope is set
850     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
851     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
852     *                                             if a number the args are inserted at the specified position
853     * @return {Number} The timeout id that can be used with clearTimeout
854     */
855    defer : function(millis, obj, args, appendArgs){
856        var fn = this.createDelegate(obj, args, appendArgs);
857        if(millis > 0){
858            return setTimeout(fn, millis);
859        }
860        fn();
861        return 0;
862    }
863});
864
865/**
866 * @class String
867 * These functions are available on every String object.
868 */
869Ext.applyIf(String, {
870    /**
871     * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each
872     * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:
873     * <pre><code>
874var cls = 'my-class', text = 'Some text';
875var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
876// s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
877     * </code></pre>
878     * @param {String} string The tokenized string to be formatted
879     * @param {String} value1 The value to replace token {0}
880     * @param {String} value2 Etc...
881     * @return {String} The formatted string
882     * @static
883     */
884    format : function(format){
885        var args = Ext.toArray(arguments, 1);
886        return format.replace(/\{(\d+)\}/g, function(m, i){
887            return args[i];
888        });
889    }
890});
891
892/**
893 * @class Array
894 */
895Ext.applyIf(Array.prototype, {
896    /**
897     * Checks whether or not the specified object exists in the array.
898     * @param {Object} o The object to check for
899     * @return {Number} The index of o in the array (or -1 if it is not found)
900     */
901    indexOf : function(o){
902        for (var i = 0, len = this.length; i < len; i++){
903            if(this[i] == o){
904                return i;
905            }
906        }
907        return -1;
908    },
909
910    /**
911     * Removes the specified object from the array.  If the object is not found nothing happens.
912     * @param {Object} o The object to remove
913     * @return {Array} this array
914     */
915    remove : function(o){
916        var index = this.indexOf(o);
917        if(index != -1){
918            this.splice(index, 1);
919        }
920        return this;
921    }
922});
Note: See TracBrowser for help on using the repository browser.