Skip to content

Commit b7efe48

Browse files
crisbetommalerba
authored andcommitted
fix(live-announcer): remove announcer element on destroy (#5404)
Implements the `ngOnDestroy` hook on the live announcer service and removes the `_removeLiveElement` method.
1 parent 44ca46a commit b7efe48

File tree

3 files changed

+14
-15
lines changed

3 files changed

+14
-15
lines changed

src/cdk/a11y/live-announcer.spec.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ describe('LiveAnnouncer', () => {
2323
})));
2424

2525
afterEach(() => {
26-
// In our tests we always remove the current live element, because otherwise we would have
27-
// multiple live elements due multiple service instantiations.
28-
announcer._removeLiveElement();
26+
// In our tests we always remove the current live element, in
27+
// order to avoid having multiple announcer elements in the DOM.
28+
announcer.ngOnDestroy();
2929
});
3030

3131
it('should correctly update the announce text', fakeAsync(() => {
@@ -58,13 +58,14 @@ describe('LiveAnnouncer', () => {
5858
expect(ariaLiveElement.getAttribute('aria-live')).toBe('polite');
5959
}));
6060

61-
it('should remove the aria-live element from the DOM', fakeAsync(() => {
61+
it('should remove the aria-live element from the DOM on destroy', fakeAsync(() => {
6262
announcer.announce('Hey Google');
6363

6464
// This flushes our 100ms timeout for the screenreaders.
6565
tick(100);
6666

67-
announcer._removeLiveElement();
67+
// Call the lifecycle hook manually since Angular won't do it in tests.
68+
announcer.ngOnDestroy();
6869

6970
expect(document.body.querySelector('[aria-live]'))
7071
.toBeFalsy('Expected that the aria-live element was remove from the DOM.');
@@ -85,10 +86,9 @@ describe('LiveAnnouncer', () => {
8586
});
8687

8788
beforeEach(inject([LiveAnnouncer], (la: LiveAnnouncer) => {
88-
announcer = la;
89-
ariaLiveElement = getLiveElement();
90-
}));
91-
89+
announcer = la;
90+
ariaLiveElement = getLiveElement();
91+
}));
9292

9393
it('should allow to use a custom live element', fakeAsync(() => {
9494
announcer.announce('Custom Element');

src/cdk/a11y/live-announcer.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
Optional,
1313
Inject,
1414
SkipSelf,
15+
OnDestroy,
1516
} from '@angular/core';
1617
import {Platform} from '../platform/platform';
1718

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

2425
@Injectable()
25-
export class LiveAnnouncer {
26-
26+
export class LiveAnnouncer implements OnDestroy {
2727
private _liveElement: Element;
2828

2929
constructor(
@@ -57,8 +57,7 @@ export class LiveAnnouncer {
5757
setTimeout(() => this._liveElement.textContent = message, 100);
5858
}
5959

60-
/** Removes the aria-live element from the DOM. */
61-
_removeLiveElement() {
60+
ngOnDestroy() {
6261
if (this._liveElement && this._liveElement.parentNode) {
6362
this._liveElement.parentNode.removeChild(this._liveElement);
6463
}

src/lib/snack-bar/snack-bar.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe('MdSnackBar', () => {
4747

4848
afterEach(() => {
4949
overlayContainerElement.innerHTML = '';
50-
liveAnnouncer._removeLiveElement();
50+
liveAnnouncer.ngOnDestroy();
5151
});
5252

5353
beforeEach(() => {
@@ -396,7 +396,7 @@ describe('MdSnackBar with parent MdSnackBar', () => {
396396

397397
afterEach(() => {
398398
overlayContainerElement.innerHTML = '';
399-
liveAnnouncer._removeLiveElement();
399+
liveAnnouncer.ngOnDestroy();
400400
});
401401

402402
it('should close snackBars opened by parent when opening from child MdSnackBar', fakeAsync(() => {

0 commit comments

Comments
 (0)