Skip to content

Commit

Permalink
fix(live-announcer): remove announcer element on destroy (#5404)
Browse files Browse the repository at this point in the history
Implements the `ngOnDestroy` hook on the live announcer service and removes the `_removeLiveElement` method.
  • Loading branch information
crisbeto authored and mmalerba committed Jul 9, 2017
1 parent 44ca46a commit b7efe48
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 15 deletions.
18 changes: 9 additions & 9 deletions src/cdk/a11y/live-announcer.spec.ts
Expand Up @@ -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(() => {
Expand Down Expand Up @@ -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.');
Expand All @@ -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');
Expand Down
7 changes: 3 additions & 4 deletions src/cdk/a11y/live-announcer.ts
Expand Up @@ -12,6 +12,7 @@ import {
Optional,
Inject,
SkipSelf,
OnDestroy,
} from '@angular/core';
import {Platform} from '../platform/platform';

Expand All @@ -22,8 +23,7 @@ export const LIVE_ANNOUNCER_ELEMENT_TOKEN = new InjectionToken<HTMLElement>('liv
export type AriaLivePoliteness = 'off' | 'polite' | 'assertive';

@Injectable()
export class LiveAnnouncer {

export class LiveAnnouncer implements OnDestroy {
private _liveElement: Element;

constructor(
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/snack-bar/snack-bar.spec.ts
Expand Up @@ -47,7 +47,7 @@ describe('MdSnackBar', () => {

afterEach(() => {
overlayContainerElement.innerHTML = '';
liveAnnouncer._removeLiveElement();
liveAnnouncer.ngOnDestroy();
});

beforeEach(() => {
Expand Down Expand Up @@ -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(() => {
Expand Down

0 comments on commit b7efe48

Please sign in to comment.