Project

General

Profile

Revision 214

View differences:

trunk/scripts/extjs/ext-all-debug-w-comments.js
1
/*
2

  
3
This file is part of Ext JS 4
4

  
5
Copyright (c) 2011 Sencha Inc
6

  
7
Contact:  http://www.sencha.com/contact
8

  
9
Commercial Usage
10
Licensees holding valid commercial licenses may use this file in accordance with the Commercial Software License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and Sencha.
11

  
12
If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13

  
14
*/
15
/**
16
 * @class Ext
17
 * @singleton
18
 */
19
var Ext = Ext || {};
20
(function() {
21
    var global = this,
22
        objectPrototype = Object.prototype,
23
        toString = objectPrototype.toString,
24
        enumerables = true,
25
        enumerablesTest = { toString: 1 },
26
        emptyFn = function(){},
27
        i;
28

  
29
    if (typeof Ext === 'undefined') {
30
        global.Ext = {};
31
    }
32

  
33
    Ext.global = global;
34

  
35
    for (i in enumerablesTest) {
36
        enumerables = null;
37
    }
38

  
39
    if (enumerables) {
40
        enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable',
41
                       'toLocaleString', 'toString', 'constructor'];
42
    }
43

  
44
    /**
45
     * An array containing extra enumerables for old browsers
46
     * @property {String[]}
47
     */
48
    Ext.enumerables = enumerables;
49

  
50
    /**
51
     * Copies all the properties of config to the specified object.
52
     * Note that if recursive merging and cloning without referencing the original objects / arrays is needed, use
53
     * {@link Ext.Object#merge} instead.
54
     * @param {Object} object The receiver of the properties
55
     * @param {Object} config The source of the properties
56
     * @param {Object} defaults A different object that will also be applied for default values
57
     * @return {Object} returns obj
58
     */
59
    Ext.apply = function(object, config, defaults) {
60
        if (defaults) {
61
            Ext.apply(object, defaults);
62
        }
63

  
64
        if (object && config && typeof config === 'object') {
65
            var i, j, k;
66

  
67
            for (i in config) {
68
                object[i] = config[i];
69
            }
70

  
71
            if (enumerables) {
72
                for (j = enumerables.length; j--;) {
73
                    k = enumerables[j];
74
                    if (config.hasOwnProperty(k)) {
75
                        object[k] = config[k];
76
                    }
77
                }
78
            }
79
        }
80

  
81
        return object;
82
    };
83

  
84
    Ext.buildSettings = Ext.apply({
85
        baseCSSPrefix: 'x-',
86
        scopeResetCSS: false
87
    }, Ext.buildSettings || {});
88

  
89
    Ext.apply(Ext, {
90

  
91
        /**
92
         * @property {String} [name='Ext']
93
         * <p>The name of the property in the global namespace (The <code>window</code> in browser environments) which refers to the current instance of Ext.</p>
94
         * <p>This is usually <code>"Ext"</code>, but if a sandboxed build of ExtJS is being used, this will be an alternative name.</p>
95
         * <p>If code is being generated for use by <code>eval</code> or to create a <code>new Function</code>, and the global instance
96
         * of Ext must be referenced, this is the name that should be built into the code.</p>
97
         */
98
        name: Ext.sandboxName || 'Ext',
99

  
100
        /**
101
         * A reusable empty function
102
         */
103
        emptyFn: emptyFn,
104

  
105
        /**
106
         * A zero length string which will pass a truth test. Useful for passing to methods
107
         * which use a truth test to reject <i>falsy</i> values where a string value must be cleared.
108
         */
109
        emptyString: new String(),
110

  
111
        baseCSSPrefix: Ext.buildSettings.baseCSSPrefix,
112

  
113
        /**
114
         * Copies all the properties of config to object if they don't already exist.
115
         * @param {Object} object The receiver of the properties
116
         * @param {Object} config The source of the properties
117
         * @return {Object} returns obj
118
         */
119
        applyIf: function(object, config) {
120
            var property;
121

  
122
            if (object) {
123
                for (property in config) {
124
                    if (object[property] === undefined) {
125
                        object[property] = config[property];
126
                    }
127
                }
128
            }
129

  
130
            return object;
131
        },
132

  
133
        /**
134
         * Iterates either an array or an object. This method delegates to
135
         * {@link Ext.Array#each Ext.Array.each} if the given value is iterable, and {@link Ext.Object#each Ext.Object.each} otherwise.
136
         *
137
         * @param {Object/Array} object The object or array to be iterated.
138
         * @param {Function} fn The function to be called for each iteration. See and {@link Ext.Array#each Ext.Array.each} and
139
         * {@link Ext.Object#each Ext.Object.each} for detailed lists of arguments passed to this function depending on the given object
140
         * type that is being iterated.
141
         * @param {Object} scope (Optional) The scope (`this` reference) in which the specified function is executed.
142
         * Defaults to the object being iterated itself.
143
         * @markdown
144
         */
145
        iterate: function(object, fn, scope) {
146
            if (Ext.isEmpty(object)) {
147
                return;
148
            }
149

  
150
            if (scope === undefined) {
151
                scope = object;
152
            }
153

  
154
            if (Ext.isIterable(object)) {
155
                Ext.Array.each.call(Ext.Array, object, fn, scope);
156
            }
157
            else {
158
                Ext.Object.each.call(Ext.Object, object, fn, scope);
159
            }
160
        }
161
    });
162

  
163
    Ext.apply(Ext, {
164

  
165
        /**
166
         * This method deprecated. Use {@link Ext#define Ext.define} instead.
167
         * @method
168
         * @param {Function} superclass
169
         * @param {Object} overrides
170
         * @return {Function} The subclass constructor from the <tt>overrides</tt> parameter, or a generated one if not provided.
171
         * @deprecated 4.0.0 Use {@link Ext#define Ext.define} instead
172
         */
173
        extend: function() {
174
            // inline overrides
175
            var objectConstructor = objectPrototype.constructor,
176
                inlineOverrides = function(o) {
177
                for (var m in o) {
178
                    if (!o.hasOwnProperty(m)) {
179
                        continue;
180
                    }
181
                    this[m] = o[m];
182
                }
183
            };
184

  
185
            return function(subclass, superclass, overrides) {
186
                // First we check if the user passed in just the superClass with overrides
187
                if (Ext.isObject(superclass)) {
188
                    overrides = superclass;
189
                    superclass = subclass;
190
                    subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() {
191
                        superclass.apply(this, arguments);
192
                    };
193
                }
194

  
195

  
196
                // We create a new temporary class
197
                var F = function() {},
198
                    subclassProto, superclassProto = superclass.prototype;
199

  
200
                F.prototype = superclassProto;
201
                subclassProto = subclass.prototype = new F();
202
                subclassProto.constructor = subclass;
203
                subclass.superclass = superclassProto;
204

  
205
                if (superclassProto.constructor === objectConstructor) {
206
                    superclassProto.constructor = superclass;
207
                }
208

  
209
                subclass.override = function(overrides) {
210
                    Ext.override(subclass, overrides);
211
                };
212

  
213
                subclassProto.override = inlineOverrides;
214
                subclassProto.proto = subclassProto;
215

  
216
                subclass.override(overrides);
217
                subclass.extend = function(o) {
218
                    return Ext.extend(subclass, o);
219
                };
220

  
221
                return subclass;
222
            };
223
        }(),
224

  
225
        /**
226
         * Proxy to {@link Ext.Base#override}. Please refer {@link Ext.Base#override} for further details.
227
         *
228
         * @param {Object} cls The class to override
229
         * @param {Object} overrides The properties to add to origClass. This should be specified as an object literal
230
         * containing one or more properties.
231
         * @method override
232
         * @markdown
233
         * @deprecated 4.1.0 Use {@link Ext#define Ext.define} instead
234
         */
235
        override: function(cls, overrides) {
236
            if (cls.$isClass) {
237
                return cls.override(overrides);
238
            }
239
            else {
240
                Ext.apply(cls.prototype, overrides);
241
            }
242
        }
243
    });
244

  
245
    // A full set of static methods to do type checking
246
    Ext.apply(Ext, {
247

  
248
        /**
249
         * Returns the given value itself if it's not empty, as described in {@link Ext#isEmpty}; returns the default
250
         * value (second argument) otherwise.
251
         *
252
         * @param {Object} value The value to test
253
         * @param {Object} defaultValue The value to return if the original value is empty
254
         * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
255
         * @return {Object} value, if non-empty, else defaultValue
256
         */
257
        valueFrom: function(value, defaultValue, allowBlank){
258
            return Ext.isEmpty(value, allowBlank) ? defaultValue : value;
259
        },
260

  
261
        /**
262
         * Returns the type of the given variable in string format. List of possible values are:
263
         *
264
         * - `undefined`: If the given value is `undefined`
265
         * - `null`: If the given value is `null`
266
         * - `string`: If the given value is a string
267
         * - `number`: If the given value is a number
268
         * - `boolean`: If the given value is a boolean value
269
         * - `date`: If the given value is a `Date` object
270
         * - `function`: If the given value is a function reference
271
         * - `object`: If the given value is an object
272
         * - `array`: If the given value is an array
273
         * - `regexp`: If the given value is a regular expression
274
         * - `element`: If the given value is a DOM Element
275
         * - `textnode`: If the given value is a DOM text node and contains something other than whitespace
276
         * - `whitespace`: If the given value is a DOM text node and contains only whitespace
277
         *
278
         * @param {Object} value
279
         * @return {String}
280
         * @markdown
281
         */
282
        typeOf: function(value) {
283
            if (value === null) {
284
                return 'null';
285
            }
286

  
287
            var type = typeof value;
288

  
289
            if (type === 'undefined' || type === 'string' || type === 'number' || type === 'boolean') {
290
                return type;
291
            }
292

  
293
            var typeToString = toString.call(value);
294

  
295
            switch(typeToString) {
296
                case '[object Array]':
297
                    return 'array';
298
                case '[object Date]':
299
                    return 'date';
300
                case '[object Boolean]':
301
                    return 'boolean';
302
                case '[object Number]':
303
                    return 'number';
304
                case '[object RegExp]':
305
                    return 'regexp';
306
            }
307

  
308
            if (type === 'function') {
309
                return 'function';
310
            }
311

  
312
            if (type === 'object') {
313
                if (value.nodeType !== undefined) {
314
                    if (value.nodeType === 3) {
315
                        return (/\S/).test(value.nodeValue) ? 'textnode' : 'whitespace';
316
                    }
317
                    else {
318
                        return 'element';
319
                    }
320
                }
321

  
322
                return 'object';
323
            }
324

  
325
        },
326

  
327
        /**
328
         * Returns true if the passed value is empty, false otherwise. The value is deemed to be empty if it is either:
329
         *
330
         * - `null`
331
         * - `undefined`
332
         * - a zero-length array
333
         * - a zero-length string (Unless the `allowEmptyString` parameter is set to `true`)
334
         *
335
         * @param {Object} value The value to test
336
         * @param {Boolean} allowEmptyString (optional) true to allow empty strings (defaults to false)
337
         * @return {Boolean}
338
         * @markdown
339
         */
340
        isEmpty: function(value, allowEmptyString) {
341
            return (value === null) || (value === undefined) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0);
342
        },
343

  
344
        /**
345
         * Returns true if the passed value is a JavaScript Array, false otherwise.
346
         *
347
         * @param {Object} target The target to test
348
         * @return {Boolean}
349
         * @method
350
         */
351
        isArray: ('isArray' in Array) ? Array.isArray : function(value) {
352
            return toString.call(value) === '[object Array]';
353
        },
354

  
355
        /**
356
         * Returns true if the passed value is a JavaScript Date object, false otherwise.
357
         * @param {Object} object The object to test
358
         * @return {Boolean}
359
         */
360
        isDate: function(value) {
361
            return toString.call(value) === '[object Date]';
362
        },
363

  
364
        /**
365
         * Returns true if the passed value is a JavaScript Object, false otherwise.
366
         * @param {Object} value The value to test
367
         * @return {Boolean}
368
         * @method
369
         */
370
        isObject: (toString.call(null) === '[object Object]') ?
371
        function(value) {
372
            // check ownerDocument here as well to exclude DOM nodes
373
            return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.ownerDocument === undefined;
374
        } :
375
        function(value) {
376
            return toString.call(value) === '[object Object]';
377
        },
378

  
379
        /**
380
         * @private
381
         */
382
        isSimpleObject: function(value) {
383
            return value instanceof Object && value.constructor === Object;
384
        },
385
        /**
386
         * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean.
387
         * @param {Object} value The value to test
388
         * @return {Boolean}
389
         */
390
        isPrimitive: function(value) {
391
            var type = typeof value;
392

  
393
            return type === 'string' || type === 'number' || type === 'boolean';
394
        },
395

  
396
        /**
397
         * Returns true if the passed value is a JavaScript Function, false otherwise.
398
         * @param {Object} value The value to test
399
         * @return {Boolean}
400
         * @method
401
         */
402
        isFunction:
403
        // Safari 3.x and 4.x returns 'function' for typeof <NodeList>, hence we need to fall back to using
404
        // Object.prorotype.toString (slower)
405
        (typeof document !== 'undefined' && typeof document.getElementsByTagName('body') === 'function') ? function(value) {
406
            return toString.call(value) === '[object Function]';
407
        } : function(value) {
408
            return typeof value === 'function';
409
        },
410

  
411
        /**
412
         * Returns true if the passed value is a number. Returns false for non-finite numbers.
413
         * @param {Object} value The value to test
414
         * @return {Boolean}
415
         */
416
        isNumber: function(value) {
417
            return typeof value === 'number' && isFinite(value);
418
        },
419

  
420
        /**
421
         * Validates that a value is numeric.
422
         * @param {Object} value Examples: 1, '1', '2.34'
423
         * @return {Boolean} True if numeric, false otherwise
424
         */
425
        isNumeric: function(value) {
426
            return !isNaN(parseFloat(value)) && isFinite(value);
427
        },
428

  
429
        /**
430
         * Returns true if the passed value is a string.
431
         * @param {Object} value The value to test
432
         * @return {Boolean}
433
         */
434
        isString: function(value) {
435
            return typeof value === 'string';
436
        },
437

  
438
        /**
439
         * Returns true if the passed value is a boolean.
440
         *
441
         * @param {Object} value The value to test
442
         * @return {Boolean}
443
         */
444
        isBoolean: function(value) {
445
            return typeof value === 'boolean';
446
        },
447

  
448
        /**
449
         * Returns true if the passed value is an HTMLElement
450
         * @param {Object} value The value to test
451
         * @return {Boolean}
452
         */
453
        isElement: function(value) {
454
            return value ? value.nodeType === 1 : false;
455
        },
456

  
457
        /**
458
         * Returns true if the passed value is a TextNode
459
         * @param {Object} value The value to test
460
         * @return {Boolean}
461
         */
462
        isTextNode: function(value) {
463
            return value ? value.nodeName === "#text" : false;
464
        },
465

  
466
        /**
467
         * Returns true if the passed value is defined.
468
         * @param {Object} value The value to test
469
         * @return {Boolean}
470
         */
471
        isDefined: function(value) {
472
            return typeof value !== 'undefined';
473
        },
474

  
475
        /**
476
         * Returns true if the passed value is iterable, false otherwise
477
         * @param {Object} value The value to test
478
         * @return {Boolean}
479
         */
480
        isIterable: function(value) {
481
            var type = typeof value,
482
                checkLength = false;
483
            if (value && type != 'string') {
484
                // Functions have a length property, so we need to filter them out
485
                if (type == 'function') {
486
                    // In Safari, NodeList/HTMLCollection both return "function" when using typeof, so we need
487
                    // to explicitly check them here.
488
                    if (Ext.isSafari) {
489
                        checkLength = value instanceof NodeList || value instanceof HTMLCollection;
490
                    }
491
                } else {
492
                    checkLength = true;
493
                }
494
            }
495
            return checkLength ? value.length !== undefined : false;
496
        }
497
    });
