Skip to content

Commit

Permalink
work for #4842 calculate cursor position
Browse files Browse the repository at this point in the history
  • Loading branch information
OlgaLarina committed Nov 28, 2023
1 parent 4fc82ee commit e16d5ab
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 51 deletions.
17 changes: 5 additions & 12 deletions src/mask/mask.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { checkValueByPattern, getMaskedValueByPattern, getUnmaskedValueByPattern } from "./mask_utils";
import { processValueWithPattern, getMaskedValueByPattern, getUnmaskedValueByPattern } from "./mask_utils";

export class InputMaskBase {
private _prevSelectionStart: number;
Expand All @@ -9,29 +9,22 @@ export class InputMaskBase {

applyValue(mask: string) {
if(!!this.input) {
const value = getMaskedValueByPattern(getUnmaskedValueByPattern(this.input.value, mask, false), mask);
this.input.value = value.text;
this.input.value = getMaskedValueByPattern(getUnmaskedValueByPattern(this.input.value, mask, false), mask);
}
}
updateMaskedString(mask: string): void {
if(!!this.input) {
const prevSelectionStart = this.input.selectionStart;
const value = getMaskedValueByPattern(getUnmaskedValueByPattern(this.input.value, mask, false), mask);
// this.input.value = value.text;
this.input.value = checkValueByPattern(this.input.value, mask, this._prevSelectionStart, this.input.selectionStart);
// this.input.setSelectionRange(value.cursorPosition, value.cursorPosition);
this.input.setSelectionRange(prevSelectionStart, prevSelectionStart);
const result = processValueWithPattern(this.input.value, mask, this._prevSelectionStart, this.input.selectionStart);
this.input.value = result.text;
this.input.setSelectionRange(result.cursorPosition, result.cursorPosition);
}
}

keydownHandler = (event: any) => {
console.log("key - " + event.key + ", code - " + event.code + ", selectionStart - " + event.target.selectionStart);
this._prevSelectionStart = event.target.selectionStart;
// this.updateMaskedString(this.mask);
};

inputHandler = (event: any) => {
console.log("data - " + event.data + ", selectionStart - " + event.target.selectionStart);
this.updateMaskedString(this.mask);
};
public addInputEventListener(): void {
Expand Down
26 changes: 14 additions & 12 deletions src/mask/mask_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@ export var settings = {
}
};

export function getMaskedValueByPattern(str: string, pattern: string,): IMaskedValue {
let result: IMaskedValue = <IMaskedValue>{ text: "", cursorPosition: -1 };
export function getMaskedValueByPattern(str: string, pattern: string, matchWholeMask = true): string {
let result = "";
let strIndex = 0;
for(let maskIndex = 0; maskIndex < pattern.length; maskIndex++) {
const currentDefinition = settings.definitions[pattern[maskIndex]];
if(currentDefinition) {
if(strIndex < str.length && str[strIndex].match(currentDefinition)) {
result.text += str[strIndex];
result += str[strIndex];
} else if(matchWholeMask) {
result += settings.placeholderChar;
} else {
result.text += settings.placeholderChar;
if(result.cursorPosition === -1) {
result.cursorPosition = maskIndex;
}
break;
}
strIndex++;
} else {
result.text += pattern[maskIndex];
result += pattern[maskIndex];
}
}
return result;
Expand All @@ -54,19 +53,22 @@ export function getUnmaskedValueByPattern(str: string, pattern: string, matchWho
return result;
}

export function checkValueByPattern(str: string, pattern: string, prevСursorPosition: number, currentCursorPosition: number): string {
export function processValueWithPattern(str: string, pattern: string, prevСursorPosition: number, currentCursorPosition: number): IMaskedValue {
let result = "";
if(!str) return result;
if(!str) return <IMaskedValue>{ text: result, cursorPosition: currentCursorPosition };
let leftPartResult = "";
let rigthPartResult = "";
let centerPart = "";
let newCursorPosition = currentCursorPosition;

const leftPartRange = Math.min(prevСursorPosition, currentCursorPosition, pattern.length - 1);
leftPartResult = getUnmaskedValueByPattern(str.substring(0, leftPartRange), pattern.substring(0, leftPartRange), false);
rigthPartResult = getUnmaskedValueByPattern(str.substring(currentCursorPosition), pattern.substring(prevСursorPosition), false);
if(currentCursorPosition > prevСursorPosition) {
centerPart = getUnmaskedValueByPattern(str.substring(leftPartRange, currentCursorPosition), pattern.substring(leftPartRange), false);
newCursorPosition = getMaskedValueByPattern(leftPartResult + centerPart, pattern, false).length;

}
result = getMaskedValueByPattern(leftPartResult + centerPart + rigthPartResult, pattern).text;
return result;
result = getMaskedValueByPattern(leftPartResult + centerPart + rigthPartResult, pattern);
return <IMaskedValue>{ text: result, cursorPosition: newCursorPosition };
}
79 changes: 52 additions & 27 deletions tests/mask_pattern_tests.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import { InputMaskBase } from "../src/mask/mask";
import { checkValueByPattern, getMaskedValueByPattern, getUnmaskedValueByPattern } from "../src/mask/mask_utils";
import { processValueWithPattern, getMaskedValueByPattern, getUnmaskedValueByPattern } from "../src/mask/mask_utils";

export default QUnit.module("Pattern mask");

const mask = "+9(999)-999-99-99";

QUnit.test("get masked valid text", function(assert) {
assert.equal(getMaskedValueByPattern("", mask).text, "+_(___)-___-__-__");
assert.equal(getMaskedValueByPattern("1", mask).text, "+1(___)-___-__-__");
assert.equal(getMaskedValueByPattern("1234", mask).text, "+1(234)-___-__-__");
assert.equal(getMaskedValueByPattern("1234567", mask).text, "+1(234)-567-__-__");
assert.equal(getMaskedValueByPattern("12345678910", mask).text, "+1(234)-567-89-10");
assert.equal(getMaskedValueByPattern("", mask, true), "+_(___)-___-__-__");
assert.equal(getMaskedValueByPattern("1", mask, true), "+1(___)-___-__-__");
assert.equal(getMaskedValueByPattern("1234", mask, true), "+1(234)-___-__-__");
assert.equal(getMaskedValueByPattern("1234567", mask, true), "+1(234)-567-__-__");
assert.equal(getMaskedValueByPattern("12345678910", mask, true), "+1(234)-567-89-10");
});

QUnit.test("get masked valid text", function(assert) {
const customMask = "+1(999)-999-99-99";
assert.equal(getMaskedValueByPattern("", customMask, false), "+1(");
assert.equal(getMaskedValueByPattern("1", customMask, false), "+1(1");
assert.equal(getMaskedValueByPattern("123", customMask, false), "+1(123)-");
assert.equal(getMaskedValueByPattern("123456", customMask, false), "+1(123)-456-");
assert.equal(getMaskedValueByPattern("12345678910", customMask, false), "+1(123)-456-78-91");
});

QUnit.test("get masked invalid text", function(assert) {
const resultMaskedText = "+_(___)-___-__-__";
assert.equal(getMaskedValueByPattern("", mask).text, resultMaskedText);
assert.equal(getMaskedValueByPattern("a", mask).text, resultMaskedText);
assert.equal(getMaskedValueByPattern("@", mask).text, resultMaskedText);
assert.equal(getMaskedValueByPattern(".", mask).text, resultMaskedText);
assert.equal(getMaskedValueByPattern("123456789101112", mask).text, "+1(234)-567-89-10");
assert.equal(getMaskedValueByPattern("", mask, true), resultMaskedText);
assert.equal(getMaskedValueByPattern("a", mask, true), resultMaskedText);
assert.equal(getMaskedValueByPattern("@", mask, true), resultMaskedText);
assert.equal(getMaskedValueByPattern(".", mask, true), resultMaskedText);
assert.equal(getMaskedValueByPattern("123456789101112", mask, true), "+1(234)-567-89-10");
});

QUnit.test("get unmasked value, matchWholeMask is true", function(assert) {
Expand Down Expand Up @@ -49,34 +58,49 @@ QUnit.test("get unmasked invalid value, matchWholeMask is false", function(asser
assert.equal(getUnmaskedValueByPattern("+1(234)-567-__-10", mask, false), "1234567");
});

QUnit.only("edit value - type", function(assert) {
QUnit.test("edit value - type", function(assert) {
const pattern = "+1(999)-999-99-99";
assert.equal(checkValueByPattern("+1(3___)-___-__-__", pattern, 3, 4), "+1(3__)-___-__-__", "type #1");
assert.equal(checkValueByPattern("+1(345)-6___-__-__", pattern, 8, 9), "+1(345)-6__-__-__", "type #2");
assert.equal(checkValueByPattern("+1(345)-a___-__-__", pattern, 8, 9), "+1(345)-___-__-__", "type #3");
assert.equal(checkValueByPattern("+1(345)-9678-10-11", pattern, 8, 9), "+1(345)-967-81-01", "type #4");
assert.equal(checkValueByPattern("+1(345)-a678-10-11", pattern, 8, 9), "+1(345)-678-10-11", "type #5");
assert.equal(checkValueByPattern("+1(345)-678-10-111", pattern, 17, 18), "+1(345)-678-10-11", "type #6");
assert.equal(processValueWithPattern("+1(3___)-___-__-__", pattern, 3, 4).text, "+1(3__)-___-__-__", "type #1");
assert.equal(processValueWithPattern("+1(3___)-___-__-__", pattern, 3, 4).cursorPosition, 4, "type #1");
assert.equal(processValueWithPattern("+1(345_)-___-__-__", pattern, 5, 6).text, "+1(345)-___-__-__", "type #2");
assert.equal(processValueWithPattern("+1(345_)-___-__-__", pattern, 5, 6).cursorPosition, 8, "type #2");
assert.equal(processValueWithPattern("+1(345)-6___-__-__", pattern, 8, 9).text, "+1(345)-6__-__-__", "type #2");
assert.equal(processValueWithPattern("+1(345)-6___-__-__", pattern, 8, 9).cursorPosition, 9, "type #2");
assert.equal(processValueWithPattern("+1(345)-a___-__-__", pattern, 8, 9).text, "+1(345)-___-__-__", "type #3");
assert.equal(processValueWithPattern("+1(345)-a___-__-__", pattern, 8, 9).cursorPosition, 8, "type #3");
assert.equal(processValueWithPattern("+1(345)-9678-10-11", pattern, 8, 9).text, "+1(345)-967-81-01", "type #4");
assert.equal(processValueWithPattern("+1(345)-9678-10-11", pattern, 8, 9).cursorPosition, 9, "type #4");
assert.equal(processValueWithPattern("+1(345)-a678-10-11", pattern, 8, 9).text, "+1(345)-678-10-11", "type #5");
assert.equal(processValueWithPattern("+1(345)-a678-10-11", pattern, 8, 9).cursorPosition, 8, "type #5");
assert.equal(processValueWithPattern("+1(345)-678-10-111", pattern, 17, 18).text, "+1(345)-678-10-11", "type #6");
assert.equal(processValueWithPattern("+1(345)-678-10-111", pattern, 17, 18).cursorPosition, 17, "type #6");
});

QUnit.only("edit value - delete", function(assert) {
QUnit.test("edit value - delete", function(assert) {
const pattern = "+1(999)-999-99-99";
assert.equal(checkValueByPattern("+1(3_)-___-__-__", pattern, 4, 3), "+1(3__)-___-__-__", "delete #1");
assert.equal(checkValueByPattern("+1(345)-__-__-__", pattern, 8, 7), "+1(345)-___-__-__", "delete #2");
assert.equal(checkValueByPattern("+1(345)-8_-__-__", pattern, 9, 8), "+1(345)-8__-__-__", "delete #3");
assert.equal(checkValueByPattern("+1(345)-91-12-15", pattern, 9, 8), "+1(345)-911-21-5_", "delete #4");
assert.equal(checkValueByPattern("+1(345)-891-11-1", pattern, 17, 16), "+1(345)-891-11-1_", "delete #5");
assert.equal(processValueWithPattern("+1(3_)-___-__-__", pattern, 5, 4).text, "+1(3__)-___-__-__", "delete #1");
assert.equal(processValueWithPattern("+1(3_)-___-__-__", pattern, 5, 4).cursorPosition, 4, "delete #1");
assert.equal(processValueWithPattern("+1(345)-__-__-__", pattern, 8, 7).text, "+1(345)-___-__-__", "delete #2");
assert.equal(processValueWithPattern("+1(345)-__-__-__", pattern, 8, 7).cursorPosition, 7, "delete #2");
assert.equal(processValueWithPattern("+1(345)-8_-__-__", pattern, 10, 9).text, "+1(345)-8__-__-__", "delete #3");
assert.equal(processValueWithPattern("+1(345)-8_-__-__", pattern, 10, 9).cursorPosition, 9, "delete #3");
assert.equal(processValueWithPattern("+1(345)-91-12-15", pattern, 9, 8).text, "+1(345)-911-21-5_", "delete #4");
assert.equal(processValueWithPattern("+1(345)-91-12-15", pattern, 9, 8).cursorPosition, 8, "delete #4");
assert.equal(processValueWithPattern("+1(345)-891-11-1", pattern, 17, 16).text, "+1(345)-891-11-1_", "delete #5");
assert.equal(processValueWithPattern("+1(345)-891-11-1", pattern, 17, 16).cursorPosition, 16, "delete #5");
});

QUnit.only("edit value - insert value", function(assert) {
QUnit.test("edit value - insert value", function(assert) {
const pattern = "+1(999)-999-99-99";
assert.equal(checkValueByPattern("+1(345)-8a_-__-__", pattern, 9, 8), "+1(345)-8__-__-__", "insert value #3");
assert.equal(processValueWithPattern("+1(345)-8a_-__-__", pattern, 9, 8).text, "+1(345)-8__-__-__", "insert value #3");
});

QUnit.test("update masked value", function(assert) {
/*
QUnit.only("update masked value", function(assert) {
const resultMaskedText = "+1(234)-567-__-__";
const testInput = document.createElement("input");
const inputMask = new InputMaskBase(testInput, mask);
inputMask["_prevSelectionStart"] = 0;
assert.equal(testInput.value, "+_(___)-___-__-__");
testInput.value = "+1(234)-567-__-__";
Expand All @@ -101,3 +125,4 @@ QUnit.test("update masked value", function(assert) {
testInput.remove();
});
*/

0 comments on commit e16d5ab

Please sign in to comment.