import { d as _inherits, e as _createSuper, a as _classCallCheck, _ as _createClass, g as _get, h as _getPrototypeOf, b as _objectWithoutProperties, i as _set } from '../_rollupPluginBabelHelpers-b054ecd2.js'; import { DIRECTION } from '../core/utils.js'; import ChangeDetails from '../core/change-details.js'; import Masked from './base.js'; import PatternInputDefinition, { DEFAULT_INPUT_DEFINITIONS } from './pattern/input-definition.js'; import PatternFixedDefinition from './pattern/fixed-definition.js'; import ChunksTailDetails from './pattern/chunk-tail-details.js'; import PatternCursor from './pattern/cursor.js'; import createMask from './factory.js'; import IMask from '../core/holder.js'; import './regexp.js'; import '../core/continuous-tail-details.js'; var _excluded = ["_blocks"]; /** Pattern mask @param {Object} opts @param {Object} opts.blocks @param {Object} opts.definitions @param {string} opts.placeholderChar @param {boolean} opts.lazy */ var MaskedPattern = /*#__PURE__*/function (_Masked) { _inherits(MaskedPattern, _Masked); var _super = _createSuper(MaskedPattern); /** */ /** */ /** Single char for empty input */ /** Show placeholder only when needed */ function MaskedPattern() { var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, MaskedPattern); // TODO type $Shape={} does not work opts.definitions = Object.assign({}, DEFAULT_INPUT_DEFINITIONS, opts.definitions); return _super.call(this, Object.assign({}, MaskedPattern.DEFAULTS, opts)); } /** @override @param {Object} opts */ _createClass(MaskedPattern, [{ key: "_update", value: function _update() { var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; opts.definitions = Object.assign({}, this.definitions, opts.definitions); _get(_getPrototypeOf(MaskedPattern.prototype), "_update", this).call(this, opts); this._rebuildMask(); } /** */ }, { key: "_rebuildMask", value: function _rebuildMask() { var _this = this; var defs = this.definitions; this._blocks = []; this._stops = []; this._maskedBlocks = {}; var pattern = this.mask; if (!pattern || !defs) return; var unmaskingBlock = false; var optionalBlock = false; for (var i = 0; i < pattern.length; ++i) { if (this.blocks) { var _ret = function () { var p = pattern.slice(i); var bNames = Object.keys(_this.blocks).filter(function (bName) { return p.indexOf(bName) === 0; }); // order by key length bNames.sort(function (a, b) { return b.length - a.length; }); // use block name with max length var bName = bNames[0]; if (bName) { // $FlowFixMe no ideas var maskedBlock = createMask(Object.assign({ parent: _this, lazy: _this.lazy, eager: _this.eager, placeholderChar: _this.placeholderChar, overwrite: _this.overwrite }, _this.blocks[bName])); if (maskedBlock) { _this._blocks.push(maskedBlock); // store block index if (!_this._maskedBlocks[bName]) _this._maskedBlocks[bName] = []; _this._maskedBlocks[bName].push(_this._blocks.length - 1); } i += bName.length - 1; return "continue"; } }(); if (_ret === "continue") continue; } var char = pattern[i]; var isInput = (char in defs); if (char === MaskedPattern.STOP_CHAR) { this._stops.push(this._blocks.length); continue; } if (char === '{' || char === '}') { unmaskingBlock = !unmaskingBlock; continue; } if (char === '[' || char === ']') { optionalBlock = !optionalBlock; continue; } if (char === MaskedPattern.ESCAPE_CHAR) { ++i; char = pattern[i]; if (!char) break; isInput = false; } var def = isInput ? new PatternInputDefinition({ parent: this, lazy: this.lazy, eager: this.eager, placeholderChar: this.placeholderChar, mask: defs[char], isOptional: optionalBlock }) : new PatternFixedDefinition({ char: char, eager: this.eager, isUnmasking: unmaskingBlock }); this._blocks.push(def); } } /** @override */ }, { key: "state", get: function get() { return Object.assign({}, _get(_getPrototypeOf(MaskedPattern.prototype), "state", this), { _blocks: this._blocks.map(function (b) { return b.state; }) }); }, set: function set(state) { var _blocks = state._blocks, maskedState = _objectWithoutProperties(state, _excluded); this._blocks.forEach(function (b, bi) { return b.state = _blocks[bi]; }); _set(_getPrototypeOf(MaskedPattern.prototype), "state", maskedState, this, true); } /** @override */ }, { key: "reset", value: function reset() { _get(_getPrototypeOf(MaskedPattern.prototype), "reset", this).call(this); this._blocks.forEach(function (b) { return b.reset(); }); } /** @override */ }, { key: "isComplete", get: function get() { return this._blocks.every(function (b) { return b.isComplete; }); } /** @override */ }, { key: "isFilled", get: function get() { return this._blocks.every(function (b) { return b.isFilled; }); } }, { key: "isFixed", get: function get() { return this._blocks.every(function (b) { return b.isFixed; }); } }, { key: "isOptional", get: function get() { return this._blocks.every(function (b) { return b.isOptional; }); } /** @override */ }, { key: "doCommit", value: function doCommit() { this._blocks.forEach(function (b) { return b.doCommit(); }); _get(_getPrototypeOf(MaskedPattern.prototype), "doCommit", this).call(this); } /** @override */ }, { key: "unmaskedValue", get: function get() { return this._blocks.reduce(function (str, b) { return str += b.unmaskedValue; }, ''); }, set: function set(unmaskedValue) { _set(_getPrototypeOf(MaskedPattern.prototype), "unmaskedValue", unmaskedValue, this, true); } /** @override */ }, { key: "value", get: function get() { // TODO return _value when not in change? return this._blocks.reduce(function (str, b) { return str += b.value; }, ''); }, set: function set(value) { _set(_getPrototypeOf(MaskedPattern.prototype), "value", value, this, true); } /** @override */ }, { key: "appendTail", value: function appendTail(tail) { return _get(_getPrototypeOf(MaskedPattern.prototype), "appendTail", this).call(this, tail).aggregate(this._appendPlaceholder()); } /** @override */ }, { key: "_appendEager", value: function _appendEager() { var _this$_mapPosToBlock; var details = new ChangeDetails(); var startBlockIndex = (_this$_mapPosToBlock = this._mapPosToBlock(this.value.length)) === null || _this$_mapPosToBlock === void 0 ? void 0 : _this$_mapPosToBlock.index; if (startBlockIndex == null) return details; // TODO test if it works for nested pattern masks if (this._blocks[startBlockIndex].isFilled) ++startBlockIndex; for (var bi = startBlockIndex; bi < this._blocks.length; ++bi) { var d = this._blocks[bi]._appendEager(); if (!d.inserted) break; details.aggregate(d); } return details; } /** @override */ }, { key: "_appendCharRaw", value: function _appendCharRaw(ch) { var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var blockIter = this._mapPosToBlock(this.value.length); var details = new ChangeDetails(); if (!blockIter) return details; for (var bi = blockIter.index;; ++bi) { var _flags$_beforeTailSta; var _block = this._blocks[bi]; if (!_block) break; var blockDetails = _block._appendChar(ch, Object.assign({}, flags, { _beforeTailState: (_flags$_beforeTailSta = flags._beforeTailState) === null || _flags$_beforeTailSta === void 0 ? void 0 : _flags$_beforeTailSta._blocks[bi] })); var skip = blockDetails.skip; details.aggregate(blockDetails); if (skip || blockDetails.rawInserted) break; // go next char } return details; } /** @override */ }, { key: "extractTail", value: function extractTail() { var _this2 = this; 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 chunkTail = new ChunksTailDetails(); if (fromPos === toPos) return chunkTail; this._forEachBlocksInRange(fromPos, toPos, function (b, bi, bFromPos, bToPos) { var blockChunk = b.extractTail(bFromPos, bToPos); blockChunk.stop = _this2._findStopBefore(bi); blockChunk.from = _this2._blockStartPos(bi); if (blockChunk instanceof ChunksTailDetails) blockChunk.blockIndex = bi; chunkTail.extend(blockChunk); }); return chunkTail; } /** @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 ? arguments[2] : {}; if (fromPos === toPos) return ''; var input = ''; this._forEachBlocksInRange(fromPos, toPos, function (b, _, fromPos, toPos) { input += b.extractInput(fromPos, toPos, flags); }); return input; } }, { key: "_findStopBefore", value: function _findStopBefore(blockIndex) { var stopBefore; for (var si = 0; si < this._stops.length; ++si) { var stop = this._stops[si]; if (stop <= blockIndex) stopBefore = stop;else break; } return stopBefore; } /** Appends placeholder depending on laziness */ }, { key: "_appendPlaceholder", value: function _appendPlaceholder(toBlockIndex) { var _this3 = this; var details = new ChangeDetails(); if (this.lazy && toBlockIndex == null) return details; var startBlockIter = this._mapPosToBlock(this.value.length); if (!startBlockIter) return details; var startBlockIndex = startBlockIter.index; var endBlockIndex = toBlockIndex != null ? toBlockIndex : this._blocks.length; this._blocks.slice(startBlockIndex, endBlockIndex).forEach(function (b) { if (!b.lazy || toBlockIndex != null) { // $FlowFixMe `_blocks` may not be present var args = b._blocks != null ? [b._blocks.length] : []; var bDetails = b._appendPlaceholder.apply(b, args); _this3._value += bDetails.inserted; details.aggregate(bDetails); } }); return details; } /** Finds block in pos */ }, { key: "_mapPosToBlock", value: function _mapPosToBlock(pos) { var accVal = ''; for (var bi = 0; bi < this._blocks.length; ++bi) { var _block2 = this._blocks[bi]; var blockStartPos = accVal.length; accVal += _block2.value; if (pos <= accVal.length) { return { index: bi, offset: pos - blockStartPos }; } } } /** */ }, { key: "_blockStartPos", value: function _blockStartPos(blockIndex) { return this._blocks.slice(0, blockIndex).reduce(function (pos, b) { return pos += b.value.length; }, 0); } /** */ }, { key: "_forEachBlocksInRange", value: function _forEachBlocksInRange(fromPos) { var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; var fn = arguments.length > 2 ? arguments[2] : undefined; var fromBlockIter = this._mapPosToBlock(fromPos); if (fromBlockIter) { var toBlockIter = this._mapPosToBlock(toPos); // process first block var isSameBlock = toBlockIter && fromBlockIter.index === toBlockIter.index; var fromBlockStartPos = fromBlockIter.offset; var fromBlockEndPos = toBlockIter && isSameBlock ? toBlockIter.offset : this._blocks[fromBlockIter.index].value.length; fn(this._blocks[fromBlockIter.index], fromBlockIter.index, fromBlockStartPos, fromBlockEndPos); if (toBlockIter && !isSameBlock) { // process intermediate blocks for (var bi = fromBlockIter.index + 1; bi < toBlockIter.index; ++bi) { fn(this._blocks[bi], bi, 0, this._blocks[bi].value.length); } // process last block fn(this._blocks[toBlockIter.index], toBlockIter.index, 0, toBlockIter.offset); } } } /** @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 removeDetails = _get(_getPrototypeOf(MaskedPattern.prototype), "remove", this).call(this, fromPos, toPos); this._forEachBlocksInRange(fromPos, toPos, function (b, _, bFromPos, bToPos) { removeDetails.aggregate(b.remove(bFromPos, bToPos)); }); return removeDetails; } /** @override */ }, { key: "nearestInputPos", value: function nearestInputPos(cursorPos) { var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DIRECTION.NONE; if (!this._blocks.length) return 0; var cursor = new PatternCursor(this, cursorPos); if (direction === DIRECTION.NONE) { // ------------------------------------------------- // NONE should only go out from fixed to the right! // ------------------------------------------------- if (cursor.pushRightBeforeInput()) return cursor.pos; cursor.popState(); if (cursor.pushLeftBeforeInput()) return cursor.pos; return this.value.length; } // FORCE is only about a|* otherwise is 0 if (direction === DIRECTION.LEFT || direction === DIRECTION.FORCE_LEFT) { // try to break fast when *|a if (direction === DIRECTION.LEFT) { cursor.pushRightBeforeFilled(); if (cursor.ok && cursor.pos === cursorPos) return cursorPos; cursor.popState(); } // forward flow cursor.pushLeftBeforeInput(); cursor.pushLeftBeforeRequired(); cursor.pushLeftBeforeFilled(); // backward flow if (direction === DIRECTION.LEFT) { cursor.pushRightBeforeInput(); cursor.pushRightBeforeRequired(); if (cursor.ok && cursor.pos <= cursorPos) return cursor.pos; cursor.popState(); if (cursor.ok && cursor.pos <= cursorPos) return cursor.pos; cursor.popState(); } if (cursor.ok) return cursor.pos; if (direction === DIRECTION.FORCE_LEFT) return 0; cursor.popState(); if (cursor.ok) return cursor.pos; cursor.popState(); if (cursor.ok) return cursor.pos; // cursor.popState(); // if ( // cursor.pushRightBeforeInput() && // // TODO HACK for lazy if has aligned left inside fixed and has came to the start - use start position // (!this.lazy || this.extractInput()) // ) return cursor.pos; return 0; } if (direction === DIRECTION.RIGHT || direction === DIRECTION.FORCE_RIGHT) { // forward flow cursor.pushRightBeforeInput(); cursor.pushRightBeforeRequired(); if (cursor.pushRightBeforeFilled()) return cursor.pos; if (direction === DIRECTION.FORCE_RIGHT) return this.value.length; // backward flow cursor.popState(); if (cursor.ok) return cursor.pos; cursor.popState(); if (cursor.ok) return cursor.pos; return this.nearestInputPos(cursorPos, DIRECTION.LEFT); } return cursorPos; } /** Get block by name */ }, { key: "maskedBlock", value: function maskedBlock(name) { return this.maskedBlocks(name)[0]; } /** Get all blocks by name */ }, { key: "maskedBlocks", value: function maskedBlocks(name) { var _this4 = this; var indices = this._maskedBlocks[name]; if (!indices) return []; return indices.map(function (gi) { return _this4._blocks[gi]; }); } }]); return MaskedPattern; }(Masked); MaskedPattern.DEFAULTS = { lazy: true, placeholderChar: '_' }; MaskedPattern.STOP_CHAR = '`'; MaskedPattern.ESCAPE_CHAR = '\\'; MaskedPattern.InputDefinition = PatternInputDefinition; MaskedPattern.FixedDefinition = PatternFixedDefinition; IMask.MaskedPattern = MaskedPattern; export { MaskedPattern as default };