498

  
499
    Ext.apply(Ext, {
500

  
501
        /**
502
         * Clone almost any type of variable including array, object, DOM nodes and Date without keeping the old reference
503
         * @param {Object} item The variable to clone
504
         * @return {Object} clone
505
         */
506
        clone: function(item) {
507
            if (item === null || item === undefined) {
508
                return item;
509
            }
510

  
511
            // DOM nodes
512
            // TODO proxy this to Ext.Element.clone to handle automatic id attribute changing
513
            // recursively
514
            if (item.nodeType && item.cloneNode) {
515
                return item.cloneNode(true);
516
            }
517

  
518
            var type = toString.call(item);
519

  
520
            // Date
521
            if (type === '[object Date]') {
522
                return new Date(item.getTime());
523
            }
524

  
525
            var i, j, k, clone, key;
526

  
527
            // Array
528
            if (type === '[object Array]') {
529
                i = item.length;
530

  
531
                clone = [];
532

  
533
                while (i--) {
534
                    clone[i] = Ext.clone(item[i]);
535
                }
536
            }
537
            // Object
538
            else if (type === '[object Object]' && item.constructor === Object) {
539
                clone = {};
540

  
541
                for (key in item) {
542
                    clone[key] = Ext.clone(item[key]);
543
                }
544

  
545
                if (enumerables) {
546
                    for (j = enumerables.length; j--;) {
547
                        k = enumerables[j];
548
                        clone[k] = item[k];
549
                    }
550
                }
551
            }
552

  
553
            return clone || item;
554
        },
555

  
556
        /**
557
         * @private
558
         * Generate a unique reference of Ext in the global scope, useful for sandboxing
559
         */
560
        getUniqueGlobalNamespace: function() {
561
            var uniqueGlobalNamespace = this.uniqueGlobalNamespace;
562

  
563
            if (uniqueGlobalNamespace === undefined) {
564
                var i = 0;
565

  
566
                do {
567
                    uniqueGlobalNamespace = 'ExtBox' + (++i);
568
                } while (Ext.global[uniqueGlobalNamespace] !== undefined);
569

  
570
                Ext.global[uniqueGlobalNamespace] = Ext;
571
                this.uniqueGlobalNamespace = uniqueGlobalNamespace;
572
            }
573

  
574
            return uniqueGlobalNamespace;
575
        },
576
        
577
        /**
578
         * @private
579
         */
580
        functionFactoryCache: {},
581
        
582
        cacheableFunctionFactory: function() {
583
            var me = this,
584
                args = Array.prototype.slice.call(arguments),
585
                cache = me.functionFactoryCache,
586
                idx, fn, ln;
587
                
588
             if (Ext.enableSandbox) {
589
                ln = args.length;
590
                if (ln > 0) {
591
                    ln--;
592
                    args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
593
                }
594
            }
595
            idx = args.join('');
596
            fn = cache[idx];
597
            if (!fn) {
598
                fn = Function.prototype.constructor.apply(Function.prototype, args);
599
                
600
                cache[idx] = fn;
601
            }
602
            return fn;
603
        },
604
        
605
        functionFactory: function() {
606
            var me = this,
607
                args = Array.prototype.slice.call(arguments),
608
                ln;
609
                
610
            if (Ext.enableSandbox) {
611
                ln = args.length;
612
                if (ln > 0) {
613
                    ln--;
614
                    args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
615
                }
616
            }
617
     
618
            return Function.prototype.constructor.apply(Function.prototype, args);
619
        },
620

  
621
        /**
622
         * @property
623
         * @private
624
         */
625
        globalEval: ('execScript' in global) ? function(code) {
626
            global.execScript(code)
627
        } : function(code) {
628
            (function(){
629
                eval(code);
630
            })();
631
        },
632

  
633
        /**
634
         * @private
635
         * @property
636
         */
637
        Logger: {
638
            verbose: emptyFn,
639
            log: emptyFn,
640
            info: emptyFn,
641
            warn: emptyFn,
642
            error: function(message) {
643
                throw new Error(message);
644
            },
645
            deprecate: emptyFn
646
        }
647
    });
