react-native-advanced-input-mask
Version:
Text input mask for React Native on iOS, Android and web. Synchronous and easy formatting without hustle
130 lines • 4.39 kB
JavaScript
import FormatError from "./FormatError";
export default class FormatSanitizer {
static sanitize(formatString) {
FormatSanitizer.checkOpenBraces(formatString);
const blocks = this.divideBlocksWithMixedCharacters(this.getFormatBlocks(formatString));
return FormatSanitizer.sortFormatBlocks(blocks).join("");
}
static getFormatBlocks(formatString) {
const blocks = [];
let currentBlock = "";
let escape = false;
for (const char of formatString) {
if (char === "\\") {
if (!escape) {
escape = true;
currentBlock += char;
continue;
}
}
if ((char === "[" || char === "{") && !escape) {
if (currentBlock.length > 0) {
blocks.push(currentBlock);
}
currentBlock = "";
}
currentBlock += char;
if ((char === "]" || char === "}") && !escape) {
blocks.push(currentBlock);
currentBlock = "";
}
escape = false;
}
if (currentBlock.length > 0) {
blocks.push(currentBlock);
}
return blocks;
}
static divideBlocksWithMixedCharacters(blocks) {
const resultingBlocks = [];
for (const block of blocks) {
if (block.startsWith("[")) {
let blockBuffer = "";
for (let i = 0; i < block.length; i++) {
const blockCharacter = block[i];
if (blockCharacter === "[") {
blockBuffer += blockCharacter;
continue;
}
if (blockCharacter === "]" && !blockBuffer.endsWith("\\")) {
blockBuffer += blockCharacter;
resultingBlocks.push(blockBuffer);
break;
}
if ((blockCharacter === "0" || blockCharacter === "9") && (blockBuffer.includes("A") || blockBuffer.includes("a") || blockBuffer.includes("-") || blockBuffer.includes("_"))) {
blockBuffer += "]";
resultingBlocks.push(blockBuffer);
blockBuffer = "[" + blockCharacter;
continue;
}
if ((blockCharacter === "A" || blockCharacter === "a") && (blockBuffer.includes("0") || blockBuffer.includes("9") || blockBuffer.includes("-") || blockBuffer.includes("_"))) {
blockBuffer += "]";
resultingBlocks.push(blockBuffer);
blockBuffer = "[" + blockCharacter;
continue;
}
if ((blockCharacter === "-" || blockCharacter === "_") && (blockBuffer.includes("0") || blockBuffer.includes("9") || blockBuffer.includes("A") || blockBuffer.includes("a"))) {
blockBuffer += "]";
resultingBlocks.push(blockBuffer);
blockBuffer = "[" + blockCharacter;
continue;
}
blockBuffer += blockCharacter;
}
} else {
resultingBlocks.push(block);
}
}
return resultingBlocks;
}
static sortFormatBlocks(blocks) {
const sortedBlocks = [];
for (const block of blocks) {
let sortedBlock;
if (block.startsWith("[")) {
if (block.includes("0") || block.includes("9") || block.includes("A") || block.includes("a")) {
sortedBlock = "[" + block.replace("[", "").replace("]", "").split("").sort().join("") + "]";
} else {
// For `_` or `-`, temporarily replace for sorting
sortedBlock = "[" + block.replace("[", "").replace("]", "").replace("_", "A").replace("-", "a").split("").sort().join("") + "]";
sortedBlock = sortedBlock.replace("A", "_").replace("a", "-");
}
} else {
sortedBlock = block;
}
sortedBlocks.push(sortedBlock);
}
return sortedBlocks;
}
static checkOpenBraces(str) {
let escape = false;
let squareBraceOpen = false;
let curlyBraceOpen = false;
for (const char of str) {
if (char === "\\") {
escape = !escape;
continue;
}
if (char === "[") {
if (squareBraceOpen) {
throw new FormatError();
}
squareBraceOpen = !escape;
}
if (char === "]" && !escape) {
squareBraceOpen = false;
}
if (char === "{") {
if (curlyBraceOpen) {
throw new FormatError();
}
curlyBraceOpen = !escape;
}
if (char === "}" && !escape) {
curlyBraceOpen = false;
}
escape = false;
}
}
}
//# sourceMappingURL=FormatSanitizer.js.map