Subversion Repositories eFlore/Applications.cel

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
27 jpm 1
/*
2
 * Ext JS Library 2.0.2
3
 * Copyright(c) 2006-2008, Ext JS, LLC.
4
 * licensing@extjs.com
5
 *
6
 * http://extjs.com/license
7
 */
8
 
9
 
10
Ext = {version: '2.0.1'};
11
 
12
// for old browsers
13
window["undefined"] = window["undefined"];
14
 
15
/**
16
 * @class Ext
17
 * Ext core utilities and functions.
18
 * @singleton
19
 */
20
 
21
/**
22
 * Copies all the properties of config to obj.
23
 * @param {Object} obj The receiver of the properties
24
 * @param {Object} config The source of the properties
25
 * @param {Object} defaults A different object that will also be applied for default values
26
 * @return {Object} returns obj
27
 * @member Ext apply
28
 */
29
Ext.apply = function(o, c, defaults){
30
    if(defaults){
31
        // no "this" reference for friendly out of scope calls
32
        Ext.apply(o, defaults);
33
    }
34
    if(o && c && typeof c == 'object'){
35
        for(var p in c){
36
            o[p] = c[p];
37
        }
38
    }
39
    return o;
40
};
41
 
42
(function(){
43
    var idSeed = 0;
44
    var ua = navigator.userAgent.toLowerCase();
45
 
46
    var isStrict = document.compatMode == "CSS1Compat",
47
        isOpera = ua.indexOf("opera") > -1,
48
        isSafari = (/webkit|khtml/).test(ua),
49
        isSafari3 = isSafari && ua.indexOf('webkit/5') != -1,
50
        isIE = !isOpera && ua.indexOf("msie") > -1,
51
        isIE7 = !isOpera && ua.indexOf("msie 7") > -1,
52
        isGecko = !isSafari && ua.indexOf("gecko") > -1,
53
        isBorderBox = isIE && !isStrict,
54
        isWindows = (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1),
55
        isMac = (ua.indexOf("macintosh") != -1 || ua.indexOf("mac os x") != -1),
56
        isAir = (ua.indexOf("adobeair") != -1),
57
        isLinux = (ua.indexOf("linux") != -1),
58
        isSecure = window.location.href.toLowerCase().indexOf("https") === 0;
59
 
60
    // remove css image flicker
61
	if(isIE && !isIE7){
62
        try{
63
            document.execCommand("BackgroundImageCache", false, true);
64
        }catch(e){}
65
    }
66
 
67
    Ext.apply(Ext, {
68
        /**
69
         * True if the browser is in strict mode
70
         * @type Boolean
71
         */
72
        isStrict : isStrict,
73
        /**
74
         * True if the page is running over SSL
75
         * @type Boolean
76
         */
77
        isSecure : isSecure,
78
        /**
79
         * True when the document is fully initialized and ready for action
80
         * @type Boolean
81
         */
82
        isReady : false,
83
 
84
        /**
85
         * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
86
         * @type Boolean
87
         */
88
        enableGarbageCollector : true,
89
 
90
        /**
91
         * True to automatically purge event listeners after uncaching an element (defaults to false).
92
         * Note: this only happens if enableGarbageCollector is true.
93
         * @type Boolean
94
         */
95
        enableListenerCollection:false,
96
 
97
 
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
        /**
106
         * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. (Defaults to
107
         * "http://extjs.com/s.gif" and you should change this to a URL on your server).
108
         * @type String
109
         */
110
        BLANK_IMAGE_URL : "http:/"+"/extjs.com/s.gif",
111
 
112
        /**
113
        * A reusable empty function
114
        * @property
115
         * @type Function
116
        */
117
        emptyFn : function(){},
118
 
119
        /**
120
         * Copies all the properties of config to obj if they don't already exist.
121
         * @param {Object} obj The receiver of the properties
122
         * @param {Object} config The source of the properties
123
         * @return {Object} returns obj
124
         */
125
        applyIf : function(o, c){
126
            if(o && c){
127
                for(var p in c){
128
                    if(typeof o[p] == "undefined"){ o[p] = c[p]; }
129
                }
130
            }
131
            return o;
132
        },
133
 
134
        /**
135
         * Applies event listeners to elements by selectors when the document is ready.
136
         * The event name is specified with an @ suffix.
137
<pre><code>
138
Ext.addBehaviors({
139
   // add a listener for click on all anchors in element with id foo
140
   '#foo a@click' : function(e, t){
141
       // do something
142
   },
143
 
144
   // add the same listener to multiple selectors (separated by comma BEFORE the @)
145
   '#foo a, #bar span.some-class@mouseover' : function(){
146
       // do something
147
   }
148
});
149
</code></pre>
150
         * @param {Object} obj The list of behaviors to apply
151
         */
152
        addBehaviors : function(o){
153
            if(!Ext.isReady){
154
                Ext.onReady(function(){
155
                    Ext.addBehaviors(o);
156
                });
157
                return;
158
            }
159
            var cache = {}; // simple cache for applying multiple behaviors to same selector does query multiple times
160
            for(var b in o){
161
                var parts = b.split('@');
162
                if(parts[1]){ // for Object prototype breakers
163
                    var s = parts[0];
164
                    if(!cache[s]){
165
                        cache[s] = Ext.select(s);
166
                    }
167
                    cache[s].on(parts[1], o[b]);
168
                }
169
            }
170
            cache = null;
171
        },
172
 
173
        /**
174
         * Generates unique ids. If the element already has an id, it is unchanged
175
         * @param {Mixed} el (optional) The element to generate an id for
176
         * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
177
         * @return {String} The generated Id.
178
         */
179
        id : function(el, prefix){
180
            prefix = prefix || "ext-gen";
181
            el = Ext.getDom(el);
182
            var id = prefix + (++idSeed);
183
            return el ? (el.id ? el.id : (el.id = id)) : id;
184
        },
185
 
186
        /**
187
         * Extends one class with another class and optionally overrides members with the passed literal. This class
188
         * also adds the function "override()" to the class that can be used to override
189
         * members on an instance.
190
         * @param {Function} subclass The class inheriting the functionality
191
         * @param {Function} superclass The class being extended
192
         * @param {Object} overrides (optional) A literal with members which are copied into the subclass's
193
         * prototype, and are therefore shared between all instances of the new class.
194
         * @return {Function} The subclass constructor.
195
         * <p>
196
         * This function also supports a 2 argument call in which the subclass's constructor is
197
         * not passed as an argument. In this form, the parameters as as follows:</p><p>
198
         * <div class="mdetail-params"><ul>
199
         * <li><code>superclass</code>
200
         * <div class="sub-desc">The class being extended</div></li>
201
         * <li><code>overrides</code>
202
         * <div class="sub-desc">A literal with members which are copied into the subclass's
203
         * prototype, and are therefore shared between all instance of the new class.<p>
204
         * This may contain a special member named <tt><b>constructor</b></tt>. This is used
205
         * to define the constructor of the new class, and is returned. If this property is
206
         * <i>not</i> specified, a constructor is generated and returned which just calls the
207
         * superclass's constructor passing on its parameters.</p></div></li>
208
         * </ul></div></p><p>
209
         * For example, to create a subclass of the Ext GridPanel:
210
         * <pre><code>
211
    MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
212
        constructor: function(config) {
213
            // Your preprocessing here
214
        	MyGridPanel.superclass.constructor.apply(this, arguments);
215
            // Your postprocessing here
216
        },
217
 
218
        yourMethod: function() {
219
            // etc.
220
        }
221
    });
222
</code></pre>
223
         * </p>
224
         * @method extend
225
         */
226
        extend : function(){
227
            // inline overrides
228
            var io = function(o){
229
                for(var m in o){
230
                    this[m] = o[m];
231
                }
232
            };
233
            var oc = Object.prototype.constructor;
234
 
235
            return function(sb, sp, overrides){
236
                if(typeof sp == 'object'){
237
                    overrides = sp;
238
                    sp = sb;
239
                    sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
240
                }
241
                var F = function(){}, sbp, spp = sp.prototype;
242
                F.prototype = spp;
243
                sbp = sb.prototype = new F();
244
                sbp.constructor=sb;
245
                sb.superclass=spp;
246
                if(spp.constructor == oc){
247
                    spp.constructor=sp;
248
                }
249
                sb.override = function(o){
250
                    Ext.override(sb, o);
251
                };
252
                sbp.override = io;
253
                Ext.override(sb, overrides);
254
                sb.extend = function(o){Ext.extend(sb, o);};
255
                return sb;
256
            };
257
        }(),
258
 
259
        /**
260
         * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
261
         * Usage:<pre><code>
262
Ext.override(MyClass, {
263
    newMethod1: function(){
264
        // etc.
265
    },
266
    newMethod2: function(foo){
267
        // etc.
268
    }
269
});
270
 </code></pre>
271
         * @param {Object} origclass The class to override
272
         * @param {Object} overrides The list of functions to add to origClass.  This should be specified as an object literal
273
         * containing one or more methods.
274
         * @method override
275
         */
276
        override : function(origclass, overrides){
277
            if(overrides){
278
                var p = origclass.prototype;
279
                for(var method in overrides){
280
                    p[method] = overrides[method];
281
                }
282
            }
283
        },
284
 
285
        /**
286
         * Creates namespaces to be used for scoping variables and classes so that they are not global.  Usage:
287
         * <pre><code>
288
Ext.namespace('Company', 'Company.data');
289
Company.Widget = function() { ... }
290
Company.data.CustomStore = function(config) { ... }
291
</code></pre>
292
         * @param {String} namespace1
293
         * @param {String} namespace2
294
         * @param {String} etc
295
         * @method namespace
296
         */
297
        namespace : function(){
298
            var a=arguments, o=null, i, j, d, rt;
299
            for (i=0; i<a.length; ++i) {
300
                d=a[i].split(".");
301
                rt = d[0];
302
                eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';');
303
                for (j=1; j<d.length; ++j) {
304
                    o[d[j]]=o[d[j]] || {};
305
                    o=o[d[j]];
306
                }
307
            }
308
        },
309
 
310
        /**
311
         * 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.
312
         * @param {Object} o
313
         * @return {String}
314
         */
315
        urlEncode : function(o){
316
            if(!o){
317
                return "";
318
            }
319
            var buf = [];
320
            for(var key in o){
321
                var ov = o[key], k = encodeURIComponent(key);
322
                var type = typeof ov;
323
                if(type == 'undefined'){
324
                    buf.push(k, "=&");
325
                }else if(type != "function" && type != "object"){
326
                    buf.push(k, "=", encodeURIComponent(ov), "&");
327
                }else if(Ext.isArray(ov)){
328
                    if (ov.length) {
329
	                    for(var i = 0, len = ov.length; i < len; i++) {
330
	                        buf.push(k, "=", encodeURIComponent(ov[i] === undefined ? '' : ov[i]), "&");
331
	                    }
332
	                } else {
333
	                    buf.push(k, "=&");
334
	                }
335
                }
336
            }
337
            buf.pop();
338
            return buf.join("");
339
        },
340
 
341
        /**
342
         * Takes an encoded URL and and converts it to an object. e.g. Ext.urlDecode("foo=1&bar=2"); would return {foo: 1, bar: 2} or Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", true); would return {foo: 1, bar: [2, 3, 4]}.
343
         * @param {String} string
344
         * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
345
         * @return {Object} A literal with members
346
         */
347
        urlDecode : function(string, overwrite){
348
            if(!string || !string.length){
349
                return {};
350
            }
351
            var obj = {};
352
            var pairs = string.split('&');
353
            var pair, name, value;
354
            for(var i = 0, len = pairs.length; i < len; i++){
355
                pair = pairs[i].split('=');
356
                name = decodeURIComponent(pair[0]);
357
                value = decodeURIComponent(pair[1]);
358
                if(overwrite !== true){
359
                    if(typeof obj[name] == "undefined"){
360
                        obj[name] = value;
361
                    }else if(typeof obj[name] == "string"){
362
                        obj[name] = [obj[name]];
363
                        obj[name].push(value);
364
                    }else{
365
                        obj[name].push(value);
366
                    }
367
                }else{
368
                    obj[name] = value;
369
                }
370
            }
371
            return obj;
372
        },
373
 
374
        /**
375
         * Iterates an array calling the passed function with each item, stopping if your function returns false. If the
376
         * passed array is not really an array, your function is called once with it.
377
         * The supplied function is called with (Object item, Number index, Array allItems).
378
         * @param {Array/NodeList/Mixed} array
379
         * @param {Function} fn
380
         * @param {Object} scope
381
         */
382
        each : function(array, fn, scope){
383
            if(typeof array.length == "undefined" || typeof array == "string"){
384
                array = [array];
385
            }
386
            for(var i = 0, len = array.length; i < len; i++){
387
                if(fn.call(scope || array[i], array[i], i, array) === false){ return i; };
388
            }
389
        },
390
 
391
        // deprecated
392
        combine : function(){
393
            var as = arguments, l = as.length, r = [];
394
            for(var i = 0; i < l; i++){
395
                var a = as[i];
396
                if(Ext.isArray(a)){
397
                    r = r.concat(a);
398
                }else if(a.length !== undefined && !a.substr){
399
                    r = r.concat(Array.prototype.slice.call(a, 0));
400
                }else{
401
                    r.push(a);
402
                }
403
            }
404
            return r;
405
        },
406
 
407
        /**
408
         * Escapes the passed string for use in a regular expression
409
         * @param {String} str
410
         * @return {String}
411
         */
412
        escapeRe : function(s) {
413
            return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");
414
        },
415
 
416
        // internal
417
        callback : function(cb, scope, args, delay){
418
            if(typeof cb == "function"){
419
                if(delay){
420
                    cb.defer(delay, scope, args || []);
421
                }else{
422
                    cb.apply(scope, args || []);
423
                }
424
            }
425
        },
426
 
427
        /**
428
         * Return the dom node for the passed string (id), dom node, or Ext.Element
429
         * @param {Mixed} el
430
         * @return HTMLElement
431
         */
432
        getDom : function(el){
433
            if(!el || !document){
434
                return null;
435
            }
436
            return el.dom ? el.dom : (typeof el == 'string' ? document.getElementById(el) : el);
437
        },
438
 
439
        /**
440
        * Returns the current HTML document object as an {@link Ext.Element}.
441
        * @return Ext.Element The document
442
        */
443
        getDoc : function(){
444
            return Ext.get(document);
445
        },
446
 
447
        /**
448
        * Returns the current document body as an {@link Ext.Element}.
449
        * @return Ext.Element The document body
450
        */
451
        getBody : function(){
452
            return Ext.get(document.body || document.documentElement);
453
        },
454
 
455
        /**
456
        * Shorthand for {@link Ext.ComponentMgr#get}
457
        * @param {String} id
458
        * @return Ext.Component
459
        */
460
        getCmp : function(id){
461
            return Ext.ComponentMgr.get(id);
462
        },
463
 
464
        /**
465
         * Utility method for validating that a value is numeric, returning the specified default value if it is not.
466
         * @param {Mixed} value Should be a number, but any type will be handled appropriately
467
         * @param {Number} defaultValue The value to return if the original value is non-numeric
468
         * @return {Number} Value, if numeric, else defaultValue
469
         */
470
        num : function(v, defaultValue){
471
            if(typeof v != 'number'){
472
                return defaultValue;
473
            }
474
            return v;
475
        },
476
 
477
        /**
478
         * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
479
         * DOM (if applicable) and calling their destroy functions (if available).  This method is primarily
480
         * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
481
         * {@link Ext.util.Observable} can be passed in.  Any number of elements and/or components can be
482
         * passed into this function in a single call as separate arguments.
483
         * @param {Mixed} arg1 An {@link Ext.Element} or {@link Ext.Component} to destroy
484
         * @param {Mixed} arg2 (optional)
485
         * @param {Mixed} etc... (optional)
486
         */
487
        destroy : function(){
488
            for(var i = 0, a = arguments, len = a.length; i < len; i++) {
489
                var as = a[i];
490
                if(as){
491
		            if(typeof as.destroy == 'function'){
492
		                as.destroy();
493
		            }
494
		            else if(as.dom){
495
		                as.removeAllListeners();
496
		                as.remove();
497
		            }
498
                }
499
            }
500
        },
501
 
502
        removeNode : isIE ? function(){
503
            var d;
504
            return function(n){
505
                if(n && n.tagName != 'BODY'){
506
                    d = d || document.createElement('div');
507
                    d.appendChild(n);
508
                    d.innerHTML = '';
509
                }
510
            }
511
        }() : function(n){
512
            if(n && n.parentNode && n.tagName != 'BODY'){
513
                n.parentNode.removeChild(n);
514
            }
515
        },
516
 
517
        // inpired by a similar function in mootools library
518
        /**
519
         * Returns the type of object that is passed in. If the object passed in is null or undefined it
520
         * return false otherwise it returns one of the following values:<ul>
521
         * <li><b>string</b>: If the object passed is a string</li>
522
         * <li><b>number</b>: If the object passed is a number</li>
523
         * <li><b>boolean</b>: If the object passed is a boolean value</li>
524
         * <li><b>function</b>: If the object passed is a function reference</li>
525
         * <li><b>object</b>: If the object passed is an object</li>
526
         * <li><b>array</b>: If the object passed is an array</li>
527
         * <li><b>regexp</b>: If the object passed is a regular expression</li>
528
         * <li><b>element</b>: If the object passed is a DOM Element</li>
529
         * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
530
         * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
531
         * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
532
         * @param {Mixed} object
533
         * @return {String}
534
         */
535
        type : function(o){
536
            if(o === undefined || o === null){
537
                return false;
538
            }
539
            if(o.htmlElement){
540
                return 'element';
541
            }
542
            var t = typeof o;
543
            if(t == 'object' && o.nodeName) {
544
                switch(o.nodeType) {
545
                    case 1: return 'element';
546
                    case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
547
                }
548
            }
549
            if(t == 'object' || t == 'function') {
550
                switch(o.constructor) {
551
                    case Array: return 'array';
552
                    case RegExp: return 'regexp';
553
                }
554
                if(typeof o.length == 'number' && typeof o.item == 'function') {
555
                    return 'nodelist';
556
                }
557
            }
558
            return t;
559
        },
560
 
561
        /**
562
         * Returns true if the passed value is null, undefined or an empty string (optional).
563
         * @param {Mixed} value The value to test
564
         * @param {Boolean} allowBlank (optional) Pass true if an empty string is not considered empty
565
         * @return {Boolean}
566
         */
567
        isEmpty : function(v, allowBlank){
568
            return v === null || v === undefined || (!allowBlank ? v === '' : false);
569
        },
570
 
571
        value : function(v, defaultValue, allowBlank){
572
            return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
573
        },
574
 
575
		isArray : function(v){
576
			return v && typeof v.pop == 'function';
577
		},
578
 
579
		isDate : function(v){
580
			return v && typeof v.getFullYear == 'function';
581
		},
582
 
583
        /** @type Boolean */
584
        isOpera : isOpera,
585
        /** @type Boolean */
586
        isSafari : isSafari,
587
        /** @type Boolean */
588
        isSafari3 : isSafari3,
589
        /** @type Boolean */
590
        isSafari2 : isSafari && !isSafari3,
591
        /** @type Boolean */
592
        isIE : isIE,
593
        /** @type Boolean */
594
        isIE6 : isIE && !isIE7,
595
        /** @type Boolean */
596
        isIE7 : isIE7,
597
        /** @type Boolean */
598
        isGecko : isGecko,
599
        /** @type Boolean */
600
        isBorderBox : isBorderBox,
601
        /** @type Boolean */
602
        isLinux : isLinux,
603
        /** @type Boolean */
604
        isWindows : isWindows,
605
        /** @type Boolean */
606
        isMac : isMac,
607
        /** @type Boolean */
608
        isAir : isAir,
609
 
610
    /**
611
     By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
612
     you may want to set this to true.
613
     @type Boolean
614
     */
615
        useShims : ((isIE && !isIE7) || (isGecko && isMac))
616
    });
617
 
618
    // in intellij using keyword "namespace" causes parsing errors
619
    Ext.ns = Ext.namespace;
620
})();
621
 