648

  
649
    /**
650
     * Old alias to {@link Ext#typeOf}
651
     * @deprecated 4.0.0 Use {@link Ext#typeOf} instead
652
     * @method
653
     * @inheritdoc Ext#typeOf
654
     */
655
    Ext.type = Ext.typeOf;
656

  
657
})();
658

  
659
/**
660
 * @author Jacky Nguyen <jacky@sencha.com>
661
 * @docauthor Jacky Nguyen <jacky@sencha.com>
662
 * @class Ext.Version
663
 *
664
 * A utility class that wrap around a string version number and provide convenient
665
 * method to perform comparison. See also: {@link Ext.Version#compare compare}. Example:
666

  
667
    var version = new Ext.Version('1.0.2beta');
668
    console.log("Version is " + version); // Version is 1.0.2beta
669

  
670
    console.log(version.getMajor()); // 1
671
    console.log(version.getMinor()); // 0
672
    console.log(version.getPatch()); // 2
673
    console.log(version.getBuild()); // 0
674
    console.log(version.getRelease()); // beta
675

  
676
    console.log(version.isGreaterThan('1.0.1')); // True
677
    console.log(version.isGreaterThan('1.0.2alpha')); // True
678
    console.log(version.isGreaterThan('1.0.2RC')); // False
679
    console.log(version.isGreaterThan('1.0.2')); // False
680
    console.log(version.isLessThan('1.0.2')); // True
681

  
682
    console.log(version.match(1.0)); // True
683
    console.log(version.match('1.0.2')); // True
684

  
685
 * @markdown
686
 */
