UNPKG

igniteui-webcomponents

Version:

Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.

211 lines 6.89 kB
const MASK_FLAGS = new Set('aACL09#&?'); const MASK_REQUIRED_FLAGS = new Set('0#LA&'); const MASK_PATTERNS = new Map([ ['C', /(?!^$)/u], ['&', /[^\p{Separator}]/u], ['a', /[\p{Letter}\p{Number}\p{Separator}]/u], ['A', /[\p{Letter}\p{Number}]/u], ['?', /[\p{Letter}\p{Separator}]/u], ['L', /\p{Letter}/u], ['0', /\p{Number}/u], ['9', /[\p{Number}\p{Separator}]/u], ['#', /[\p{Number}\-+]/u], ]); function replaceIMENumbers(string) { return string.replace(/[0123456789]/g, (num) => ({ '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '0': '0', })[num]); } function validate(char, flag) { return MASK_PATTERNS.get(flag)?.test(char) ?? false; } const MaskDefaultOptions = { format: 'CCCCCCCCCC', promptCharacter: '_', }; export class MaskParser { get literalPositions() { return this._literalPositions; } get escapedMask() { return this._escapedMask; } get mask() { return this._options.format; } set mask(value) { this._options.format = value || this._options.format; this._parseMaskLiterals(); } get prompt() { return this._options.promptCharacter; } set prompt(value) { this._options.promptCharacter = value ? value.substring(0, 1) : this._options.promptCharacter; } constructor(options) { this._literals = new Map(); this._literalPositions = new Set(); this._escapedMask = ''; this._options = { ...MaskDefaultOptions, ...options }; this._parseMaskLiterals(); } _parseMaskLiterals() { const mask = this.mask; const length = mask.length; const escapedMaskChars = []; let currentPos = 0; this._literals.clear(); for (let i = 0; i < length; i++) { const [current, next] = [mask.charAt(i), mask.charAt(i + 1)]; if (current === '\\' && MASK_FLAGS.has(next)) { this._literals.set(currentPos, next); escapedMaskChars.push(next); i++; } else if (MASK_FLAGS.has(current)) { escapedMaskChars.push(current); } else { this._literals.set(currentPos, current); escapedMaskChars.push(current); } currentPos++; } this._escapedMask = escapedMaskChars.join(''); this._literalPositions = new Set(this._literals.keys()); } _getRequiredNonLiteralPositions() { const literalPositions = this.literalPositions; const escapedMask = this._escapedMask; const length = escapedMask.length; const result = []; for (let i = 0; i < length; i++) { const char = escapedMask[i]; if (MASK_REQUIRED_FLAGS.has(char) && !literalPositions.has(i)) { result.push(i); } } return result; } getPreviousNonLiteralPosition(start) { const literalPositions = this.literalPositions; for (let i = start; i > 0; i--) { if (!literalPositions.has(i)) { return i; } } return start; } getNextNonLiteralPosition(start) { const literalPositions = this.literalPositions; const length = this._escapedMask.length; for (let i = start; i < length; i++) { if (!literalPositions.has(i)) { return i; } } return start; } replace(maskString, value, start, end) { const literalPositions = this.literalPositions; const escapedMask = this._escapedMask; const length = this._escapedMask.length; const prompt = this.prompt; const endBoundary = Math.min(end, length); const maskedChars = Array.from(maskString || this.apply('')); const inputChars = Array.from(replaceIMENumbers(value)); const inputLength = inputChars.length; for (let i = start; i < endBoundary; i++) { if (!literalPositions.has(i)) { maskedChars[i] = prompt; } } let cursor = start; let inputIndex = 0; let maskPosition = start; for (; maskPosition < length && inputIndex < inputLength; maskPosition++) { if (literalPositions.has(maskPosition)) { cursor = maskPosition + 1; continue; } const char = inputChars[inputIndex]; if (validate(char, escapedMask[maskPosition]) && char !== prompt) { maskedChars[maskPosition] = char; cursor = maskPosition + 1; inputIndex++; } else { inputIndex++; maskPosition--; } } while (cursor < length && literalPositions.has(cursor)) { cursor++; } return { value: maskedChars.join(''), end: cursor, }; } parse(masked = '') { const literalPositions = this.literalPositions; const prompt = this.prompt; const length = masked.length; let result = ''; for (let i = 0; i < length; i++) { const char = masked[i]; if (!literalPositions.has(i) && char !== prompt) { result += char; } } return result; } isValidString(input = '') { const prompt = this.prompt; return this._getRequiredNonLiteralPositions().every((position) => { const char = input.charAt(position); return (validate(char, this._escapedMask.charAt(position)) && char !== prompt); }); } apply(input = '') { const literals = this._literals; const prompt = this.prompt; const escapedMask = this._escapedMask; const length = escapedMask.length; const inputLength = input.length; const result = new Array(escapedMask.length).fill(prompt); for (const [position, literal] of literals.entries()) { result[position] = literal; } if (!input) { return result.join(''); } let inputIndex = 0; for (let i = 0; i < length; i++) { if (inputIndex >= inputLength) { break; } if (literals.has(i)) { continue; } if (validate(input.charAt(inputIndex), escapedMask.charAt(i))) { result[i] = input.charAt(inputIndex); } inputIndex++; } return result.join(''); } } //# sourceMappingURL=mask-parser.js.map