]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/src/util/Version.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / src / util / Version.js
CommitLineData
6527f429
DM
1/**\r
2 * @class Ext.Version\r
3 *\r
4 * A utility class that wraps around a version number string and provides convenient methods\r
5 * to perform comparisons. A version number is expressed in the following general format:\r
6 *\r
7 * major[.minor[.patch[.build[release]]]]\r
8 * \r
9 * The `Version` instance holds various readonly properties that contain the digested form\r
10 * of the version string. The numeric componnets of `major`, `minor`, `patch` and `build`\r
11 * as well as the textual suffix called `release`.\r
12 * \r
13 * Not depicted in the above syntax are three possible prefixes used to control partial\r
14 * matching. These are '^' (the default), '>' and '~'. These are discussed below.\r
15 *\r
16 * Examples:\r
17 *\r
18 * var version = new Ext.Version('1.0.2beta'); // or maybe "1.0" or "1.2.3.4RC"\r
19 * console.log("Version is " + version); // Version is 1.0.2beta\r
20 *\r
21 * console.log(version.getMajor()); // 1\r
22 * console.log(version.getMinor()); // 0\r
23 * console.log(version.getPatch()); // 2\r
24 * console.log(version.getBuild()); // 0\r
25 * console.log(version.getRelease()); // beta\r
26 *\r
27 * The understood values of `release` are assigned numberic equivalents for the sake of\r
28 * comparsion. The order of these from smallest to largest is as follows:\r
29 *\r
30 * * `"dev"`\r
31 * * `"alpha"` or `"a"`\r
32 * * `"beta"` or `"b"`\r
33 * * `"RC"` or `"rc"`\r
34 * * `"#"`\r
35 * * `"pl"` or `"p"`\r
36 *\r
37 * Any other (unrecognized) suffix is consider greater than any of these.\r
38 * \r
39 * ## Comparisons\r
40 * There are two forms of comparison that are commonly needed: full and partial. Full\r
41 * comparison is simpler and is also the default.\r
42 * \r
43 * Example:\r
44 *\r
45 * var version = new Ext.Version('1.0.2beta');\r
46 *\r
47 * console.log(version.isGreaterThan('1.0.1')); // True\r
48 * console.log(version.isGreaterThan('1.0.2alpha')); // True\r
49 * console.log(version.isGreaterThan('1.0.2RC')); // False\r
50 * console.log(version.isGreaterThan('1.0.2')); // False\r
51 * console.log(version.isLessThan('1.0.2')); // True\r
52 *\r
53 * console.log(version.match(1.0)); // True (using a Number)\r
54 * console.log(version.match('1.0.2')); // True (using a String)\r
55 * \r
56 * These comparisons are ultimately implemented by {@link Ext.Version#compareTo compareTo}\r
57 * which returns -1, 0 or 1 depending on whether the `Version' instance is less than, equal\r
58 * to, or greater than the given "other" version.\r
59 * \r
60 * For example:\r
61 * \r
62 * var n = version.compareTo('1.0.1'); // == 1 (because 1.0.2beta > 1.0.1)\r
63 * \r
64 * n = version.compareTo('1.1'); // == -1\r
65 * n = version.compareTo(version); // == 0\r
66 * \r
67 * ### Partial Comparisons\r
68 * By default, unspecified version number fields are filled with 0. In other words, the\r
69 * version number fields are 0-padded on the right or a "lower bound". This produces the\r
70 * most commonly used forms of comparsion:\r
71 * \r
72 * var ver = new Version('4.2');\r
73 *\r
74 * n = ver.compareTo('4.2.1'); // == -1 (4.2 promotes to 4.2.0 and is less than 4.2.1)\r
75 * \r
76 * There are two other ways to interpret comparisons of versions of different length. The\r
77 * first of these is to change the padding on the right to be a large number (scuh as\r
78 * Infinity) instead of 0. This has the effect of making the version an upper bound. For\r
79 * example:\r
80 * \r
81 * var ver = new Version('^4.2'); // NOTE: the '^' prefix used\r
82 *\r
83 * n = ver.compareTo('4.3'); // == -1 (less than 4.3)\r
84 * \r
85 * n = ver.compareTo('4.2'); // == 1 (greater than all 4.2's)\r
86 * n = ver.compareTo('4.2.1'); // == 1\r
87 * n = ver.compareTo('4.2.9'); // == 1\r
88 * \r
89 * The second way to interpret this comparison is to ignore the extra digits, making the\r
90 * match a prefix match. For example:\r
91 * \r
92 * var ver = new Version('~4.2'); // NOTE: the '~' prefix used\r
93 *\r
94 * n = ver.compareTo('4.3'); // == -1\r
95 * \r
96 * n = ver.compareTo('4.2'); // == 0\r
97 * n = ver.compareTo('4.2.1'); // == 0\r
98 * \r
99 * This final form can be useful when version numbers contain more components than are\r
100 * important for certain comparisons. For example, the full version of Ext JS 4.2.1 is\r
101 * "4.2.1.883" where 883 is the `build` number.\r
102 * \r
103 * This is how to create a "partial" `Version` and compare versions to it:\r
104 * \r
105 * var version421ish = new Version('~4.2.1');\r
106 * \r
107 * n = version421ish.compareTo('4.2.1.883'); // == 0\r
108 * n = version421ish.compareTo('4.2.1.2'); // == 0\r
109 * n = version421ish.compareTo('4.2.1'); // == 0\r
110 *\r
111 * n = version421ish.compareTo('4.2'); // == 1\r
112 *\r
113 * In the above example, '4.2.1.2' compares as equal to '4.2.1' because digits beyond the\r
114 * given "4.2.1" are ignored. However, '4.2' is less than the '4.2.1' prefix; its missing\r
115 * digit is filled with 0.\r
116 */\r
117(function() {\r
118// @define Ext.Version\r
119// @require Ext.String\r
120 var // used by checkVersion to avoid temp arrays:\r
121 checkVerTemp = [''],\r
122 endOfVersionRe = /([^\d\.])/,\r
123 notDigitsRe = /[^\d]/g,\r
124 plusMinusRe = /[\-+]/g,\r
125 stripRe = /\s/g,\r
126 underscoreRe = /_/g,\r
127 toolkitNames = { classic: 1, modern: 1},\r
128 Version;\r
129\r
130 Ext.Version = Version = function(version, defaultMode) {\r
131 var me = this,\r
132 padModes = me.padModes,\r
133 ch, i, pad, parts, release, releaseStartIndex, ver;\r
134\r
135 if (version.isVersion) {\r
136 version = version.version;\r
137 }\r
138\r
139 me.version = ver = String(version).toLowerCase().\r
140 replace(underscoreRe, '.').replace(plusMinusRe, '');\r
141\r
142 ch = ver.charAt(0);\r
143 if (ch in padModes) {\r
144 ver = ver.substring(1);\r
145 pad = padModes[ch];\r
146 } else {\r
147 pad = defaultMode ? padModes[defaultMode] : 0; // careful - NaN is falsey!\r
148 }\r
149 me.pad = pad;\r
150\r
151 releaseStartIndex = ver.search(endOfVersionRe);\r
152 me.shortVersion = ver;\r
153\r
154 if (releaseStartIndex !== -1) {\r
155 me.release = release = ver.substr(releaseStartIndex, version.length);\r
156 me.shortVersion = ver.substr(0, releaseStartIndex);\r
157 release = Version.releaseValueMap[release] || release;\r
158 }\r
159\r
160 me.releaseValue = release || pad;\r
161 me.shortVersion = me.shortVersion.replace(notDigitsRe, '');\r
162\r
163 /**\r
164 * @property {Number[]} parts\r
165 * The split array of version number components found in the version string.\r
166 * For example, for "1.2.3", this would be `[1, 2, 3]`.\r
167 * @readonly\r
168 * @private\r
169 */\r
170 me.parts = parts = ver.split('.');\r
171 for (i = parts.length; i--; ) {\r
172 parts[i] = parseInt(parts[i], 10);\r
173 }\r
174 if (pad === Infinity) {\r
175 // have to add this to the end to create an upper bound:\r
176 parts.push(pad);\r
177 }\r
178\r
179 /**\r
180 * @property {Number} major\r
181 * The first numeric part of the version number string.\r
182 * @readonly\r
183 */\r
184 me.major = parts[0] || pad;\r
185\r
186 /**\r
187 * @property {Number} [minor]\r
188 * The second numeric part of the version number string.\r
189 * @readonly\r
190 */\r
191 me.minor = parts[1] || pad;\r
192\r
193 /**\r
194 * @property {Number} [patch]\r
195 * The third numeric part of the version number string.\r
196 * @readonly\r
197 */\r
198 me.patch = parts[2] || pad;\r
199\r
200 /**\r
201 * @property {Number} [build]\r
202 * The fourth numeric part of the version number string.\r
203 * @readonly\r
204 */\r
205 me.build = parts[3] || pad;\r
206\r
207 return me;\r
208 };\r
209\r
210 Version.prototype = {\r
211 isVersion: true,\r
212\r
213 padModes: {\r
214 '~': NaN,\r
215 '^': Infinity\r
216 },\r
217\r
218 /**\r
219 * @property {String} [release=""]\r
220 * The release level. The following values are understood:\r
221 * \r
222 * * `"dev"`\r
223 * * `"alpha"` or `"a"`\r
224 * * `"beta"` or `"b"`\r
225 * * `"RC"` or `"rc"`\r
226 * * `"#"`\r
227 * * `"pl"` or `"p"`\r
228 * @readonly\r
229 */\r
230 release: '',\r
231\r
232 /**\r
233 * Compares this version instance to the specified `other` version.\r
234 *\r
235 * @param {String/Number/Ext.Version} other The other version to which to compare.\r
236 * @return {Number} -1 if this version is less than the target version, 1 if this\r
237 * version is greater, and 0 if they are equal.\r
238 */\r
239 compareTo: function (other) {\r
240 // "lhs" == "left-hand-side"\r
241 // "rhs" == "right-hand-side"\r
242 var me = this,\r
243 lhsPad = me.pad,\r
244 lhsParts = me.parts,\r
245 lhsLength = lhsParts.length,\r
246 rhsVersion = other.isVersion ? other : new Version(other),\r
247 rhsPad = rhsVersion.pad,\r
248 rhsParts = rhsVersion.parts,\r
249 rhsLength = rhsParts.length,\r
250 length = Math.max(lhsLength, rhsLength),\r
251 i, lhs, rhs;\r
252\r
253 for (i = 0; i < length; i++) {\r
254 lhs = (i < lhsLength) ? lhsParts[i] : lhsPad;\r
255 rhs = (i < rhsLength) ? rhsParts[i] : rhsPad;\r
256\r
257 // When one or both of the values are NaN these tests produce false\r
258 // and we end up treating NaN as equal to anything.\r
259 if (lhs < rhs) {\r
260 return -1;\r
261 }\r
262 if (lhs > rhs) {\r
263 return 1;\r
264 }\r
265 }\r
266\r
267 // same comments about NaN apply here...\r
268 lhs = me.releaseValue;\r
269 rhs = rhsVersion.releaseValue;\r
270 if (lhs < rhs) {\r
271 return -1;\r
272 }\r
273 if (lhs > rhs) {\r
274 return 1;\r
275 }\r
276\r
277 return 0;\r
278 },\r
279 \r
280 /**\r
281 * Override the native `toString` method\r
282 * @private\r
283 * @return {String} version\r
284 */\r
285 toString: function() {\r
286 return this.version;\r
287 },\r
288\r
289 /**\r
290 * Override the native `valueOf` method\r
291 * @private\r
292 * @return {String} version\r
293 */\r
294 valueOf: function() {\r
295 return this.version;\r
296 },\r
297\r
298 /**\r
299 * Returns the major component value.\r
300 * @return {Number}\r
301 */\r
302 getMajor: function() {\r
303 return this.major;\r
304 },\r
305\r
306 /**\r
307 * Returns the minor component value.\r
308 * @return {Number}\r
309 */\r
310 getMinor: function() {\r
311 return this.minor;\r
312 },\r
313\r
314 /**\r
315 * Returns the patch component value.\r
316 * @return {Number}\r
317 */\r
318 getPatch: function() {\r
319 return this.patch;\r
320 },\r
321\r
322 /**\r
323 * Returns the build component value.\r
324 * @return {Number}\r
325 */\r
326 getBuild: function() {\r
327 return this.build;\r
328 },\r
329\r
330 /**\r
331 * Returns the release component text (e.g., "beta").\r
332 * @return {String}\r
333 */\r
334 getRelease: function() {\r
335 return this.release;\r
336 },\r
337\r
338 /**\r
339 * Returns the release component value for comparison purposes.\r
340 * @return {Number/String}\r
341 */\r
342 getReleaseValue: function() {\r
343 return this.releaseValue;\r
344 },\r
345\r
346 /**\r
347 * Returns whether this version if greater than the supplied argument\r
348 * @param {String/Number} target The version to compare with\r
349 * @return {Boolean} `true` if this version if greater than the target, `false` otherwise\r
350 */\r
351 isGreaterThan: function(target) {\r
352 return this.compareTo(target) > 0;\r
353 },\r
354\r
355 /**\r
356 * Returns whether this version if greater than or equal to the supplied argument\r
357 * @param {String/Number} target The version to compare with\r
358 * @return {Boolean} `true` if this version if greater than or equal to the target, `false` otherwise\r
359 */\r
360 isGreaterThanOrEqual: function(target) {\r
361 return this.compareTo(target) >= 0;\r
362 },\r
363\r
364 /**\r
365 * Returns whether this version if smaller than the supplied argument\r
366 * @param {String/Number} target The version to compare with\r
367 * @return {Boolean} `true` if this version if smaller than the target, `false` otherwise\r
368 */\r
369 isLessThan: function(target) {\r
370 return this.compareTo(target) < 0;\r
371 },\r
372\r
373 /**\r
374 * Returns whether this version if less than or equal to the supplied argument\r
375 * @param {String/Number} target The version to compare with\r
376 * @return {Boolean} `true` if this version if less than or equal to the target, `false` otherwise\r
377 */\r
378 isLessThanOrEqual: function(target) {\r
379 return this.compareTo(target) <= 0;\r
380 },\r
381\r
382 /**\r
383 * Returns whether this version equals to the supplied argument\r
384 * @param {String/Number} target The version to compare with\r
385 * @return {Boolean} `true` if this version equals to the target, `false` otherwise\r
386 */\r
387 equals: function(target) {\r
388 return this.compareTo(target) === 0;\r
389 },\r
390\r
391 /**\r
392 * Returns whether this version matches the supplied argument. Example:\r
393 *\r
394 * var version = new Ext.Version('1.0.2beta');\r
395 * console.log(version.match(1)); // true\r
396 * console.log(version.match(1.0)); // true\r
397 * console.log(version.match('1.0.2')); // true\r
398 * console.log(version.match('1.0.2RC')); // false\r
399 *\r
400 * @param {String/Number} target The version to compare with\r
401 * @return {Boolean} `true` if this version matches the target, `false` otherwise\r
402 */\r
403 match: function(target) {\r
404 target = String(target);\r
405 return this.version.substr(0, target.length) === target;\r
406 },\r
407\r
408 /**\r
409 * Returns this format: [major, minor, patch, build, release]. Useful for comparison.\r
410 * @return {Number[]}\r
411 */\r
412 toArray: function() {\r
413 var me = this;\r
414 return [me.getMajor(), me.getMinor(), me.getPatch(), me.getBuild(), me.getRelease()];\r
415 },\r
416\r
417 /**\r
418 * Returns shortVersion version without dots and release\r
419 * @return {String}\r
420 */\r
421 getShortVersion: function() {\r
422 return this.shortVersion;\r
423 },\r
424\r
425 /**\r
426 * Convenient alias to {@link Ext.Version#isGreaterThan isGreaterThan}\r
427 * @param {String/Number/Ext.Version} target\r
428 * @return {Boolean}\r
429 */\r
430 gt: function (target) {\r
431 return this.compareTo(target) > 0;\r
432 },\r
433\r
434 /**\r
435 * Convenient alias to {@link Ext.Version#isLessThan isLessThan}\r
436 * @param {String/Number/Ext.Version} target\r
437 * @return {Boolean}\r
438 */\r
439 lt: function (target) {\r
440 return this.compareTo(target) < 0;\r
441 },\r
442\r
443 /**\r
444 * Convenient alias to {@link Ext.Version#isGreaterThanOrEqual isGreaterThanOrEqual}\r
445 * @param {String/Number/Ext.Version} target\r
446 * @return {Boolean}\r
447 */\r
448 gtEq: function (target) {\r
449 return this.compareTo(target) >= 0;\r
450 },\r
451\r
452 /**\r
453 * Convenient alias to {@link Ext.Version#isLessThanOrEqual isLessThanOrEqual}\r
454 * @param {String/Number/Ext.Version} target\r
455 * @return {Boolean}\r
456 */\r
457 ltEq: function (target) {\r
458 return this.compareTo(target) <= 0;\r
459 }\r
460 };\r
461\r
462 Ext.apply(Version, {\r
463 aliases: {\r
464 from: {\r
465 extjs: 'ext',\r
466 core: 'core',\r
467 touch: 'modern'\r
468 },\r
469 to: {\r
470 ext: ['extjs'],\r
471 'core': ['core'],\r
472 modern: ['touch']\r
473 }\r
474 },\r
475\r
476 /**\r
477 * @private\r
478 */\r
479 releaseValueMap: {\r
480 dev: -6,\r
481 alpha: -5,\r
482 a: -5,\r
483 beta: -4,\r
484 b: -4,\r
485 rc: -3,\r
486 '#': -2,\r
487 p: -1,\r
488 pl: -1\r
489 },\r
490\r
491 /**\r
492 * Converts a version component to a comparable value\r
493 *\r
494 * @static\r
495 * @param {Object} value The value to convert\r
496 * @return {Object}\r
497 */\r
498 getComponentValue: function(value) {\r
499 return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10));\r
500 },\r
501\r
502 /**\r
503 * Compare 2 specified versions by ensuring the first parameter is a `Version`\r
504 * instance and then calling the `compareTo` method.\r
505 *\r
506 * @static\r
507 * @param {String} current The current version to compare to\r
508 * @param {String} target The target version to compare to\r
509 * @return {Number} Returns -1 if the current version is smaller than the target version, 1 if greater, and 0 if they're equivalent\r
510 */\r
511 compare: function (current, target) {\r
512 var ver = current.isVersion ? current : new Version(current);\r
513 return ver.compareTo(target);\r
514 },\r
515\r
516 set: function (collection, packageName, version) {\r
517 var aliases = Version.aliases.to[packageName],\r
518 ver = version.isVersion ? version : new Version(version),\r
519 i;\r
520\r
521 collection[packageName] = ver;\r
522 if (aliases) {\r
523 for (i = aliases.length; i-- > 0; ) {\r
524 collection[aliases[i]] = ver;\r
525 }\r
526 }\r
527\r
528 return ver;\r
529 }\r
530 });\r
531\r
532 /**\r
533 * @class Ext\r
534 */\r
535 Ext.apply(Ext, {\r
536 /**\r
537 * @private\r
538 */\r
539 compatVersions: {},\r
540\r
541 /**\r
542 * @private\r
543 * \r
544 * Object containing version information for all packages utilized by your \r
545 * application. \r
546 * \r
547 * For a public getter, please see `Ext.getVersion()`.\r
548 */\r
549 versions: {},\r
550\r
551 /**\r
552 * @private\r
553 */\r
554 lastRegisteredVersion: null,\r
555\r
556 /**\r
557 * Get the compatibility level (a version number) for the given package name. If\r
558 * none has been registered with `Ext.setCompatVersion` then `Ext.getVersion` is\r
559 * used to get the current version.\r
560 *\r
561 * @param {String} packageName The package name, e.g. 'core', 'touch', 'ext'.\r
562 * @since 5.0.0\r
563 * @private\r
564 */\r
565 getCompatVersion: function (packageName) {\r
566 var versions = Ext.compatVersions,\r
567 compat;\r
568\r
569 if (!packageName) {\r
570 compat = versions.ext || versions.touch || versions.core;\r
571 } else {\r
572 compat = versions[Version.aliases.from[packageName] || packageName];\r
573 }\r
574\r
575 return compat || Ext.getVersion(packageName);\r
576 },\r
577\r
578 /**\r
579 * Set the compatibility level (a version number) for the given package name.\r
580 *\r
581 * @param {String} packageName The package name, e.g. 'core', 'touch', 'ext'.\r
582 * @param {String/Ext.Version} version The version, e.g. '4.2'.\r
583 * @since 5.0.0\r
584 * @private\r
585 */\r
586 setCompatVersion: function (packageName, version) {\r
587 Version.set(Ext.compatVersions, packageName, version);\r
588 },\r
589\r
590 /**\r
591 * Set version number for the given package name.\r
592 *\r
593 * @param {String} packageName The package name, e.g. 'core', 'touch', 'ext'.\r
594 * @param {String/Ext.Version} version The version, e.g. '1.2.3alpha', '2.4.0-dev'.\r
595 * @return {Ext}\r
596 */\r
597 setVersion: function (packageName, version) {\r
598 if (packageName in toolkitNames) {\r
599 Ext.toolkit = packageName;\r
600 }\r
601 Ext.lastRegisteredVersion = Version.set(Ext.versions, packageName, version);\r
602 return this;\r
603 },\r
604\r
605 /**\r
606 * Get the version number of the supplied package name; will return the version of\r
607 * the framework.\r
608 *\r
609 * @param {String} [packageName] The package name, e.g., 'core', 'touch', 'ext'.\r
610 * @return {Ext.Version} The version.\r
611 */\r
612 getVersion: function (packageName) {\r
613 var versions = Ext.versions;\r
614\r
615 if (!packageName) {\r
616 return versions.ext || versions.touch || versions.core;\r
617 }\r
618\r
619 return versions[Version.aliases.from[packageName] || packageName];\r
620 },\r
621\r
622 /**\r
623 * This method checks the registered package versions against the provided version\r
624 * `specs`. A `spec` is either a string or an object indicating a boolean operator.\r
625 * This method accepts either form or an array of these as the first argument. The\r
626 * second argument applies only when the first is an array and indicates whether\r
627 * all `specs` must match or just one.\r
628 * \r
629 * ## Package Version Specifications\r
630 * The string form of a `spec` is used to indicate a version or range of versions\r
631 * for a particular package. This form of `spec` consists of three (3) parts:\r
632 * \r
633 * * Package name followed by "@". If not provided, the framework is assumed.\r
634 * * Minimum version.\r
635 * * Maximum version.\r
636 * \r
637 * At least one version number must be provided. If both minimum and maximum are\r
638 * provided, these must be separated by a "-".\r
639 * \r
640 * Some examples of package version specifications:\r
641 * \r
642 * 4.2.2 (exactly version 4.2.2 of the framework)\r
643 * 4.2.2+ (version 4.2.2 or higher of the framework)\r
644 * 4.2.2- (version 4.2.2 or higher of the framework)\r
645 * 4.2.1 - 4.2.3 (versions from 4.2.1 up to 4.2.3 of the framework)\r
646 * - 4.2.2 (any version up to version 4.2.1 of the framework)\r
647 * \r
648 * foo@1.0 (exactly version 1.0 of package "foo")\r
649 * foo@1.0-1.3 (versions 1.0 up to 1.3 of package "foo")\r
650 * \r
651 * **NOTE:** This syntax is the same as that used in Sencha Cmd's package\r
652 * requirements declarations.\r
653 * \r
654 * ## Boolean Operator Specifications\r
655 * Instead of a string, an object can be used to describe a boolean operation to\r
656 * perform on one or more `specs`. The operator is either **`and`** or **`or`**\r
657 * and can contain an optional **`not`**.\r
658 * \r
659 * For example:\r
660 * \r
661 * {\r
662 * not: true, // negates boolean result\r
663 * and: [\r
664 * '4.2.2',\r
665 * 'foo@1.0.1 - 2.0.1'\r
666 * ]\r
667 * }\r
668 * \r
669 * Each element of the array can in turn be a string or object spec. In other\r
670 * words, the value is passed to this method (recursively) as the first argument\r
671 * so these two calls are equivalent:\r
672 * \r
673 * Ext.checkVersion({\r
674 * not: true, // negates boolean result\r
675 * and: [\r
676 * '4.2.2',\r
677 * 'foo@1.0.1 - 2.0.1'\r
678 * ]\r
679 * });\r
680 *\r
681 * !Ext.checkVersion([\r
682 * '4.2.2',\r
683 * 'foo@1.0.1 - 2.0.1'\r
684 * ], true);\r
685 * \r
686 * ## Examples\r
687 * \r
688 * // A specific framework version\r
689 * Ext.checkVersion('4.2.2');\r
690 * \r
691 * // A range of framework versions:\r
692 * Ext.checkVersion('4.2.1-4.2.3');\r
693 * \r
694 * // A specific version of a package:\r
695 * Ext.checkVersion('foo@1.0.1');\r
696 * \r
697 * // A single spec that requires both a framework version and package\r
698 * // version range to match:\r
699 * Ext.checkVersion({\r
700 * and: [\r
701 * '4.2.2',\r
702 * 'foo@1.0.1-1.0.2'\r
703 * ]\r
704 * });\r
705 * \r
706 * // These checks can be nested:\r
707 * Ext.checkVersion({\r
708 * and: [\r
709 * '4.2.2', // exactly version 4.2.2 of the framework *AND*\r
710 * {\r
711 * // either (or both) of these package specs:\r
712 * or: [\r
713 * 'foo@1.0.1-1.0.2',\r
714 * 'bar@3.0+'\r
715 * ]\r
716 * }\r
717 * ]\r
718 * });\r
719 * \r
720 * ## Version Comparisons\r
721 * Version comparsions are assumed to be "prefix" based. That is to say, `"foo@1.2"`\r
722 * matches any version of "foo" that has a major version 1 and a minor version of 2.\r
723 * \r
724 * This also applies to ranges. For example `"foo@1.2-2.2"` matches all versions\r
725 * of "foo" from 1.2 up to 2.2 regardless of the specific patch and build.\r
726 * \r
727 * ## Use in Overrides\r
728 * This methods primary use is in support of conditional overrides on an\r
729 * `Ext.define` declaration.\r
730 * \r
731 * @param {String/Array/Object} specs A version specification string, an object\r
732 * containing `or` or `and` with a value that is equivalent to `specs` or an array\r
733 * of either of these.\r
734 * @param {Boolean} [matchAll=false] Pass `true` to require all specs to match.\r
735 * @return {Boolean} True if `specs` matches the registered package versions.\r
736 */\r
737 checkVersion: function (specs, matchAll) {\r
738 var isArray = Ext.isArray(specs),\r
739 aliases = Version.aliases.from,\r
740 compat = isArray ? specs : checkVerTemp,\r
741 length = compat.length,\r
742 versions = Ext.versions,\r
743 frameworkVer = versions.ext || versions.touch,\r
744 i, index, matches, minVer, maxVer, packageName, spec, range, ver;\r
745\r
746 if (!isArray) {\r
747 checkVerTemp[0] = specs;\r
748 }\r
749\r
750 for (i = 0; i < length; ++i) {\r
751 if (!Ext.isString(spec = compat[i])) {\r
752 matches = Ext.checkVersion(spec.and || spec.or, !spec.or);\r
753 if (spec.not) {\r
754 matches = !matches;\r
755 }\r
756 } else {\r
757 if (spec.indexOf(' ') >= 0) {\r
758 spec = spec.replace(stripRe, '');\r
759 }\r
760\r
761 // For "name@..." syntax, we need to find the package by the given name\r
762 // as a registered package.\r
763 index = spec.indexOf('@');\r
764 if (index < 0) {\r
765 range = spec;\r
766 ver = frameworkVer;\r
767 } else {\r
768 packageName = spec.substring(0, index);\r
769 if (!(ver = versions[aliases[packageName] || packageName])) {\r
770 // The package is not registered, so if we must matchAll then\r
771 // we are done - FAIL:\r
772 if (matchAll) {\r
773 return false;\r
774 }\r
775 // Otherwise this spec is not a match so we can move on to the\r
776 // next...\r
777 continue;\r
778 }\r
779 range = spec.substring(index+1);\r
780 }\r
781\r
782 // Now look for a version, version range or partial range:\r
783 index = range.indexOf('-');\r
784 if (index < 0) {\r
785 // just a version or "1.0+"\r
786 if (range.charAt(index = range.length - 1) === '+') {\r
787 minVer = range.substring(0, index);\r
788 maxVer = null;\r
789 } else {\r
790 minVer = maxVer = range;\r
791 }\r
792 } else if (index > 0) {\r
793 // a range like "1.0-1.5" or "1.0-"\r
794 minVer = range.substring(0, index);\r
795 maxVer = range.substring(index+1); // may be empty\r
796 } else {\r
797 // an upper limit like "-1.5"\r
798 minVer = null;\r
799 maxVer = range.substring(index+1);\r
800 }\r
801\r
802 matches = true;\r
803 if (minVer) {\r
804 minVer = new Version(minVer, '~'); // prefix matching\r
805 matches = minVer.ltEq(ver);\r
806 }\r
807 if (matches && maxVer) {\r
808 maxVer = new Version(maxVer, '~'); // prefix matching\r
809 matches = maxVer.gtEq(ver);\r
810 }\r
811 } // string spec\r
812\r
813 if (matches) {\r
814 // spec matched and we are looking for any match, so we are GO!\r
815 if (!matchAll) {\r
816 return true;\r
817 }\r
818 } else if (matchAll) {\r
819 // spec does not match the registered package version\r
820 return false;\r
821 }\r
822 }\r
823\r
824 // In the loop above, for matchAll we return FALSE on mismatch, so getting\r
825 // here with matchAll means we had no mismatches. On the other hand, if we\r
826 // are !matchAll, we return TRUE on match and so we get here only if we found\r
827 // no matches.\r
828 return !!matchAll;\r
829 },\r
830\r
831 /**\r
832 * Create a closure for deprecated code.\r
833 *\r
834 * // This means Ext.oldMethod is only supported in 4.0.0beta and older.\r
835 * // If Ext.getVersion('extjs') returns a version that is later than '4.0.0beta', for example '4.0.0RC',\r
836 * // the closure will not be invoked\r
837 * Ext.deprecate('extjs', '4.0.0beta', function() {\r
838 * Ext.oldMethod = Ext.newMethod;\r
839 *\r
840 * ...\r
841 * });\r
842 *\r
843 * @param {String} packageName The package name\r
844 * @param {String} since The last version before it's deprecated\r
845 * @param {Function} closure The callback function to be executed with the specified version is less than the current version\r
846 * @param {Object} scope The execution scope (`this`) if the closure\r
847 * @private\r
848 */\r
849 deprecate: function(packageName, since, closure, scope) {\r
850 if (Version.compare(Ext.getVersion(packageName), since) < 1) {\r
851 closure.call(scope);\r
852 }\r
853 }\r
854 }); // End Versioning\r
855}());\r
856\r
857// load the cmd-5 style app manifest metadata now, if available...\r
858(function (manifest){\r
859 var packages = (manifest && manifest.packages) || {},\r
860 compat = manifest && manifest.compatibility,\r
861 name, pkg;\r
862 \r
863 for (name in packages) {\r
864 pkg = packages[name];\r
865 Ext.setVersion(name, pkg.version);\r
866 }\r
867\r
868 if (compat) {\r
869 if (Ext.isString(compat)) {\r
870 Ext.setCompatVersion('core', compat);\r
871 } else {\r
872 for (name in compat) {\r
873 Ext.setCompatVersion(name, compat[name]);\r
874 }\r
875 }\r
876 }\r
877\r
878 if (!packages.ext && !packages.touch) {\r
879 Ext.setVersion('ext','6.0.1.250');Ext.setVersion('core','6.0.1.250');\r
880 }\r
881})(Ext.manifest);\r