@v4fire/client
Version:
V4Fire client core library
119 lines (89 loc) • 2.63 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 {
fitForText,
convertCursorPositionToRaw,
getNormalizedSelectionBounds
} from 'super/i-input-text/modules/mask/helpers';
/**
* Handler: removing characters from the mask via `backspace/delete` buttons
*
* @param component
* @param e
*/
export function onDelete<C extends iInputText>(component: C, e: KeyboardEvent): boolean {
const {
unsafe,
unsafe: {text, compiledMask: mask, $refs: {input}}
} = component;
const canIgnore =
mask == null ||
!Object.isTruly(input) ||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
!{Backspace: true, Delete: true}[e.key];
if (canIgnore) {
return false;
}
e.preventDefault();
const
[selectionStart, selectionEnd] = getNormalizedSelectionBounds(component);
switch (e.key) {
case 'Delete': {
void unsafe.syncMaskWithText('', {
from: selectionStart,
to: selectionEnd - selectionStart > 1 ? selectionEnd - 1 : selectionEnd,
preserveCursor: true
});
break;
}
case 'Backspace': {
const
textChunks = [...text.letters()],
fittedMask = fitForText(component, textChunks);
if (fittedMask == null) {
return false;
}
const
maskSymbols = fittedMask.symbols,
fittedTextChunks = textChunks.slice(0, maskSymbols.length),
withoutSelection = selectionStart === selectionEnd;
let
cursorPos = 0,
symbolsInSelection = selectionEnd - selectionStart + (withoutSelection ? 1 : 0);
while (symbolsInSelection-- > 0) {
const
rangeStart = selectionEnd - symbolsInSelection - 1;
let
maskElPos = rangeStart,
maskEl = maskSymbols[maskElPos];
if (!Object.isRegExp(maskEl) && withoutSelection) {
do {
maskElPos--;
} while (maskElPos >= 0 && !Object.isRegExp(maskSymbols[maskElPos]));
maskEl = maskSymbols[maskElPos];
}
if (Object.isRegExp(maskEl)) {
cursorPos = rangeStart - (rangeStart - maskElPos);
fittedTextChunks[cursorPos] = unsafe.maskPlaceholder;
}
}
cursorPos = withoutSelection ? cursorPos : selectionStart;
while (cursorPos < maskSymbols.length && !Object.isRegExp(maskSymbols[cursorPos])) {
cursorPos++;
}
unsafe.updateTextStore(fittedTextChunks.join(''));
cursorPos = convertCursorPositionToRaw(component, cursorPos);
input.setSelectionRange(cursorPos, cursorPos);
break;
}
default:
// Do nothing
}
return true;
}