@ngx-mask/core
Version:
[@ngx-mask/core](https://github.com/IKatsuba/ngx-mask#readme)
156 lines • 6.13 kB
JavaScript
export var MaskPatterns;
(function (MaskPatterns) {
MaskPatterns["number"] = "\\d";
})(MaskPatterns || (MaskPatterns = {}));
function insertChar(text, char, position) {
var t = text.split('');
t.splice(position, 0, char);
return t.join('');
}
function calcOptionalNumbersToUse(pattern, value, tokens) {
var numberToken = Object.keys(tokens).find(function (token) { return tokens[token].pattern === MaskPatterns.number; });
if (!numberToken) {
return 0;
}
var numbersInPattern = pattern.replace(new RegExp("[^" + numberToken + "]", 'g'), '').length;
var 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) {
var pc = pattern.charAt(pos);
var token = tokens[pc];
if (pc === '') {
return false;
}
return token && !token.escape ? true : hasMoreTokens(pattern, pos + inc, inc, tokens);
}
var Mask = /** @class */ (function () {
function Mask(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
};
}
Mask.process = function (value, pattern, options) {
return new Mask(pattern, options).process(value);
};
;
Mask.applyMask = function (value, pattern, options) {
return new Mask(pattern, options).apply(value);
};
;
Mask.validate = function (value, pattern, options) {
return new Mask(pattern, options).validate(value);
};
;
Mask.prototype.process = function (value) {
if (!value) {
return { result: '', valid: false };
}
var tokens = this.options.tokens;
var pattern2 = this.pattern;
var valid = true;
var formatted = '';
var valuePos = 0;
var patternPos = 0;
var optionalNumbersToUse = calcOptionalNumbersToUse(pattern2, value, tokens);
var escapeNext = false;
var 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
var vc = value.charAt(valuePos);
// Pattern char to match with the value char
var pc = pattern2.charAt(patternPos);
var 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 };
};
Mask.prototype.apply = function (value) {
return this.process(value).result;
};
Mask.prototype.validate = function (value) {
return this.process(value).valid;
};
return Mask;
}());
export { Mask };
//# sourceMappingURL=mask.js.map