Skip to content

Commit 6bf2741

Browse files
crisbetommalerba
authored andcommitted
refactor(live-announcer): expose promise when announcing a message (#9812)
Since there's a timeout when announcing something through the `LiveAnnouncer.announce` method, it may be hard/prone to race conditions for the consumer to coordinate it with some other action. These changes expose a promise that will be resolved once the message has been added to the DOM.
1 parent c36b512 commit 6bf2741

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ describe('LiveAnnouncer', () => {
7070
expect(document.body.querySelector('[aria-live]'))
7171
.toBeFalsy('Expected that the aria-live element was remove from the DOM.');
7272
}));
73+
74+
it('should return a promise that resolves after the text has been announced', fakeAsync(() => {
75+
const spy = jasmine.createSpy('announce spy');
76+
const promise = announcer.announce('something').then(spy);
77+
78+
expect(spy).not.toHaveBeenCalled();
79+
tick(100);
80+
expect(spy).toHaveBeenCalled();
81+
}));
7382
});
7483

7584
describe('with a custom element', () => {

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ export class LiveAnnouncer implements OnDestroy {
4040
* Announces a message to screenreaders.
4141
* @param message Message to be announced to the screenreader
4242
* @param politeness The politeness of the announcer element
43+
* @returns Promise that will be resolved when the message is added to the DOM.
4344
*/
44-
announce(message: string, politeness: AriaLivePoliteness = 'polite'): void {
45+
announce(message: string, politeness: AriaLivePoliteness = 'polite'): Promise<void> {
4546
this._liveElement.textContent = '';
4647

4748
// TODO: ensure changing the politeness works on all environments we support.
@@ -52,7 +53,12 @@ export class LiveAnnouncer implements OnDestroy {
5253
// - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a
5354
// second time without clearing and then using a non-zero delay.
5455
// (using JAWS 17 at time of this writing).
55-
setTimeout(() => this._liveElement.textContent = message, 100);
56+
return new Promise(resolve => {
57+
setTimeout(() => {
58+
this._liveElement.textContent = message;
59+
resolve();
60+
}, 100);
61+
});
5662
}
5763

5864
ngOnDestroy() {

0 commit comments

Comments
 (0)