From acbf3c8ec0372bc41e7da5bfe3f0d8a7310a5aac Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 1 Feb 2018 20:26:14 +0100 Subject: [PATCH] fix(dialog): server-side rendering error when attempting to trap focus (#9698) Fixes an error that is being thrown when trying to open a dialog on the server. Also adds a dialog sanity check to the kitchen sink. Relates to #9066. --- src/lib/dialog/dialog-container.ts | 11 +++++++---- src/universal-app/kitchen-sink/kitchen-sink.ts | 18 ++++++++++++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/lib/dialog/dialog-container.ts b/src/lib/dialog/dialog-container.ts index 7129c41cbe3..2e371fdd2fb 100644 --- a/src/lib/dialog/dialog-container.ts +++ b/src/lib/dialog/dialog-container.ts @@ -163,10 +163,13 @@ export class MatDialogContainer extends BasePortalOutlet { if (this._document) { this._elementFocusedBeforeDialogWasOpened = this._document.activeElement as HTMLElement; - // Move focus onto the dialog immediately in order to prevent the user from accidentally - // opening multiple dialogs at the same time. Needs to be async, because the element - // may not be focusable immediately. - Promise.resolve().then(() => this._elementRef.nativeElement.focus()); + // Note that there is no focus method when rendering on the server. + if (this._elementRef.nativeElement.focus) { + // Move focus onto the dialog immediately in order to prevent the user from accidentally + // opening multiple dialogs at the same time. Needs to be async, because the element + // may not be focusable immediately. + Promise.resolve().then(() => this._elementRef.nativeElement.focus()); + } } } diff --git a/src/universal-app/kitchen-sink/kitchen-sink.ts b/src/universal-app/kitchen-sink/kitchen-sink.ts index c2af9466440..06ddabdd27b 100644 --- a/src/universal-app/kitchen-sink/kitchen-sink.ts +++ b/src/universal-app/kitchen-sink/kitchen-sink.ts @@ -36,14 +36,23 @@ import { MatTooltipModule, MatStepperModule, MatSnackBar, + MatDialog, } from '@angular/material'; import { CdkTableModule, DataSource } from '@angular/cdk/table'; +import {Overlay} from '@angular/cdk/overlay'; import {of as observableOf} from 'rxjs/observable/of'; + +@Component({ + template: `` +}) +export class TestDialog {} + + @Component({ selector: 'kitchen-sink', templateUrl: './kitchen-sink.html', @@ -60,9 +69,13 @@ export class KitchenSink { disconnect: () => {} }; - constructor(snackBar: MatSnackBar) { + constructor(snackBar: MatSnackBar, dialog: MatDialog, overlay: Overlay) { // Open a snack bar to do a basic sanity check of the overlays. snackBar.open('Hello there'); + + // TODO(crisbeto): use the noop scroll strategy until + // the fixes for the block scroll strategy get in. + dialog.open(TestDialog, {scrollStrategy: overlay.scrollStrategies.noop()}); } } @@ -109,7 +122,8 @@ export class KitchenSink { CdkTableModule ], bootstrap: [KitchenSink], - declarations: [KitchenSink], + declarations: [KitchenSink, TestDialog], + entryComponents: [TestDialog], }) export class KitchenSinkClientModule { }