From ed763f5ef6c480224929f96f04fd336ac0910bf5 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 26 Feb 2020 16:13:04 +0100 Subject: [PATCH] fix(sidenav): not restoring focus to SVG elements (#18614) SVG nodes can be focusable, but they won't match `instanceof HTMLElement` so we never restore focus to them. (cherry picked from commit 99d3e1289a801e3390fd2fb380736c27aa52aa1a) --- src/material/sidenav/drawer.spec.ts | 31 +++++++++++++++++++++++++++++ src/material/sidenav/drawer.ts | 3 ++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/material/sidenav/drawer.spec.ts b/src/material/sidenav/drawer.spec.ts index 8d6e83ecb5a4..0fbd846b3789 100644 --- a/src/material/sidenav/drawer.spec.ts +++ b/src/material/sidenav/drawer.spec.ts @@ -307,6 +307,28 @@ describe('MatDrawer', () => { .toBe(openButton, 'Expected focus to be restored to the open button on close.'); })); + it('should restore focus to an SVG element', fakeAsync(() => { + const fixture = TestBed.createComponent(BasicTestApp); + fixture.detectChanges(); + + const drawer = fixture.debugElement.query(By.directive(MatDrawer))!.componentInstance; + const svg = fixture.componentInstance.svg.nativeElement; + const drawerButton = fixture.componentInstance.drawerButton.nativeElement; + + svg.focus(); + drawer.open(); + fixture.detectChanges(); + flush(); + drawerButton.focus(); + + drawer.close(); + fixture.detectChanges(); + flush(); + + expect(document.activeElement) + .toBe(svg, 'Expected focus to be restored to the SVG element on close.'); + })); + it('should not restore focus on close if focus is outside drawer', fakeAsync(() => { let fixture = TestBed.createComponent(BasicTestApp); let drawer: MatDrawer = fixture.debugElement @@ -907,6 +929,14 @@ class DrawerContainerTwoDrawerTestApp { + + + `, }) class BasicTestApp { @@ -920,6 +950,7 @@ class BasicTestApp { @ViewChild('drawer') drawer: MatDrawer; @ViewChild('drawerButton') drawerButton: ElementRef; @ViewChild('openButton') openButton: ElementRef; + @ViewChild('svg') svg: ElementRef; @ViewChild('closeButton') closeButton: ElementRef; open() { diff --git a/src/material/sidenav/drawer.ts b/src/material/sidenav/drawer.ts index 934483a101ab..d4fe9f880624 100644 --- a/src/material/sidenav/drawer.ts +++ b/src/material/sidenav/drawer.ts @@ -350,7 +350,8 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr const activeEl = this._doc && this._doc.activeElement; if (activeEl && this._elementRef.nativeElement.contains(activeEl)) { - if (this._elementFocusedBeforeDrawerWasOpened instanceof HTMLElement) { + // Note that we don't check via `instanceof HTMLElement` so that we can cover SVGs as well. + if (this._elementFocusedBeforeDrawerWasOpened) { this._focusMonitor.focusVia(this._elementFocusedBeforeDrawerWasOpened, this._openedVia); } else { this._elementRef.nativeElement.blur();