687
(function() {
688

  
689
// Current core version
690
var version = '4.1.0', Version;
691
    Ext.Version = Version = Ext.extend(Object, {
692

  
693
        /**
694
         * @param {String/Number} version The version number in the follow standard format: major[.minor[.patch[.build[release]]]]
695
         * Examples: 1.0 or 1.2.3beta or 1.2.3.4RC
696
         * @return {Ext.Version} this
697
         */
698
        constructor: function(version) {
699
            var parts, releaseStartIndex;
700

  
701
            if (version instanceof Version) {
702
                return version;
703
            }
704

  
705
            this.version = this.shortVersion = String(version).toLowerCase().replace(/_/g, '.').replace(/[\-+]/g, '');
706

  
707
            releaseStartIndex = this.version.search(/([^\d\.])/);
708

  
709
            if (releaseStartIndex !== -1) {
710
                this.release = this.version.substr(releaseStartIndex, version.length);
711
                this.shortVersion = this.version.substr(0, releaseStartIndex);
712
            }
713

  
714
            this.shortVersion = this.shortVersion.replace(/[^\d]/g, '');
715

  
716
            parts = this.version.split('.');
717

  
718
            this.major = parseInt(parts.shift() || 0, 10);
719
            this.minor = parseInt(parts.shift() || 0, 10);
720
            this.patch = parseInt(parts.shift() || 0, 10);
721
            this.build = parseInt(parts.shift() || 0, 10);
722

  
723
            return this;
724
        },
725

  
726
        /**
727
         * Override the native toString method
728
         * @private
729
         * @return {String} version
730
         */
731
        toString: function() {
732
            return this.version;
733
        },
734

  
735
        /**
736
         * Override the native valueOf method
737
         * @private
738
         * @return {String} version
739
         */
740
        valueOf: function() {
741
            return this.version;
742
        },
743

  
744
        /**
745
         * Returns the major component value
746
         * @return {Number} major
747
         */
748
        getMajor: function() {
749
            return this.major || 0;
750
        },
751

  
752
        /**
753
         * Returns the minor component value
754
         * @return {Number} minor
755
         */
756
        getMinor: function() {
757
            return this.minor || 0;
758
        },
759

  
760
        /**
761
         * Returns the patch component value
762
         * @return {Number} patch
763
         */
764
        getPatch: function() {
765
            return this.patch || 0;
766
        },
767

  
768
        /**
769
         * Returns the build component value
770
         * @return {Number} build
771
         */
772
        getBuild: function() {
773
            return this.build || 0;
774
        },
775

  
776
        /**
777
         * Returns the release component value
778
         * @return {Number} release
779
         */
780
        getRelease: function() {
781
            return this.release || '';
782
        },
783

  
784
        /**
785
         * Returns whether this version if greater than the supplied argument
786
         * @param {String/Number} target The version to compare with
787
         * @return {Boolean} True if this version if greater than the target, false otherwise
788
         */
789
        isGreaterThan: function(target) {
790
            return Version.compare(this.version, target) === 1;
791
        },
792

  
793
        /**
794
         * Returns whether this version if greater than or equal to the supplied argument
795
         * @param {String/Number} target The version to compare with
796
         * @return {Boolean} True if this version if greater than or equal to the target, false otherwise
797
         */
798
        isGreaterThanOrEqual: function(target) {
799
            return Version.compare(this.version, target) >= 0;
800
        },
801

  
802
        /**
803
         * Returns whether this version if smaller than the supplied argument
804
         * @param {String/Number} target The version to compare with
805
         * @return {Boolean} True if this version if smaller than the target, false otherwise
806
         */
807
        isLessThan: function(target) {
808
            return Version.compare(this.version, target) === -1;
809
        },
810

  
811
        /**
812
         * Returns whether this version if less than or equal to the supplied argument
813
         * @param {String/Number} target The version to compare with
814
         * @return {Boolean} True if this version if less than or equal to the target, false otherwise
815
         */
816
        isLessThanOrEqual: function(target) {
817
            return Version.compare(this.version, target) <= 0;
818
        },
819

  
820
        /**
821
         * Returns whether this version equals to the supplied argument
822
         * @param {String/Number} target The version to compare with
823
         * @return {Boolean} True if this version equals to the target, false otherwise
824
         */
825
        equals: function(target) {
826
            return Version.compare(this.version, target) === 0;
827
        },
828

  
829
        /**
830
         * Returns whether this version matches the supplied argument. Example:
831
         * <pre><code>
832
         * var version = new Ext.Version('1.0.2beta');
833
         * console.log(version.match(1)); // True
834
         * console.log(version.match(1.0)); // True
835
         * console.log(version.match('1.0.2')); // True
836
         * console.log(version.match('1.0.2RC')); // False
837
         * </code></pre>
838
         * @param {String/Number} target The version to compare with
839
         * @return {Boolean} True if this version matches the target, false otherwise
840
         */
841
        match: function(target) {
842
            target = String(target);
843
            return this.version.substr(0, target.length) === target;
844
        },
845

  
846
        /**
847
         * Returns this format: [major, minor, patch, build, release]. Useful for comparison
848
         * @return {Number[]}
849
         */
850
        toArray: function() {
851
            return [this.getMajor(), this.getMinor(), this.getPatch(), this.getBuild(), this.getRelease()];
852
        },
853

  
854
        /**
855
         * Returns shortVersion version without dots and release
856
         * @return {String}
857
         */
858
        getShortVersion: function() {
859
            return this.shortVersion;
860
        },
861

  
862
        /**
863
         * Convenient alias to {@link Ext.Version#isGreaterThan isGreaterThan}
864
         * @param {String/Number} target
865
         * @return {Boolean}
866
         */
867
        gt: function() {
868
            return this.isGreaterThan.apply(this, arguments);
869
        },
870

  
871
        /**
872
         * Convenient alias to {@link Ext.Version#isLessThan isLessThan}
873
         * @param {String/Number} target
874
         * @return {Boolean}
875
         */
876
        lt: function() {
877
            return this.isLessThan.apply(this, arguments);
878
        },
879

  
880
        /**
881
         * Convenient alias to {@link Ext.Version#isGreaterThanOrEqual isGreaterThanOrEqual}
882
         * @param {String/Number} target
883
         * @return {Boolean}
884
         */
885
        gtEq: function() {
886
            return this.isGreaterThanOrEqual.apply(this, arguments);
887
        },
888

  
889
        /**
890
         * Convenient alias to {@link Ext.Version#isLessThanOrEqual isLessThanOrEqual}
891
         * @param {String/Number} target
892
         * @return {Boolean}
893
         */
894
        ltEq: function() {
895
            return this.isLessThanOrEqual.apply(this, arguments);
896
        }
897
    });
898

  
899
    Ext.apply(Version, {
900
        // @private
901
        releaseValueMap: {
902
            'dev': -6,
903
            'alpha': -5,
904
            'a': -5,
905
            'beta': -4,
906
            'b': -4,
907
            'rc': -3,
908
            '#': -2,
909
            'p': -1,
910
            'pl': -1
911
        },
912

  
913
        /**
914
         * Converts a version component to a comparable value
915
         *
916
         * @static
917
         * @param {Object} value The value to convert
918
         * @return {Object}
919
         */
920
        getComponentValue: function(value) {
921
            return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10));
922
        },
923

  
924
        /**
925
         * Compare 2 specified versions, starting from left to right. If a part contains special version strings,
926
         * they are handled in the following order:
927
         * 'dev' < 'alpha' = 'a' < 'beta' = 'b' < 'RC' = 'rc' < '#' < 'pl' = 'p' < 'anything else'
928
         *
929
         * @static
930
         * @param {String} current The current version to compare to
931
         * @param {String} target The target version to compare to
932
         * @return {Number} Returns -1 if the current version is smaller than the target version, 1 if greater, and 0 if they're equivalent
933
         */
934
        compare: function(current, target) {
935
            var currentValue, targetValue, i;
936

  
937
            current = new Version(current).toArray();
938
            target = new Version(target).toArray();
939

  
940
            for (i = 0; i < Math.max(current.length, target.length); i++) {
941
                currentValue = this.getComponentValue(current[i]);
942
                targetValue = this.getComponentValue(target[i]);
943

  
944
                if (currentValue < targetValue) {
945
                    return -1;
946
                } else if (currentValue > targetValue) {
947
                    return 1;
948
                }
949
            }
950

  
951
            return 0;
952
        }
953
    });
