Skip to content

Commit 10e26a5

Browse files
crisbetojelbourn
authored andcommitted
fix(viewport-ruler): fix server-side rendering errors when attempting to measure the viewport (#9870)
Fixes some errors being thrown by the `ViewportRuler` when attempting to measure the viewport or to get the scroll position while rendering on the server. Relates to #9066.
1 parent 87bbfc5 commit 10e26a5

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

src/cdk/scrolling/viewport-ruler.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ export class ViewportRuler implements OnDestroy {
3333
/** Subscription to streams that invalidate the cached viewport dimensions. */
3434
private _invalidateCache: Subscription;
3535

36-
constructor(platform: Platform, ngZone: NgZone) {
37-
this._change = platform.isBrowser ? ngZone.runOutsideAngular(() => {
36+
constructor(private _platform: Platform, ngZone: NgZone) {
37+
this._change = _platform.isBrowser ? ngZone.runOutsideAngular(() => {
3838
return merge<Event>(fromEvent(window, 'resize'), fromEvent(window, 'orientationchange'));
3939
}) : observableOf();
4040

@@ -51,7 +51,14 @@ export class ViewportRuler implements OnDestroy {
5151
this._updateViewportSize();
5252
}
5353

54-
return {width: this._viewportSize.width, height: this._viewportSize.height};
54+
const output = {width: this._viewportSize.width, height: this._viewportSize.height};
55+
56+
// If we're not on a browser, don't cache the size since it'll be mocked out anyway.
57+
if (!this._platform.isBrowser) {
58+
this._viewportSize = null!;
59+
}
60+
61+
return output;
5562
}
5663

5764
/** Gets a ClientRect for the viewport's bounds. */
@@ -80,6 +87,12 @@ export class ViewportRuler implements OnDestroy {
8087

8188
/** Gets the (top, left) scroll position of the viewport. */
8289
getViewportScrollPosition() {
90+
// While we can get a reference to the fake document
91+
// during SSR, it doesn't have getBoundingClientRect.
92+
if (!this._platform.isBrowser) {
93+
return {top: 0, left: 0};
94+
}
95+
8396
// The top-left-corner of the viewport is determined by the scroll position of the document
8497
// body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about
8598
// whether `document.body` or `document.documentElement` is the scrolled element, so reading
@@ -107,7 +120,9 @@ export class ViewportRuler implements OnDestroy {
107120

108121
/** Updates the cached viewport size. */
109122
private _updateViewportSize() {
110-
this._viewportSize = {width: window.innerWidth, height: window.innerHeight};
123+
this._viewportSize = this._platform.isBrowser ?
124+
{width: window.innerWidth, height: window.innerHeight} :
125+
{width: 0, height: 0};
111126
}
112127
}
113128

src/universal-app/kitchen-sink/kitchen-sink.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ import {
4242
CdkTableModule,
4343
DataSource
4444
} from '@angular/cdk/table';
45-
import {Overlay} from '@angular/cdk/overlay';
46-
45+
import {ViewportRuler} from '@angular/cdk/scrolling';
4746
import {of as observableOf} from 'rxjs/observable/of';
4847
import {Observable} from 'rxjs/Observable';
4948

@@ -75,13 +74,17 @@ export class KitchenSink {
7574
/** Data source for the CDK and Material table. */
7675
tableDataSource = new TableDataSource();
7776

78-
constructor(snackBar: MatSnackBar, dialog: MatDialog, overlay: Overlay) {
79-
// Open a snack bar to do a basic sanity check of the overlays.
77+
constructor(
78+
snackBar: MatSnackBar,
79+
dialog: MatDialog,
80+
viewportRuler: ViewportRuler) {
8081
snackBar.open('Hello there');
82+
dialog.open(TestDialog);
8183

82-
// TODO(crisbeto): use the noop scroll strategy until
83-
// the fixes for the block scroll strategy get in.
84-
dialog.open(TestDialog, {scrollStrategy: overlay.scrollStrategies.noop()});
84+
// Do a sanity check on the viewport ruler.
85+
viewportRuler.getViewportRect();
86+
viewportRuler.getViewportSize();
87+
viewportRuler.getViewportScrollPosition();
8588
}
8689
}
8790

0 commit comments

Comments
 (0)