@angular/cdk
Version:
Angular Material Component Development Kit
177 lines (173 loc) • 4.93 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, CSP_NONCE, Injectable, NgZone } from '@angular/core';
import { Subject, combineLatest, concat, Observable } from 'rxjs';
import { take, skip, debounceTime, map, startWith, takeUntil } from 'rxjs/operators';
import { Platform } from './_platform-chunk.mjs';
import { coerceArray } from './_array-chunk.mjs';
const mediaQueriesForWebkitCompatibility = new Set();
let mediaQueryStyleNode;
class MediaMatcher {
_platform = inject(Platform);
_nonce = inject(CSP_NONCE, {
optional: true
});
_matchMedia;
constructor() {
this._matchMedia = this._platform.isBrowser && window.matchMedia ? window.matchMedia.bind(window) : noopMatchMedia;
}
matchMedia(query) {
if (this._platform.WEBKIT || this._platform.BLINK) {
createEmptyStyleRule(query, this._nonce);
}
return this._matchMedia(query);
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.0",
ngImport: i0,
type: MediaMatcher,
deps: [],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.0",
ngImport: i0,
type: MediaMatcher,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.0",
ngImport: i0,
type: MediaMatcher,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}],
ctorParameters: () => []
});
function createEmptyStyleRule(query, nonce) {
if (mediaQueriesForWebkitCompatibility.has(query)) {
return;
}
try {
if (!mediaQueryStyleNode) {
mediaQueryStyleNode = document.createElement('style');
if (nonce) {
mediaQueryStyleNode.setAttribute('nonce', nonce);
}
mediaQueryStyleNode.setAttribute('type', 'text/css');
document.head.appendChild(mediaQueryStyleNode);
}
if (mediaQueryStyleNode.sheet) {
mediaQueryStyleNode.sheet.insertRule(`@media ${query} {body{ }}`, 0);
mediaQueriesForWebkitCompatibility.add(query);
}
} catch (e) {
console.error(e);
}
}
function noopMatchMedia(query) {
return {
matches: query === 'all' || query === '',
media: query,
addListener: () => {},
removeListener: () => {}
};
}
class BreakpointObserver {
_mediaMatcher = inject(MediaMatcher);
_zone = inject(NgZone);
_queries = new Map();
_destroySubject = new Subject();
constructor() {}
ngOnDestroy() {
this._destroySubject.next();
this._destroySubject.complete();
}
isMatched(value) {
const queries = splitQueries(coerceArray(value));
return queries.some(mediaQuery => this._registerQuery(mediaQuery).mql.matches);
}
observe(value) {
const queries = splitQueries(coerceArray(value));
const observables = queries.map(query => this._registerQuery(query).observable);
let stateObservable = combineLatest(observables);
stateObservable = concat(stateObservable.pipe(take(1)), stateObservable.pipe(skip(1), debounceTime(0)));
return stateObservable.pipe(map(breakpointStates => {
const response = {
matches: false,
breakpoints: {}
};
breakpointStates.forEach(({
matches,
query
}) => {
response.matches = response.matches || matches;
response.breakpoints[query] = matches;
});
return response;
}));
}
_registerQuery(query) {
if (this._queries.has(query)) {
return this._queries.get(query);
}
const mql = this._mediaMatcher.matchMedia(query);
const queryObservable = new Observable(observer => {
const handler = e => this._zone.run(() => observer.next(e));
mql.addListener(handler);
return () => {
mql.removeListener(handler);
};
}).pipe(startWith(mql), map(({
matches
}) => ({
query,
matches
})), takeUntil(this._destroySubject));
const output = {
observable: queryObservable,
mql
};
this._queries.set(query, output);
return output;
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.0",
ngImport: i0,
type: BreakpointObserver,
deps: [],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.0",
ngImport: i0,
type: BreakpointObserver,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.0",
ngImport: i0,
type: BreakpointObserver,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}],
ctorParameters: () => []
});
function splitQueries(queries) {
return queries.map(query => query.split(',')).reduce((a1, a2) => a1.concat(a2)).map(query => query.trim());
}
export { BreakpointObserver, MediaMatcher };
//# sourceMappingURL=_breakpoints-observer-chunk.mjs.map