import { d as _inherits, e as _createSuper, a as _classCallCheck, _ as _createClass, g as _get, h as _getPrototypeOf, f as _slicedToArray, i as _set } from '../_rollupPluginBabelHelpers-a0b34764.js'; import { escapeRegExp, DIRECTION } from '../core/utils.js'; import ChangeDetails from '../core/change-details.js'; import Masked from './base.js'; import IMask from '../core/holder.js'; import '../core/continuous-tail-details.js'; /** Number mask @param {Object} opts @param {string} opts.radix - Single char @param {string} opts.thousandsSeparator - Single char @param {Array} opts.mapToRadix - Array of single chars @param {number} opts.min @param {number} opts.max @param {number} opts.scale - Digits after point @param {boolean} opts.signed - Allow negative @param {boolean} opts.normalizeZeros - Flag to remove leading and trailing zeros in the end of editing @param {boolean} opts.padFractionalZeros - Flag to pad trailing zeros after point in the end of editing */ var MaskedNumber = /*#__PURE__*/function (_Masked) { _inherits(MaskedNumber, _Masked); var _super = _createSuper(MaskedNumber); /** Single char */ /** Single char */ /** Array of single chars */ /** */ /** */ /** Digits after point */ /** */ /** Flag to remove leading and trailing zeros in the end of editing */ /** Flag to pad trailing zeros after point in the end of editing */ function MaskedNumber(opts) { _classCallCheck(this, MaskedNumber); return _super.call(this, Object.assign({}, MaskedNumber.DEFAULTS, opts)); } /** @override */ _createClass(MaskedNumber, [{ key: "_update", value: function _update(opts) { _get(_getPrototypeOf(MaskedNumber.prototype), "_update", this).call(this, opts); this._updateRegExps(); } /** */ }, { key: "_updateRegExps", value: function _updateRegExps() { // use different regexp to process user input (more strict, input suffix) and tail shifting var start = '^' + (this.allowNegative ? '[+|\\-]?' : ''); var midInput = '(0|([1-9]+\\d*))?'; var mid = '\\d*'; var end = (this.scale ? '(' + escapeRegExp(this.radix) + '\\d{0,' + this.scale + '})?' : '') + '$'; this._numberRegExpInput = new RegExp(start + midInput + end); this._numberRegExp = new RegExp(start + mid + end); this._mapToRadixRegExp = new RegExp('[' + this.mapToRadix.map(escapeRegExp).join('') + ']', 'g'); this._thousandsSeparatorRegExp = new RegExp(escapeRegExp(this.thousandsSeparator), 'g'); } /** */ }, { key: "_removeThousandsSeparators", value: function _removeThousandsSeparators(value) { return value.replace(this._thousandsSeparatorRegExp, ''); } /** */ }, { key: "_insertThousandsSeparators", value: function _insertThousandsSeparators(value) { // https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript var parts = value.split(this.radix); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandsSeparator); return parts.join(this.radix); } /** @override */ }, { key: "doPrepare", value: function doPrepare(str) { var _get2; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } return (_get2 = _get(_getPrototypeOf(MaskedNumber.prototype), "doPrepare", this)).call.apply(_get2, [this, this._removeThousandsSeparators(str.replace(this._mapToRadixRegExp, this.radix))].concat(args)); } /** */ }, { key: "_separatorsCount", value: function _separatorsCount(to) { var extendOnSeparators = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var count = 0; for (var pos = 0; pos < to; ++pos) { if (this._value.indexOf(this.thousandsSeparator, pos) === pos) { ++count; if (extendOnSeparators) to += this.thousandsSeparator.length; } } return count; } /** */ }, { key: "_separatorsCountFromSlice", value: function _separatorsCountFromSlice() { var slice = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._value; return this._separatorsCount(this._removeThousandsSeparators(slice).length, true); } /** @override */ }, { key: "extractInput", value: function extractInput() { var fromPos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; var flags = arguments.length > 2 ? arguments[2] : undefined; var _this$_adjustRangeWit = this._adjustRangeWithSeparators(fromPos, toPos); var _this$_adjustRangeWit2 = _slicedToArray(_this$_adjustRangeWit, 2); fromPos = _this$_adjustRangeWit2[0]; toPos = _this$_adjustRangeWit2[1]; return this._removeThousandsSeparators(_get(_getPrototypeOf(MaskedNumber.prototype), "extractInput", this).call(this, fromPos, toPos, flags)); } /** @override */ }, { key: "_appendCharRaw", value: function _appendCharRaw(ch) { var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!this.thousandsSeparator) return _get(_getPrototypeOf(MaskedNumber.prototype), "_appendCharRaw", this).call(this, ch, flags); var prevBeforeTailValue = flags.tail && flags._beforeTailState ? flags._beforeTailState._value : this._value; var prevBeforeTailSeparatorsCount = this._separatorsCountFromSlice(prevBeforeTailValue); this._value = this._removeThousandsSeparators(this.value); var appendDetails = _get(_getPrototypeOf(MaskedNumber.prototype), "_appendCharRaw", this).call(this, ch, flags); this._value = this._insertThousandsSeparators(this._value); var beforeTailValue = flags.tail && flags._beforeTailState ? flags._beforeTailState._value : this._value; var beforeTailSeparatorsCount = this._separatorsCountFromSlice(beforeTailValue); appendDetails.tailShift += (beforeTailSeparatorsCount - prevBeforeTailSeparatorsCount) * this.thousandsSeparator.length; appendDetails.skip = !appendDetails.rawInserted && ch === this.thousandsSeparator; return appendDetails; } /** */ }, { key: "_findSeparatorAround", value: function _findSeparatorAround(pos) { if (this.thousandsSeparator) { var searchFrom = pos - this.thousandsSeparator.length + 1; var separatorPos = this.value.indexOf(this.thousandsSeparator, searchFrom); if (separatorPos <= pos) return separatorPos; } return -1; } }, { key: "_adjustRangeWithSeparators", value: function _adjustRangeWithSeparators(from, to) { var separatorAroundFromPos = this._findSeparatorAround(from); if (separatorAroundFromPos >= 0) from = separatorAroundFromPos; var separatorAroundToPos = this._findSeparatorAround(to); if (separatorAroundToPos >= 0) to = separatorAroundToPos + this.thousandsSeparator.length; return [from, to]; } /** @override */ }, { key: "remove", value: function remove() { var fromPos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; var _this$_adjustRangeWit3 = this._adjustRangeWithSeparators(fromPos, toPos); var _this$_adjustRangeWit4 = _slicedToArray(_this$_adjustRangeWit3, 2); fromPos = _this$_adjustRangeWit4[0]; toPos = _this$_adjustRangeWit4[1]; var valueBeforePos = this.value.slice(0, fromPos); var valueAfterPos = this.value.slice(toPos); var prevBeforeTailSeparatorsCount = this._separatorsCount(valueBeforePos.length); this._value = this._insertThousandsSeparators(this._removeThousandsSeparators(valueBeforePos + valueAfterPos)); var beforeTailSeparatorsCount = this._separatorsCountFromSlice(valueBeforePos); return new ChangeDetails({ tailShift: (beforeTailSeparatorsCount - prevBeforeTailSeparatorsCount) * this.thousandsSeparator.length }); } /** @override */ }, { key: "nearestInputPos", value: function nearestInputPos(cursorPos, direction) { if (!this.thousandsSeparator) return cursorPos; switch (direction) { case DIRECTION.NONE: case DIRECTION.LEFT: case DIRECTION.FORCE_LEFT: { var separatorAtLeftPos = this._findSeparatorAround(cursorPos - 1); if (separatorAtLeftPos >= 0) { var separatorAtLeftEndPos = separatorAtLeftPos + this.thousandsSeparator.length; if (cursorPos < separatorAtLeftEndPos || this.value.length <= separatorAtLeftEndPos || direction === DIRECTION.FORCE_LEFT) { return separatorAtLeftPos; } } break; } case DIRECTION.RIGHT: case DIRECTION.FORCE_RIGHT: { var separatorAtRightPos = this._findSeparatorAround(cursorPos); if (separatorAtRightPos >= 0) { return separatorAtRightPos + this.thousandsSeparator.length; } } } return cursorPos; } /** @override */ }, { key: "doValidate", value: function doValidate(flags) { var regexp = flags.input ? this._numberRegExpInput : this._numberRegExp; // validate as string var valid = regexp.test(this._removeThousandsSeparators(this.value)); if (valid) { // validate as number var number = this.number; valid = valid && !isNaN(number) && (this.min == null || this.min >= 0 || this.min <= this.number) && (this.max == null || this.max <= 0 || this.number <= this.max); } return valid && _get(_getPrototypeOf(MaskedNumber.prototype), "doValidate", this).call(this, flags); } /** @override */ }, { key: "doCommit", value: function doCommit() { if (this.value) { var number = this.number; var validnum = number; // check bounds if (this.min != null) validnum = Math.max(validnum, this.min); if (this.max != null) validnum = Math.min(validnum, this.max); if (validnum !== number) this.unmaskedValue = String(validnum); var formatted = this.value; if (this.normalizeZeros) formatted = this._normalizeZeros(formatted); if (this.padFractionalZeros) formatted = this._padFractionalZeros(formatted); this._value = formatted; } _get(_getPrototypeOf(MaskedNumber.prototype), "doCommit", this).call(this); } /** */ }, { key: "_normalizeZeros", value: function _normalizeZeros(value) { var parts = this._removeThousandsSeparators(value).split(this.radix); // remove leading zeros parts[0] = parts[0].replace(/^(\D*)(0*)(\d*)/, function (match, sign, zeros, num) { return sign + num; }); // add leading zero if (value.length && !/\d$/.test(parts[0])) parts[0] = parts[0] + '0'; if (parts.length > 1) { parts[1] = parts[1].replace(/0*$/, ''); // remove trailing zeros if (!parts[1].length) parts.length = 1; // remove fractional } return this._insertThousandsSeparators(parts.join(this.radix)); } /** */ }, { key: "_padFractionalZeros", value: function _padFractionalZeros(value) { if (!value) return value; var parts = value.split(this.radix); if (parts.length < 2) parts.push(''); parts[1] = parts[1].padEnd(this.scale, '0'); return parts.join(this.radix); } /** @override */ }, { key: "unmaskedValue", get: function get() { return this._removeThousandsSeparators(this._normalizeZeros(this.value)).replace(this.radix, '.'); }, set: function set(unmaskedValue) { _set(_getPrototypeOf(MaskedNumber.prototype), "unmaskedValue", unmaskedValue.replace('.', this.radix), this, true); } /** @override */ }, { key: "typedValue", get: function get() { return Number(this.unmaskedValue); }, set: function set(n) { _set(_getPrototypeOf(MaskedNumber.prototype), "unmaskedValue", String(n), this, true); } /** Parsed Number */ }, { key: "number", get: function get() { return this.typedValue; }, set: function set(number) { this.typedValue = number; } /** Is negative allowed @readonly */ }, { key: "allowNegative", get: function get() { return this.signed || this.min != null && this.min < 0 || this.max != null && this.max < 0; } }]); return MaskedNumber; }(Masked); MaskedNumber.DEFAULTS = { radix: ',', thousandsSeparator: '', mapToRadix: ['.'], scale: 2, signed: false, normalizeZeros: true, padFractionalZeros: false }; IMask.MaskedNumber = MaskedNumber; export { MaskedNumber as default };