Skip to content

Commit

Permalink
fix(dom): Fix a message only being announced once when the message ha…
Browse files Browse the repository at this point in the history
…s not changed.

PiperOrigin-RevId: 580617574
  • Loading branch information
material-web-copybara authored and copybara-github committed Nov 10, 2023
1 parent 9cec940 commit 386cd4a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
14 changes: 10 additions & 4 deletions packages/mdc-dom/announce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface AnnouncerMessageOptions {
* Data attribute added to live region element.
*/
export const DATA_MDC_DOM_ANNOUNCE = 'data-mdc-dom-announce';
const NBSP = String.fromCharCode(0xa0);

/**
* Announces the given message with optional priority, defaulting to "polite"
Expand Down Expand Up @@ -70,12 +71,17 @@ class Announcer {
const priority = options?.priority ?? AnnouncerPriority.POLITE;
const ownerDocument = options?.ownerDocument ?? document;
const liveRegion = this.getLiveRegion(priority, ownerDocument);
// Reset the region to pick up the message, even if the message is the
// exact same as before.
liveRegion.textContent = '';
// Tweak the message if it's identical to what was last announced, to
// ensure it is announced.
const lastMessageAnnounced = liveRegion.textContent;
const announceMessage =
lastMessageAnnounced && lastMessageAnnounced === message ?
message + NBSP :
message;

// Timeout is necessary for screen readers like NVDA and VoiceOver.
setTimeout(() => {
liveRegion.textContent = message;
liveRegion.textContent = announceMessage;
ownerDocument.addEventListener('click', clearLiveRegion);
}, 1);

Expand Down
9 changes: 9 additions & 0 deletions packages/mdc-dom/test/announce.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ describe('announce', () => {
expect(liveRegion!.textContent).toEqual('Baz');
});

it('appends an invisible space for a repeated message', () => {
announce('Baz');
jasmine.clock().tick(1);
announce('Baz');
jasmine.clock().tick(1);
const liveRegion = document.querySelector(LIVE_REGION_SELECTOR);
expect(liveRegion!.textContent).toEqual(`Baz${String.fromCharCode(0xa0)}`);
});

it('reuses same live region on successive calls per document', () => {
const secondDocument = document.implementation.createHTMLDocument('Title');
announce('aaa');
Expand Down

0 comments on commit 386cd4a

Please sign in to comment.