Skip to content

fix(viewport-ruler): server-side rendering errors when attempting to measure the viewport #9870

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/cdk/scrolling/viewport-ruler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export class ViewportRuler implements OnDestroy {
/** Subscription to streams that invalidate the cached viewport dimensions. */
private _invalidateCache: Subscription;

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

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

return {width: this._viewportSize.width, height: this._viewportSize.height};
const output = {width: this._viewportSize.width, height: this._viewportSize.height};

// If we're not on a browser, don't cache the size since it'll be mocked out anyway.
if (!this._platform.isBrowser) {
this._viewportSize = null!;
}

return output;
}

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

/** Gets the (top, left) scroll position of the viewport. */
getViewportScrollPosition() {
// While we can get a reference to the fake document
// during SSR, it doesn't have getBoundingClientRect.
if (!this._platform.isBrowser) {
return {top: 0, left: 0};
}

// The top-left-corner of the viewport is determined by the scroll position of the document
// body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about
// whether `document.body` or `document.documentElement` is the scrolled element, so reading
Expand Down Expand Up @@ -107,7 +120,9 @@ export class ViewportRuler implements OnDestroy {

/** Updates the cached viewport size. */
private _updateViewportSize() {
this._viewportSize = {width: window.innerWidth, height: window.innerHeight};
this._viewportSize = this._platform.isBrowser ?
{width: window.innerWidth, height: window.innerHeight} :
{width: 0, height: 0};
}
}

Expand Down
17 changes: 10 additions & 7 deletions src/universal-app/kitchen-sink/kitchen-sink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ import {
CdkTableModule,
DataSource
} from '@angular/cdk/table';
import {Overlay} from '@angular/cdk/overlay';

import {ViewportRuler} from '@angular/cdk/scrolling';
import {of as observableOf} from 'rxjs/observable/of';
import {Observable} from 'rxjs/Observable';

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

constructor(snackBar: MatSnackBar, dialog: MatDialog, overlay: Overlay) {
// Open a snack bar to do a basic sanity check of the overlays.
constructor(
snackBar: MatSnackBar,
dialog: MatDialog,
viewportRuler: ViewportRuler) {
snackBar.open('Hello there');
dialog.open(TestDialog);

// TODO(crisbeto): use the noop scroll strategy until
// the fixes for the block scroll strategy get in.
dialog.open(TestDialog, {scrollStrategy: overlay.scrollStrategies.noop()});
// Do a sanity check on the viewport ruler.
viewportRuler.getViewportRect();
viewportRuler.getViewportSize();
viewportRuler.getViewportScrollPosition();
}
}

Expand Down