@v4fire/client
Version:
V4Fire client core library
93 lines (74 loc) • 1.94 kB
text/typescript
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
import type iInputText from 'super/i-input-text/i-input-text';
import type { CompiledMask } from 'super/i-input-text/modules/mask/interface';
/**
* Compiles the specified component mask and returns the compiled object.
*
* To determine non-terminal symbols within the mask is used the symbol `%` and the symbol after it, like `%d` or `%w`.
* The character `%` is replaced to `\`, and after, the expression will be compiled to RegExp.
* To escape system characters, you can use a backslash, for instance, `\\%d`.
*
* @param component
* @param mask
*/
export function compile<C extends iInputText>(component: C, mask: string): CompiledMask {
const {
unsafe,
unsafe: {maskRepetitions, maskPlaceholder, maskDelimiter}
} = component;
const
symbols = <Array<string | RegExp>>[],
nonTerminals = <RegExp[]>[];
let
placeholder = '';
let
needEscape = false,
isNonTerminal = false;
for (let o = [...mask.letters()], i = 0, j = 0; i < o.length && j < maskRepetitions; i++) {
const
char = o[i];
if (!needEscape) {
if (char === '\\') {
needEscape = true;
continue;
}
if (char === '%') {
isNonTerminal = true;
continue;
}
}
needEscape = false;
placeholder += isNonTerminal ? maskPlaceholder : char;
if (isNonTerminal) {
const
symbol = unsafe.regExps?.[char] ?? new RegExp(`\\${char}`);
symbols.push(symbol);
nonTerminals.push(symbol);
isNonTerminal = false;
} else {
symbols.push(char);
}
if (i === o.length - 1) {
i = -1;
j++;
if (j < maskRepetitions && maskDelimiter !== '') {
placeholder += maskDelimiter;
symbols.push(maskDelimiter);
}
}
}
return {
symbols,
nonTerminals,
text: '',
placeholder,
selectionStart: 0,
selectionEnd: 0
};
}