UNPKG

@ngx-mask/core

Version:

[@ngx-mask/core](https://github.com/IKatsuba/ngx-mask#readme)

154 lines 5.95 kB
export var MaskPatterns; (function (MaskPatterns) { MaskPatterns["number"] = "\\d"; })(MaskPatterns || (MaskPatterns = {})); function insertChar(text, char, position) { const t = text.split(''); t.splice(position, 0, char); return t.join(''); } function calcOptionalNumbersToUse(pattern, value, tokens) { const numberToken = Object.keys(tokens).find(token => tokens[token].pattern === MaskPatterns.number); if (!numberToken) { return 0; } const numbersInPattern = pattern.replace(new RegExp(`[^${numberToken}]`, 'g'), '').length; const numbersInValue = value.replace(/[^\d]/g, '').length; return numbersInValue - numbersInPattern; } function concatChar(text, character, options, token) { if (token && typeof token.transform === 'function') { character = token.transform(character); } return text + character; } function hasMoreTokens(pattern, pos, inc, tokens) { const pc = pattern.charAt(pos); const token = tokens[pc]; if (pc === '') { return false; } return token && !token.escape ? true : hasMoreTokens(pattern, pos + inc, inc, tokens); } export class Mask { constructor(pattern, options) { var _a, _b; this.pattern = pattern; this.options = { useDefaults: (_b = (_a = options) === null || _a === void 0 ? void 0 : _a.useDefaults, (_b !== null && _b !== void 0 ? _b : false)), tokens: options.tokens }; } static process(value, pattern, options) { return new Mask(pattern, options).process(value); } ; static applyMask(value, pattern, options) { return new Mask(pattern, options).apply(value); } ; static validate(value, pattern, options) { return new Mask(pattern, options).validate(value); } ; process(value) { if (!value) { return { result: '', valid: false }; } const { tokens } = this.options; const pattern2 = this.pattern; let valid = true; let formatted = ''; let valuePos = 0; let patternPos = 0; let optionalNumbersToUse = calcOptionalNumbersToUse(pattern2, value, tokens); let escapeNext = false; const steps = { start: 0, end: pattern2.length, inc: 1 }; function continueCondition() { if (hasMoreTokens(pattern2, patternPos, steps.inc, tokens)) { // continue in the normal iteration return true; } return patternPos < pattern2.length && patternPos >= 0; } /** * Iterate over the pattern's chars parsing/matching the input value chars * until the end of the pattern. If the pattern ends with recursive chars * the iteration will continue until the end of the input value. * * Note: The iteration must stop if an invalid char is found. */ for (patternPos = steps.start; continueCondition();) { // Value char const vc = value.charAt(valuePos); // Pattern char to match with the value char const pc = pattern2.charAt(patternPos); const token = tokens[pc]; // 1. Handle escape tokens in pattern // go to next iteration: if the pattern char is a escape char or was escaped if (escapeNext) { // pattern char is escaped, just add it and move on formatted = concatChar(formatted, pc, this.options, token); escapeNext = false; patternPos = patternPos + steps.inc; continue; } else if (token && token.escape) { // mark to escape the next pattern char escapeNext = true; patternPos = patternPos + steps.inc; continue; } // 3. Handle the value // break iterations: if value is invalid for the given pattern if (!token) { // add char of the pattern formatted = concatChar(formatted, pc, this.options, token); if (pc === vc) { valuePos += steps.inc; } } else if (token.optional) { // if token is optional, only add the value char if it matchs the token pattern // if not, move on to the next pattern char if (new RegExp(token.pattern).test(vc) && optionalNumbersToUse) { formatted = concatChar(formatted, vc, this.options, token); valuePos += steps.inc; optionalNumbersToUse--; } } else if (new RegExp(token.pattern).test(vc)) { // if token isn't optional the value char must match the token pattern formatted = concatChar(formatted, vc, this.options, token); valuePos += steps.inc; } else if (!vc && token.default && this.options.useDefaults) { // if the token isn't optional and has a default value, use it if the value is finished formatted = concatChar(formatted, token.default, this.options, token); } else if (vc) { // the string value don't match the given pattern valuePos += steps.inc; continue; } else { // the string value don't match the given pattern valid = false; break; } patternPos = patternPos + steps.inc; } return { result: formatted, valid: valid }; } apply(value) { return this.process(value).result; } validate(value) { return this.process(value).valid; } } //# sourceMappingURL=mask.js.map