622
Ext.ns("Ext", "Ext.util", "Ext.grid", "Ext.dd", "Ext.tree", "Ext.data",
623
                "Ext.form", "Ext.menu", "Ext.state", "Ext.lib", "Ext.layout", "Ext.app", "Ext.ux");
624
 
625
 
626
/**
627
 * @class Function
628
 * These functions are available on every Function object (any JavaScript function).
629
 */
630
Ext.apply(Function.prototype, {
631
     /**
632
     * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
633
     * Call directly on any function. Example: <code>myFunction.createCallback(myarg, myarg2)</code>
634
     * Will create a function that is bound to those 2 args.
635
     * @return {Function} The new function
636
    */
637
    createCallback : function(/*args...*/){
638
        // make args available, in function below
639
        var args = arguments;
640
        var method = this;
641
        return function() {
642
            return method.apply(window, args);
643
        };
644
    },
645
 
646
    /**
647
     * Creates a delegate (callback) that sets the scope to obj.
648
     * Call directly on any function. Example: <code>this.myFunction.createDelegate(this)</code>
649
     * Will create a function that is automatically scoped to this.
650
     * @param {Object} obj (optional) The object for which the scope is set
651
     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
652
     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
653
     *                                             if a number the args are inserted at the specified position
654
     * @return {Function} The new function
655
     */
656
    createDelegate : function(obj, args, appendArgs){
657
        var method = this;
658
        return function() {
659
            var callArgs = args || arguments;
660
            if(appendArgs === true){
661
                callArgs = Array.prototype.slice.call(arguments, 0);
662
                callArgs = callArgs.concat(args);
663
            }else if(typeof appendArgs == "number"){
664
                callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
665
                var applyArgs = [appendArgs, 0].concat(args); // create method call params
666
                Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
667
            }
668
            return method.apply(obj || window, callArgs);
669
        };
670
    },
671
 
672
    /**
673
     * Calls this function after the number of millseconds specified.
674
     * @param {Number} millis The number of milliseconds for the setTimeout call (if 0 the function is executed immediately)
675
     * @param {Object} obj (optional) The object for which the scope is set
676
     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
677
     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
678
     *                                             if a number the args are inserted at the specified position
679
     * @return {Number} The timeout id that can be used with clearTimeout
680
     */
681
    defer : function(millis, obj, args, appendArgs){
682
        var fn = this.createDelegate(obj, args, appendArgs);
683
        if(millis){
684
            return setTimeout(fn, millis);
685
        }
686
        fn();
687
        return 0;
688
    },
689
    /**
690
     * Create a combined function call sequence of the original function + the passed function.
691
     * The resulting function returns the results of the original function.
692
     * The passed fcn is called with the parameters of the original function
693
     * @param {Function} fcn The function to sequence
694
     * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
695
     * @return {Function} The new function
696
     */
697
    createSequence : function(fcn, scope){
698
        if(typeof fcn != "function"){
699
            return this;
700
        }
701
        var method = this;
702
        return function() {
703
            var retval = method.apply(this || window, arguments);
704
            fcn.apply(scope || this || window, arguments);
705
            return retval;
706
        };
707
    },
708
 
709
    /**
710
     * Creates an interceptor function. The passed fcn is called before the original one. If it returns false, the original one is not called.
711
     * The resulting function returns the results of the original function.
712
     * The passed fcn is called with the parameters of the original function.
713
     * @addon
714
     * @param {Function} fcn The function to call before the original
715
     * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
716
     * @return {Function} The new function
717
     */
718
    createInterceptor : function(fcn, scope){
719
        if(typeof fcn != "function"){
720
            return this;
721
        }
722
        var method = this;
723
        return function() {
724
            fcn.target = this;
725
            fcn.method = method;
726
            if(fcn.apply(scope || this || window, arguments) === false){
727
                return;
728
            }
729
            return method.apply(this || window, arguments);
730
        };
731
    }
732
});
733
 
