/ext-4.1.0_b3/builds/ext-core-debug-w-comments.js
JavaScript | 14240 lines | 6492 code | 1590 blank | 6158 comment | 1480 complexity | 52b43a9b21ab8a7a7a4aca5537b04488 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1/*
2This file is part of Ext JS 4.1
3
4Copyright (c) 2011-2012 Sencha Inc
5
6Contact: http://www.sencha.com/contact
7
8Pre-release code in the Ext repository is intended for development purposes only and will
9not always be stable.
10
11Use of pre-release code is permitted with your application at your own risk under standard
12Ext license terms. Public redistribution is prohibited.
13
14For early licensing, please contact us at licensing@sencha.com
15
16Build date: 2012-02-21 23:18:31 (3a639ae9dd5443bffbde7bec9922e6fb07a923a8)
17*/
18/**
19 * @class Ext
20 * @singleton
21 */
22var Ext = Ext || {};
23Ext._startTime = new Date().getTime();
24(function() {
25 var global = this,
26 objectPrototype = Object.prototype,
27 toString = objectPrototype.toString,
28 enumerables = true,
29 enumerablesTest = { toString: 1 },
30 emptyFn = function(){},
31 i;
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.prototype.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.isSandboxed) {
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.isSandboxed) {
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
690var version = '4.1.0beta', 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
1031Ext.String = (function() {
1032 var 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 varReplace = /(^[^a-z]*|[^\w])/gi,
1039 charToEntity = {
1040 '&': '&',
1041 '>': '>',
1042 '<': '<',
1043 '"': '"'
1044 },
1045 entityToChar = {
1046 '&': '&',
1047 '>': '>',
1048 '<': '<',
1049 '"': '"'
1050 },
1051 keys = [],
1052 key,
1053 charToEntityRegex,
1054 entityToCharRegex,
1055 htmlEncodeReplaceFn = function(match, capture) {
1056 return charToEntity[capture];
1057 },
1058 htmlEncode = function(value) {
1059 return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
1060 },
1061 htmlDecodeReplaceFn = function(match, capture) {
1062 return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
1063 },
1064 htmlDecode = function(value) {
1065 return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
1066 };
1067
1068 // Compile RexExps for HTML encode and decode functions
1069 for (key in charToEntity) {
1070 keys.push(key);
1071 }
1072 charToEntityRegex = new RegExp('(' + keys.join('|') + ')', 'g');
1073
1074 keys = [];
1075 for (key in entityToChar) {
1076 keys.push(key);
1077 }
1078 entityToCharRegex = new RegExp('(' + keys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
1079
1080 return {
1081
1082 /**
1083 * Converts a string of characters into a legal, parseable Javascript `var` name as long as the passed
1084 * string contains at least one alphabetic character. Non alphanumeric characters, and *leading* non alphabetic
1085 * characters will be removed.
1086 * @param {String} s A string to be converted into a `var` name.
1087 * @return {String} A legal Javascript `var` name.
1088 */
1089 createVarName: function(s) {
1090 return s.replace(varReplace, '');
1091 },
1092
1093 /**
1094 * Convert certain characters (&, <, >, and ") to their HTML character equivalents for literal display in web pages.
1095 * @param {String} value The string to encode
1096 * @return {String} The encoded text
1097 * @method
1098 */
1099 htmlEncode: htmlEncode,
1100
1101 /**
1102 * Convert certain characters (&, <, >, and ") from their HTML character equivalents.
1103 * @param {String} value The string to decode
1104 * @return {String} The decoded text
1105 * @method
1106 */
1107 htmlDecode: htmlDecode,
1108
1109 /**
1110 * Appends content to the query string of a URL, handling logic for whether to place
1111 * a question mark or ampersand.
1112 * @param {String} url The URL to append to.
1113 * @param {String} string The content to append to the URL.
1114 * @return {String} The resulting URL
1115 */
1116 urlAppend : function(url, string) {
1117 if (!Ext.isEmpty(string)) {
1118 return url + (url.indexOf('?') === -1 ? '?' : '&') + string;
1119 }
1120
1121 return url;
1122 },
1123
1124 /**
1125 * Trims whitespace from either end of a string, leaving spaces within the string intact. Example:
1126 * @example
1127 var s = ' foo bar ';
1128 alert('-' + s + '-'); //alerts "- foo bar -"
1129 alert('-' + Ext.String.trim(s) + '-'); //alerts "-foo bar-"
1130
1131 * @param {String} string The string to escape
1132 * @return {String} The trimmed string
1133 */
1134 trim: function(string) {
1135 return string.replace(trimRegex, "");
1136 },
1137
1138 /**
1139 * Capitalize the given string
1140 * @param {String} string
1141 * @return {String}
1142 */
1143 capitalize: function(string) {
1144 return string.charAt(0).toUpperCase() + string.substr(1);
1145 },
1146
1147 /**
1148 * Uncapitalize the given string
1149 * @param {String} string
1150 * @return {String}
1151 */
1152 uncapitalize: function(string) {
1153 return string.charAt(0).toLowerCase() + string.substr(1);
1154 },
1155
1156 /**
1157 * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length
1158 * @param {String} value The string to truncate
1159 * @param {Number} length The maximum length to allow before truncating
1160 * @param {Boolean} word True to try to find a common word break
1161 * @return {String} The converted text
1162 */
1163 ellipsis: function(value, len, word) {
1164 if (value && value.length > len) {
1165 if (word) {
1166 var vs = value.substr(0, len - 2),
1167 index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
1168 if (index !== -1 && index >= (len - 15)) {
1169 return vs.substr(0, index) + "...";
1170 }
1171 }
1172 return value.substr(0, len - 3) + "...";
1173 }
1174 return value;
1175 },
1176
1177 /**
1178 * Escapes the passed string for use in a regular expression
1179 * @param {String} string
1180 * @return {String}
1181 */
1182 escapeRegex: function(string) {
1183 return string.replace(escapeRegexRe, "\\$1");
1184 },
1185
1186 /**
1187 * Escapes the passed string for ' and \
1188 * @param {String} string The string to escape
1189 * @return {String} The escaped string
1190 */
1191 escape: function(string) {
1192 return string.replace(escapeRe, "\\$1");
1193 },
1194
1195 /**
1196 * Utility function that allows you to easily switch a string between two alternating values. The passed value
1197 * is compared to the current string, and if they are equal, the other value that was passed in is returned. If
1198 * they are already different, the first value passed in is returned. Note that this method returns the new value
1199 * but does not change the current string.
1200 * <pre><code>
1201 // alternate sort directions
1202 sort = Ext.String.toggle(sort, 'ASC', 'DESC');
1203
1204 // instead of conditional logic:
1205 sort = (sort == 'ASC' ? 'DESC' : 'ASC');
1206 </code></pre>
1207 * @param {String} string The current string
1208 * @param {String} value The value to compare to the current string
1209 * @param {String} other The new value to use if the string already equals the first value passed in
1210 * @return {String} The new value
1211 */
1212 toggle: function(string, value, other) {
1213 return string === value ? other : value;
1214 },
1215
1216 /**
1217 * Pads the left side of a string with a specified character. This is especially useful
1218 * for normalizing number and date strings. Example usage:
1219 *
1220 * <pre><code>
1221 var s = Ext.String.leftPad('123', 5, '0');
1222 // s now contains the string: '00123'
1223 </code></pre>
1224 * @param {String} string The original string
1225 * @param {Number} size The total length of the output string
1226 * @param {String} character (optional) The character with which to pad the original string (defaults to empty string " ")
1227 * @return {String} The padded string
1228 */
1229 leftPad: function(string, size, character) {
1230 var result = String(string);
1231 character = character || " ";
1232 while (result.length < size) {
1233 result = character + result;
1234 }
1235 return result;
1236 },
1237
1238 /**
1239 * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each
1240 * token must be unique, and must increment in the format {0}, {1}, etc. Example usage:
1241 * <pre><code>
1242 var cls = 'my-class', text = 'Some text';
1243 var s = Ext.String.format('<div class="{0}">{1}</div>', cls, text);
1244 // s now contains the string: '<div class="my-class">Some text</div>'
1245 </code></pre>
1246 * @param {String} string The tokenized string to be formatted
1247 * @param {String} value1 The value to replace token {0}
1248 * @param {String} value2 Etc...
1249 * @return {String} The formatted string
1250 */
1251 format: function(format) {
1252 var args = Ext.Array.toArray(arguments, 1);
1253 return format.replace(formatRe, function(m, i) {
1254 return args[i];
1255 });
1256 },
1257
1258 /**
1259 * Returns a string with a specified number of repititions a given string pattern.
1260 * The pattern be separated by a different string.
1261 *
1262 * var s = Ext.String.repeat('---', 4); // = '------------'
1263 * var t = Ext.String.repeat('--', 3, '/'); // = '--/--/--'
1264 *
1265 * @param {String} pattern The pattern to repeat.
1266 * @param {Number} count The number of times to repeat the pattern (may be 0).
1267 * @param {String} sep An option string to separate each pattern.
1268 */
1269 repeat: function(pattern, count, sep) {
1270 for (var buf = [], i = count; i--; ) {
1271 buf.push(pattern);
1272 }
1273 return buf.join(sep || '');
1274 },
1275
1276 /**
1277 * Splits a string of space separated words into an array, trimming as needed. If the
1278 * words are already an array, it is returned.
1279 *
1280 * @param {String/Array} words
1281 */
1282 splitWords: function (words) {
1283 if (words && typeof words == 'string') {
1284 return words.replace(basicTrimRe, '').split(whitespaceRe);
1285 }
1286 return words || [];
1287 }
1288 };
1289})();
1290
1291/**
1292 * Old alias to {@link Ext.String#htmlEncode}
1293 * @deprecated Use {@link Ext.String#htmlEncode} instead
1294 * @method
1295 * @member Ext
1296 * @inheritdoc Ext.String#htmlEncode
1297 */
1298Ext.htmlEncode = Ext.String.htmlEncode;
1299
1300
1301/**
1302 * Old alias to {@link Ext.String#htmlDecode}
1303 * @deprecated Use {@link Ext.String#htmlDecode} instead
1304 * @method
1305 * @member Ext
1306 * @inheritdoc Ext.String#htmlDecode
1307 */
1308Ext.htmlDecode = Ext.String.htmlDecode;
1309
1310/**
1311 * Old alias to {@link Ext.String#urlAppend}
1312 * @deprecated Use {@link Ext.String#urlAppend} instead
1313 * @method
1314 * @member Ext
1315 * @inheritdoc Ext.String#urlAppend
1316 */
1317Ext.urlAppend = Ext.String.urlAppend;
1318/**
1319 * @class Ext.Number
1320 *
1321 * A collection of useful static methods to deal with numbers
1322 * @singleton
1323 */
1324
1325Ext.Number = new function() {
1326
1327 var me = this,
1328 isToFixedBroken = (0.9).toFixed() !== '1',
1329 math = Math;
1330
1331 Ext.apply(this, {
1332 /**
1333 * Checks whether or not the passed number is within a desired range. If the number is already within the
1334 * range it is returned, otherwise the min or max value is returned depending on which side of the range is
1335 * exceeded. Note that this method returns the constrained value but does not change the current number.
1336 * @param {Number} number The number to check
1337 * @param {Number} min The minimum number in the range
1338 * @param {Number} max The maximum number in the range
1339 * @return {Number} The constrained value if outside the range, otherwise the current value
1340 */
1341 constrain: function(number, min, max) {
1342 number = parseFloat(number);
1343
1344 if (!isNaN(min)) {
1345 number = math.max(number, min);
1346 }
1347 if (!isNaN(max)) {
1348 number = math.min(number, max);
1349 }
1350 return number;
1351 },
1352
1353 /**
1354 * Snaps the passed number between stopping points based upon a passed increment value.
1355 *
1356 * The difference between this and {@link #snapInRange} is that {@link #snapInRange} uses the minValue
1357 * when calculating snap points:
1358 *
1359 * r = Ext.Number.snap(56, 2, 55, 65); // Returns 56 - snap points are zero based
1360 *
1361 * r = Ext.Number.snapInRange(56, 2, 55, 65); // Returns 57 - snap points are based from minValue
1362 *
1363 * @param {Number} value The unsnapped value.
1364 * @param {Number} increment The increment by which the value must move.
1365 * @param {Number} minValue The minimum value to which the returned value must be constrained. Overrides the increment.
1366 * @param {Number} maxValue The maximum value to which the returned value must be constrained. Overrides the increment.
1367 * @return {Number} The value of the nearest snap target.
1368 */
1369 snap : function(value, increment, minValue, maxValue) {
1370 var m;
1371
1372 // If no value passed, or minValue was passed and value is less than minValue (anything < undefined is false)
1373 // Then use the minValue (or zero if the value was undefined)
1374 if (value === undefined || value < minValue) {
1375 return minValue || 0;
1376 }
1377
1378 if (increment) {
1379 m = value % increment;
1380 if (m !== 0) {
1381 value -= m;
1382 if (m * 2 >= increment) {
1383 value += increment;
1384 } else if (m * 2 < -increment) {
1385 value -= increment;
1386 }
1387 }
1388 }
1389 return me.constrain(value, minValue, maxValue);
1390 },
1391
1392 /**
1393 * Snaps the passed number between stopping points based upon a passed increment value.
1394 *
1395 * The difference between this and {@link #snap} is that {@link #snap} does not use the minValue
1396 * when calculating snap points:
1397 *
1398 * r = Ext.Number.snap(56, 2, 55, 65); // Returns 56 - snap points are zero based
1399 *
1400 * r = Ext.Number.snapInRange(56, 2, 55, 65); // Returns 57 - snap points are based from minValue
1401 *
1402 * @param {Number} value The unsnapped value.
1403 * @param {Number} increment The increment by which the value must move.
1404 * @param {Number} [minValue=0] The minimum value to which the returned value must be constrained.
1405 * @param {Number} [maxValue=Infinity] The maximum value to which the returned value must be constrained.
1406 * @return {Number} The value of the nearest snap target.
1407 */
1408 snapInRange : function(value, increment, minValue, maxValue) {
1409 var tween;
1410
1411 // default minValue to zero
1412 minValue = (minValue || 0);
1413
1414 // If value is undefined, or less than minValue, use minValue
1415 if (value === undefined || value < minValue) {
1416 return minValue;
1417 }
1418
1419 // Calculate how many snap points from the minValue the passed value is.
1420 if (increment && (tween = ((value - minValue) % increment))) {
1421 value…
Large files files are truncated, but you can click here to view the full file