From c09aa52ffc007140e72ce144336174489781e068 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 1 Jun 2021 20:49:12 +0200 Subject: [PATCH] fix(material/autocomplete): don't handle enter events with modifier keys Doesn't handle `ENTER` key presses and doesn't prevent their default action, if they have a modifier, in order to avoid intefering with any OS-level shortcuts. --- .../mdc-autocomplete/autocomplete.spec.ts | 20 +++++++++++++++++++ .../autocomplete/autocomplete-trigger.ts | 2 +- .../autocomplete/autocomplete.spec.ts | 20 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/material-experimental/mdc-autocomplete/autocomplete.spec.ts b/src/material-experimental/mdc-autocomplete/autocomplete.spec.ts index 73e3db5957fd..8b703f1630b5 100644 --- a/src/material-experimental/mdc-autocomplete/autocomplete.spec.ts +++ b/src/material-experimental/mdc-autocomplete/autocomplete.spec.ts @@ -1005,6 +1005,26 @@ describe('MDC-based MatAutocomplete', () => { expect(ENTER_EVENT.defaultPrevented).toBe(false, 'Default action should not be prevented.'); }); + it('should not interfere with the ENTER key when pressing a modifier', fakeAsync(() => { + const trigger = fixture.componentInstance.trigger; + + expect(input.value).toBeFalsy('Expected input to start off blank.'); + expect(trigger.panelOpen).toBe(true, 'Expected panel to start off open.'); + + fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT); + flush(); + fixture.detectChanges(); + + Object.defineProperty(ENTER_EVENT, 'altKey', {get: () => true}); + fixture.componentInstance.trigger._handleKeydown(ENTER_EVENT); + fixture.detectChanges(); + + expect(trigger.panelOpen).toBe(true, 'Expected panel to remain open.'); + expect(input.value).toBeFalsy('Expected input to remain blank.'); + expect(ENTER_EVENT.defaultPrevented) + .toBe(false, 'Expected the default ENTER action not to have been prevented.'); + })); + it('should fill the text field, not select an option, when SPACE is entered', () => { typeInElement(input, 'New'); fixture.detectChanges(); diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts index 165c24055fc9..e7fd3a1662d8 100644 --- a/src/material/autocomplete/autocomplete-trigger.ts +++ b/src/material/autocomplete/autocomplete-trigger.ts @@ -378,7 +378,7 @@ export abstract class _MatAutocompleteTriggerBase implements ControlValueAccesso event.preventDefault(); } - if (this.activeOption && keyCode === ENTER && this.panelOpen) { + if (this.activeOption && keyCode === ENTER && this.panelOpen && !hasModifierKey(event)) { this.activeOption._selectViaInteraction(); this._resetActiveItem(); event.preventDefault(); diff --git a/src/material/autocomplete/autocomplete.spec.ts b/src/material/autocomplete/autocomplete.spec.ts index 7e7b05b838e5..ea6eaca04094 100644 --- a/src/material/autocomplete/autocomplete.spec.ts +++ b/src/material/autocomplete/autocomplete.spec.ts @@ -1000,6 +1000,26 @@ describe('MatAutocomplete', () => { expect(ENTER_EVENT.defaultPrevented).toBe(false, 'Default action should not be prevented.'); }); + it('should not interfere with the ENTER key when pressing a modifier', fakeAsync(() => { + const trigger = fixture.componentInstance.trigger; + + expect(input.value).toBeFalsy('Expected input to start off blank.'); + expect(trigger.panelOpen).toBe(true, 'Expected panel to start off open.'); + + fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT); + flush(); + fixture.detectChanges(); + + Object.defineProperty(ENTER_EVENT, 'altKey', {get: () => true}); + fixture.componentInstance.trigger._handleKeydown(ENTER_EVENT); + fixture.detectChanges(); + + expect(trigger.panelOpen).toBe(true, 'Expected panel to remain open.'); + expect(input.value).toBeFalsy('Expected input to remain blank.'); + expect(ENTER_EVENT.defaultPrevented) + .toBe(false, 'Expected the default ENTER action not to have been prevented.'); + })); + it('should fill the text field, not select an option, when SPACE is entered', () => { typeInElement(input, 'New'); fixture.detectChanges();