From c693df89481731754337b82385bf1e1ec48fd69f Mon Sep 17 00:00:00 2001 From: Andrii Kamaldinov <129040945+andriikamaldinov1@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:46:13 +0300 Subject: [PATCH] fix(ref: no-ref): fix issue * fix(ref: no-ref): fix issue * fix(ref: no-ref): fix issue * fix(ref: no-ref): fix issue * fix(ref: no-ref): fix issue * fix(ref: no-ref): fix comment * fix(ref: no-ref): fix naming * fix(ref: no-ref): fix naming --- .github/hooks/pre-commit | 1 - CHANGELOG.md | 10 +++ package.json | 2 +- projects/ngx-mask-lib/package.json | 2 +- .../src/lib/ngx-mask-applier.service.ts | 13 +++ .../src/lib/ngx-mask.directive.ts | 18 +++-- .../ngx-mask-lib/src/test/basic-logic.spec.ts | 80 +++++++++++++++++++ .../ngx-mask-lib/src/test/cursor.cy-spec.ts | 48 +++++++++++ .../ngx-mask-lib/src/test/delete.cy-spec.ts | 2 +- .../ngx-mask-lib/src/test/dynamic.spec.ts | 15 ++++ 10 files changed, 180 insertions(+), 11 deletions(-) diff --git a/.github/hooks/pre-commit b/.github/hooks/pre-commit index f68d8624..e4765c96 100755 --- a/.github/hooks/pre-commit +++ b/.github/hooks/pre-commit @@ -3,7 +3,6 @@ set -e bun lint-staged -bun lint # bun run snyk:test diff --git a/CHANGELOG.md b/CHANGELOG.md index 1de51cb4..e7bbd008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 17.1.0(2024-07-05) + +### Fix + +- Fix ([#1294](https://github.com/JsDaddy/ngx-mask/issues/1294)) +- Fix ([#1344](https://github.com/JsDaddy/ngx-mask/issues/1344)) +- Fix ([#1365](https://github.com/JsDaddy/ngx-mask/issues/1365)) + + + # 17.0.9(2024-07-02) ### Fix diff --git a/package.json b/package.json index d142a801..49012d0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ngx-mask", - "version": "17.0.9", + "version": "17.1.0", "description": "Awesome ngx mask", "license": "MIT", "engines": { diff --git a/projects/ngx-mask-lib/package.json b/projects/ngx-mask-lib/package.json index d38772ad..4c03ed6b 100644 --- a/projects/ngx-mask-lib/package.json +++ b/projects/ngx-mask-lib/package.json @@ -1,6 +1,6 @@ { "name": "ngx-mask", - "version": "17.0.9", + "version": "17.1.0", "description": "awesome ngx mask", "keywords": [ "ng2-mask", diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts b/projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts index 4cbdc5a2..10b4b628 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts @@ -724,6 +724,19 @@ export class NgxMaskApplierService { if (result.length === 0) { res = !this.dropSpecialCharacters ? `${this.prefix}${result}` : `${result}`; } + + const isSpecialCharacterMaskFirstSymbol = + inputValue.length === 1 && + this.specialCharacters.includes(maskExpression[0] as string) && + inputValue !== maskExpression[0]; + + if ( + !this._checkSymbolMask(inputValue, maskExpression[1] as string) && + isSpecialCharacterMaskFirstSymbol + ) { + return ''; + } + if (result.includes(MaskExpression.MINUS) && this.prefix && this.allowNegativeNumbers) { if (backspaced && result === MaskExpression.MINUS) { return ''; diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts b/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts index 279ca6dc..d62905e9 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts @@ -614,12 +614,13 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida } // update position after applyValueChanges to prevent cursor on wrong position when it has an array of maskExpression if (this._maskExpressionArray.length) { - if (this._code === MaskExpression.BACKSPACE) { - position = this.specialCharacters.includes( - this._inputValue.slice(position - 1, position) - ) - ? position - 1 - : position; + const isBackSpaceInSpecialCharactersPosition = + this._code === MaskExpression.BACKSPACE && + this.specialCharacters.includes( + el.value.slice(position, this._maskService.actualValue.length) + ); + if (isBackSpaceInSpecialCharactersPosition) { + position = position - 1; } else { position = el.selectionStart === 1 @@ -974,6 +975,7 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida typeof this.inputTransformFn !== 'function' ? (this._maskService.writingValue = true) : ''; + this._maskService.formElementProperty = [ 'value', this._maskService.applyMask(inputValue, this._maskService.maskExpression), @@ -1077,6 +1079,7 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida const specialChart: boolean = mask .split(MaskExpression.EMPTY_STRING) .some((char) => this._maskService.specialCharacters.includes(char)); + if ( (specialChart && this._inputValue && !mask.includes(MaskExpression.LETTER_S)) || mask.includes(MaskExpression.CURLY_BRACKETS_LEFT) @@ -1111,7 +1114,8 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida const indexMask = mask.charAt(index); return this._maskService._checkSymbolMask(character, indexMask); }); - if (check) { + + if (check || this._justPasted) { this._maskValue = this.maskExpression = this._maskService.maskExpression = mask; return check; } diff --git a/projects/ngx-mask-lib/src/test/basic-logic.spec.ts b/projects/ngx-mask-lib/src/test/basic-logic.spec.ts index 4281cc01..a588d932 100644 --- a/projects/ngx-mask-lib/src/test/basic-logic.spec.ts +++ b/projects/ngx-mask-lib/src/test/basic-logic.spec.ts @@ -816,4 +816,84 @@ describe('Directive: Mask', () => { equal('4', '4', fixture); expect(component.form.value).toBe('4'); }); + + it('should return empty string if first character not same in mask (000) 000-0000', () => { + component.mask = '(000) 000-0000'; + + equal('', '', fixture); + equal('@', '', fixture); + equal('!', '', fixture); + equal('$', '', fixture); + equal('#', '', fixture); + equal('.', '', fixture); + equal('-', '', fixture); + equal('/', '', fixture); + equal('[', '', fixture); + equal(']', '', fixture); + equal('=', '', fixture); + }); + + it('should return empty string if first character not same in mask (000) 000-0000 with prefix', () => { + component.mask = '(000) 000-0000'; + component.prefix = '+7'; + equal('', '', fixture); + equal('@', '', fixture); + equal('!', '', fixture); + equal('$', '', fixture); + equal('#', '', fixture); + equal('.', '', fixture); + equal('-', '', fixture); + equal('/', '', fixture); + equal('[', '', fixture); + equal(']', '', fixture); + equal('=', '', fixture); + }); + + it('should return empty string if first character not same in mask (000) 000-0000 with suffix', () => { + component.mask = '(000) 000-0000'; + component.prefix = '+7'; + equal('', '', fixture); + equal('@', '', fixture); + equal('!', '', fixture); + equal('$', '', fixture); + equal('#', '', fixture); + equal('.', '', fixture); + equal('-', '', fixture); + equal('/', '', fixture); + equal('[', '', fixture); + equal(']', '', fixture); + equal('=', '', fixture); + }); + + it('should return empty string if first character not same in mask (000) 000-0000||+000000000000000', () => { + component.mask = '(000) 000-0000||+000000000000000'; + + equal('', '', fixture); + equal('@', '', fixture); + equal('!', '', fixture); + equal('$', '', fixture); + equal('#', '', fixture); + equal('.', '', fixture); + equal('-', '', fixture); + equal('/', '', fixture); + equal('[', '', fixture); + equal(']', '', fixture); + equal('=', '', fixture); + }); + + it('should return empty string if first character not same in mask +(000) 000-0000', () => { + component.mask = '(000) 000-0000'; + component.prefix = '+7'; + equal('', '', fixture); + equal('@', '', fixture); + equal('!', '', fixture); + equal('$', '', fixture); + equal('#', '', fixture); + equal('.', '', fixture); + equal('-', '', fixture); + equal('/', '', fixture); + equal('[', '', fixture); + equal(']', '', fixture); + equal('=', '', fixture); + }); }); diff --git a/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts b/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts index f1cede80..a731ff7c 100644 --- a/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts +++ b/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts @@ -319,4 +319,52 @@ describe('Test Date Hh:m0', () => { .should('have.value', '123') .should('have.prop', 'selectionStart', 3); }); + + it('dynamic mask after backspace should have right cursor position (000) 000-0000||+000000000000000', () => { + cy.mount(CypressTestMaskComponent, { + componentProperties: { + mask: '(000) 000-0000||+000000000000000', + }, + imports: [CypressTestMaskModule], + }); + + cy.get('#masked') + .type('123 45678901') + + .should('have.value', '+1245678901') + .type('{backspace}') + .should('have.prop', 'selectionStart', 13); + }); + + it('dynamic mask after backspace should have right cursor position', () => { + cy.mount(CypressTestMaskComponent, { + componentProperties: { + mask: '(000) 000-0000||+000000000000000', + }, + imports: [CypressTestMaskModule], + }); + + cy.get('#masked') + .type('123 4') + + .should('have.value', '(123) 4') + .type('{backspace}'.repeat(2)) + .should('have.prop', 'selectionStart', 4); + }); + + it('dynamic mask after backspace should have right cursor position (00) 00000000||+00 (00) 00000000', () => { + cy.mount(CypressTestMaskComponent, { + componentProperties: { + mask: '(00) 00000000||+00 (00) 00000000', + }, + imports: [CypressTestMaskModule], + }); + + cy.get('#masked') + .type('123') + + .should('have.value', '(12) 3') + .type('{backspace}'.repeat(2)) + .should('have.prop', 'selectionStart', 3); + }); }); diff --git a/projects/ngx-mask-lib/src/test/delete.cy-spec.ts b/projects/ngx-mask-lib/src/test/delete.cy-spec.ts index ea800820..9c287289 100644 --- a/projects/ngx-mask-lib/src/test/delete.cy-spec.ts +++ b/projects/ngx-mask-lib/src/test/delete.cy-spec.ts @@ -114,7 +114,7 @@ describe('Directive: Mask (Delete)', () => { .type('123') .should('have.value', '(12) 3') .type('{backspace}') - .should('have.prop', 'selectionStart', 4) + .should('have.prop', 'selectionStart', 5) .should('have.value', '(12) ') .type('{rightArrow}') .type('{backspace}') diff --git a/projects/ngx-mask-lib/src/test/dynamic.spec.ts b/projects/ngx-mask-lib/src/test/dynamic.spec.ts index c8482b73..cd2623d5 100644 --- a/projects/ngx-mask-lib/src/test/dynamic.spec.ts +++ b/projects/ngx-mask-lib/src/test/dynamic.spec.ts @@ -268,4 +268,19 @@ describe('Directive: Mask (Dynamic)', () => { equal('123456789', '12345-6789', fixture); expect(component.form.valid).toBeTrue(); }); + + it('should work with when justPasted', () => { + component.mask = '00000||S0S 0S0'; + equal('1', '1', fixture); + equal('12', '12', fixture); + equal('123', '123', fixture); + equal('1234', '1234', fixture); + equal('12345', '12345', fixture); + equal('A', 'A', fixture); + equal('A5', 'A5', fixture); + equal('A5A', 'A5A', fixture); + equal('A5A 0', 'A5A 0', fixture); + equal('A5A 0A', 'A5A 0A', fixture); + equal('A5A 0A9', 'A5A 0A9', fixture); + }); });