react-native-advanced-input-mask
Version:
Text input mask for React Native on iOS, Android and web. Synchronous and easy formatting without hustle
110 lines (109 loc) • 4.33 kB
JavaScript
import { FIXED_STATE_TYPES, OPTIONAL_STATE_TYPES } from "../model/constants";
import EOLState from "../model/state/EOLState";
import FixedState from "../model/state/FixedState";
import FreeState from "../model/state/FreeState";
import OptionalValueState from "../model/state/OptionalValueState";
import ValueState from "../model/state/ValueState";
import FormatError from "./FormatError";
import FormatSanitizer from "./FormatSanitizer";
export default class Compiler {
constructor(customNotations) {
this.customNotations = customNotations;
}
compile(formatString) {
const sanitizedString = FormatSanitizer.sanitize(formatString);
return this.compileInternal(sanitizedString, false, false, null);
}
compileInternal(formatString, valuable, fixed, lastCharacter) {
if (!formatString) {
return new EOLState(null);
}
const char = formatString.charAt(0);
switch (char) {
case "[":
if (lastCharacter !== "\\") {
return this.compileInternal(formatString.slice(1), true, false, char);
}
break;
case "{":
if (lastCharacter !== "\\") {
return this.compileInternal(formatString.slice(1), false, true, char);
}
break;
case "]":
case "}":
if (lastCharacter !== "\\") {
return this.compileInternal(formatString.slice(1), false, false, char);
}
break;
case "\\":
if (lastCharacter !== "\\") {
return this.compileInternal(formatString.slice(1), valuable, fixed, char);
}
break;
}
if (valuable) {
switch (char) {
case "0":
return new ValueState(this.compileInternal(formatString.substring(1), true, false, char), FIXED_STATE_TYPES.numeric);
case "A":
return new ValueState(this.compileInternal(formatString.substring(1), true, false, char), FIXED_STATE_TYPES.literal);
case "_":
return new ValueState(this.compileInternal(formatString.substring(1), true, false, char), FIXED_STATE_TYPES.alphaNumeric);
case "…":
// Ellipses remain elliptical: re-construct inherited type from lastCharacter
return new ValueState(null, this.determineInheritedType(lastCharacter));
case "9":
return new OptionalValueState(this.compileInternal(formatString.substring(1), true, false, char), OPTIONAL_STATE_TYPES.numeric);
case "a":
return new OptionalValueState(this.compileInternal(formatString.substring(1), true, false, char), OPTIONAL_STATE_TYPES.literal);
case "-":
return new OptionalValueState(this.compileInternal(formatString.substring(1), true, false, char), OPTIONAL_STATE_TYPES.alphaNumeric);
default:
return this.compileWithCustomNotations(char, formatString.substring(1));
}
}
if (fixed) {
return new FixedState(this.compileInternal(formatString.slice(1), false, true, char), char);
}
// Not in valuable or fixed => treat as FreeState
return new FreeState(this.compileInternal(formatString.slice(1), false, false, char), char);
}
determineInheritedType(lastCharacter) {
switch (lastCharacter) {
case "0":
case "9":
return FIXED_STATE_TYPES.numeric;
case "A":
case "a":
return FIXED_STATE_TYPES.literal;
case "_":
case "-":
case "…":
case "[":
return FIXED_STATE_TYPES.alphaNumeric;
default:
return this.determineTypeWithCustomNotations(lastCharacter);
}
}
compileWithCustomNotations(char, remaining) {
for (const customNotation of this.customNotations) {
if (customNotation.character === char) {
return customNotation.isOptional ? new OptionalValueState(this.compileInternal(remaining, true, false, char), customNotation) : new ValueState(this.compileInternal(remaining, true, false, char), customNotation);
}
}
throw new FormatError();
}
determineTypeWithCustomNotations(lastCharacter) {
if (lastCharacter === null || lastCharacter === undefined) {
throw new FormatError();
}
for (const notation of this.customNotations) {
if (notation.character === lastCharacter) {
return notation;
}
}
throw new FormatError();
}
}
//# sourceMappingURL=Compiler.js.map