/ext-4.0.7/ext-all-debug-w-comments.js

https://bitbucket.org/srogerf/javascript · JavaScript · 27823 lines · 14877 code · 2469 blank · 10477 comment · 3006 complexity · cd31a3bae62ba15b08ea7e8779ed7476 MD5 · raw file

Large files are truncated click here to view the full file

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