@@ -10,7 +10,7 @@ import {HighContrastModeDetector} from '@angular/cdk/a11y';
1010import { BidiModule } from '@angular/cdk/bidi' ;
1111import { Inject , InjectionToken , isDevMode , NgModule , Optional , Version } from '@angular/core' ;
1212import { VERSION as CDK_VERSION } from '@angular/cdk' ;
13-
13+ import { DOCUMENT } from '@angular/common' ;
1414
1515// Private version constant to circumvent test/build issues,
1616// i.e. avoid core to depend on the @angular /material primary entry-point
@@ -62,18 +62,19 @@ export class MatCommonModule {
6262 /** Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype). */
6363 private _hasDoneGlobalChecks = false ;
6464
65- /** Reference to the global `document` object. */
66- private _document = typeof document === 'object' && document ? document : null ;
67-
68- /** Reference to the global 'window' object. */
69- private _window = typeof window === 'object' && window ? window : null ;
70-
7165 /** Configured sanity checks. */
7266 private _sanityChecks : SanityChecks ;
7367
68+ /** Used to reference correct document/window */
69+ protected _document ?: Document ;
70+
7471 constructor (
7572 highContrastModeDetector : HighContrastModeDetector ,
76- @Optional ( ) @Inject ( MATERIAL_SANITY_CHECKS ) sanityChecks : any ) {
73+ @Optional ( ) @Inject ( MATERIAL_SANITY_CHECKS ) sanityChecks : any ,
74+ /** @breaking -change 11.0.0 make document required */
75+ @Optional ( ) @Inject ( DOCUMENT ) document ?: any ) {
76+ this . _document = document ;
77+
7778 // While A11yModule also does this, we repeat it here to avoid importing A11yModule
7879 // in MatCommonModule.
7980 highContrastModeDetector . _applyBodyHighContrastModeCssClasses ( ) ;
@@ -90,22 +91,36 @@ export class MatCommonModule {
9091 }
9192 }
9293
94+ /** Access injected document if available or fallback to global document reference */
95+ private _getDocument ( ) : Document | null {
96+ const doc = this . _document || document ;
97+ return typeof doc === 'object' && doc ? doc : null ;
98+ }
99+
100+ /** Use defaultView of injected document if available or fallback to global window reference */
101+ private _getWindow ( ) : Window | null {
102+ const doc = this . _getDocument ( ) ;
103+ const win = doc ?. defaultView || window ;
104+ return typeof win === 'object' && win ? win : null ;
105+ }
106+
93107 /** Whether any sanity checks are enabled. */
94108 private _checksAreEnabled ( ) : boolean {
95109 return isDevMode ( ) && ! this . _isTestEnv ( ) ;
96110 }
97111
98112 /** Whether the code is running in tests. */
99113 private _isTestEnv ( ) {
100- const window = this . _window as any ;
114+ const window = this . _getWindow ( ) as any ;
101115 return window && ( window . __karma__ || window . jasmine ) ;
102116 }
103117
104118 private _checkDoctypeIsDefined ( ) : void {
105119 const isEnabled = this . _checksAreEnabled ( ) &&
106120 ( this . _sanityChecks === true || ( this . _sanityChecks as GranularSanityChecks ) . doctype ) ;
121+ const document = this . _getDocument ( ) ;
107122
108- if ( isEnabled && this . _document && ! this . _document . doctype ) {
123+ if ( isEnabled && document && ! document . doctype ) {
109124 console . warn (
110125 'Current document does not have a doctype. This may cause ' +
111126 'some Angular Material components not to behave as expected.'
@@ -118,16 +133,17 @@ export class MatCommonModule {
118133 // and the `body` won't be defined if the consumer put their scripts in the `head`.
119134 const isDisabled = ! this . _checksAreEnabled ( ) ||
120135 ( this . _sanityChecks === false || ! ( this . _sanityChecks as GranularSanityChecks ) . theme ) ;
136+ const document = this . _getDocument ( ) ;
121137
122- if ( isDisabled || ! this . _document || ! this . _document . body ||
138+ if ( isDisabled || ! document || ! document . body ||
123139 typeof getComputedStyle !== 'function' ) {
124140 return ;
125141 }
126142
127- const testElement = this . _document . createElement ( 'div' ) ;
143+ const testElement = document . createElement ( 'div' ) ;
128144
129145 testElement . classList . add ( 'mat-theme-loaded-marker' ) ;
130- this . _document . body . appendChild ( testElement ) ;
146+ document . body . appendChild ( testElement ) ;
131147
132148 const computedStyle = getComputedStyle ( testElement ) ;
133149
@@ -142,7 +158,7 @@ export class MatCommonModule {
142158 ) ;
143159 }
144160
145- this . _document . body . removeChild ( testElement ) ;
161+ document . body . removeChild ( testElement ) ;
146162 }
147163
148164 /** Checks whether the material version matches the cdk version */
0 commit comments