| 1 |
import ChangeDetails from '../core/change-details.js'; |
| 2 |
import IMask from '../core/holder.js'; |
| 3 |
import createMask, { normalizeOpts } from './factory.js'; |
| 4 |
import MaskedPattern from './pattern.js'; |
| 5 |
import '../core/utils.js'; |
| 6 |
import './base.js'; |
| 7 |
import '../core/continuous-tail-details.js'; |
| 8 |
import './pattern/chunk-tail-details.js'; |
| 9 |
import './pattern/cursor.js'; |
| 10 |
import './pattern/fixed-definition.js'; |
| 11 |
import './pattern/input-definition.js'; |
| 12 |
import './regexp.js'; |
| 13 |
|
| 14 |
/** Pattern mask */ |
| 15 |
class RepeatBlock extends MaskedPattern { |
| 16 |
get repeatFrom() { |
| 17 |
var _ref; |
| 18 |
return (_ref = Array.isArray(this.repeat) ? this.repeat[0] : this.repeat === Infinity ? 0 : this.repeat) != null ? _ref : 0; |
| 19 |
} |
| 20 |
get repeatTo() { |
| 21 |
var _ref2; |
| 22 |
return (_ref2 = Array.isArray(this.repeat) ? this.repeat[1] : this.repeat) != null ? _ref2 : Infinity; |
| 23 |
} |
| 24 |
constructor(opts) { |
| 25 |
super(opts); |
| 26 |
} |
| 27 |
updateOptions(opts) { |
| 28 |
super.updateOptions(opts); |
| 29 |
} |
| 30 |
_update(opts) { |
| 31 |
var _ref3, _ref4, _this$_blocks; |
| 32 |
const { |
| 33 |
repeat, |
| 34 |
...blockOpts |
| 35 |
} = normalizeOpts(opts); // TODO type |
| 36 |
this._blockOpts = Object.assign({}, this._blockOpts, blockOpts); |
| 37 |
const block = createMask(this._blockOpts); |
| 38 |
this.repeat = (_ref3 = (_ref4 = repeat != null ? repeat : block.repeat) != null ? _ref4 : this.repeat) != null ? _ref3 : Infinity; // TODO type |
| 39 |
|
| 40 |
super._update({ |
| 41 |
mask: 'm'.repeat(Math.max(this.repeatTo === Infinity && ((_this$_blocks = this._blocks) == null ? void 0 : _this$_blocks.length) || 0, this.repeatFrom)), |
| 42 |
blocks: { |
| 43 |
m: block |
| 44 |
}, |
| 45 |
eager: block.eager, |
| 46 |
overwrite: block.overwrite, |
| 47 |
skipInvalid: block.skipInvalid, |
| 48 |
lazy: block.lazy, |
| 49 |
placeholderChar: block.placeholderChar, |
| 50 |
displayChar: block.displayChar |
| 51 |
}); |
| 52 |
} |
| 53 |
_allocateBlock(bi) { |
| 54 |
if (bi < this._blocks.length) return this._blocks[bi]; |
| 55 |
if (this.repeatTo === Infinity || this._blocks.length < this.repeatTo) { |
| 56 |
this._blocks.push(createMask(this._blockOpts)); |
| 57 |
this.mask += 'm'; |
| 58 |
return this._blocks[this._blocks.length - 1]; |
| 59 |
} |
| 60 |
} |
| 61 |
_appendCharRaw(ch, flags) { |
| 62 |
if (flags === void 0) { |
| 63 |
flags = {}; |
| 64 |
} |
| 65 |
const details = new ChangeDetails(); |
| 66 |
for (let bi = (_this$_mapPosToBlock$ = (_this$_mapPosToBlock = this._mapPosToBlock(this.displayValue.length)) == null ? void 0 : _this$_mapPosToBlock.index) != null ? _this$_mapPosToBlock$ : Math.max(this._blocks.length - 1, 0), block, allocated; |
| 67 |
// try to get a block or |
| 68 |
// try to allocate a new block if not allocated already |
| 69 |
block = (_this$_blocks$bi = this._blocks[bi]) != null ? _this$_blocks$bi : allocated = !allocated && this._allocateBlock(bi); ++bi) { |
| 70 |
var _this$_mapPosToBlock$, _this$_mapPosToBlock, _this$_blocks$bi, _flags$_beforeTailSta; |
| 71 |
const blockDetails = block._appendChar(ch, { |
| 72 |
...flags, |
| 73 |
_beforeTailState: (_flags$_beforeTailSta = flags._beforeTailState) == null || (_flags$_beforeTailSta = _flags$_beforeTailSta._blocks) == null ? void 0 : _flags$_beforeTailSta[bi] |
| 74 |
}); |
| 75 |
if (blockDetails.skip && allocated) { |
| 76 |
// remove the last allocated block and break |
| 77 |
this._blocks.pop(); |
| 78 |
this.mask = this.mask.slice(1); |
| 79 |
break; |
| 80 |
} |
| 81 |
details.aggregate(blockDetails); |
| 82 |
if (blockDetails.consumed) break; // go next char |
| 83 |
} |
| 84 |
return details; |
| 85 |
} |
| 86 |
_trimEmptyTail(fromPos, toPos) { |
| 87 |
var _this$_mapPosToBlock2, _this$_mapPosToBlock3; |
| 88 |
if (fromPos === void 0) { |
| 89 |
fromPos = 0; |
| 90 |
} |
| 91 |
const firstBlockIndex = Math.max(((_this$_mapPosToBlock2 = this._mapPosToBlock(fromPos)) == null ? void 0 : _this$_mapPosToBlock2.index) || 0, this.repeatFrom, 0); |
| 92 |
let lastBlockIndex; |
| 93 |
if (toPos != null) lastBlockIndex = (_this$_mapPosToBlock3 = this._mapPosToBlock(toPos)) == null ? void 0 : _this$_mapPosToBlock3.index; |
| 94 |
if (lastBlockIndex == null) lastBlockIndex = this._blocks.length - 1; |
| 95 |
let removeCount = 0; |
| 96 |
for (let blockIndex = lastBlockIndex; firstBlockIndex <= blockIndex; --blockIndex, ++removeCount) { |
| 97 |
if (this._blocks[blockIndex].unmaskedValue) break; |
| 98 |
} |
| 99 |
if (removeCount) { |
| 100 |
this._blocks.splice(lastBlockIndex - removeCount + 1, removeCount); |
| 101 |
this.mask = this.mask.slice(removeCount); |
| 102 |
} |
| 103 |
} |
| 104 |
reset() { |
| 105 |
super.reset(); |
| 106 |
this._trimEmptyTail(); |
| 107 |
} |
| 108 |
remove(fromPos, toPos) { |
| 109 |
if (fromPos === void 0) { |
| 110 |
fromPos = 0; |
| 111 |
} |
| 112 |
if (toPos === void 0) { |
| 113 |
toPos = this.displayValue.length; |
| 114 |
} |
| 115 |
const removeDetails = super.remove(fromPos, toPos); |
| 116 |
this._trimEmptyTail(fromPos, toPos); |
| 117 |
return removeDetails; |
| 118 |
} |
| 119 |
totalInputPositions(fromPos, toPos) { |
| 120 |
if (fromPos === void 0) { |
| 121 |
fromPos = 0; |
| 122 |
} |
| 123 |
if (toPos == null && this.repeatTo === Infinity) return Infinity; |
| 124 |
return super.totalInputPositions(fromPos, toPos); |
| 125 |
} |
| 126 |
get state() { |
| 127 |
return super.state; |
| 128 |
} |
| 129 |
set state(state) { |
| 130 |
this._blocks.length = state._blocks.length; |
| 131 |
this.mask = this.mask.slice(0, this._blocks.length); |
| 132 |
super.state = state; |
| 133 |
} |
| 134 |
} |
| 135 |
IMask.RepeatBlock = RepeatBlock; |
| 136 |
|
| 137 |
export { RepeatBlock as default }; |
| 138 |
|