@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
93 lines • 4.7 kB
JavaScript
const defaultArray = [];
const emptyString = '';
export default function adjustCaretPosition(_ref) {
let {
previousConformedValue = emptyString,
previousPlaceholder = emptyString,
currentCaretPosition = 0,
conformedValue,
rawValue,
placeholderChar,
placeholder,
indexesOfPipedChars = defaultArray,
caretTrapIndexes = defaultArray,
keepCharPositions = false
} = _ref;
if (currentCaretPosition === 0 || !rawValue.length) {
return 0;
}
const rawValueLength = rawValue.length;
const previousConformedValueLength = previousConformedValue.length;
const placeholderLength = placeholder.length;
const conformedValueLength = conformedValue.length;
const editLength = rawValueLength - previousConformedValueLength;
const isAddition = editLength > 0;
const isFirstRawValue = previousConformedValueLength === 0;
const isPartialMultiCharEdit = editLength > 1 && !isAddition && !isFirstRawValue;
if (isPartialMultiCharEdit) {
return currentCaretPosition;
}
const possiblyHasRejectedChar = isAddition && (keepCharPositions !== false && previousConformedValue === conformedValue || conformedValue === placeholder);
let startingSearchIndex = 0;
let trackRightCharacter;
let targetChar;
if (possiblyHasRejectedChar) {
startingSearchIndex = currentCaretPosition - editLength;
} else {
const normalizedConformedValue = conformedValue.toLowerCase();
const normalizedRawValue = rawValue.toLowerCase();
const leftHalfChars = normalizedRawValue.substr(0, currentCaretPosition).split(emptyString);
const intersection = leftHalfChars.filter(char => normalizedConformedValue.indexOf(char) !== -1);
targetChar = intersection[intersection.length - 1];
const previousLeftMaskChars = previousPlaceholder.substr(0, intersection.length).split(emptyString).filter(char => char !== placeholderChar).length;
const leftMaskChars = placeholder.substr(0, intersection.length).split(emptyString).filter(char => char !== placeholderChar).length;
const maskLengthChanged = leftMaskChars !== previousLeftMaskChars;
const targetIsMaskMovingLeft = previousPlaceholder[intersection.length - 1] !== undefined && placeholder[intersection.length - 2] !== undefined && previousPlaceholder[intersection.length - 1] !== placeholderChar && previousPlaceholder[intersection.length - 1] !== placeholder[intersection.length - 1] && previousPlaceholder[intersection.length - 1] === placeholder[intersection.length - 2];
if (!isAddition && (maskLengthChanged || targetIsMaskMovingLeft) && previousLeftMaskChars > 0 && placeholder.indexOf(targetChar) > -1 && rawValue[currentCaretPosition] !== undefined) {
trackRightCharacter = true;
targetChar = rawValue[currentCaretPosition];
}
const pipedChars = indexesOfPipedChars.map(index => normalizedConformedValue[index]);
const countTargetCharInPipedChars = pipedChars.filter(char => char === targetChar).length;
const countTargetCharInIntersection = intersection.filter(char => char === targetChar).length;
const countTargetCharInPlaceholder = placeholder.substr(0, placeholder.indexOf(placeholderChar)).split(emptyString).filter((char, index) => char === targetChar && rawValue[index] !== char).length;
const requiredNumberOfMatches = countTargetCharInPlaceholder + countTargetCharInIntersection + countTargetCharInPipedChars + (trackRightCharacter ? 1 : 0);
let numberOfEncounteredMatches = 0;
for (let i = 0; i < conformedValueLength; i++) {
const conformedValueChar = normalizedConformedValue[i];
startingSearchIndex = i + 1;
if (conformedValueChar === targetChar) {
numberOfEncounteredMatches++;
}
if (numberOfEncounteredMatches >= requiredNumberOfMatches) {
break;
}
}
}
if (isAddition) {
let lastPlaceholderChar = startingSearchIndex;
for (let i = startingSearchIndex; i <= placeholderLength; i++) {
if (placeholder[i] === placeholderChar) {
lastPlaceholderChar = i;
}
if (placeholder[i] === placeholderChar || caretTrapIndexes.indexOf(i) !== -1 || i === placeholderLength) {
return lastPlaceholderChar;
}
}
} else {
if (trackRightCharacter) {
for (let i = startingSearchIndex - 1; i >= 0; i--) {
if (conformedValue[i] === targetChar || caretTrapIndexes.indexOf(i) !== -1 || i === 0) {
return i;
}
}
} else {
for (let i = startingSearchIndex; i >= 0; i--) {
if (placeholder[i - 1] === placeholderChar || caretTrapIndexes.indexOf(i) !== -1 || i === 0) {
return i;
}
}
}
}
}
//# sourceMappingURL=adjustCaretPosition.js.map