734
/**
735
 * @class String
736
 * These functions are available as static methods on the JavaScript String object.
737
 */
738
Ext.applyIf(String, {
739
 
740
    /**
741
     * Escapes the passed string for ' and \
742
     * @param {String} string The string to escape
743
     * @return {String} The escaped string
744
     * @static
745
     */
746
    escape : function(string) {
747
        return string.replace(/('|\\)/g, "\\$1");
748
    },
749
 
750
    /**
751
     * Pads the left side of a string with a specified character.  This is especially useful
752
     * for normalizing number and date strings.  Example usage:
753
     * <pre><code>
754
var s = String.leftPad('123', 5, '0');
755
// s now contains the string: '00123'
756
</code></pre>
757
     * @param {String} string The original string
758
     * @param {Number} size The total length of the output string
759
     * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
760
     * @return {String} The padded string
761
     * @static
762
     */
763
    leftPad : function (val, size, ch) {
764
        var result = new String(val);
765
        if(!ch) {
766
            ch = " ";
767
        }
768
        while (result.length < size) {
769
            result = ch + result;
770
        }
771
        return result.toString();
772
    },
773
 
774
    /**
775
     * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each
776
     * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:
777
     * <pre><code>
778
var cls = 'my-class', text = 'Some text';
779
var s = String.format('<div class="{0}">{1}</div>', cls, text);
780
// s now contains the string: '<div class="my-class">Some text</div>'
781
</code></pre>
782
     * @param {String} string The tokenized string to be formatted
783
     * @param {String} value1 The value to replace token {0}
784
     * @param {String} value2 Etc...
785
     * @return {String} The formatted string
786
     * @static
787
     */
788
    format : function(format){
789
        var args = Array.prototype.slice.call(arguments, 1);
790
        return format.replace(/\{(\d+)\}/g, function(m, i){
791
            return args[i];
792
        });
793
    }
794
});
795
 
796
/**
797
 * Utility function that allows you to easily switch a string between two alternating values.  The passed value
798
 * is compared to the current string, and if they are equal, the other value that was passed in is returned.  If
799
 * they are already different, the first value passed in is returned.  Note that this method returns the new value
800
 * but does not change the current string.
801
 * <pre><code>
802
// alternate sort directions
803
sort = sort.toggle('ASC', 'DESC');
804
 
805
// instead of conditional logic:
806
sort = (sort == 'ASC' ? 'DESC' : 'ASC');
807
</code></pre>
808
 * @param {String} value The value to compare to the current string
809
 * @param {String} other The new value to use if the string already equals the first value passed in
810
 * @return {String} The new value
811
 */
812
String.prototype.toggle = function(value, other){
813
    return this == value ? other : value;
814
};
815
 
816
/**
817
 * Trims whitespace from either end of a string, leaving spaces within the string intact.  Example:
818
 * <pre><code>
819
var s = '  foo bar  ';
820
alert('-' + s + '-');         //alerts "- foo bar -"
821
alert('-' + s.trim() + '-');  //alerts "-foo bar-"
822
</code></pre>
823
 * @return {String} The trimmed string
824
 */
825
String.prototype.trim = function(){
826
    var re = /^\s+|\s+$/g;
827
    return function(){ return this.replace(re, ""); };
828
}();
829
/**
830
 * @class Number
831
 */
832
Ext.applyIf(Number.prototype, {
833
    /**
834
     * Checks whether or not the current number is within a desired range.  If the number is already within the
835
     * range it is returned, otherwise the min or max value is returned depending on which side of the range is
836
     * exceeded.  Note that this method returns the constrained value but does not change the current number.
837
     * @param {Number} min The minimum number in the range
838
     * @param {Number} max The maximum number in the range
839
     * @return {Number} The constrained value if outside the range, otherwise the current value
840
     */
841
    constrain : function(min, max){
842
        return Math.min(Math.max(this, min), max);
843
    }
844
});
845
/**
846
 * @class Array
847
 */
848
Ext.applyIf(Array.prototype, {
849
    /**
850
     * Checks whether or not the specified object exists in the array.
851
     * @param {Object} o The object to check for
852
     * @return {Number} The index of o in the array (or -1 if it is not found)
853
     */
854
    indexOf : function(o){
855
       for (var i = 0, len = this.length; i < len; i++){
856
 	      if(this[i] == o) return i;
857
       }
858
 	   return -1;
859
    },
860
 
861
    /**
862
     * Removes the specified object from the array.  If the object is not found nothing happens.
863
     * @param {Object} o The object to remove
864
     * @return {Array} this array
865
     */
866
    remove : function(o){
867
       var index = this.indexOf(o);
868
       if(index != -1){
869
           this.splice(index, 1);
870
       }
871
       return this;
872
    }
873
});
874
 
875
/**
876
 Returns the number of milliseconds between this date and date
877
 @param {Date} date (optional) Defaults to now
878
 @return {Number} The diff in milliseconds
879
 @member Date getElapsed
880
 */
881
Date.prototype.getElapsed = function(date) {
882
	return Math.abs((date || new Date()).getTime()-this.getTime());
883
};