954

  
955
    Ext.apply(Ext, {
956
        /**
957
         * @private
958
         */
959
        versions: {},
960

  
961
        /**
962
         * @private
963
         */
964
        lastRegisteredVersion: null,
965

  
966
        /**
967
         * Set version number for the given package name.
968
         *
969
         * @param {String} packageName The package name, for example: 'core', 'touch', 'extjs'
970
         * @param {String/Ext.Version} version The version, for example: '1.2.3alpha', '2.4.0-dev'
971
         * @return {Ext}
972
         */
973
        setVersion: function(packageName, version) {
974
            Ext.versions[packageName] = new Version(version);
975
            Ext.lastRegisteredVersion = Ext.versions[packageName];
976

  
977
            return this;
978
        },
979

  
980
        /**
981
         * Get the version number of the supplied package name; will return the last registered version
982
         * (last Ext.setVersion call) if there's no package name given.
983
         *
984
         * @param {String} packageName (Optional) The package name, for example: 'core', 'touch', 'extjs'
985
         * @return {Ext.Version} The version
986
         */
987
        getVersion: function(packageName) {
988
            if (packageName === undefined) {
989
                return Ext.lastRegisteredVersion;
990
            }
991

  
992
            return Ext.versions[packageName];
993
        },
994

  
995
        /**
996
         * Create a closure for deprecated code.
997
         *
998
    // This means Ext.oldMethod is only supported in 4.0.0beta and older.
999
    // If Ext.getVersion('extjs') returns a version that is later than '4.0.0beta', for example '4.0.0RC',
1000
    // the closure will not be invoked
1001
    Ext.deprecate('extjs', '4.0.0beta', function() {
1002
        Ext.oldMethod = Ext.newMethod;
1003

  
1004
        ...
1005
    });
1006

  
1007
         * @param {String} packageName The package name
1008
         * @param {String} since The last version before it's deprecated
1009
         * @param {Function} closure The callback function to be executed with the specified version is less than the current version
1010
         * @param {Object} scope The execution scope (<tt>this</tt>) if the closure
1011
         * @markdown
1012
         */
1013
        deprecate: function(packageName, since, closure, scope) {
1014
            if (Version.compare(Ext.getVersion(packageName), since) < 1) {
1015
                closure.call(scope);
1016
            }
1017
        }
1018
    }); // End Versioning
