Skip to content

Commit f066809

Browse files
committed
chore: improve type safety in breakpoint observer
* Fixes a workaround where we cast the MediaQueryList event listener to any because TypeScript didn't have proper types before TS 3.1.
1 parent fe26614 commit f066809

File tree

3 files changed

+24
-25
lines changed

3 files changed

+24
-25
lines changed

.bazelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ build:remote --project_id=internal-200822
6363

6464
# Setup the build strategy for various types of actions. Mixing "local" and "remote"
6565
# can cause unexpected results and we want to run everything remotely if possible.
66-
build:remote --spawn_strategy=remote
66+
build:remote --spawn_strategy=remote,local
6767
build:remote --strategy=Javac=remote
6868
build:remote --strategy=Closure=remote
6969
build:remote --strategy=Genrule=remote

src/cdk/layout/breakpoints-observer.ts

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {coerceArray} from '@angular/cdk/coercion';
910
import {Injectable, NgZone, OnDestroy} from '@angular/core';
1011
import {MediaMatcher} from './media-matcher';
1112
import {combineLatest, concat, Observable, Subject, Observer} from 'rxjs';
1213
import {debounceTime, map, skip, startWith, take, takeUntil} from 'rxjs/operators';
13-
import {coerceArray} from '@angular/cdk/coercion';
1414

1515

1616
/** The current state of a layout breakpoint. */
@@ -60,7 +60,7 @@ export class BreakpointObserver implements OnDestroy {
6060
* @param value One or more media queries to check.
6161
* @returns Whether any of the media queries match.
6262
*/
63-
isMatched(value: string | string[]): boolean {
63+
isMatched(value: string|string[]): boolean {
6464
const queries = splitQueries(coerceArray(value));
6565
return queries.some(mediaQuery => this._registerQuery(mediaQuery).mql.matches);
6666
}
@@ -71,7 +71,7 @@ export class BreakpointObserver implements OnDestroy {
7171
* @param value One or more media queries to check.
7272
* @returns A stream of matches for the given queries.
7373
*/
74-
observe(value: string | string[]): Observable<BreakpointState> {
74+
observe(value: string|string[]): Observable<BreakpointState> {
7575
const queries = splitQueries(coerceArray(value));
7676
const observables = queries.map(query => this._registerQuery(query).observable);
7777

@@ -103,23 +103,24 @@ export class BreakpointObserver implements OnDestroy {
103103
const mql: MediaQueryList = this._mediaMatcher.matchMedia(query);
104104

105105
// Create callback for match changes and add it is as a listener.
106-
const queryObservable = new Observable<MediaQueryList>((observer: Observer<MediaQueryList>) => {
107-
// Listener callback methods are wrapped to be placed back in ngZone. Callbacks must be placed
108-
// back into the zone because matchMedia is only included in Zone.js by loading the
109-
// webapis-media-query.js file alongside the zone.js file. Additionally, some browsers do not
110-
// have MediaQueryList inherit from EventTarget, which causes inconsistencies in how Zone.js
111-
// patches it.
112-
const handler = (e: any) => this._zone.run(() => observer.next(e));
113-
mql.addListener(handler);
114-
115-
return () => {
116-
mql.removeListener(handler);
117-
};
118-
}).pipe(
119-
startWith(mql),
120-
map((nextMql: MediaQueryList) => ({query, matches: nextMql.matches})),
121-
takeUntil(this._destroySubject)
122-
);
106+
const queryObservable =
107+
new Observable<MediaQueryListEvent>((observer: Observer<MediaQueryListEvent>) => {
108+
// Listener callback methods are wrapped to be placed back in ngZone. Callbacks must be
109+
// placed back into the zone because matchMedia is only included in Zone.js by loading the
110+
// webapis-media-query.js file alongside the zone.js file. Additionally, some browsers do
111+
// not have MediaQueryList inherit from EventTarget, which causes inconsistencies in how
112+
// Zone.js patches it.
113+
const handler: (event: MediaQueryListEvent) => void = e =>
114+
this._zone.run(() => observer.next(e));
115+
mql.addListener(handler);
116+
117+
return () => {
118+
mql.removeListener(handler);
119+
};
120+
})
121+
.pipe(
122+
map((nextMql: MediaQueryListEvent) => ({query, matches: nextMql.matches})),
123+
startWith({query, matches: mql.matches}), takeUntil(this._destroySubject));
123124

124125
// Add the MediaQueryList to the set of queries.
125126
const output = {observable: queryObservable, mql};
@@ -134,6 +135,6 @@ export class BreakpointObserver implements OnDestroy {
134135
*/
135136
function splitQueries(queries: string[]): string[] {
136137
return queries.map((query: string) => query.split(','))
137-
.reduce((a1: string[], a2: string[]) => a1.concat(a2))
138-
.map(query => query.trim());
138+
.reduce((a1: string[], a2: string[]) => a1.concat(a2))
139+
.map(query => query.trim());
139140
}

test/browser-providers.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
* - local: Launches the browser locally on the current operating system.
77
* - BS: Launches the browser within BrowserStack
88
* - SL: Launches the browser within Saucelabs
9-
*
10-
* TODO(devversion): rename this to "browserstack" and "saucelabs".
119
*/
1210
const browserConfig = {
1311
'ChromeHeadlessCI': { unitTest: {target: 'local', }},

0 commit comments

Comments
 (0)