@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
129 lines • 4.96 kB
JavaScript
import { convertMaskToPlaceholder, isArray, processCaretTraps } from "./utilities.js";
import { placeholderChar as defaultPlaceholderChar, strFunction } from "./constants.js";
const emptyArray = [];
const emptyString = '';
export default function conformToMask(rawValue = emptyString, mask = emptyArray, config = {}) {
let finalMask;
if (!isArray(mask)) {
if (typeof mask === strFunction) {
const generated = mask(rawValue, config);
finalMask = processCaretTraps(generated).maskWithoutCaretTraps;
} else {
throw new Error('Text-mask:conformToMask; The mask property must be an array.');
}
} else {
finalMask = mask;
}
const {
guide = true,
previousConformedValue = emptyString,
placeholderChar = defaultPlaceholderChar,
placeholder = convertMaskToPlaceholder(finalMask, placeholderChar),
currentCaretPosition,
keepCharPositions
} = config;
const suppressGuide = guide === false && previousConformedValue !== undefined;
const rawValueLength = rawValue.length;
const previousConformedValueLength = previousConformedValue.length;
const placeholderLength = placeholder.length;
const maskLength = finalMask.length;
const editDistance = rawValueLength - previousConformedValueLength;
const isAddition = editDistance > 0;
const indexOfFirstChange = currentCaretPosition + (isAddition ? -editDistance : 0);
const indexOfLastChange = indexOfFirstChange + Math.abs(editDistance);
if (keepCharPositions === true && !isAddition) {
let compensatingPlaceholderChars = emptyString;
for (let i = indexOfFirstChange; i < indexOfLastChange; i++) {
if (placeholder[i] === placeholderChar) {
compensatingPlaceholderChars += placeholderChar;
}
}
rawValue = rawValue.slice(0, indexOfFirstChange) + compensatingPlaceholderChars + rawValue.slice(indexOfFirstChange, rawValueLength);
}
const rawValueArr = rawValue.split(emptyString).map((char, i) => ({
char,
isNew: i >= indexOfFirstChange && i < indexOfLastChange
}));
for (let i = rawValueLength - 1; i >= 0; i--) {
const {
char
} = rawValueArr[i];
if (char !== placeholderChar) {
const shouldOffset = i >= indexOfFirstChange && previousConformedValueLength === maskLength;
if (char === placeholder[shouldOffset ? i - editDistance : i]) {
rawValueArr.splice(i, 1);
}
}
}
let conformedValue = emptyString;
let someCharsRejected = false;
placeholderLoop: for (let i = 0; i < placeholderLength; i++) {
const charInPlaceholder = placeholder[i];
if (charInPlaceholder === placeholderChar) {
if (rawValueArr.length > 0) {
while (rawValueArr.length > 0) {
const {
char: rawValueChar,
isNew
} = rawValueArr.shift();
if (rawValueChar === placeholderChar && suppressGuide !== true) {
conformedValue += placeholderChar;
continue placeholderLoop;
} else if (finalMask[i] instanceof RegExp && finalMask[i].test(rawValueChar)) {
if (keepCharPositions !== true || isNew === false || previousConformedValue === emptyString || guide === false || !isAddition) {
conformedValue += rawValueChar;
} else {
const rawValueArrLength = rawValueArr.length;
let indexOfNextAvailablePlaceholderChar = null;
for (let i = 0; i < rawValueArrLength; i++) {
const charData = rawValueArr[i];
if (charData.char !== placeholderChar && charData.isNew === false) {
break;
}
if (charData.char === placeholderChar) {
indexOfNextAvailablePlaceholderChar = i;
break;
}
}
if (indexOfNextAvailablePlaceholderChar !== null) {
conformedValue += rawValueChar;
rawValueArr.splice(indexOfNextAvailablePlaceholderChar, 1);
} else {
i--;
}
}
continue placeholderLoop;
} else {
someCharsRejected = true;
}
}
}
if (suppressGuide === false) {
conformedValue += placeholder.substring(i, i + placeholderLength);
}
break;
} else {
conformedValue += charInPlaceholder;
}
}
if (suppressGuide && isAddition === false) {
let indexOfLastFilledPlaceholderChar = null;
for (let i = 0; i < conformedValue.length; i++) {
if (placeholder[i] === placeholderChar) {
indexOfLastFilledPlaceholderChar = i;
}
}
if (indexOfLastFilledPlaceholderChar !== null) {
conformedValue = conformedValue.substring(0, indexOfLastFilledPlaceholderChar + 1);
} else {
conformedValue = emptyString;
}
}
return {
conformedValue,
meta: {
someCharsRejected
}
};
}
//# sourceMappingURL=conformToMask.js.map