1019

  
1020
    Ext.setVersion('core', version);
1021

  
1022
})();
1023

  
1024
/**
1025
 * @class Ext.String
1026
 *
1027
 * A collection of useful static methods to deal with strings
1028
 * @singleton
1029
 */
1030

  
1031
Ext.String = {
1032
    trimRegex: /^[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+|[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+$/g,
1033
    escapeRe: /('|\\)/g,
1034
    formatRe: /\{(\d+)\}/g,
1035
    escapeRegexRe: /([-.*+?^${}()|[\]\/\\])/g,
1036
    basicTrimRe: /^\s+|\s+$/g,
1037
    whitespaceRe: /\s+/,
1038

  
1039
    /**
1040
     * Convert certain characters (&, <, >, and ") to their HTML character equivalents for literal display in web pages.
1041
     * @param {String} value The string to encode
1042
     * @return {String} The encoded text
1043
     * @method
1044
     */
1045
    htmlEncode: (function() {
1046
        var entities = {
1047
            '&': '&amp;',
1048
            '>': '&gt;',
1049
            '<': '&lt;',
1050
            '"': '&quot;'
1051
        }, keys = [], p, regex;
1052

  
1053
        for (p in entities) {
1054
            keys.push(p);
1055
        }
1056

  
1057
        regex = new RegExp('(' + keys.join('|') + ')', 'g');
1058

  
1059
        return function(value) {
1060
            return (!value) ? value : String(value).replace(regex, function(match, capture) {
1061
                return entities[capture];
1062
            });
1063
        };
1064
    })(),
1065

  
1066
    /**
1067
     * Convert certain characters (&, <, >, and ") from their HTML character equivalents.
1068
     * @param {String} value The string to decode
1069
     * @return {String} The decoded text
1070
     * @method
1071
     */
1072
    htmlDecode: (function() {
1073
        var entities = {
1074
            '&amp;': '&',
1075
            '&gt;': '>',
1076
            '&lt;': '<',
1077
            '&quot;': '"'
1078
        }, keys = [], p, regex;
1079

  
1080
        for (p in entities) {
1081
            keys.push(p);
1082
        }
1083

  
1084
        regex = new RegExp('(' + keys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
1085

  
1086
        return function(value) {
1087
            return (!value) ? value : String(value).replace(regex, function(match, capture) {
1088
                if (capture in entities) {
1089
                    return entities[capture];
1090
                } else {
1091
                    return String.fromCharCode(parseInt(capture.substr(2), 10));
1092
                }
1093
            });
1094
        };
1095
    })(),
1096

  
1097
    /**
1098
     * Appends content to the query string of a URL, handling logic for whether to place
1099
     * a question mark or ampersand.
1100
     * @param {String} url The URL to append to.
1101
     * @param {String} string The content to append to the URL.
1102
     * @return {String} The resulting URL
1103
     */
1104
    urlAppend : function(url, string) {
1105
        if (!Ext.isEmpty(string)) {
1106
            return url + (url.indexOf('?') === -1 ? '?' : '&') + string;
1107
        }
1108

  
1109
        return url;
1110
    },
1111

  
1112
    /**
1113
     * Trims whitespace from either end of a string, leaving spaces within the string intact.  Example:
1114
     * @example
1115
var s = '  foo bar  ';
1116
alert('-' + s + '-');         //alerts "- foo bar -"
1117
alert('-' + Ext.String.trim(s) + '-');  //alerts "-foo bar-"
1118

  
1119
     * @param {String} string The string to escape
1120
     * @return {String} The trimmed string
1121
     */
1122
    trim: function(string) {
1123
        return string.replace(Ext.String.trimRegex, "");
1124
    },
1125

  
1126
    /**
1127
     * Capitalize the given string
1128
     * @param {String} string
1129
     * @return {String}
1130
     */
1131
    capitalize: function(string) {
1132
        return string.charAt(0).toUpperCase() + string.substr(1);
1133
    },
1134

  
1135
    /**
1136
     * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length
1137
     * @param {String} value The string to truncate
1138
     * @param {Number} length The maximum length to allow before truncating
1139
     * @param {Boolean} word True to try to find a common word break
1140
     * @return {String} The converted text
1141
     */
1142
    ellipsis: function(value, len, word) {
1143
        if (value && value.length > len) {
1144
            if (word) {
1145
                var vs = value.substr(0, len - 2),
1146
                index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
1147
                if (index !== -1 && index >= (len - 15)) {
1148
                    return vs.substr(0, index) + "...";
1149
                }
1150
            }
1151
            return value.substr(0, len - 3) + "...";
1152
        }
1153
        return value;
1154
    },
1155

  
1156
    /**
1157
     * Escapes the passed string for use in a regular expression
1158
     * @param {String} string
1159
     * @return {String}
1160
     */
1161
    escapeRegex: function(string) {
1162
        return string.replace(Ext.String.escapeRegexRe, "\\$1");
1163
    },
1164

  
1165
    /**
1166
     * Escapes the passed string for ' and \
1167
     * @param {String} string The string to escape
1168
     * @return {String} The escaped string
1169
     */
1170
    escape: function(string) {
1171
        return string.replace(Ext.String.escapeRe, "\\$1");
1172
    },
1173

  
1174
    /**
1175
     * Utility function that allows you to easily switch a string between two alternating values.  The passed value
1176
     * is compared to the current string, and if they are equal, the other value that was passed in is returned.  If
1177
     * they are already different, the first value passed in is returned.  Note that this method returns the new value
1178
     * but does not change the current string.
1179
     * <pre><code>
1180
    // alternate sort directions
1181
    sort = Ext.String.toggle(sort, 'ASC', 'DESC');
1182

  
1183
    // instead of conditional logic:
1184
    sort = (sort == 'ASC' ? 'DESC' : 'ASC');
1185
       </code></pre>
1186
     * @param {String} string The current string
1187
     * @param {String} value The value to compare to the current string
1188
     * @param {String} other The new value to use if the string already equals the first value passed in
1189
     * @return {String} The new value
1190
     */
1191
    toggle: function(string, value, other) {
1192
        return string === value ? other : value;
1193
    },
1194

  
1195
    /**
1196
     * Pads the left side of a string with a specified character.  This is especially useful
1197
     * for normalizing number and date strings.  Example usage:
1198
     *
1199
     * <pre><code>
1200
var s = Ext.String.leftPad('123', 5, '0');
1201
// s now contains the string: '00123'
1202
       </code></pre>
1203
     * @param {String} string The original string
1204
     * @param {Number} size The total length of the output string
1205
     * @param {String} character (optional) The character with which to pad the original string (defaults to empty string " ")
1206
     * @return {String} The padded string
1207
     */
1208
    leftPad: function(string, size, character) {
1209
        var result = String(string);
1210
        character = character || " ";
1211
        while (result.length < size) {
1212
            result = character + result;
1213
        }
1214
        return result;
1215
    },
1216

  
1217
    /**
1218
     * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each
1219
     * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:
1220
     * <pre><code>
1221
var cls = 'my-class', text = 'Some text';
1222
var s = Ext.String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
1223
// s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
1224
       </code></pre>
1225
     * @param {String} string The tokenized string to be formatted
1226
     * @param {String} value1 The value to replace token {0}
1227
     * @param {String} value2 Etc...
1228
     * @return {String} The formatted string
1229
     */
1230
    format: function(format) {
1231
        var args = Ext.Array.toArray(arguments, 1);
1232
        return format.replace(Ext.String.formatRe, function(m, i) {
1233
            return args[i];
1234
        });
1235
    },
1236

  
1237
    /**
1238
     * Returns a string with a specified number of repititions a given string pattern.
1239
     * The pattern be separated by a different string.
1240
     *
1241
     *      var s = Ext.String.repeat('---', 4); // = '------------'
1242
     *      var t = Ext.String.repeat('--', 3, '/'); // = '--/--/--'
1243
     *
1244
     * @param {String} pattern The pattern to repeat.
1245
     * @param {Number} count The number of times to repeat the pattern (may be 0).
1246
     * @param {String} sep An option string to separate each pattern.
1247
     */
1248
    repeat: function(pattern, count, sep) {
1249
        for (var buf = [], i = count; i--; ) {
1250
            buf.push(pattern);
1251
        }
1252
        return buf.join(sep || '');
1253
    },
1254

  
1255
    /**
1256
     * Splits a string of space separated words into an array, trimming as needed. If the
1257
     * words are already an array, it is returned.
1258
     *
1259
     * @param {String/Array} words
1260
     */
1261
    splitWords: function (words) {
1262
        if (words && typeof words == 'string') {
1263
            return words.replace(Ext.String.basicTrimRe, '').split(Ext.String.whitespaceRe);
1264
        }
1265
        return words || [];
1266
    }
1267
};
1268

  
1269
/**
1270
 * Old alias to {@link Ext.String#htmlEncode}
1271
 * @deprecated Use {@link Ext.String#htmlEncode} instead
1272
 * @method
1273
 * @member Ext
1274
 * @inheritdoc Ext.String#htmlEncode
1275
 */
1276
Ext.htmlEncode = Ext.String.htmlEncode;
1277

  
1278

  
1279
/**
1280
 * Old alias to {@link Ext.String#htmlDecode}
1281
 * @deprecated Use {@link Ext.String#htmlDecode} instead
1282
 * @method
1283
 * @member Ext
1284
 * @inheritdoc Ext.String#htmlDecode
1285
 */
1286
Ext.htmlDecode = Ext.String.htmlDecode;
1287

  
1288
/**
1289
 * Old alias to {@link Ext.String#urlAppend}
1290
 * @deprecated Use {@link Ext.String#urlAppend} instead
1291
 * @method
1292
 * @member Ext
1293
 * @inheritdoc Ext.String#urlAppend
1294
 */
1295
Ext.urlAppend = Ext.String.urlAppend;
1296

  
1297
/**
1298
 * @class Ext.Number
1299
 *
1300
 * A collection of useful static methods to deal with numbers
1301
 * @singleton
1302
 */
1303

  
1304
(function() {
1305

  
1306
var isToFixedBroken = (0.9).toFixed() !== '1';
1307

  
1308
Ext.Number = {
1309
    /**
1310
     * Checks whether or not the passed number is within a desired range.  If the number is already within the
1311
     * range it is returned, otherwise the min or max value is returned depending on which side of the range is
1312
     * exceeded. Note that this method returns the constrained value but does not change the current number.
1313
     * @param {Number} number The number to check
1314
     * @param {Number} min The minimum number in the range
1315
     * @param {Number} max The maximum number in the range
1316
     * @return {Number} The constrained value if outside the range, otherwise the current value
1317
     */
1318
    constrain: function(number, min, max) {
1319
        number = parseFloat(number);
1320

  
1321
        if (!isNaN(min)) {
1322
            number = Math.max(number, min);
1323
        }
1324
        if (!isNaN(max)) {
1325
            number = Math.min(number, max);
1326
        }
1327
        return number;
1328
    },
1329

  
1330
    /**
1331
     * Snaps the passed number between stopping points based upon a passed increment value.
1332
     * @param {Number} value The unsnapped value.
1333
     * @param {Number} increment The increment by which the value must move.
1334
     * @param {Number} minValue The minimum value to which the returned value must be constrained. Overrides the increment..
1335
     * @param {Number} maxValue The maximum value to which the returned value must be constrained. Overrides the increment..
1336
     * @return {Number} The value of the nearest snap target.
1337
     */
1338
    snap : function(value, increment, minValue, maxValue) {
1339
        var newValue = value,
1340
            m;
1341

  
1342
        if (!(increment && value)) {
1343
            return value;
1344
        }
1345
        m = value % increment;
1346
        if (m !== 0) {
1347
            newValue -= m;
1348
            if (m * 2 >= increment) {
1349
                newValue += increment;
1350
            } else if (m * 2 < -increment) {
1351
                newValue -= increment;
1352
            }
1353
        }
1354
        return Ext.Number.constrain(newValue, minValue,  maxValue);
1355
    },
1356

  
1357
    /**
1358
     * Formats a number using fixed-point notation
1359
     * @param {Number} value The number to format
1360
     * @param {Number} precision The number of digits to show after the decimal point
1361
     */
1362
    toFixed: function(value, precision) {
1363
        if (isToFixedBroken) {
1364
            precision = precision || 0;
1365
            var pow = Math.pow(10, precision);
1366
            return (Math.round(value * pow) / pow).toFixed(precision);
1367
        }
1368

  
1369
        return value.toFixed(precision);
1370
    },
1371

  
1372
    /**
1373
     * Validate that a value is numeric and convert it to a number if necessary. Returns the specified default value if
1374
     * it is not.
1375

  
1376
Ext.Number.from('1.23', 1); // returns 1.23
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff