Skip to content

Commit 4c7a4f3

Browse files
crisbetojelbourn
authored andcommitted
fix(aria-describer): exception when attempting to describe a non-element node (#9392)
* Fixes an error that was being thrown when trying to describe a non-element node. This could happen if the consumer is attempting to describe an `ng-container` which corresponds to a comment node. * Switches a few cases, that had hard-coded the `Node.ELEMENT_NODE` constant for to Universal compatibility, to take the constant from the `Document`. Relates to #8724.
1 parent 5136361 commit 4c7a4f3

File tree

4 files changed

+14
-13
lines changed

4 files changed

+14
-13
lines changed

src/cdk/a11y/aria-describer.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ describe('AriaDescriber', () => {
107107
expectMessages(['My Message']);
108108
expectMessage(component.element1, 'My Message');
109109
});
110+
111+
it('should not throw when attempting to describe a non-element node', () => {
112+
const node: any = document.createComment('Not an element node');
113+
expect(() => ariaDescriber.describe(node, 'This looks like an element')).not.toThrow();
114+
});
110115
});
111116

112117
function getMessagesContainer() {

src/cdk/a11y/aria-describer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class AriaDescriber {
6060
* message element.
6161
*/
6262
describe(hostElement: Element, message: string) {
63-
if (!message.trim()) {
63+
if (hostElement.nodeType !== this._document.ELEMENT_NODE || !message.trim()) {
6464
return;
6565
}
6666

@@ -75,7 +75,7 @@ export class AriaDescriber {
7575

7676
/** Removes the host element's aria-describedby reference to the message element. */
7777
removeDescription(hostElement: Element, message: string) {
78-
if (!message.trim()) {
78+
if (hostElement.nodeType !== this._document.ELEMENT_NODE || !message.trim()) {
7979
return;
8080
}
8181

src/cdk/a11y/focus-trap.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ import {take} from 'rxjs/operators/take';
2121
import {InteractivityChecker} from './interactivity-checker';
2222
import {DOCUMENT} from '@angular/common';
2323

24-
/**
25-
* Node type of element nodes. Used instead of Node.ELEMENT_NODE
26-
* which is unsupported in Universal.
27-
* @docs-private
28-
*/
29-
const ELEMENT_NODE_TYPE = 1;
3024

3125
/**
3226
* Class that allows for trapping focus within a DOM element.
@@ -229,7 +223,7 @@ export class FocusTrap {
229223
let children = root.children || root.childNodes;
230224

231225
for (let i = 0; i < children.length; i++) {
232-
let tabbableChild = children[i].nodeType === ELEMENT_NODE_TYPE ?
226+
let tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ?
233227
this._getFirstTabbableElement(children[i] as HTMLElement) :
234228
null;
235229

@@ -251,7 +245,7 @@ export class FocusTrap {
251245
let children = root.children || root.childNodes;
252246

253247
for (let i = children.length - 1; i >= 0; i--) {
254-
let tabbableChild = children[i].nodeType === ELEMENT_NODE_TYPE ?
248+
let tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ?
255249
this._getLastTabbableElement(children[i] as HTMLElement) :
256250
null;
257251

src/lib/icon/icon-registry.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class SvgIconConfig {
7878
*/
7979
@Injectable()
8080
export class MatIconRegistry {
81+
private _document: Document;
82+
8183
/**
8284
* URLs and cached SVG elements for individual icons. Keys are of the format "[namespace]:[icon]".
8385
*/
@@ -108,8 +110,9 @@ export class MatIconRegistry {
108110
constructor(
109111
@Optional() private _httpClient: HttpClient,
110112
private _sanitizer: DomSanitizer,
111-
@Optional() @Inject(DOCUMENT) private _document?: any) {
113+
@Optional() @Inject(DOCUMENT) document?: any) {
112114
// TODO(crisbeto): make _document required next major release.
115+
this._document = document;
113116
}
114117

115118
/**
@@ -438,8 +441,7 @@ export class MatIconRegistry {
438441
let svg = this._svgElementFromString('<svg></svg>');
439442

440443
for (let i = 0; i < element.childNodes.length; i++) {
441-
// Note: 1 corresponds to `Node.ELEMENT_NODE` which we can't use in Universal.
442-
if (element.childNodes[i].nodeType === 1) {
444+
if (element.childNodes[i].nodeType === this._document.ELEMENT_NODE) {
443445
svg.appendChild(element.childNodes[i].cloneNode(true));
444446
}
445447
}

0 commit comments

Comments
 (0)