tui-code-snippet
Version:
TOAST UI Utility: CodeSnippet
160 lines (138 loc) • 3.5 kB
JavaScript
/**
* @fileoverview This module provides a Enum Constructor.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
* @example
* // CommonJS
* const Enum = require('tui-code-snippet/enum/enum');
*/
;
var isNumber = require('../type/isNumber');
var isArray = require('../type/isArray');
var toArray = require('../collection/toArray');
var forEach = require('../collection/forEach');
/**
* Check whether the defineProperty() method is supported.
* @type {boolean}
* @ignore
*/
var isSupportDefinedProperty = (function() {
try {
Object.defineProperty({}, 'x', {});
return true;
} catch (e) {
return false;
}
})();
/**
* A unique value of a constant.
* @type {number}
* @ignore
*/
var enumValue = 0;
/**
* Make a constant-list that has unique values.
* In modern browsers (except IE8 and lower),
* a value defined once can not be changed.
*
* @param {...string|string[]} itemList Constant-list (An array of string is available)
* @class
*
* @example
* // CommonJS
* const Enum = require('tui-code-snippet/enum/enum');
*
* const MYENUM = new Enum('TYPE1', 'TYPE2');
* const MYENUM2 = new Enum(['TYPE1', 'TYPE2']);
*
* // usage
* if (value === MYENUM.TYPE1) {
* // ...
* }
*
* //add (If a duplicate name is inputted, will be disregarded.)
* MYENUM.set('TYPE3', 'TYPE4');
*
* //get name of a constant by a value
* MYENUM.getName(MYENUM.TYPE1); // 'TYPE1'
*
* // In modern browsers (except IE8 and lower), a value can not be changed in constants.
* const originalValue = MYENUM.TYPE1;
* MYENUM.TYPE1 = 1234; // maybe TypeError
* MYENUM.TYPE1 === originalValue; // true
**/
function Enum(itemList) {
if (itemList) {
this.set.apply(this, arguments);
}
}
/**
* Define a constants-list
* @param {...string|string[]} itemList Constant-list (An array of string is available)
*/
Enum.prototype.set = function(itemList) {
var self = this;
if (!isArray(itemList)) {
itemList = toArray(arguments);
}
forEach(itemList, function itemListIteratee(item) {
self._addItem(item);
});
};
/**
* Return a key of the constant.
* @param {number} value A value of the constant.
* @returns {string|undefined} Key of the constant.
*/
Enum.prototype.getName = function(value) {
var self = this;
var foundedKey;
forEach(this, function(itemValue, key) { // eslint-disable-line consistent-return
if (self._isEnumItem(key) && value === itemValue) {
foundedKey = key;
return false;
}
});
return foundedKey;
};
/**
* Create a constant.
* @private
* @param {string} name Constant name. (It will be a key of a constant)
*/
Enum.prototype._addItem = function(name) {
var value;
if (!this.hasOwnProperty(name)) {
value = this._makeEnumValue();
if (isSupportDefinedProperty) {
Object.defineProperty(this, name, {
enumerable: true,
configurable: false,
writable: false,
value: value
});
} else {
this[name] = value;
}
}
};
/**
* Return a unique value for assigning to a constant.
* @private
* @returns {number} A unique value
*/
Enum.prototype._makeEnumValue = function() {
var value;
value = enumValue;
enumValue += 1;
return value;
};
/**
* Return whether a constant from the given key is in instance or not.
* @param {string} key - A constant key
* @returns {boolean} Result
* @private
*/
Enum.prototype._isEnumItem = function(key) {
return isNumber(this[key]);
};
module.exports = Enum;