Skip to content

Commit

Permalink
fix(cdk/layout): breakpoint observer not firing callback on chrome in…
Browse files Browse the repository at this point in the history
… specific cases (#23571)

There appears to be a bug in Chrome, where if we try to use `matchMedia` on a media query that doesn't match anything on the page and a style recalculation is trigger on the `body`, the `matchMedia` callback stops firing which in turn breaks `BreakpointObserver`.

These changes expand an existing workaround that we had for WebKit browsers involving inserting a dummy `style` tag on the page so that there's always at least one matching element.

Fixes #23546.
  • Loading branch information
crisbeto committed Sep 16, 2021
1 parent 4160f11 commit cfe79b8
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions src/cdk/layout/media-matcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@ export class MediaMatcher {
* MediaQueryList for the query provided.
*/
matchMedia(query: string): MediaQueryList {
if (this._platform.WEBKIT) {
if (this._platform.WEBKIT || this._platform.BLINK) {
createEmptyStyleRule(query);
}
return this._matchMedia(query);
}
}

/**
* For Webkit engines that only trigger the MediaQueryListListener when
* there is at least one CSS selector for the respective media query.
* Creates an empty stylesheet that is used to work around browser inconsistencies related to
* `matchMedia`. At the time of writing, it handles the following cases:
* 1. On WebKit browsers, a media query has to have at least one rule in order for `matchMedia`
* to fire. We work around it by declaring a dummy stylesheet with a `@media` declaration.
* 2. In some cases Blink browsers will stop firing the `matchMedia` listener if none of the rules
* inside the `@media` match existing elements on the page. We work around it by having one rule
* targeting the `body`. See https://github.com/angular/components/issues/23546.
*/
function createEmptyStyleRule(query: string) {
if (mediaQueriesForWebkitCompatibility.has(query)) {
Expand All @@ -59,8 +64,7 @@ function createEmptyStyleRule(query: string) {
}

if (mediaQueryStyleNode.sheet) {
(mediaQueryStyleNode.sheet as CSSStyleSheet)
.insertRule(`@media ${query} {.fx-query-test{ }}`, 0);
mediaQueryStyleNode.sheet.insertRule(`@media ${query} {body{ }}`, 0);
mediaQueriesForWebkitCompatibility.add(query);
}
} catch (e) {
Expand Down

0 comments on commit cfe79b8

Please sign in to comment.