/ext-4.1.0_b3/builds/ext-core-debug-w-comments.js

https://bitbucket.org/srogerf/javascript · JavaScript · 24770 lines · 12390 code · 2615 blank · 9765 comment · 2993 complexity · 52b43a9b21ab8a7a7a4aca5537b04488 MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. This file is part of Ext JS 4.1
  3. Copyright (c) 2011-2012 Sencha Inc
  4. Contact: http://www.sencha.com/contact
  5. Pre-release code in the Ext repository is intended for development purposes only and will
  6. not always be stable.
  7. Use of pre-release code is permitted with your application at your own risk under standard
  8. Ext license terms. Public redistribution is prohibited.
  9. For early licensing, please contact us at licensing@sencha.com
  10. Build date: 2012-02-21 23:18:31 (3a639ae9dd5443bffbde7bec9922e6fb07a923a8)
  11. */
  12. /**
  13. * @class Ext
  14. * @singleton
  15. */
  16. var Ext = Ext || {};
  17. Ext._startTime = new Date().getTime();
  18. (function() {
  19. var global = this,
  20. objectPrototype = Object.prototype,
  21. toString = objectPrototype.toString,
  22. enumerables = true,
  23. enumerablesTest = { toString: 1 },
  24. emptyFn = function(){},
  25. i;
  26. Ext.global = global;
  27. for (i in enumerablesTest) {
  28. enumerables = null;
  29. }
  30. if (enumerables) {
  31. enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable',
  32. 'toLocaleString', 'toString', 'constructor'];
  33. }
  34. /**
  35. * An array containing extra enumerables for old browsers
  36. * @property {String[]}
  37. */
  38. Ext.enumerables = enumerables;
  39. /**
  40. * Copies all the properties of config to the specified object.
  41. * Note that if recursive merging and cloning without referencing the original objects / arrays is needed, use
  42. * {@link Ext.Object#merge} instead.
  43. * @param {Object} object The receiver of the properties
  44. * @param {Object} config The source of the properties
  45. * @param {Object} defaults A different object that will also be applied for default values
  46. * @return {Object} returns obj
  47. */
  48. Ext.apply = function(object, config, defaults) {
  49. if (defaults) {
  50. Ext.apply(object, defaults);
  51. }
  52. if (object && config && typeof config === 'object') {
  53. var i, j, k;
  54. for (i in config) {
  55. object[i] = config[i];
  56. }
  57. if (enumerables) {
  58. for (j = enumerables.length; j--;) {
  59. k = enumerables[j];
  60. if (config.hasOwnProperty(k)) {
  61. object[k] = config[k];
  62. }
  63. }
  64. }
  65. }
  66. return object;
  67. };
  68. Ext.buildSettings = Ext.apply({
  69. baseCSSPrefix: 'x-',
  70. scopeResetCSS: false
  71. }, Ext.buildSettings || {});
  72. Ext.apply(Ext, {
  73. /**
  74. * @property {String} [name='Ext']
  75. * <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>
  76. * <p>This is usually <code>"Ext"</code>, but if a sandboxed build of ExtJS is being used, this will be an alternative name.</p>
  77. * <p>If code is being generated for use by <code>eval</code> or to create a <code>new Function</code>, and the global instance
  78. * of Ext must be referenced, this is the name that should be built into the code.</p>
  79. */
  80. name: Ext.sandboxName || 'Ext',
  81. /**
  82. * A reusable empty function
  83. */
  84. emptyFn: emptyFn,
  85. /**
  86. * A zero length string which will pass a truth test. Useful for passing to methods
  87. * which use a truth test to reject <i>falsy</i> values where a string value must be cleared.
  88. */
  89. emptyString: new String(),
  90. baseCSSPrefix: Ext.buildSettings.baseCSSPrefix,
  91. /**
  92. * Copies all the properties of config to object if they don't already exist.
  93. * @param {Object} object The receiver of the properties
  94. * @param {Object} config The source of the properties
  95. * @return {Object} returns obj
  96. */
  97. applyIf: function(object, config) {
  98. var property;
  99. if (object) {
  100. for (property in config) {
  101. if (object[property] === undefined) {
  102. object[property] = config[property];
  103. }
  104. }
  105. }
  106. return object;
  107. },
  108. /**
  109. * Iterates either an array or an object. This method delegates to
  110. * {@link Ext.Array#each Ext.Array.each} if the given value is iterable, and {@link Ext.Object#each Ext.Object.each} otherwise.
  111. *
  112. * @param {Object/Array} object The object or array to be iterated.
  113. * @param {Function} fn The function to be called for each iteration. See and {@link Ext.Array#each Ext.Array.each} and
  114. * {@link Ext.Object#each Ext.Object.each} for detailed lists of arguments passed to this function depending on the given object
  115. * type that is being iterated.
  116. * @param {Object} scope (Optional) The scope (`this` reference) in which the specified function is executed.
  117. * Defaults to the object being iterated itself.
  118. * @markdown
  119. */
  120. iterate: function(object, fn, scope) {
  121. if (Ext.isEmpty(object)) {
  122. return;
  123. }
  124. if (scope === undefined) {
  125. scope = object;
  126. }
  127. if (Ext.isIterable(object)) {
  128. Ext.Array.each.call(Ext.Array, object, fn, scope);
  129. }
  130. else {
  131. Ext.Object.each.call(Ext.Object, object, fn, scope);
  132. }
  133. }
  134. });
  135. Ext.apply(Ext, {
  136. /**
  137. * This method deprecated. Use {@link Ext#define Ext.define} instead.
  138. * @method
  139. * @param {Function} superclass
  140. * @param {Object} overrides
  141. * @return {Function} The subclass constructor from the <tt>overrides</tt> parameter, or a generated one if not provided.
  142. * @deprecated 4.0.0 Use {@link Ext#define Ext.define} instead
  143. */
  144. extend: function() {
  145. // inline overrides
  146. var objectConstructor = objectPrototype.constructor,
  147. inlineOverrides = function(o) {
  148. for (var m in o) {
  149. if (!o.hasOwnProperty(m)) {
  150. continue;
  151. }
  152. this[m] = o[m];
  153. }
  154. };
  155. return function(subclass, superclass, overrides) {
  156. // First we check if the user passed in just the superClass with overrides
  157. if (Ext.isObject(superclass)) {
  158. overrides = superclass;
  159. superclass = subclass;
  160. subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() {
  161. superclass.apply(this, arguments);
  162. };
  163. }
  164. // We create a new temporary class
  165. var F = function() {},
  166. subclassProto, superclassProto = superclass.prototype;
  167. F.prototype = superclassProto;
  168. subclassProto = subclass.prototype = new F();
  169. subclassProto.constructor = subclass;
  170. subclass.superclass = superclassProto;
  171. if (superclassProto.constructor === objectConstructor) {
  172. superclassProto.constructor = superclass;
  173. }
  174. subclass.override = function(overrides) {
  175. Ext.override(subclass, overrides);
  176. };
  177. subclassProto.override = inlineOverrides;
  178. subclassProto.proto = subclassProto;
  179. subclass.override(overrides);
  180. subclass.extend = function(o) {
  181. return Ext.extend(subclass, o);
  182. };
  183. return subclass;
  184. };
  185. }(),
  186. /**
  187. * Proxy to {@link Ext.Base#override}. Please refer {@link Ext.Base#override} for further details.
  188. *
  189. * @param {Object} cls The class to override
  190. * @param {Object} overrides The properties to add to origClass. This should be specified as an object literal
  191. * containing one or more properties.
  192. * @method override
  193. * @markdown
  194. * @deprecated 4.1.0 Use {@link Ext#define Ext.define} instead
  195. */
  196. override: function(cls, overrides) {
  197. if (cls.$isClass) {
  198. return cls.override(overrides);
  199. }
  200. else {
  201. Ext.apply(cls.prototype, overrides);
  202. }
  203. }
  204. });
  205. // A full set of static methods to do type checking
  206. Ext.apply(Ext, {
  207. /**
  208. * Returns the given value itself if it's not empty, as described in {@link Ext#isEmpty}; returns the default
  209. * value (second argument) otherwise.
  210. *
  211. * @param {Object} value The value to test
  212. * @param {Object} defaultValue The value to return if the original value is empty
  213. * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
  214. * @return {Object} value, if non-empty, else defaultValue
  215. */
  216. valueFrom: function(value, defaultValue, allowBlank){
  217. return Ext.isEmpty(value, allowBlank) ? defaultValue : value;
  218. },
  219. /**
  220. * Returns the type of the given variable in string format. List of possible values are:
  221. *
  222. * - `undefined`: If the given value is `undefined`
  223. * - `null`: If the given value is `null`
  224. * - `string`: If the given value is a string
  225. * - `number`: If the given value is a number
  226. * - `boolean`: If the given value is a boolean value
  227. * - `date`: If the given value is a `Date` object
  228. * - `function`: If the given value is a function reference
  229. * - `object`: If the given value is an object
  230. * - `array`: If the given value is an array
  231. * - `regexp`: If the given value is a regular expression
  232. * - `element`: If the given value is a DOM Element
  233. * - `textnode`: If the given value is a DOM text node and contains something other than whitespace
  234. * - `whitespace`: If the given value is a DOM text node and contains only whitespace
  235. *
  236. * @param {Object} value
  237. * @return {String}
  238. * @markdown
  239. */
  240. typeOf: function(value) {
  241. if (value === null) {
  242. return 'null';
  243. }
  244. var type = typeof value;
  245. if (type === 'undefined' || type === 'string' || type === 'number' || type === 'boolean') {
  246. return type;
  247. }
  248. var typeToString = toString.call(value);
  249. switch(typeToString) {
  250. case '[object Array]':
  251. return 'array';
  252. case '[object Date]':
  253. return 'date';
  254. case '[object Boolean]':
  255. return 'boolean';
  256. case '[object Number]':
  257. return 'number';
  258. case '[object RegExp]':
  259. return 'regexp';
  260. }
  261. if (type === 'function') {
  262. return 'function';
  263. }
  264. if (type === 'object') {
  265. if (value.nodeType !== undefined) {
  266. if (value.nodeType === 3) {
  267. return (/\S/).test(value.nodeValue) ? 'textnode' : 'whitespace';
  268. }
  269. else {
  270. return 'element';
  271. }
  272. }
  273. return 'object';
  274. }
  275. },
  276. /**
  277. * Returns true if the passed value is empty, false otherwise. The value is deemed to be empty if it is either:
  278. *
  279. * - `null`
  280. * - `undefined`
  281. * - a zero-length array
  282. * - a zero-length string (Unless the `allowEmptyString` parameter is set to `true`)
  283. *
  284. * @param {Object} value The value to test
  285. * @param {Boolean} allowEmptyString (optional) true to allow empty strings (defaults to false)
  286. * @return {Boolean}
  287. * @markdown
  288. */
  289. isEmpty: function(value, allowEmptyString) {
  290. return (value === null) || (value === undefined) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0);
  291. },
  292. /**
  293. * Returns true if the passed value is a JavaScript Array, false otherwise.
  294. *
  295. * @param {Object} target The target to test
  296. * @return {Boolean}
  297. * @method
  298. */
  299. isArray: ('isArray' in Array) ? Array.isArray : function(value) {
  300. return toString.call(value) === '[object Array]';
  301. },
  302. /**
  303. * Returns true if the passed value is a JavaScript Date object, false otherwise.
  304. * @param {Object} object The object to test
  305. * @return {Boolean}
  306. */
  307. isDate: function(value) {
  308. return toString.call(value) === '[object Date]';
  309. },
  310. /**
  311. * Returns true if the passed value is a JavaScript Object, false otherwise.
  312. * @param {Object} value The value to test
  313. * @return {Boolean}
  314. * @method
  315. */
  316. isObject: (toString.call(null) === '[object Object]') ?
  317. function(value) {
  318. // check ownerDocument here as well to exclude DOM nodes
  319. return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.ownerDocument === undefined;
  320. } :
  321. function(value) {
  322. return toString.call(value) === '[object Object]';
  323. },
  324. /**
  325. * @private
  326. */
  327. isSimpleObject: function(value) {
  328. return value instanceof Object && value.constructor === Object;
  329. },
  330. /**
  331. * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean.
  332. * @param {Object} value The value to test
  333. * @return {Boolean}
  334. */
  335. isPrimitive: function(value) {
  336. var type = typeof value;
  337. return type === 'string' || type === 'number' || type === 'boolean';
  338. },
  339. /**
  340. * Returns true if the passed value is a JavaScript Function, false otherwise.
  341. * @param {Object} value The value to test
  342. * @return {Boolean}
  343. * @method
  344. */
  345. isFunction:
  346. // Safari 3.x and 4.x returns 'function' for typeof <NodeList>, hence we need to fall back to using
  347. // Object.prototype.toString (slower)
  348. (typeof document !== 'undefined' && typeof document.getElementsByTagName('body') === 'function') ? function(value) {
  349. return toString.call(value) === '[object Function]';
  350. } : function(value) {
  351. return typeof value === 'function';
  352. },
  353. /**
  354. * Returns true if the passed value is a number. Returns false for non-finite numbers.
  355. * @param {Object} value The value to test
  356. * @return {Boolean}
  357. */
  358. isNumber: function(value) {
  359. return typeof value === 'number' && isFinite(value);
  360. },
  361. /**
  362. * Validates that a value is numeric.
  363. * @param {Object} value Examples: 1, '1', '2.34'
  364. * @return {Boolean} True if numeric, false otherwise
  365. */
  366. isNumeric: function(value) {
  367. return !isNaN(parseFloat(value)) && isFinite(value);
  368. },
  369. /**
  370. * Returns true if the passed value is a string.
  371. * @param {Object} value The value to test
  372. * @return {Boolean}
  373. */
  374. isString: function(value) {
  375. return typeof value === 'string';
  376. },
  377. /**
  378. * Returns true if the passed value is a boolean.
  379. *
  380. * @param {Object} value The value to test
  381. * @return {Boolean}
  382. */
  383. isBoolean: function(value) {
  384. return typeof value === 'boolean';
  385. },
  386. /**
  387. * Returns true if the passed value is an HTMLElement
  388. * @param {Object} value The value to test
  389. * @return {Boolean}
  390. */
  391. isElement: function(value) {
  392. return value ? value.nodeType === 1 : false;
  393. },
  394. /**
  395. * Returns true if the passed value is a TextNode
  396. * @param {Object} value The value to test
  397. * @return {Boolean}
  398. */
  399. isTextNode: function(value) {
  400. return value ? value.nodeName === "#text" : false;
  401. },
  402. /**
  403. * Returns true if the passed value is defined.
  404. * @param {Object} value The value to test
  405. * @return {Boolean}
  406. */
  407. isDefined: function(value) {
  408. return typeof value !== 'undefined';
  409. },
  410. /**
  411. * Returns true if the passed value is iterable, false otherwise
  412. * @param {Object} value The value to test
  413. * @return {Boolean}
  414. */
  415. isIterable: function(value) {
  416. var type = typeof value,
  417. checkLength = false;
  418. if (value && type != 'string') {
  419. // Functions have a length property, so we need to filter them out
  420. if (type == 'function') {
  421. // In Safari, NodeList/HTMLCollection both return "function" when using typeof, so we need
  422. // to explicitly check them here.
  423. if (Ext.isSafari) {
  424. checkLength = value instanceof NodeList || value instanceof HTMLCollection;
  425. }
  426. } else {
  427. checkLength = true;
  428. }
  429. }
  430. return checkLength ? value.length !== undefined : false;
  431. }
  432. });
  433. Ext.apply(Ext, {
  434. /**
  435. * Clone almost any type of variable including array, object, DOM nodes and Date without keeping the old reference
  436. * @param {Object} item The variable to clone
  437. * @return {Object} clone
  438. */
  439. clone: function(item) {
  440. if (item === null || item === undefined) {
  441. return item;
  442. }
  443. // DOM nodes
  444. // TODO proxy this to Ext.Element.clone to handle automatic id attribute changing
  445. // recursively
  446. if (item.nodeType && item.cloneNode) {
  447. return item.cloneNode(true);
  448. }
  449. var type = toString.call(item);
  450. // Date
  451. if (type === '[object Date]') {
  452. return new Date(item.getTime());
  453. }
  454. var i, j, k, clone, key;
  455. // Array
  456. if (type === '[object Array]') {
  457. i = item.length;
  458. clone = [];
  459. while (i--) {
  460. clone[i] = Ext.clone(item[i]);
  461. }
  462. }
  463. // Object
  464. else if (type === '[object Object]' && item.constructor === Object) {
  465. clone = {};
  466. for (key in item) {
  467. clone[key] = Ext.clone(item[key]);
  468. }
  469. if (enumerables) {
  470. for (j = enumerables.length; j--;) {
  471. k = enumerables[j];
  472. clone[k] = item[k];
  473. }
  474. }
  475. }
  476. return clone || item;
  477. },
  478. /**
  479. * @private
  480. * Generate a unique reference of Ext in the global scope, useful for sandboxing
  481. */
  482. getUniqueGlobalNamespace: function() {
  483. var uniqueGlobalNamespace = this.uniqueGlobalNamespace;
  484. if (uniqueGlobalNamespace === undefined) {
  485. var i = 0;
  486. do {
  487. uniqueGlobalNamespace = 'ExtBox' + (++i);
  488. } while (Ext.global[uniqueGlobalNamespace] !== undefined);
  489. Ext.global[uniqueGlobalNamespace] = Ext;
  490. this.uniqueGlobalNamespace = uniqueGlobalNamespace;
  491. }
  492. return uniqueGlobalNamespace;
  493. },
  494. /**
  495. * @private
  496. */
  497. functionFactoryCache: {},
  498. cacheableFunctionFactory: function() {
  499. var me = this,
  500. args = Array.prototype.slice.call(arguments),
  501. cache = me.functionFactoryCache,
  502. idx, fn, ln;
  503. if (Ext.isSandboxed) {
  504. ln = args.length;
  505. if (ln > 0) {
  506. ln--;
  507. args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
  508. }
  509. }
  510. idx = args.join('');
  511. fn = cache[idx];
  512. if (!fn) {
  513. fn = Function.prototype.constructor.apply(Function.prototype, args);
  514. cache[idx] = fn;
  515. }
  516. return fn;
  517. },
  518. functionFactory: function() {
  519. var me = this,
  520. args = Array.prototype.slice.call(arguments),
  521. ln;
  522. if (Ext.isSandboxed) {
  523. ln = args.length;
  524. if (ln > 0) {
  525. ln--;
  526. args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
  527. }
  528. }
  529. return Function.prototype.constructor.apply(Function.prototype, args);
  530. },
  531. /**
  532. * @property
  533. * @private
  534. */
  535. globalEval: ('execScript' in global) ? function(code) {
  536. global.execScript(code)
  537. } : function(code) {
  538. (function(){
  539. eval(code);
  540. })();
  541. },
  542. /**
  543. * @private
  544. * @property
  545. */
  546. Logger: {
  547. verbose: emptyFn,
  548. log: emptyFn,
  549. info: emptyFn,
  550. warn: emptyFn,
  551. error: function(message) {
  552. throw new Error(message);
  553. },
  554. deprecate: emptyFn
  555. }
  556. });
  557. /**
  558. * Old alias to {@link Ext#typeOf}
  559. * @deprecated 4.0.0 Use {@link Ext#typeOf} instead
  560. * @method
  561. * @inheritdoc Ext#typeOf
  562. */
  563. Ext.type = Ext.typeOf;
  564. })();
  565. /**
  566. * @author Jacky Nguyen <jacky@sencha.com>
  567. * @docauthor Jacky Nguyen <jacky@sencha.com>
  568. * @class Ext.Version
  569. *
  570. * A utility class that wrap around a string version number and provide convenient
  571. * method to perform comparison. See also: {@link Ext.Version#compare compare}. Example:
  572. var version = new Ext.Version('1.0.2beta');
  573. console.log("Version is " + version); // Version is 1.0.2beta
  574. console.log(version.getMajor()); // 1
  575. console.log(version.getMinor()); // 0
  576. console.log(version.getPatch()); // 2
  577. console.log(version.getBuild()); // 0
  578. console.log(version.getRelease()); // beta
  579. console.log(version.isGreaterThan('1.0.1')); // True
  580. console.log(version.isGreaterThan('1.0.2alpha')); // True
  581. console.log(version.isGreaterThan('1.0.2RC')); // False
  582. console.log(version.isGreaterThan('1.0.2')); // False
  583. console.log(version.isLessThan('1.0.2')); // True
  584. console.log(version.match(1.0)); // True
  585. console.log(version.match('1.0.2')); // True
  586. * @markdown
  587. */
  588. (function() {
  589. // Current core version
  590. var version = '4.1.0beta', Version;
  591. Ext.Version = Version = Ext.extend(Object, {
  592. /**
  593. * @param {String/Number} version The version number in the follow standard format: major[.minor[.patch[.build[release]]]]
  594. * Examples: 1.0 or 1.2.3beta or 1.2.3.4RC
  595. * @return {Ext.Version} this
  596. */
  597. constructor: function(version) {
  598. var parts, releaseStartIndex;
  599. if (version instanceof Version) {
  600. return version;
  601. }
  602. this.version = this.shortVersion = String(version).toLowerCase().replace(/_/g, '.').replace(/[\-+]/g, '');
  603. releaseStartIndex = this.version.search(/([^\d\.])/);
  604. if (releaseStartIndex !== -1) {
  605. this.release = this.version.substr(releaseStartIndex, version.length);
  606. this.shortVersion = this.version.substr(0, releaseStartIndex);
  607. }
  608. this.shortVersion = this.shortVersion.replace(/[^\d]/g, '');
  609. parts = this.version.split('.');
  610. this.major = parseInt(parts.shift() || 0, 10);
  611. this.minor = parseInt(parts.shift() || 0, 10);
  612. this.patch = parseInt(parts.shift() || 0, 10);
  613. this.build = parseInt(parts.shift() || 0, 10);
  614. return this;
  615. },
  616. /**
  617. * Override the native toString method
  618. * @private
  619. * @return {String} version
  620. */
  621. toString: function() {
  622. return this.version;
  623. },
  624. /**
  625. * Override the native valueOf method
  626. * @private
  627. * @return {String} version
  628. */
  629. valueOf: function() {
  630. return this.version;
  631. },
  632. /**
  633. * Returns the major component value
  634. * @return {Number} major
  635. */
  636. getMajor: function() {
  637. return this.major || 0;
  638. },
  639. /**
  640. * Returns the minor component value
  641. * @return {Number} minor
  642. */
  643. getMinor: function() {
  644. return this.minor || 0;
  645. },
  646. /**
  647. * Returns the patch component value
  648. * @return {Number} patch
  649. */
  650. getPatch: function() {
  651. return this.patch || 0;
  652. },
  653. /**
  654. * Returns the build component value
  655. * @return {Number} build
  656. */
  657. getBuild: function() {
  658. return this.build || 0;
  659. },
  660. /**
  661. * Returns the release component value
  662. * @return {Number} release
  663. */
  664. getRelease: function() {
  665. return this.release || '';
  666. },
  667. /**
  668. * Returns whether this version if greater than the supplied argument
  669. * @param {String/Number} target The version to compare with
  670. * @return {Boolean} True if this version if greater than the target, false otherwise
  671. */
  672. isGreaterThan: function(target) {
  673. return Version.compare(this.version, target) === 1;
  674. },
  675. /**
  676. * Returns whether this version if greater than or equal to the supplied argument
  677. * @param {String/Number} target The version to compare with
  678. * @return {Boolean} True if this version if greater than or equal to the target, false otherwise
  679. */
  680. isGreaterThanOrEqual: function(target) {
  681. return Version.compare(this.version, target) >= 0;
  682. },
  683. /**
  684. * Returns whether this version if smaller than the supplied argument
  685. * @param {String/Number} target The version to compare with
  686. * @return {Boolean} True if this version if smaller than the target, false otherwise
  687. */
  688. isLessThan: function(target) {
  689. return Version.compare(this.version, target) === -1;
  690. },
  691. /**
  692. * Returns whether this version if less than or equal to the supplied argument
  693. * @param {String/Number} target The version to compare with
  694. * @return {Boolean} True if this version if less than or equal to the target, false otherwise
  695. */
  696. isLessThanOrEqual: function(target) {
  697. return Version.compare(this.version, target) <= 0;
  698. },
  699. /**
  700. * Returns whether this version equals to the supplied argument
  701. * @param {String/Number} target The version to compare with
  702. * @return {Boolean} True if this version equals to the target, false otherwise
  703. */
  704. equals: function(target) {
  705. return Version.compare(this.version, target) === 0;
  706. },
  707. /**
  708. * Returns whether this version matches the supplied argument. Example:
  709. * <pre><code>
  710. * var version = new Ext.Version('1.0.2beta');
  711. * console.log(version.match(1)); // True
  712. * console.log(version.match(1.0)); // True
  713. * console.log(version.match('1.0.2')); // True
  714. * console.log(version.match('1.0.2RC')); // False
  715. * </code></pre>
  716. * @param {String/Number} target The version to compare with
  717. * @return {Boolean} True if this version matches the target, false otherwise
  718. */
  719. match: function(target) {
  720. target = String(target);
  721. return this.version.substr(0, target.length) === target;
  722. },
  723. /**
  724. * Returns this format: [major, minor, patch, build, release]. Useful for comparison
  725. * @return {Number[]}
  726. */
  727. toArray: function() {
  728. return [this.getMajor(), this.getMinor(), this.getPatch(), this.getBuild(), this.getRelease()];
  729. },
  730. /**
  731. * Returns shortVersion version without dots and release
  732. * @return {String}
  733. */
  734. getShortVersion: function() {
  735. return this.shortVersion;
  736. },
  737. /**
  738. * Convenient alias to {@link Ext.Version#isGreaterThan isGreaterThan}
  739. * @param {String/Number} target
  740. * @return {Boolean}
  741. */
  742. gt: function() {
  743. return this.isGreaterThan.apply(this, arguments);
  744. },
  745. /**
  746. * Convenient alias to {@link Ext.Version#isLessThan isLessThan}
  747. * @param {String/Number} target
  748. * @return {Boolean}
  749. */
  750. lt: function() {
  751. return this.isLessThan.apply(this, arguments);
  752. },
  753. /**
  754. * Convenient alias to {@link Ext.Version#isGreaterThanOrEqual isGreaterThanOrEqual}
  755. * @param {String/Number} target
  756. * @return {Boolean}
  757. */
  758. gtEq: function() {
  759. return this.isGreaterThanOrEqual.apply(this, arguments);
  760. },
  761. /**
  762. * Convenient alias to {@link Ext.Version#isLessThanOrEqual isLessThanOrEqual}
  763. * @param {String/Number} target
  764. * @return {Boolean}
  765. */
  766. ltEq: function() {
  767. return this.isLessThanOrEqual.apply(this, arguments);
  768. }
  769. });
  770. Ext.apply(Version, {
  771. // @private
  772. releaseValueMap: {
  773. 'dev': -6,
  774. 'alpha': -5,
  775. 'a': -5,
  776. 'beta': -4,
  777. 'b': -4,
  778. 'rc': -3,
  779. '#': -2,
  780. 'p': -1,
  781. 'pl': -1
  782. },
  783. /**
  784. * Converts a version component to a comparable value
  785. *
  786. * @static
  787. * @param {Object} value The value to convert
  788. * @return {Object}
  789. */
  790. getComponentValue: function(value) {
  791. return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10));
  792. },
  793. /**
  794. * Compare 2 specified versions, starting from left to right. If a part contains special version strings,
  795. * they are handled in the following order:
  796. * 'dev' < 'alpha' = 'a' < 'beta' = 'b' < 'RC' = 'rc' < '#' < 'pl' = 'p' < 'anything else'
  797. *
  798. * @static
  799. * @param {String} current The current version to compare to
  800. * @param {String} target The target version to compare to
  801. * @return {Number} Returns -1 if the current version is smaller than the target version, 1 if greater, and 0 if they're equivalent
  802. */
  803. compare: function(current, target) {
  804. var currentValue, targetValue, i;
  805. current = new Version(current).toArray();
  806. target = new Version(target).toArray();
  807. for (i = 0; i < Math.max(current.length, target.length); i++) {
  808. currentValue = this.getComponentValue(current[i]);
  809. targetValue = this.getComponentValue(target[i]);
  810. if (currentValue < targetValue) {
  811. return -1;
  812. } else if (currentValue > targetValue) {
  813. return 1;
  814. }
  815. }
  816. return 0;
  817. }
  818. });
  819. Ext.apply(Ext, {
  820. /**
  821. * @private
  822. */
  823. versions: {},
  824. /**
  825. * @private
  826. */
  827. lastRegisteredVersion: null,
  828. /**
  829. * Set version number for the given package name.
  830. *
  831. * @param {String} packageName The package name, for example: 'core', 'touch', 'extjs'
  832. * @param {String/Ext.Version} version The version, for example: '1.2.3alpha', '2.4.0-dev'
  833. * @return {Ext}
  834. */
  835. setVersion: function(packageName, version) {
  836. Ext.versions[packageName] = new Version(version);
  837. Ext.lastRegisteredVersion = Ext.versions[packageName];
  838. return this;
  839. },
  840. /**
  841. * Get the version number of the supplied package name; will return the last registered version
  842. * (last Ext.setVersion call) if there's no package name given.
  843. *
  844. * @param {String} packageName (Optional) The package name, for example: 'core', 'touch', 'extjs'
  845. * @return {Ext.Version} The version
  846. */
  847. getVersion: function(packageName) {
  848. if (packageName === undefined) {
  849. return Ext.lastRegisteredVersion;
  850. }
  851. return Ext.versions[packageName];
  852. },
  853. /**
  854. * Create a closure for deprecated code.
  855. *
  856. // This means Ext.oldMethod is only supported in 4.0.0beta and older.
  857. // If Ext.getVersion('extjs') returns a version that is later than '4.0.0beta', for example '4.0.0RC',
  858. // the closure will not be invoked
  859. Ext.deprecate('extjs', '4.0.0beta', function() {
  860. Ext.oldMethod = Ext.newMethod;
  861. ...
  862. });
  863. * @param {String} packageName The package name
  864. * @param {String} since The last version before it's deprecated
  865. * @param {Function} closure The callback function to be executed with the specified version is less than the current version
  866. * @param {Object} scope The execution scope (<tt>this</tt>) if the closure
  867. * @markdown
  868. */
  869. deprecate: function(packageName, since, closure, scope) {
  870. if (Version.compare(Ext.getVersion(packageName), since) < 1) {
  871. closure.call(scope);
  872. }
  873. }
  874. }); // End Versioning
  875. Ext.setVersion('core', version);
  876. })();
  877. /**
  878. * @class Ext.String
  879. *
  880. * A collection of useful static methods to deal with strings
  881. * @singleton
  882. */
  883. Ext.String = (function() {
  884. 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,
  885. escapeRe = /('|\\)/g,
  886. formatRe = /\{(\d+)\}/g,
  887. escapeRegexRe = /([-.*+?^${}()|[\]\/\\])/g,
  888. basicTrimRe = /^\s+|\s+$/g,
  889. whitespaceRe = /\s+/,
  890. varReplace = /(^[^a-z]*|[^\w])/gi,
  891. charToEntity = {
  892. '&': '&amp;',
  893. '>': '&gt;',
  894. '<': '&lt;',
  895. '"': '&quot;'
  896. },
  897. entityToChar = {
  898. '&amp;': '&',
  899. '&gt;': '>',
  900. '&lt;': '<',
  901. '&quot;': '"'
  902. },
  903. keys = [],
  904. key,
  905. charToEntityRegex,
  906. entityToCharRegex,
  907. htmlEncodeReplaceFn = function(match, capture) {
  908. return charToEntity[capture];
  909. },
  910. htmlEncode = function(value) {
  911. return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
  912. },
  913. htmlDecodeReplaceFn = function(match, capture) {
  914. return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
  915. },
  916. htmlDecode = function(value) {
  917. return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
  918. };
  919. // Compile RexExps for HTML encode and decode functions
  920. for (key in charToEntity) {
  921. keys.push(key);
  922. }
  923. charToEntityRegex = new RegExp('(' + keys.join('|') + ')', 'g');
  924. keys = [];
  925. for (key in entityToChar) {
  926. keys.push(key);
  927. }
  928. entityToCharRegex = new RegExp('(' + keys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
  929. return {
  930. /**
  931. * Converts a string of characters into a legal, parseable Javascript `var` name as long as the passed
  932. * string contains at least one alphabetic character. Non alphanumeric characters, and *leading* non alphabetic
  933. * characters will be removed.
  934. * @param {String} s A string to be converted into a `var` name.
  935. * @return {String} A legal Javascript `var` name.
  936. */
  937. createVarName: function(s) {
  938. return s.replace(varReplace, '');
  939. },
  940. /**
  941. * Convert certain characters (&, <, >, and ") to their HTML character equivalents for literal display in web pages.
  942. * @param {String} value The string to encode
  943. * @return {String} The encoded text
  944. * @method
  945. */
  946. htmlEncode: htmlEncode,
  947. /**
  948. * Convert certain characters (&, <, >, and ") from their HTML character equivalents.
  949. * @param {String} value The string to decode
  950. * @return {String} The decoded text
  951. * @method
  952. */
  953. htmlDecode: htmlDecode,
  954. /**
  955. * Appends content to the query string of a URL, handling logic for whether to place
  956. * a question mark or ampersand.
  957. * @param {String} url The URL to append to.
  958. * @param {String} string The content to append to the URL.
  959. * @return {String} The resulting URL
  960. */
  961. urlAppend : function(url, string) {
  962. if (!Ext.isEmpty(string)) {
  963. return url + (url.indexOf('?') === -1 ? '?' : '&') + string;
  964. }
  965. return url;
  966. },
  967. /**
  968. * Trims whitespace from either end of a string, leaving spaces within the string intact. Example:
  969. * @example
  970. var s = ' foo bar ';
  971. alert('-' + s + '-'); //alerts "- foo bar -"
  972. alert('-' + Ext.String.trim(s) + '-'); //alerts "-foo bar-"
  973. * @param {String} string The string to escape
  974. * @return {String} The trimmed string
  975. */
  976. trim: function(string) {
  977. return string.replace(trimRegex, "");
  978. },
  979. /**
  980. * Capitalize the given string
  981. * @param {String} string
  982. * @return {String}
  983. */
  984. capitalize: function(string) {
  985. return string.charAt(0).toUpperCase() + string.substr(1);
  986. },
  987. /**
  988. * Uncapitalize the given string
  989. * @param {String} string
  990. * @return {String}
  991. */
  992. uncapitalize: function(string) {
  993. return string.charAt(0).toLowerCase() + string.substr(1);
  994. },
  995. /**
  996. * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length
  997. * @param {String} value The string to truncate
  998. * @param {Number} length The maximum length to allow before truncating
  999. * @param {Boolean} word True to try to find a common word break
  1000. * @return {String} The converted text
  1001. */
  1002. ellipsis: function(value, len, word) {
  1003. if (value && value.length > len) {
  1004. if (word) {
  1005. var vs = value.substr(0, len - 2),
  1006. index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
  1007. if (index !== -1 && index >= (len - 15)) {
  1008. return vs.substr(0, index) + "...";
  1009. }
  1010. }
  1011. return value.substr(0, len - 3) + "...";
  1012. }
  1013. return value;
  1014. },
  1015. /**
  1016. * Escapes the passed string for use in a regular expression
  1017. * @param {String} string
  1018. * @return {String}
  1019. */
  1020. escapeRegex: function(string) {
  1021. return string.replace(escapeRegexRe, "\\$1");
  1022. },
  1023. /**
  1024. * Escapes the passed string for ' and \
  1025. * @param {String} string The string to escape
  1026. * @return {String} The escaped string
  1027. */
  1028. escape: function(string) {
  1029. return string.replace(escapeRe, "\\$1");
  1030. },
  1031. /**
  1032. * Utility function that allows you to easily switch a string between two alternating values. The passed value
  1033. * is compared to the current string, and if they are equal, the other value that was passed in is returned. If
  1034. * they are already different, the first value passed in is returned. Note that this method returns the new value
  1035. * but does not change the current string.
  1036. * <pre><code>
  1037. // alternate sort directions
  1038. sort = Ext.String.toggle(sort, 'ASC', 'DESC');
  1039. // instead of conditional logic:
  1040. sort = (sort == 'ASC' ? 'DESC' : 'ASC');
  1041. </code></pre>
  1042. * @param {String} string The current string
  1043. * @param {String} value The value to compare to the current string
  1044. * @param {String} other The new value to use if the string already equals the first value passed in
  1045. * @return {String} The new value
  1046. */
  1047. toggle: function(string, value, other) {
  1048. return string === value ? other : value;
  1049. },
  1050. /**
  1051. * Pads the left side of a string with a specified character. This is especially useful
  1052. * for normalizing number and date strings. Example usage:
  1053. *
  1054. * <pre><code>
  1055. var s = Ext.String.leftPad('123', 5, '0');
  1056. // s now contains the string: '00123'
  1057. </code></pre>
  1058. * @param {String} string The original string
  1059. * @param {Number} size The total length of the output string
  1060. * @param {String} character (optional) The character with which to pad the original string (defaults to empty string " ")
  1061. * @return {String} The padded string
  1062. */
  1063. leftPad: function(string, size, character) {
  1064. var result = String(string);
  1065. character = character || " ";
  1066. while (result.length < size) {
  1067. result = character + result;
  1068. }
  1069. return result;
  1070. },
  1071. /**
  1072. * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each
  1073. * token must be unique, and must increment in the format {0}, {1}, etc. Example usage:
  1074. * <pre><code>
  1075. var cls = 'my-class', text = 'Some text';
  1076. var s = Ext.String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
  1077. // s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
  1078. </code></pre>
  1079. * @param {String} string The tokenized string to be formatted
  1080. * @param {String} value1 The value to replace token {0}
  1081. * @param {String} value2 Etc...
  1082. * @return {String} The formatted string
  1083. */
  1084. format: function(format) {
  1085. var args = Ext.Array.toArray(arguments, 1);
  1086. return format.replace(formatRe, function(m, i) {
  1087. return args[i];
  1088. });
  1089. },
  1090. /**
  1091. * Returns a string with a specified number of repititions a given string pattern.
  1092. * The pattern be separated by a different string.
  1093. *
  1094. * var s = Ext.String.repeat('---', 4); // = '------------'
  1095. * var t = Ext.String.repeat('--', 3, '/'); // = '--/--/--'
  1096. *
  1097. * @param {String} pattern The pattern to repeat.
  1098. * @param {Number} count The number of times to repeat the pattern (may be 0).
  1099. * @param {String} sep An option string to separate each pattern.
  1100. */
  1101. repeat: function(pattern, count, sep) {
  1102. for (var buf = [], i = count; i--; ) {
  1103. buf.push(pattern);
  1104. }
  1105. return buf.join(sep || '');
  1106. },
  1107. /**
  1108. * Splits a string of space separated words into an array, trimming as needed. If the
  1109. * words are already an array, it is returned.
  1110. *
  1111. * @param {String/Array} words
  1112. */
  1113. splitWords: function (words) {
  1114. if (words && typeof words == 'string') {
  1115. return words.replace(basicTrimRe, '').split(whitespaceRe);
  1116. }
  1117. return words || [];
  1118. }
  1119. };
  1120. })();
  1121. /**
  1122. * Old alias to {@link Ext.String#htmlEncode}
  1123. * @deprecated Use {@link Ext.String#htmlEncode} instead
  1124. * @method
  1125. * @member Ext
  1126. * @inheritdoc Ext.String#htmlEncode
  1127. */
  1128. Ext.htmlEncode = Ext.String.htmlEncode;
  1129. /**
  1130. * Old alias to {@link Ext.String#htmlDecode}
  1131. * @deprecated Use {@link Ext.String#htmlDecode} instead
  1132. * @method
  1133. * @member Ext
  1134. * @inheritdoc Ext.String#htmlDecode
  1135. */
  1136. Ext.htmlDecode = Ext.String.htmlDecode;
  1137. /**
  1138. * Old alias to {@link Ext.String#urlAppend}
  1139. * @deprecated Use {@link Ext.String#urlAppend} instead
  1140. * @method
  1141. * @member Ext
  1142. * @inheritdoc Ext.String#urlAppend
  1143. */
  1144. Ext.urlAppend = Ext.String.urlAppend;
  1145. /**
  1146. * @class Ext.Number
  1147. *
  1148. * A collection of useful static methods to deal with numbers
  1149. * @singleton
  1150. */
  1151. Ext.Number = new function() {
  1152. var me = this,
  1153. isToFixedBroken = (0.9).toFixed() !== '1',
  1154. math = Math;
  1155. Ext.apply(this, {
  1156. /**
  1157. * Checks whether or not the passed number is within a desired range. If the number is already within the
  1158. * range it is returned, otherwise the min or max value is returned depending on which side of the range is
  1159. * exceeded. Note that this method returns the constrained value but does not change the current number.
  1160. * @param {Number} number The number to check
  1161. * @param {Number} min The minimum number in the range
  1162. * @param {Number} max The maximum number in the range
  1163. * @return {Number} The constrained value if outside the range, otherwise the current value
  1164. */
  1165. constrain: function(number, min, max) {
  1166. number = parseFloat(number);
  1167. if (!isNaN(min)) {
  1168. number = math.max(number, min);
  1169. }
  1170. if (!isNaN(max)) {
  1171. number = math.min(number, max);
  1172. }
  1173. return number;
  1174. },
  1175. /**
  1176. * Snaps the passed number between stopping points based upon a passed increment value.
  1177. *
  1178. * The difference between this and {@link #snapInRange} is that {@link #snapInRange} uses the minValue
  1179. * when calculating snap points:
  1180. *
  1181. * r = Ext.Number.snap(56, 2, 55, 65); // Returns 56 - snap points are zero based
  1182. *
  1183. * r = Ext.Number.snapInRange(56, 2, 55, 65); // Returns 57 - snap points are based from minValue
  1184. *
  1185. * @param {Number} value The unsnapped value.
  1186. * @param {Number} increment The increment by which the value must move.
  1187. * @param {Number} minValue The minimum value to which the returned value must be constrained. Overrides the increment.
  1188. * @param {Number} maxValue The maximum value to which the returned value must be constrained. Overrides the increment.
  1189. * @return {Number} The value of the nearest snap target.
  1190. */
  1191. snap : function(value, increment, minValue, maxValue) {
  1192. var m;
  1193. // If no value passed, or minValue was passed and value is less than minValue (anything < undefined is false)
  1194. // Then use the minValue (or zero if the value was undefined)
  1195. if (value === undefined || value < minValue) {
  1196. return minValue || 0;
  1197. }
  1198. if (increment) {
  1199. m = value % increment;
  1200. if (m !== 0) {
  1201. value -= m;
  1202. if (m * 2 >= increment) {
  1203. value += increment;
  1204. } else if (m * 2 < -increment) {
  1205. value -= increment;
  1206. }
  1207. }
  1208. }
  1209. return me.constrain(value, minValue, maxValue);
  1210. },
  1211. /**
  1212. * Snaps the passed number between stopping points based upon a passed increment value.
  1213. *
  1214. * The difference between this and {@link #snap} is that {@link #snap} does not use the minValue
  1215. * when calculating snap points:
  1216. *
  1217. * r = Ext.Number.snap(56, 2, 55, 65); // Returns 56 - snap points are zero based
  1218. *
  1219. * r = Ext.Number.snapInRange(56, 2, 55, 65); // Returns 57 - snap points are based from minValue
  1220. *
  1221. * @param {Number} value The unsnapped value.
  1222. * @param {Number} increment The increment by which the value must move.
  1223. * @param {Number} [minValue=0] The minimum value to which the returned value must be constrained.
  1224. * @param {Number} [maxValue=Infinity] The maximum value to which the returned value must be constrained.
  1225. * @return {Number} The value of the nearest snap target.
  1226. */
  1227. snapInRange : function(value, increment, minValue, maxValue) {
  1228. var tween;
  1229. // default minValue to zero
  1230. minValue = (minValue || 0);
  1231. // If value is undefined, or less than minValue, use minValue
  1232. if (value === undefined || value < minValue) {
  1233. return minValue;
  1234. }
  1235. // Calculate how many snap points from the minValue the passed value is.
  1236. if (increment && (tween = ((value - minValue) % increment))) {
  1237. value