/** * @author Jacky Nguyen <jacky@sencha.com> * @docauthor Jacky Nguyen <jacky@sencha.com> * @class Ext.Version * * A utility class that wrap around a string version number and provide convenient * method to perform comparison. See also: {@link Ext.Version#compare compare}. Example: var version = new Ext.Version('1.0.2beta'); console.log("Version is " + version); // Version is 1.0.2beta console.log(version.getMajor()); // 1 console.log(version.getMinor()); // 0 console.log(version.getPatch()); // 2 console.log(version.getBuild()); // 0 console.log(version.getRelease()); // beta console.log(version.isGreaterThan('1.0.1')); // True console.log(version.isGreaterThan('1.0.2alpha')); // True console.log(version.isGreaterThan('1.0.2RC')); // False console.log(version.isGreaterThan('1.0.2')); // False console.log(version.isLessThan('1.0.2')); // True console.log(version.match(1.0)); // True console.log(version.match('1.0.2')); // True * @markdown */ (function() { // Current core version var version = '4.0.7', Version; Ext.Version = Version = Ext.extend(Object, { /** * @param {String/Number} version The version number in the follow standard format: major[.minor[.patch[.build[release]]]] * Examples: 1.0 or 1.2.3beta or 1.2.3.4RC * @return {Ext.Version} this */ constructor: function(version) { var parts, releaseStartIndex; if (version instanceof Version) { return version; } this.version = this.shortVersion = String(version).toLowerCase().replace(/_/g, '.').replace(/[\-+]/g, ''); releaseStartIndex = this.version.search(/([^\d\.])/); if (releaseStartIndex !== -1) { this.release = this.version.substr(releaseStartIndex, version.length); this.shortVersion = this.version.substr(0, releaseStartIndex); } this.shortVersion = this.shortVersion.replace(/[^\d]/g, ''); parts = this.version.split('.'); this.major = parseInt(parts.shift() || 0, 10); this.minor = parseInt(parts.shift() || 0, 10); this.patch = parseInt(parts.shift() || 0, 10); this.build = parseInt(parts.shift() || 0, 10); return this; }, /** * Override the native toString method * @private * @return {String} version */ toString: function() { return this.version; }, /** * Override the native valueOf method * @private * @return {String} version */ valueOf: function() { return this.version; }, /** * Returns the major component value * @return {Number} major */ getMajor: function() { return this.major || 0; }, /** * Returns the minor component value * @return {Number} minor */ getMinor: function() { return this.minor || 0; }, /** * Returns the patch component value * @return {Number} patch */ getPatch: function() { return this.patch || 0; }, /** * Returns the build component value * @return {Number} build */ getBuild: function() { return this.build || 0; }, /** * Returns the release component value * @return {Number} release */ getRelease: function() { return this.release || ''; }, /** * Returns whether this version if greater than the supplied argument * @param {String/Number} target The version to compare with * @return {Boolean} True if this version if greater than the target, false otherwise */ isGreaterThan: function(target) { return Version.compare(this.version, target) === 1; }, /** * Returns whether this version if smaller than the supplied argument * @param {String/Number} target The version to compare with * @return {Boolean} True if this version if smaller than the target, false otherwise */ isLessThan: function(target) { return Version.compare(this.version, target) === -1; }, /** * Returns whether this version equals to the supplied argument * @param {String/Number} target The version to compare with * @return {Boolean} True if this version equals to the target, false otherwise */ equals: function(target) { return Version.compare(this.version, target) === 0; }, /** * Returns whether this version matches the supplied argument. Example: * <pre><code> * var version = new Ext.Version('1.0.2beta'); * console.log(version.match(1)); // True * console.log(version.match(1.0)); // True * console.log(version.match('1.0.2')); // True * console.log(version.match('1.0.2RC')); // False * </code></pre> * @param {String/Number} target The version to compare with * @return {Boolean} True if this version matches the target, false otherwise */ match: function(target) { target = String(target); return this.version.substr(0, target.length) === target; }, /** * Returns this format: [major, minor, patch, build, release]. Useful for comparison * @return {Number[]} */ toArray: function() { return [this.getMajor(), this.getMinor(), this.getPatch(), this.getBuild(), this.getRelease()]; }, /** * Returns shortVersion version without dots and release * @return {String} */ getShortVersion: function() { return this.shortVersion; } }); Ext.apply(Version, { // @private releaseValueMap: { 'dev': -6, 'alpha': -5, 'a': -5, 'beta': -4, 'b': -4, 'rc': -3, '#': -2, 'p': -1, 'pl': -1 }, /** * Converts a version component to a comparable value * * @static * @param {Object} value The value to convert * @return {Object} */ getComponentValue: function(value) { return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10)); }, /** * Compare 2 specified versions, starting from left to right. If a part contains special version strings, * they are handled in the following order: * 'dev' < 'alpha' = 'a' < 'beta' = 'b' < 'RC' = 'rc' < '#' < 'pl' = 'p' < 'anything else' * * @static * @param {String} current The current version to compare to * @param {String} target The target version to compare to * @return {Number} Returns -1 if the current version is smaller than the target version, 1 if greater, and 0 if they're equivalent */ compare: function(current, target) { var currentValue, targetValue, i; current = new Version(current).toArray(); target = new Version(target).toArray(); for (i = 0; i < Math.max(current.length, target.length); i++) { currentValue = this.getComponentValue(current[i]); targetValue = this.getComponentValue(target[i]); if (currentValue < targetValue) { return -1; } else if (currentValue > targetValue) { return 1; } } return 0; } }); Ext.apply(Ext, { /** * @private */ versions: {}, /** * @private */ lastRegisteredVersion: null, /** * Set version number for the given package name. * * @param {String} packageName The package name, for example: 'core', 'touch', 'extjs' * @param {String/Ext.Version} version The version, for example: '1.2.3alpha', '2.4.0-dev' * @return {Ext} */ setVersion: function(packageName, version) { Ext.versions[packageName] = new Version(version); Ext.lastRegisteredVersion = Ext.versions[packageName]; return this; }, /** * Get the version number of the supplied package name; will return the last registered version * (last Ext.setVersion call) if there's no package name given. * * @param {String} packageName (Optional) The package name, for example: 'core', 'touch', 'extjs' * @return {Ext.Version} The version */ getVersion: function(packageName) { if (packageName === undefined) { return Ext.lastRegisteredVersion; } return Ext.versions[packageName]; }, /** * Create a closure for deprecated code. * // This means Ext.oldMethod is only supported in 4.0.0beta and older. // If Ext.getVersion('extjs') returns a version that is later than '4.0.0beta', for example '4.0.0RC', // the closure will not be invoked Ext.deprecate('extjs', '4.0.0beta', function() { Ext.oldMethod = Ext.newMethod; ... }); * @param {String} packageName The package name * @param {String} since The last version before it's deprecated * @param {Function} closure The callback function to be executed with the specified version is less than the current version * @param {Object} scope The execution scope (<tt>this</tt>) if the closure * @markdown */ deprecate: function(packageName, since, closure, scope) { if (Version.compare(Ext.getVersion(packageName), since) < 1) { closure.call(scope); } } }); // End Versioning Ext.setVersion('core', version); })();