5
5
* Use of this source code is governed by an MIT-style license that can be
6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
- import { Injectable , NgZone } from '@angular/core' ;
9
-
8
+ import { Inject , Injectable , NgZone } from '@angular/core' ;
9
+ import { ɵgetDOM as getDom , DOCUMENT } from '@angular/platform-browser' ;
10
10
import { BehaviorSubject } from 'rxjs/BehaviorSubject' ;
11
11
import { Observable } from 'rxjs/Observable' ;
12
12
import { filter } from 'rxjs/operator/filter' ;
@@ -27,7 +27,9 @@ export interface MediaQueryListListener {
27
27
export interface MediaQueryList {
28
28
readonly matches : boolean ;
29
29
readonly media : string ;
30
+
30
31
addListener ( listener : MediaQueryListListener ) : void ;
32
+
31
33
removeListener ( listener : MediaQueryListListener ) : void ;
32
34
}
33
35
@@ -45,7 +47,7 @@ export class MatchMedia {
45
47
protected _source : BehaviorSubject < MediaChange > ;
46
48
protected _observable$ : Observable < MediaChange > ;
47
49
48
- constructor ( protected _zone : NgZone ) {
50
+ constructor ( protected _zone : NgZone , @ Inject ( DOCUMENT ) protected _document : any ) {
49
51
this . _registry = new Map < string , MediaQueryList > ( ) ;
50
52
this . _source = new BehaviorSubject < MediaChange > ( new MediaChange ( true ) ) ;
51
53
this . _observable$ = this . _source . asObservable ( ) ;
@@ -86,7 +88,7 @@ export class MatchMedia {
86
88
let list = normalizeQuery ( mediaQuery ) ;
87
89
88
90
if ( list . length > 0 ) {
89
- prepareQueryCSS ( list ) ;
91
+ prepareQueryCSS ( list , this . _document ) ;
90
92
91
93
list . forEach ( query => {
92
94
let mql = this . _registry . get ( query ) ;
@@ -114,8 +116,9 @@ export class MatchMedia {
114
116
* Call window.matchMedia() to build a MediaQueryList; which
115
117
* supports 0..n listeners for activation/deactivation
116
118
*/
117
- protected _buildMQL ( query : string ) : MediaQueryList {
118
- let canListen = ! ! ( < any > window ) . matchMedia ( 'all' ) . addListener ;
119
+ protected _buildMQL ( query : string ) : MediaQueryList {
120
+ let canListen = isBrowser ( ) && ! ! ( < any > window ) . matchMedia ( 'all' ) . addListener ;
121
+
119
122
return canListen ? ( < any > window ) . matchMedia ( query ) : < MediaQueryList > {
120
123
matches : query === 'all' || query === '' ,
121
124
media : query ,
@@ -127,6 +130,13 @@ export class MatchMedia {
127
130
}
128
131
}
129
132
133
+ /**
134
+ * Determine if SSR or Browser rendering.
135
+ */
136
+ export function isBrowser ( ) {
137
+ return getDom ( ) . supportsDOMEvents ( ) ;
138
+ }
139
+
130
140
/**
131
141
* Private global registry for all dynamically-created, injected style tags
132
142
* @see prepare(query)
@@ -140,27 +150,28 @@ const ALL_STYLES = {};
140
150
* @param query string The mediaQuery used to create a faux CSS selector
141
151
*
142
152
*/
143
- function prepareQueryCSS ( mediaQueries : string [ ] ) {
153
+ function prepareQueryCSS ( mediaQueries : string [ ] , _document : any ) {
144
154
let list = mediaQueries . filter ( it => ! ALL_STYLES [ it ] ) ;
145
155
if ( list . length > 0 ) {
146
156
let query = list . join ( ', ' ) ;
157
+
147
158
try {
148
- let style = document . createElement ( 'style' ) ;
159
+ let styleEl = getDom ( ) . createElement ( 'style' ) ;
149
160
150
- style . setAttribute ( 'type' , 'text/css' ) ;
151
- if ( ! style [ 'styleSheet' ] ) {
161
+ getDom ( ) . setAttribute ( styleEl , 'type' , 'text/css' ) ;
162
+ if ( ! styleEl [ 'styleSheet' ] ) {
152
163
let cssText = `/*
153
164
@angular/flex-layout - workaround for possible browser quirk with mediaQuery listeners
154
165
see http://bit.ly/2sd4HMP
155
166
*/
156
167
@media ${ query } {.fx-query-test{ }}` ;
157
- style . appendChild ( document . createTextNode ( cssText ) ) ;
168
+ getDom ( ) . appendChild ( styleEl , getDom ( ) . createTextNode ( cssText ) ) ;
158
169
}
159
170
160
- document . getElementsByTagName ( 'head' ) [ 0 ] . appendChild ( style ) ;
171
+ getDom ( ) . appendChild ( _document . head , styleEl ) ;
161
172
162
173
// Store in private global registry
163
- list . forEach ( mq => ALL_STYLES [ mq ] = style ) ;
174
+ list . forEach ( mq => ALL_STYLES [ mq ] = styleEl ) ;
164
175
165
176
} catch ( e ) {
166
177
console . error ( e ) ;
0 commit comments