UNPKG

@angular/cdk

Version:

Angular Material Component Development Kit

177 lines (173 loc) 4.93 kB
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