ipsos-components
Version:
Material Design components for Angular
78 lines (68 loc) • 2.5 kB
text/typescript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable} from '@angular/core';
import {Platform} from '@angular/cdk/platform';
/**
* Global registry for all dynamically-created, injected style tags.
*/
const styleElementForWebkitCompatibility: Map<string, HTMLStyleElement> = new Map();
/** A utility for calling matchMedia queries. */
()
export class MediaMatcher {
/** The internal matchMedia method to return back a MediaQueryList like object. */
private _matchMedia: (query: string) => MediaQueryList;
constructor(private platform: Platform) {
this._matchMedia = this.platform.isBrowser ?
// matchMedia is bound to the window scope intentionally as it is an illegal invocation to
// call it from a different scope.
window.matchMedia.bind(window) :
noopMatchMedia;
}
/**
* Evaluates the given media query and returns the native MediaQueryList from which results
* can be retrieved.
* Confirms the layout engine will trigger for the selector query provided and returns the
* MediaQueryList for the query provided.
*/
matchMedia(query: string): MediaQueryList {
if (this.platform.WEBKIT) {
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.
*/
function createEmptyStyleRule(query: string) {
if (!styleElementForWebkitCompatibility.has(query)) {
try {
const style = document.createElement('style');
style.setAttribute('type', 'text/css');
if (!style.sheet) {
const cssText = `@media ${query} {.fx-query-test{ }}`;
style.appendChild(document.createTextNode(cssText));
}
document.getElementsByTagName('head')[0].appendChild(style);
// Store in private global registry
styleElementForWebkitCompatibility.set(query, style);
} catch (e) {
console.error(e);
}
}
}
/** No-op matchMedia replacement for non-browser platforms. */
function noopMatchMedia(query: string): MediaQueryList {
return {
matches: query === 'all' || query === '',
media: query,
addListener: () => {},
removeListener: () => {}
};
}