UNPKG

react-hook-mask

Version:
349 lines 19.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getExpectedCursorPos = void 0; var maskMain = function (value, maskGenerator) { var _a, _b; value = value.toString(); var rules = maskGenerator.rules; var mask = maskGenerator.generateMask(value); var transform = maskGenerator.transform; var len = value.length; var maskLen = mask.length; var pos = 0; var newValue = ''; for (var i = 0; i < Math.min(len, maskLen); i++) { var maskChar = mask.charAt(i); var newChar = value.charAt(pos); var regex = rules.get(maskChar); if (regex) { pos++; if (regex.test(newChar)) { newValue += newChar; } else { i--; len--; } } else { if (maskChar === newChar) { pos++; } else { len++; } newValue += maskChar; } } var transformOffset = 0; if (transform) { var beforeTransform = newValue; newValue = transform(beforeTransform); transformOffset = ((_a = newValue === null || newValue === void 0 ? void 0 : newValue.length) !== null && _a !== void 0 ? _a : 0) - ((_b = beforeTransform === null || beforeTransform === void 0 ? void 0 : beforeTransform.length) !== null && _b !== void 0 ? _b : 0); } return { maskedValue: newValue, mask: mask, transformOffset: transformOffset }; }; var mask = function (value, maskGenerator) { var _a = maskMain(value, maskGenerator), maskedValue = _a.maskedValue, mask = _a.mask, transformOffset = _a.transformOffset; var _b = maskMain(maskedValue !== null && maskedValue !== void 0 ? maskedValue : '', maskGenerator), shouldBeTheSame = _b.maskedValue, newMask = _b.mask; if (maskedValue !== shouldBeTheSame) { if (typeof console !== 'undefined') { console === null || console === void 0 ? void 0 : console.error('mask applied to value should not change when applied again', '-> before: ' + value, '-> after: ' + maskedValue + ' (mask: ' + mask + ')', '-> again: ' + shouldBeTheSame + ' (mask: ' + newMask + ')'); } return { maskedValue: value, mask: mask, transformOffset: 0 }; } return { maskedValue: maskedValue, mask: mask, transformOffset: transformOffset }; }; var unmask = function (displayValue, maskGenerator) { var _a; if (!maskGenerator) { return displayValue; } var rules = maskGenerator.rules; var mask = maskGenerator.generateMask(displayValue); var maskLen = (_a = mask === null || mask === void 0 ? void 0 : mask.length) !== null && _a !== void 0 ? _a : 0; return displayValue .split('') .filter(function (_, idx) { return idx < maskLen && rules.has(mask[idx]); }) .join(''); }; var processValue = function (displayValue, maskGenerator) { var keepMask = maskGenerator.keepMask; var value = keepMask ? displayValue : unmask(displayValue, maskGenerator); return value; }; // Algorithm to get the cursor position after the mask is applied var getExpectedCursorPos = function (args) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1; var displayValue = args.displayValue, oldDisplayValue = args.oldDisplayValue, valueBeforeMask = args.valueBeforeMask, newMask = args.newMask, oldMask = args.oldMask, cursorPosition = args.cursorPosition, lastWentBack = args.lastWentBack; var oldMaskStr = (_a = oldMask === null || oldMask === void 0 ? void 0 : oldMask.generateMask(oldDisplayValue)) !== null && _a !== void 0 ? _a : ''; var newMaskStr = (_b = newMask === null || newMask === void 0 ? void 0 : newMask.generateMask(displayValue)) !== null && _b !== void 0 ? _b : ''; var oldDynamicAmount = oldMaskStr .split('') .filter(function (char, idx) { return (oldDisplayValue === null || oldDisplayValue === void 0 ? void 0 : oldDisplayValue[idx]) && (oldMask ? oldMask.rules.has(char) : true); }).length; var newDynamicAmount = newMaskStr .split('') .filter(function (char, idx) { return (displayValue === null || displayValue === void 0 ? void 0 : displayValue[idx]) && (newMask ? newMask.rules.has(char) : true); }).length; if (oldDynamicAmount === newDynamicAmount && displayValue === oldDisplayValue) { var afterMaskLen = (_c = displayValue === null || displayValue === void 0 ? void 0 : displayValue.length) !== null && _c !== void 0 ? _c : 0; var beforeMaskLen = (_d = valueBeforeMask === null || valueBeforeMask === void 0 ? void 0 : valueBeforeMask.length) !== null && _d !== void 0 ? _d : 0; if (afterMaskLen > beforeMaskLen) { // When the new value before the mask was applied had less chars, // consider to be a case in which a char was deleted. // Because it's not known if it was deleted before or after the cursor // (the cursor position before the change is unknown), the flag lastWentBack // is used to consider if the cursor was before or after the deleted char. var position = cursorPosition + afterMaskLen - beforeMaskLen; var goOn = true; var wentBack = !lastWentBack; var offset = 0; // advance the adjacent static chars until there's no more remaining // if wentBack is true, it will go back until it finds a dynamic char // if wentBack is false, it will go forward until it finds a dynamic char while (goOn) { var idx = position + offset + (wentBack ? -1 : 0); var maskChar = idx >= 0 && idx < ((_e = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.length) !== null && _e !== void 0 ? _e : 0) ? newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.charAt(idx) : undefined; if (!maskChar) { goOn = false; } else { var regex = (_f = newMask === null || newMask === void 0 ? void 0 : newMask.rules) === null || _f === void 0 ? void 0 : _f.get(maskChar); if (regex) { goOn = false; } else { offset = wentBack ? offset - 1 : offset + 1; } } } var newPosition = Math.max(Math.min(position + offset, (_g = displayValue === null || displayValue === void 0 ? void 0 : displayValue.length) !== null && _g !== void 0 ? _g : 0), 0); return { position: newPosition, wentBack: wentBack, }; } else if (afterMaskLen < beforeMaskLen) { // If 1 or more chars were added, but the end value ended up // being the same after the mask was applied, the cursor should // return a number of positions equal to the number of ignored // chars (those that should have been placed in dynamic positions, // but the rule wasn't satisfied). var initial = { ignored: 0, idx: 0 }; var ignored = ((_m = (_l = (_k = valueBeforeMask === null || valueBeforeMask === void 0 ? void 0 : valueBeforeMask.substring(0, Math.min((_h = valueBeforeMask === null || valueBeforeMask === void 0 ? void 0 : valueBeforeMask.length) !== null && _h !== void 0 ? _h : 0, (_j = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.length) !== null && _j !== void 0 ? _j : 0, cursorPosition))) === null || _k === void 0 ? void 0 : _k.split('')) === null || _l === void 0 ? void 0 : _l.reduce(function (acc, char) { var _a, _b; var ignored = acc.ignored; var idx = acc.idx; var len = (_a = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.length) !== null && _a !== void 0 ? _a : 0; while (idx < len) { if (idx >= cursorPosition) { return acc; } var maskChar = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.charAt(idx); var regex = (_b = newMask === null || newMask === void 0 ? void 0 : newMask.rules) === null || _b === void 0 ? void 0 : _b.get(maskChar); if (regex) { if (regex.test(char)) { return { ignored: ignored, idx: idx + 1 }; } else { return { ignored: ignored + 1, idx: idx }; } } else { if (maskChar === char) { return { ignored: ignored, idx: idx + 1 }; } idx++; } } return { ignored: ignored, idx: idx + 1, }; }, initial)) !== null && _m !== void 0 ? _m : initial).ignored; var newPosition = Math.max(Math.min(cursorPosition - ignored, (_o = displayValue === null || displayValue === void 0 ? void 0 : displayValue.length) !== null && _o !== void 0 ? _o : 0), 0); return { position: newPosition, wentBack: lastWentBack, }; } else { return { position: cursorPosition, wentBack: lastWentBack, }; } } else if (oldDynamicAmount <= newDynamicAmount) { var dynamicOffset = newDynamicAmount - oldDynamicAmount; // Guess the last position of the cursor var cursorBeforeDynamic_1 = Math.max(Math.min(cursorPosition - dynamicOffset, (_p = oldDisplayValue === null || oldDisplayValue === void 0 ? void 0 : oldDisplayValue.length) !== null && _p !== void 0 ? _p : 0), 0); var oldStaticAmountBefore = oldMaskStr === null || oldMaskStr === void 0 ? void 0 : oldMaskStr.substring(0, Math.max(cursorBeforeDynamic_1, 0)).split('').filter(function (char, idx) { return (oldDisplayValue === null || oldDisplayValue === void 0 ? void 0 : oldDisplayValue[idx]) && (oldMask ? !oldMask.rules.has(char) : false); }).length; var newStaticAmountBefore = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.substring(0, Math.max(cursorBeforeDynamic_1, 0)).split('').filter(function (char, idx) { return (displayValue === null || displayValue === void 0 ? void 0 : displayValue[idx]) && (newMask ? !newMask.rules.has(char) : false); }).length; // the difference of static chars between the new and old mask, before the cursor // and not considering the cursor changes due to dynamic chars var initialStaticOffset_1 = newStaticAmountBefore - oldStaticAmountBefore; var exceededOffset_1 = Math.max(((_q = valueBeforeMask === null || valueBeforeMask === void 0 ? void 0 : valueBeforeMask.length) !== null && _q !== void 0 ? _q : 0) - ((_r = displayValue === null || displayValue === void 0 ? void 0 : displayValue.length) !== null && _r !== void 0 ? _r : 0), 0); // Calculates the number of ignored chars (those that have not satisfied the mask) // and the number of exceeded chars (those that have not been added to the mask, // because the end of the mask was reached) var initial = { ignored: 0, exceeded: 0, staticAdded: 0, idx: 0 }; var _2 = (_t = (_s = valueBeforeMask === null || valueBeforeMask === void 0 ? void 0 : valueBeforeMask.split('')) === null || _s === void 0 ? void 0 : _s.reduce(function (_a, char) { var _b, _c; var ignored = _a.ignored, exceeded = _a.exceeded, staticAdded = _a.staticAdded, idx = _a.idx; var len = (_b = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.length) !== null && _b !== void 0 ? _b : 0; while (idx < len) { var maskChar = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.charAt(idx); var regex = (_c = newMask === null || newMask === void 0 ? void 0 : newMask.rules) === null || _c === void 0 ? void 0 : _c.get(maskChar); if (regex) { if (regex.test(char)) { return { ignored: ignored, exceeded: exceeded, staticAdded: staticAdded, idx: idx + 1 }; } else { var newIgnored = idx > cursorBeforeDynamic_1 + initialStaticOffset_1 - exceededOffset_1 && idx < cursorPosition ? ignored + 1 : ignored; return { ignored: newIgnored, exceeded: exceeded, staticAdded: !newIgnored && idx < cursorPosition ? staticAdded - 1 : staticAdded, idx: idx, }; } } else { if (maskChar === char) { var newIgnored = idx > cursorBeforeDynamic_1 + initialStaticOffset_1 - exceededOffset_1 && idx < cursorPosition ? ignored + 1 : ignored; return { ignored: newIgnored, exceeded: exceeded, staticAdded: staticAdded, idx: idx + 1, }; } else { if (idx < cursorPosition) { staticAdded = staticAdded + 1; } } idx++; } } // after the entire masked was surpassed, increase the exceeded chars amount return { ignored: ignored, exceeded: exceeded + 1, staticAdded: staticAdded, idx: idx + 1 }; }, initial)) !== null && _t !== void 0 ? _t : initial, _3 = _2.ignored, charsIgnored = _3 === void 0 ? 0 : _3, _4 = _2.exceeded, charsExceeded = _4 === void 0 ? 0 : _4, _5 = _2.staticAdded, staticAdded = _5 === void 0 ? 0 : _5; var currentPos = cursorBeforeDynamic_1; var staticOffset = initialStaticOffset_1; // calculates the number of static chars that were added to the value, // starting from the expected last position of the cursor while (currentPos - staticOffset - charsExceeded < cursorBeforeDynamic_1 + dynamicOffset) { var idx = currentPos - charsExceeded; if (idx < 0) { currentPos++; continue; } var char = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr[idx]; if (!char) { break; } var dynamic = newMask ? newMask.rules.has(char) : true; if (!dynamic) { staticOffset++; } currentPos++; } staticOffset = Math.max(staticAdded, staticOffset, 0); return { position: Math.min(cursorPosition + staticOffset - charsIgnored, (_u = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.length) !== null && _u !== void 0 ? _u : 0), wentBack: lastWentBack, }; } else { // If a new static char is added to the display value, not present before the mask was applied, // the cursor position should be moved to the right. // If a char is removed from the display value, because it was supposed to be dynamic, // but have not satisfied the condition, the cursor position should be moved to the left. var offset = (_y = (_x = (_w = valueBeforeMask === null || valueBeforeMask === void 0 ? void 0 : valueBeforeMask.substring(0, Math.min(cursorPosition, (_v = valueBeforeMask === null || valueBeforeMask === void 0 ? void 0 : valueBeforeMask.length) !== null && _v !== void 0 ? _v : 0))) === null || _w === void 0 ? void 0 : _w.split('')) === null || _x === void 0 ? void 0 : _x.reduce(function (acc, char, idx) { var _a; var maskChar = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr[idx]; var regex = (_a = newMask === null || newMask === void 0 ? void 0 : newMask.rules) === null || _a === void 0 ? void 0 : _a.get(maskChar); if (regex) { if (regex.test(char)) { return acc; } else { return acc - 1; } } else { if (maskChar === char) { return acc; } else { return acc + 1; } } }, 0)) !== null && _y !== void 0 ? _y : 0; // Consider the dynamic chars added when the mask was applied // (due to a call to transform). In this case, the cursor position should // be moved to the right according to the number of dynamic chars added. var initial = { dynamic: 0, idx: 0 }; var dynamic = ((_0 = (_z = valueBeforeMask === null || valueBeforeMask === void 0 ? void 0 : valueBeforeMask.split('')) === null || _z === void 0 ? void 0 : _z.reduce(function (acc, char) { var _a, _b; var dynamic = acc.dynamic; var idx = acc.idx; var len = (_a = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr.length) !== null && _a !== void 0 ? _a : 0; while (idx < len) { var maskChar = newMaskStr === null || newMaskStr === void 0 ? void 0 : newMaskStr[idx]; var regex = (_b = newMask === null || newMask === void 0 ? void 0 : newMask.rules) === null || _b === void 0 ? void 0 : _b.get(maskChar); if (regex) { if (regex.test(char)) { return { dynamic: dynamic + 1, idx: idx + 1 }; } else { return acc; } } else { if (maskChar === char) { return { dynamic: dynamic, idx: idx + 1 }; } idx++; } } return acc; }, initial)) !== null && _0 !== void 0 ? _0 : initial).dynamic; var dynamicOffset = Math.max(newDynamicAmount - dynamic, 0); var position = Math.max(Math.min(cursorPosition + offset + dynamicOffset, (_1 = displayValue === null || displayValue === void 0 ? void 0 : displayValue.length) !== null && _1 !== void 0 ? _1 : 0), 0); return { position: position, wentBack: lastWentBack }; } }; exports.getExpectedCursorPos = getExpectedCursorPos; var MaskFunctions = { getExpectedCursorPos: exports.getExpectedCursorPos, mask: mask, processValue: processValue, unmask: unmask, }; exports.default = MaskFunctions; //# sourceMappingURL=mask.js.map