Skip to content

Commit

Permalink
fix(aria-describer): clear duplicate container coming in from the ser…
Browse files Browse the repository at this point in the history
…ver (#11900)
  • Loading branch information
crisbeto authored and josephperrott committed Jun 26, 2018
1 parent ab14539 commit 31c8f6b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
11 changes: 11 additions & 0 deletions src/cdk/a11y/aria-describer/aria-describer.spec.ts
Expand Up @@ -121,6 +121,17 @@ describe('AriaDescriber', () => {
const node: any = document.createComment('Not an element node');
expect(() => ariaDescriber.describe(node, 'This looks like an element')).not.toThrow();
});

it('should clear any pre-existing containers', () => {
const extraContainer = document.createElement('div');
extraContainer.id = MESSAGES_CONTAINER_ID;
document.body.appendChild(extraContainer);

ariaDescriber.describe(component.element1, 'Hello');

// Use `querySelectorAll` with an attribute since `getElementById` will stop at the first match.
expect(document.querySelectorAll(`[id='${MESSAGES_CONTAINER_ID}']`).length).toBe(1);
});
});

function getMessagesContainer() {
Expand Down
24 changes: 18 additions & 6 deletions src/cdk/a11y/aria-describer/aria-describer.ts
Expand Up @@ -127,7 +127,7 @@ export class AriaDescriber implements OnDestroy {
messageElement.setAttribute('id', `${CDK_DESCRIBEDBY_ID_PREFIX}-${nextId++}`);
messageElement.appendChild(this._document.createTextNode(message)!);

if (!messagesContainer) { this._createMessagesContainer(); }
this._createMessagesContainer();
messagesContainer!.appendChild(messageElement);

messageRegistry.set(message, {messageElement, referenceCount: 0});
Expand All @@ -145,11 +145,23 @@ export class AriaDescriber implements OnDestroy {

/** Creates the global container for all aria-describedby messages. */
private _createMessagesContainer() {
messagesContainer = this._document.createElement('div');
messagesContainer.setAttribute('id', MESSAGES_CONTAINER_ID);
messagesContainer.setAttribute('aria-hidden', 'true');
messagesContainer.style.display = 'none';
this._document.body.appendChild(messagesContainer);
if (!messagesContainer) {
const preExistingContainer = this._document.getElementById(MESSAGES_CONTAINER_ID);

// When going from the server to the client, we may end up in a situation where there's
// already a container on the page, but we don't have a reference to it. Clear the
// old container so we don't get duplicates. Doing this, instead of emptying the previous
// container, should be slightly faster.
if (preExistingContainer) {
preExistingContainer.parentNode!.removeChild(preExistingContainer);
}

messagesContainer = this._document.createElement('div');
messagesContainer.id = MESSAGES_CONTAINER_ID;
messagesContainer.setAttribute('aria-hidden', 'true');
messagesContainer.style.display = 'none';
this._document.body.appendChild(messagesContainer);
}
}

/** Deletes the global messages container. */
Expand Down

0 comments on commit 31c8f6b

Please sign in to comment.