fix(expansion-panel): don't handle enter/space if modifier is pressed (#13790)

Doesn't `preventDefault` and handle the enter and space key presses if the user is pressing any of the modifier keys.

Fixes #13783.
This commit is contained in:
Kristiyan Kostadinov
2018-10-25 17:15:35 +02:00
committed by mmalerba
parent 5d54920e81
commit 04716b1ad0
3 changed files with 30 additions and 6 deletions
+6 -3
View File
@@ -56,11 +56,14 @@ export function createTouchEvent(type: string, pageX = 0, pageY = 0) {
/** Dispatches a keydown event from an element. */
export function createKeyboardEvent(type: string, keyCode: number, target?: Element, key?: string) {
let event = document.createEvent('KeyboardEvent') as any;
// Firefox does not support `initKeyboardEvent`, but supports `initKeyEvent`.
let initEventFn = (event.initKeyEvent || event.initKeyboardEvent).bind(event);
let originalPreventDefault = event.preventDefault;
initEventFn(type, true, true, window, 0, 0, 0, 0, 0, keyCode);
// Firefox does not support `initKeyboardEvent`, but supports `initKeyEvent`.
if (event.initKeyEvent) {
event.initKeyEvent(type, true, true, window, 0, 0, 0, 0, 0, keyCode);
} else {
event.initKeyboardEvent(type, true, true, window, 0, key, 0, '', false);
}
// Webkit Browsers don't set the keyCode when calling the init function.
// See related bug https://bugs.webkit.org/show_bug.cgi?id=16735
+5 -2
View File
@@ -140,8 +140,11 @@ export class MatExpansionPanelHeader implements OnDestroy, FocusableOption {
// Toggle for space and enter keys.
case SPACE:
case ENTER:
event.preventDefault();
this._toggle();
if (!event.altKey && !event.metaKey && !event.shiftKey && !event.ctrlKey) {
event.preventDefault();
this._toggle();
}
break;
default:
if (this.panel.accordion) {
+19 -1
View File
@@ -4,7 +4,7 @@ import {By} from '@angular/platform-browser';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MatExpansionModule, MatExpansionPanel} from './index';
import {SPACE, ENTER} from '@angular/cdk/keycodes';
import {dispatchKeyboardEvent} from '@angular/cdk/testing';
import {dispatchKeyboardEvent, createKeyboardEvent, dispatchEvent} from '@angular/cdk/testing';
describe('MatExpansionPanel', () => {
@@ -139,6 +139,24 @@ describe('MatExpansionPanel', () => {
expect(event.defaultPrevented).toBe(true);
});
it('should not toggle if a modifier key is pressed', () => {
const fixture = TestBed.createComponent(PanelWithContent);
const headerEl = fixture.nativeElement.querySelector('.mat-expansion-panel-header');
spyOn(fixture.componentInstance.panel, 'toggle');
['altKey', 'metaKey', 'shiftKey', 'ctrlKey'].forEach(modifier => {
const event = createKeyboardEvent('keydown', ENTER);
Object.defineProperty(event, modifier, {get: () => true});
dispatchEvent(headerEl, event);
fixture.detectChanges();
expect(fixture.componentInstance.panel.toggle).not.toHaveBeenCalled();
expect(event.defaultPrevented).toBe(false);
});
});
it('should not be able to focus content while closed', fakeAsync(() => {
const fixture = TestBed.createComponent(PanelWithContent);
fixture.componentInstance.expanded = true;