UNPKG

imask

Version:

vanilla javascript input mask

105 lines (102 loc) 3.29 kB
import MaskedPattern from './pattern.js'; import IMask from '../core/holder.js'; import ChangeDetails from '../core/change-details.js'; import { DIRECTION } from '../core/utils.js'; import ContinuousTailDetails from '../core/continuous-tail-details.js'; import './base.js'; import './factory.js'; import './pattern/chunk-tail-details.js'; import './pattern/cursor.js'; import './pattern/fixed-definition.js'; import './pattern/input-definition.js'; import './regexp.js'; /** Pattern which validates enum values */ class MaskedEnum extends MaskedPattern { constructor(opts) { super({ ...MaskedEnum.DEFAULTS, ...opts }); // mask will be created in _update } updateOptions(opts) { super.updateOptions(opts); } _update(opts) { const { enum: enum_, ...eopts } = opts; if (enum_) { const lengths = enum_.map(e => e.length); const requiredLength = Math.min(...lengths); const optionalLength = Math.max(...lengths) - requiredLength; eopts.mask = '*'.repeat(requiredLength); if (optionalLength) eopts.mask += '[' + '*'.repeat(optionalLength) + ']'; this.enum = enum_; } super._update(eopts); } _appendCharRaw(ch, flags) { if (flags === void 0) { flags = {}; } const matchFrom = Math.min(this.nearestInputPos(0, DIRECTION.FORCE_RIGHT), this.value.length); const matches = this.enum.filter(e => this.matchValue(e, this.unmaskedValue + ch, matchFrom)); if (matches.length) { if (matches.length === 1) { this._forEachBlocksInRange(0, this.value.length, (b, bi) => { const mch = matches[0][bi]; if (bi >= this.value.length || mch === b.value) return; b.reset(); b._appendChar(mch, flags); }); } const d = super._appendCharRaw(matches[0][this.value.length], flags); if (matches.length === 1) { matches[0].slice(this.unmaskedValue.length).split('').forEach(mch => d.aggregate(super._appendCharRaw(mch))); } return d; } return new ChangeDetails({ skip: !this.isComplete }); } extractTail(fromPos, toPos) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this.displayValue.length; } // just drop tail return new ContinuousTailDetails('', fromPos); } remove(fromPos, toPos) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this.displayValue.length; } if (fromPos === toPos) return new ChangeDetails(); const matchFrom = Math.min(super.nearestInputPos(0, DIRECTION.FORCE_RIGHT), this.value.length); let pos; for (pos = fromPos; pos >= 0; --pos) { const matches = this.enum.filter(e => this.matchValue(e, this.value.slice(matchFrom, pos), matchFrom)); if (matches.length > 1) break; } const details = super.remove(pos, toPos); details.tailShift += pos - fromPos; return details; } get isComplete() { return this.enum.indexOf(this.value) >= 0; } } /** Match enum value */ MaskedEnum.DEFAULTS = { ...MaskedPattern.DEFAULTS, matchValue: (estr, istr, matchFrom) => estr.indexOf(istr, matchFrom) === matchFrom }; IMask.MaskedEnum = MaskedEnum; export { MaskedEnum as default };