diff --git a/src/cdk/a11y/live-announcer.spec.ts b/src/cdk/a11y/live-announcer.spec.ts index c871ba53a85..e88c30ebe7a 100644 --- a/src/cdk/a11y/live-announcer.spec.ts +++ b/src/cdk/a11y/live-announcer.spec.ts @@ -23,9 +23,9 @@ describe('LiveAnnouncer', () => { }))); afterEach(() => { - // In our tests we always remove the current live element, because otherwise we would have - // multiple live elements due multiple service instantiations. - announcer._removeLiveElement(); + // In our tests we always remove the current live element, in + // order to avoid having multiple announcer elements in the DOM. + announcer.ngOnDestroy(); }); it('should correctly update the announce text', fakeAsync(() => { @@ -58,13 +58,14 @@ describe('LiveAnnouncer', () => { expect(ariaLiveElement.getAttribute('aria-live')).toBe('polite'); })); - it('should remove the aria-live element from the DOM', fakeAsync(() => { + it('should remove the aria-live element from the DOM on destroy', fakeAsync(() => { announcer.announce('Hey Google'); // This flushes our 100ms timeout for the screenreaders. tick(100); - announcer._removeLiveElement(); + // Call the lifecycle hook manually since Angular won't do it in tests. + announcer.ngOnDestroy(); expect(document.body.querySelector('[aria-live]')) .toBeFalsy('Expected that the aria-live element was remove from the DOM.'); @@ -85,10 +86,9 @@ describe('LiveAnnouncer', () => { }); beforeEach(inject([LiveAnnouncer], (la: LiveAnnouncer) => { - announcer = la; - ariaLiveElement = getLiveElement(); - })); - + announcer = la; + ariaLiveElement = getLiveElement(); + })); it('should allow to use a custom live element', fakeAsync(() => { announcer.announce('Custom Element'); diff --git a/src/cdk/a11y/live-announcer.ts b/src/cdk/a11y/live-announcer.ts index a827c47238b..48d6d3b06e2 100644 --- a/src/cdk/a11y/live-announcer.ts +++ b/src/cdk/a11y/live-announcer.ts @@ -12,6 +12,7 @@ import { Optional, Inject, SkipSelf, + OnDestroy, } from '@angular/core'; import {Platform} from '../platform/platform'; @@ -22,8 +23,7 @@ export const LIVE_ANNOUNCER_ELEMENT_TOKEN = new InjectionToken('liv export type AriaLivePoliteness = 'off' | 'polite' | 'assertive'; @Injectable() -export class LiveAnnouncer { - +export class LiveAnnouncer implements OnDestroy { private _liveElement: Element; constructor( @@ -57,8 +57,7 @@ export class LiveAnnouncer { setTimeout(() => this._liveElement.textContent = message, 100); } - /** Removes the aria-live element from the DOM. */ - _removeLiveElement() { + ngOnDestroy() { if (this._liveElement && this._liveElement.parentNode) { this._liveElement.parentNode.removeChild(this._liveElement); } diff --git a/src/lib/snack-bar/snack-bar.spec.ts b/src/lib/snack-bar/snack-bar.spec.ts index 882a82191ab..ff3232a5ca0 100644 --- a/src/lib/snack-bar/snack-bar.spec.ts +++ b/src/lib/snack-bar/snack-bar.spec.ts @@ -47,7 +47,7 @@ describe('MdSnackBar', () => { afterEach(() => { overlayContainerElement.innerHTML = ''; - liveAnnouncer._removeLiveElement(); + liveAnnouncer.ngOnDestroy(); }); beforeEach(() => { @@ -396,7 +396,7 @@ describe('MdSnackBar with parent MdSnackBar', () => { afterEach(() => { overlayContainerElement.innerHTML = ''; - liveAnnouncer._removeLiveElement(); + liveAnnouncer.ngOnDestroy(); }); it('should close snackBars opened by parent when opening from child MdSnackBar', fakeAsync(() => {