Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / core / src / version / Version.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 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.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @author Jacky Nguyen <jacky@sencha.com>
17  * @docauthor Jacky Nguyen <jacky@sencha.com>
18  * @class Ext.Version
19  *
20  * A utility class that wrap around a string version number and provide convenient
21  * method to perform comparison. See also: {@link Ext.Version#compare compare}. Example:
22
23     var version = new Ext.Version('1.0.2beta');
24     console.log("Version is " + version); // Version is 1.0.2beta
25
26     console.log(version.getMajor()); // 1
27     console.log(version.getMinor()); // 0
28     console.log(version.getPatch()); // 2
29     console.log(version.getBuild()); // 0
30     console.log(version.getRelease()); // beta
31
32     console.log(version.isGreaterThan('1.0.1')); // True
33     console.log(version.isGreaterThan('1.0.2alpha')); // True
34     console.log(version.isGreaterThan('1.0.2RC')); // False
35     console.log(version.isGreaterThan('1.0.2')); // False
36     console.log(version.isLessThan('1.0.2')); // True
37
38     console.log(version.match(1.0)); // True
39     console.log(version.match('1.0.2')); // True
40
41  * @markdown
42  */
43 (function() {
44
45 // Current core version
46 var version = '4.0.7', Version;
47     Ext.Version = Version = Ext.extend(Object, {
48
49         /**
50          * @param {String/Number} version The version number in the follow standard format: major[.minor[.patch[.build[release]]]]
51          * Examples: 1.0 or 1.2.3beta or 1.2.3.4RC
52          * @return {Ext.Version} this
53          */
54         constructor: function(version) {
55             var parts, releaseStartIndex;
56
57             if (version instanceof Version) {
58                 return version;
59             }
60
61             this.version = this.shortVersion = String(version).toLowerCase().replace(/_/g, '.').replace(/[\-+]/g, '');
62
63             releaseStartIndex = this.version.search(/([^\d\.])/);
64
65             if (releaseStartIndex !== -1) {
66                 this.release = this.version.substr(releaseStartIndex, version.length);
67                 this.shortVersion = this.version.substr(0, releaseStartIndex);
68             }
69
70             this.shortVersion = this.shortVersion.replace(/[^\d]/g, '');
71
72             parts = this.version.split('.');
73
74             this.major = parseInt(parts.shift() || 0, 10);
75             this.minor = parseInt(parts.shift() || 0, 10);
76             this.patch = parseInt(parts.shift() || 0, 10);
77             this.build = parseInt(parts.shift() || 0, 10);
78
79             return this;
80         },
81
82         /**
83          * Override the native toString method
84          * @private
85          * @return {String} version
86          */
87         toString: function() {
88             return this.version;
89         },
90
91         /**
92          * Override the native valueOf method
93          * @private
94          * @return {String} version
95          */
96         valueOf: function() {
97             return this.version;
98         },
99
100         /**
101          * Returns the major component value
102          * @return {Number} major
103          */
104         getMajor: function() {
105             return this.major || 0;
106         },
107
108         /**
109          * Returns the minor component value
110          * @return {Number} minor
111          */
112         getMinor: function() {
113             return this.minor || 0;
114         },
115
116         /**
117          * Returns the patch component value
118          * @return {Number} patch
119          */
120         getPatch: function() {
121             return this.patch || 0;
122         },
123
124         /**
125          * Returns the build component value
126          * @return {Number} build
127          */
128         getBuild: function() {
129             return this.build || 0;
130         },
131
132         /**
133          * Returns the release component value
134          * @return {Number} release
135          */
136         getRelease: function() {
137             return this.release || '';
138         },
139
140         /**
141          * Returns whether this version if greater than the supplied argument
142          * @param {String/Number} target The version to compare with
143          * @return {Boolean} True if this version if greater than the target, false otherwise
144          */
145         isGreaterThan: function(target) {
146             return Version.compare(this.version, target) === 1;
147         },
148
149         /**
150          * Returns whether this version if smaller than the supplied argument
151          * @param {String/Number} target The version to compare with
152          * @return {Boolean} True if this version if smaller than the target, false otherwise
153          */
154         isLessThan: function(target) {
155             return Version.compare(this.version, target) === -1;
156         },
157
158         /**
159          * Returns whether this version equals to the supplied argument
160          * @param {String/Number} target The version to compare with
161          * @return {Boolean} True if this version equals to the target, false otherwise
162          */
163         equals: function(target) {
164             return Version.compare(this.version, target) === 0;
165         },
166
167         /**
168          * Returns whether this version matches the supplied argument. Example:
169          * <pre><code>
170          * var version = new Ext.Version('1.0.2beta');
171          * console.log(version.match(1)); // True
172          * console.log(version.match(1.0)); // True
173          * console.log(version.match('1.0.2')); // True
174          * console.log(version.match('1.0.2RC')); // False
175          * </code></pre>
176          * @param {String/Number} target The version to compare with
177          * @return {Boolean} True if this version matches the target, false otherwise
178          */
179         match: function(target) {
180             target = String(target);
181             return this.version.substr(0, target.length) === target;
182         },
183
184         /**
185          * Returns this format: [major, minor, patch, build, release]. Useful for comparison
186          * @return {Number[]}
187          */
188         toArray: function() {
189             return [this.getMajor(), this.getMinor(), this.getPatch(), this.getBuild(), this.getRelease()];
190         },
191
192         /**
193          * Returns shortVersion version without dots and release
194          * @return {String}
195          */
196         getShortVersion: function() {
197             return this.shortVersion;
198         }
199     });
200
201     Ext.apply(Version, {
202         // @private
203         releaseValueMap: {
204             'dev': -6,
205             'alpha': -5,
206             'a': -5,
207             'beta': -4,
208             'b': -4,
209             'rc': -3,
210             '#': -2,
211             'p': -1,
212             'pl': -1
213         },
214
215         /**
216          * Converts a version component to a comparable value
217          *
218          * @static
219          * @param {Object} value The value to convert
220          * @return {Object}
221          */
222         getComponentValue: function(value) {
223             return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10));
224         },
225
226         /**
227          * Compare 2 specified versions, starting from left to right. If a part contains special version strings,
228          * they are handled in the following order:
229          * 'dev' < 'alpha' = 'a' < 'beta' = 'b' < 'RC' = 'rc' < '#' < 'pl' = 'p' < 'anything else'
230          *
231          * @static
232          * @param {String} current The current version to compare to
233          * @param {String} target The target version to compare to
234          * @return {Number} Returns -1 if the current version is smaller than the target version, 1 if greater, and 0 if they're equivalent
235          */
236         compare: function(current, target) {
237             var currentValue, targetValue, i;
238
239             current = new Version(current).toArray();
240             target = new Version(target).toArray();
241
242             for (i = 0; i < Math.max(current.length, target.length); i++) {
243                 currentValue = this.getComponentValue(current[i]);
244                 targetValue = this.getComponentValue(target[i]);
245
246                 if (currentValue < targetValue) {
247                     return -1;
248                 } else if (currentValue > targetValue) {
249                     return 1;
250                 }
251             }
252
253             return 0;
254         }
255     });
256
257     Ext.apply(Ext, {
258         /**
259          * @private
260          */
261         versions: {},
262
263         /**
264          * @private
265          */
266         lastRegisteredVersion: null,
267
268         /**
269          * Set version number for the given package name.
270          *
271          * @param {String} packageName The package name, for example: 'core', 'touch', 'extjs'
272          * @param {String/Ext.Version} version The version, for example: '1.2.3alpha', '2.4.0-dev'
273          * @return {Ext}
274          */
275         setVersion: function(packageName, version) {
276             Ext.versions[packageName] = new Version(version);
277             Ext.lastRegisteredVersion = Ext.versions[packageName];
278
279             return this;
280         },
281
282         /**
283          * Get the version number of the supplied package name; will return the last registered version
284          * (last Ext.setVersion call) if there's no package name given.
285          *
286          * @param {String} packageName (Optional) The package name, for example: 'core', 'touch', 'extjs'
287          * @return {Ext.Version} The version
288          */
289         getVersion: function(packageName) {
290             if (packageName === undefined) {
291                 return Ext.lastRegisteredVersion;
292             }
293
294             return Ext.versions[packageName];
295         },
296
297         /**
298          * Create a closure for deprecated code.
299          *
300     // This means Ext.oldMethod is only supported in 4.0.0beta and older.
301     // If Ext.getVersion('extjs') returns a version that is later than '4.0.0beta', for example '4.0.0RC',
302     // the closure will not be invoked
303     Ext.deprecate('extjs', '4.0.0beta', function() {
304         Ext.oldMethod = Ext.newMethod;
305
306         ...
307     });
308
309          * @param {String} packageName The package name
310          * @param {String} since The last version before it's deprecated
311          * @param {Function} closure The callback function to be executed with the specified version is less than the current version
312          * @param {Object} scope The execution scope (<tt>this</tt>) if the closure
313          * @markdown
314          */
315         deprecate: function(packageName, since, closure, scope) {
316             if (Version.compare(Ext.getVersion(packageName), since) < 1) {
317                 closure.call(scope);
318             }
319         }
320     }); // End Versioning
321
322     Ext.setVersion('core', version);
323
324 })();
325