From 063125b45d1c0d7f4135ab6f956c2c51cc407789 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 10 Aug 2018 13:07:49 +0200 Subject: [PATCH 1/2] fix(selection-list): do not allow toggling disabled options * Currently due to a misplaced `disabled` check in the selection list, users can toggle the state of a disabled `` by using the keyboard. Fixes #12608 --- src/lib/list/selection-list.spec.ts | 15 +++++++++++++++ src/lib/list/selection-list.ts | 17 +++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/lib/list/selection-list.spec.ts b/src/lib/list/selection-list.spec.ts index dcb2e8c452de..befea582cd9f 100644 --- a/src/lib/list/selection-list.spec.ts +++ b/src/lib/list/selection-list.spec.ts @@ -211,6 +211,21 @@ describe('MatSelectionList without forms', () => { expect(ENTER_EVENT.defaultPrevented).toBe(true); }); + it('should not be able to toggle a disabled option using SPACE', () => { + const testListItem = listOptions[1].nativeElement as HTMLElement; + const selectionModel = selectionList.componentInstance.selectedOptions; + + expect(selectionModel.selected.length).toBe(0); + + listOptions[1].componentInstance.disabled = true; + + dispatchFakeEvent(testListItem, 'focus'); + selectionList.componentInstance._keydown(createKeyboardEvent('keydown', SPACE, testListItem)); + fixture.detectChanges(); + + expect(selectionModel.selected.length).toBe(0); + }); + it('should restore focus if active option is destroyed', () => { const manager = selectionList.componentInstance._keyManager; diff --git a/src/lib/list/selection-list.ts b/src/lib/list/selection-list.ts index f2dc0862da31..043e4f8e5c44 100644 --- a/src/lib/list/selection-list.ts +++ b/src/lib/list/selection-list.ts @@ -410,12 +410,9 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu switch (keyCode) { case SPACE: case ENTER: - if (!this.disabled) { - this._toggleSelectOnFocusedOption(); - - // Always prevent space from scrolling the page since the list has focus - event.preventDefault(); - } + this._toggleFocusedOptionIfEnabled(); + // Always prevent space from scrolling the page since the list has focus + event.preventDefault(); break; case HOME: case END: @@ -434,7 +431,7 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu if ((keyCode === UP_ARROW || keyCode === DOWN_ARROW) && event.shiftKey && manager.activeItemIndex !== previousFocusIndex) { - this._toggleSelectOnFocusedOption(); + this._toggleFocusedOptionIfEnabled(); } } @@ -492,14 +489,14 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu return this.options.filter(option => option.selected).map(option => option.value); } - /** Toggles the selected state of the currently focused option. */ - private _toggleSelectOnFocusedOption(): void { + /** Toggles the state of the currently focused option if enabled. */ + private _toggleFocusedOptionIfEnabled(): void { let focusedIndex = this._keyManager.activeItemIndex; if (focusedIndex != null && this._isValidIndex(focusedIndex)) { let focusedOption: MatListOption = this.options.toArray()[focusedIndex]; - if (focusedOption) { + if (focusedOption && !focusedOption.disabled) { focusedOption.toggle(); // Emit a change event because the focused option changed its state through user From bf5ff8e5e4b1ac57c0f652895e98a0f8f41aaf8b Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 10 Aug 2018 14:29:20 +0200 Subject: [PATCH 2/2] Rename function --- src/lib/list/selection-list.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/list/selection-list.ts b/src/lib/list/selection-list.ts index 043e4f8e5c44..48dae829e50d 100644 --- a/src/lib/list/selection-list.ts +++ b/src/lib/list/selection-list.ts @@ -410,7 +410,7 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu switch (keyCode) { case SPACE: case ENTER: - this._toggleFocusedOptionIfEnabled(); + this._toggleFocusedOption(); // Always prevent space from scrolling the page since the list has focus event.preventDefault(); break; @@ -431,7 +431,7 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu if ((keyCode === UP_ARROW || keyCode === DOWN_ARROW) && event.shiftKey && manager.activeItemIndex !== previousFocusIndex) { - this._toggleFocusedOptionIfEnabled(); + this._toggleFocusedOption(); } } @@ -490,7 +490,7 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu } /** Toggles the state of the currently focused option if enabled. */ - private _toggleFocusedOptionIfEnabled(): void { + private _toggleFocusedOption(): void { let focusedIndex = this._keyManager.activeItemIndex; if (focusedIndex != null && this._isValidIndex(focusedIndex)) {