From 222f2df70a3bddc0045badf4a80f93e509cb0170 Mon Sep 17 00:00:00 2001 From: Andre Asselin Date: Tue, 9 Jan 2024 18:27:18 -0500 Subject: [PATCH] Fix #183 Multiple modifier breaks other custom tokens When a token with multiple:true does not match the next character, we need to determine if it matched any previous characters or not. If it hasn't matched any characters yet, then we skip the invalid input character and remain on the same token. If it has matched 1 or more input characters, then we advance to the next token, but stay on the same input character. The old code had several issues with this. I replaced it with a simple flag (multipleMatched) that is set to true whenever a token with multiple==true matches an input character, and can then be tested when a token with multiple==true doesn't match an input character. --- src/mask.ts | 10 ++++++---- test/mask.test.ts | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/mask.ts b/src/mask.ts index 49e1a82..627dd16 100644 --- a/src/mask.ts +++ b/src/mask.ts @@ -142,6 +142,7 @@ export class Mask { let repeatedPos = -1 let m = this.isReversed() ? mask.length - 1 : 0 let v = this.isReversed() ? value.length - 1 : 0 + let multipleMatched = false while (check()) { const maskChar = mask.charAt(m) @@ -166,18 +167,19 @@ export class Mask { m -= offset } } else if (token.multiple as boolean) { + multipleMatched = true m -= offset } m += offset } else if (token.multiple as boolean) { - const hasValue = result[v - offset]?.match(token.pattern) != null - const nextMask = mask.charAt(m + offset) - if (hasValue && nextMask !== '' && tokens[nextMask] == null) { + if (multipleMatched) { m += offset v -= offset + + multipleMatched = false } else { - result[method]('') + // invalid input } } else if (valueChar === lastRawMaskChar) { // matched the last untranslated (raw) mask character that we encountered diff --git a/test/mask.test.ts b/test/mask.test.ts index 9a4de18..6950b83 100644 --- a/test/mask.test.ts +++ b/test/mask.test.ts @@ -685,19 +685,19 @@ test('multiple numbers mask', () => { expect(mask.masked('1')).toBe('1') expect(mask.masked('1 2')).toBe('1 2') - expect(mask.masked('1 2 3')).toBe('1 23') + expect(mask.masked('1 2 3')).toBe('1 2') expect(mask.masked('12')).toBe('12') expect(mask.masked('12 ')).toBe('12 ') expect(mask.masked('12 3')).toBe('12 3') expect(mask.masked('12 34')).toBe('12 34') expect(mask.masked('12 34 ')).toBe('12 34') - expect(mask.masked('12 34 5')).toBe('12 345') - expect(mask.masked('a12 34 5')).toBe('12 345') - expect(mask.masked('12.34.5')).toBe('12 345') + expect(mask.masked('12 34 5')).toBe('12 34') + expect(mask.masked('a12 34 5')).toBe('12 34') + expect(mask.masked('12.34.5')).toBe('12 34') - expect(mask.unmasked('a1 2 3')).toBe('123') + expect(mask.unmasked('a1 2 3')).toBe('12') expect(mask.unmasked('12 3')).toBe('123') - expect(mask.unmasked('12 34 5')).toBe('12345') + expect(mask.unmasked('12 34 5')).toBe('1234') }) test('multiple letters mask', () => { @@ -714,13 +714,13 @@ test('multiple letters mask', () => { expect(mask.masked('ab c')).toBe('ab c') expect(mask.masked('ab cd')).toBe('ab cd') expect(mask.masked('ab cd ')).toBe('ab cd') - expect(mask.masked('ab cd e')).toBe('ab cde') - expect(mask.masked('1ab cd e')).toBe('ab cde') - expect(mask.masked('ab.cd.e')).toBe('ab cde') + expect(mask.masked('ab cd e')).toBe('ab cd') + expect(mask.masked('1ab cd e')).toBe('ab cd') + expect(mask.masked('ab.cd.e')).toBe('ab cd') - expect(mask.unmasked('1a b c')).toBe('abc') + expect(mask.unmasked('1a b c')).toBe('ab') expect(mask.unmasked('ab c')).toBe('abc') - expect(mask.unmasked('ab cd e')).toBe('abcde') + expect(mask.unmasked('ab cd e')).toBe('abcd') }) test('dynamic empty mask', () => {