Skip to content

Commit 8f85a26

Browse files
committed
fix(menu,toolbar): avoid potential server-side rendering errors
Avoids a couple of potential server-side rendering errors due to the menu item and toolbar components referring to the `Node` global variable directly.
1 parent 60b0625 commit 8f85a26

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

src/lib/menu/menu-item.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
ElementRef,
1414
OnDestroy,
1515
ViewEncapsulation,
16+
Inject,
1617
} from '@angular/core';
1718
import {
1819
CanDisable,
@@ -21,6 +22,7 @@ import {
2122
mixinDisableRipple
2223
} from '@angular/material/core';
2324
import {Subject} from 'rxjs/Subject';
25+
import {DOCUMENT} from '@angular/common';
2426

2527
// Boilerplate for applying mixins to MatMenuItem.
2628
/** @docs-private */
@@ -55,6 +57,8 @@ export const _MatMenuItemMixinBase = mixinDisableRipple(mixinDisabled(MatMenuIte
5557
export class MatMenuItem extends _MatMenuItemMixinBase
5658
implements FocusableOption, CanDisable, CanDisableRipple, OnDestroy {
5759

60+
private _document: Document;
61+
5862
/** Stream that emits when the menu item is hovered. */
5963
_hovered: Subject<MatMenuItem> = new Subject();
6064

@@ -64,8 +68,11 @@ export class MatMenuItem extends _MatMenuItemMixinBase
6468
/** Whether the menu item acts as a trigger for a sub-menu. */
6569
_triggersSubmenu: boolean = false;
6670

67-
constructor(private _elementRef: ElementRef) {
71+
constructor(private _elementRef: ElementRef, @Inject(DOCUMENT) document?: any) {
6872
super();
73+
74+
// TODO: make the document a required param when doing breaking changes.
75+
this._document = document;
6976
}
7077

7178
/** Focuses the menu item. */
@@ -105,6 +112,7 @@ export class MatMenuItem extends _MatMenuItemMixinBase
105112
/** Gets the label to be used when determining whether the option should be focused. */
106113
getLabel(): string {
107114
const element: HTMLElement = this._elementRef.nativeElement;
115+
const textNodeType = this._document ? this._document.TEXT_NODE : 3;
108116
let output = '';
109117

110118
if (element.childNodes) {
@@ -114,7 +122,7 @@ export class MatMenuItem extends _MatMenuItemMixinBase
114122
// We skip anything that's not a text node to prevent the text from
115123
// being thrown off by something like an icon.
116124
for (let i = 0; i < length; i++) {
117-
if (element.childNodes[i].nodeType === Node.TEXT_NODE) {
125+
if (element.childNodes[i].nodeType === textNodeType) {
118126
output += element.childNodes[i].textContent;
119127
}
120128
}

src/lib/toolbar/toolbar.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ import {
1515
ElementRef,
1616
isDevMode,
1717
QueryList,
18-
ViewEncapsulation
18+
ViewEncapsulation,
19+
Inject,
1920
} from '@angular/core';
2021
import {CanColor, mixinColor} from '@angular/material/core';
2122
import {Platform} from '@angular/cdk/platform';
23+
import {DOCUMENT} from '@angular/common';
2224

2325
// Boilerplate for applying mixins to MatToolbar.
2426
/** @docs-private */
@@ -51,12 +53,19 @@ export class MatToolbarRow {}
5153
preserveWhitespaces: false,
5254
})
5355
export class MatToolbar extends _MatToolbarMixinBase implements CanColor, AfterViewInit {
56+
private _document: Document;
5457

5558
/** Reference to all toolbar row elements that have been projected. */
5659
@ContentChildren(MatToolbarRow) _toolbarRows: QueryList<MatToolbarRow>;
5760

58-
constructor(elementRef: ElementRef, private _platform: Platform) {
61+
constructor(
62+
elementRef: ElementRef,
63+
private _platform: Platform,
64+
@Inject(DOCUMENT) document?: any) {
5965
super(elementRef);
66+
67+
// TODO: make the document a required param when doing breaking changes.
68+
this._document = document;
6069
}
6170

6271
ngAfterViewInit() {
@@ -80,7 +89,7 @@ export class MatToolbar extends _MatToolbarMixinBase implements CanColor, AfterV
8089
// a <mat-toolbar-row> element.
8190
const isCombinedUsage = [].slice.call(this._elementRef.nativeElement.childNodes)
8291
.filter(node => !(node.classList && node.classList.contains('mat-toolbar-row')))
83-
.filter(node => node.nodeType !== Node.COMMENT_NODE)
92+
.filter(node => node.nodeType !== (this._document ? this._document.COMMENT_NODE : 8))
8493
.some(node => node.textContent.trim());
8594

8695
if (isCombinedUsage) {

0 commit comments

Comments
 (0)