UNPKG

11.6 kBJavaScriptView Raw
1import * as i0 from '@angular/core';
2import { NgModule, Injectable } from '@angular/core';
3import { coerceArray } from '@angular/cdk/coercion';
4import { Subject, combineLatest, concat, Observable } from 'rxjs';
5import { take, skip, debounceTime, map, startWith, takeUntil } from 'rxjs/operators';
6import * as i1 from '@angular/cdk/platform';
7
8/**
9 * @license
10 * Copyright Google LLC All Rights Reserved.
11 *
12 * Use of this source code is governed by an MIT-style license that can be
13 * found in the LICENSE file at https://angular.io/license
14 */
15class LayoutModule {
16}
17LayoutModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: LayoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
18LayoutModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: LayoutModule });
19LayoutModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: LayoutModule });
20i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: LayoutModule, decorators: [{
21 type: NgModule,
22 args: [{}]
23 }] });
24
25/**
26 * @license
27 * Copyright Google LLC All Rights Reserved.
28 *
29 * Use of this source code is governed by an MIT-style license that can be
30 * found in the LICENSE file at https://angular.io/license
31 */
32/** Global registry for all dynamically-created, injected media queries. */
33const mediaQueriesForWebkitCompatibility = new Set();
34/** Style tag that holds all of the dynamically-created media queries. */
35let mediaQueryStyleNode;
36/** A utility for calling matchMedia queries. */
37class MediaMatcher {
38 constructor(_platform) {
39 this._platform = _platform;
40 this._matchMedia =
41 this._platform.isBrowser && window.matchMedia
42 ? // matchMedia is bound to the window scope intentionally as it is an illegal invocation to
43 // call it from a different scope.
44 window.matchMedia.bind(window)
45 : noopMatchMedia;
46 }
47 /**
48 * Evaluates the given media query and returns the native MediaQueryList from which results
49 * can be retrieved.
50 * Confirms the layout engine will trigger for the selector query provided and returns the
51 * MediaQueryList for the query provided.
52 */
53 matchMedia(query) {
54 if (this._platform.WEBKIT || this._platform.BLINK) {
55 createEmptyStyleRule(query);
56 }
57 return this._matchMedia(query);
58 }
59}
60MediaMatcher.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: MediaMatcher, deps: [{ token: i1.Platform }], target: i0.ɵɵFactoryTarget.Injectable });
61MediaMatcher.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: MediaMatcher, providedIn: 'root' });
62i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: MediaMatcher, decorators: [{
63 type: Injectable,
64 args: [{ providedIn: 'root' }]
65 }], ctorParameters: function () { return [{ type: i1.Platform }]; } });
66/**
67 * Creates an empty stylesheet that is used to work around browser inconsistencies related to
68 * `matchMedia`. At the time of writing, it handles the following cases:
69 * 1. On WebKit browsers, a media query has to have at least one rule in order for `matchMedia`
70 * to fire. We work around it by declaring a dummy stylesheet with a `@media` declaration.
71 * 2. In some cases Blink browsers will stop firing the `matchMedia` listener if none of the rules
72 * inside the `@media` match existing elements on the page. We work around it by having one rule
73 * targeting the `body`. See https://github.com/angular/components/issues/23546.
74 */
75function createEmptyStyleRule(query) {
76 if (mediaQueriesForWebkitCompatibility.has(query)) {
77 return;
78 }
79 try {
80 if (!mediaQueryStyleNode) {
81 mediaQueryStyleNode = document.createElement('style');
82 mediaQueryStyleNode.setAttribute('type', 'text/css');
83 document.head.appendChild(mediaQueryStyleNode);
84 }
85 if (mediaQueryStyleNode.sheet) {
86 mediaQueryStyleNode.sheet.insertRule(`@media ${query} {body{ }}`, 0);
87 mediaQueriesForWebkitCompatibility.add(query);
88 }
89 }
90 catch (e) {
91 console.error(e);
92 }
93}
94/** No-op matchMedia replacement for non-browser platforms. */
95function noopMatchMedia(query) {
96 // Use `as any` here to avoid adding additional necessary properties for
97 // the noop matcher.
98 return {
99 matches: query === 'all' || query === '',
100 media: query,
101 addListener: () => { },
102 removeListener: () => { },
103 };
104}
105
106/**
107 * @license
108 * Copyright Google LLC All Rights Reserved.
109 *
110 * Use of this source code is governed by an MIT-style license that can be
111 * found in the LICENSE file at https://angular.io/license
112 */
113/** Utility for checking the matching state of @media queries. */
114class BreakpointObserver {
115 constructor(_mediaMatcher, _zone) {
116 this._mediaMatcher = _mediaMatcher;
117 this._zone = _zone;
118 /** A map of all media queries currently being listened for. */
119 this._queries = new Map();
120 /** A subject for all other observables to takeUntil based on. */
121 this._destroySubject = new Subject();
122 }
123 /** Completes the active subject, signalling to all other observables to complete. */
124 ngOnDestroy() {
125 this._destroySubject.next();
126 this._destroySubject.complete();
127 }
128 /**
129 * Whether one or more media queries match the current viewport size.
130 * @param value One or more media queries to check.
131 * @returns Whether any of the media queries match.
132 */
133 isMatched(value) {
134 const queries = splitQueries(coerceArray(value));
135 return queries.some(mediaQuery => this._registerQuery(mediaQuery).mql.matches);
136 }
137 /**
138 * Gets an observable of results for the given queries that will emit new results for any changes
139 * in matching of the given queries.
140 * @param value One or more media queries to check.
141 * @returns A stream of matches for the given queries.
142 */
143 observe(value) {
144 const queries = splitQueries(coerceArray(value));
145 const observables = queries.map(query => this._registerQuery(query).observable);
146 let stateObservable = combineLatest(observables);
147 // Emit the first state immediately, and then debounce the subsequent emissions.
148 stateObservable = concat(stateObservable.pipe(take(1)), stateObservable.pipe(skip(1), debounceTime(0)));
149 return stateObservable.pipe(map(breakpointStates => {
150 const response = {
151 matches: false,
152 breakpoints: {},
153 };
154 breakpointStates.forEach(({ matches, query }) => {
155 response.matches = response.matches || matches;
156 response.breakpoints[query] = matches;
157 });
158 return response;
159 }));
160 }
161 /** Registers a specific query to be listened for. */
162 _registerQuery(query) {
163 // Only set up a new MediaQueryList if it is not already being listened for.
164 if (this._queries.has(query)) {
165 return this._queries.get(query);
166 }
167 const mql = this._mediaMatcher.matchMedia(query);
168 // Create callback for match changes and add it is as a listener.
169 const queryObservable = new Observable((observer) => {
170 // Listener callback methods are wrapped to be placed back in ngZone. Callbacks must be placed
171 // back into the zone because matchMedia is only included in Zone.js by loading the
172 // webapis-media-query.js file alongside the zone.js file. Additionally, some browsers do not
173 // have MediaQueryList inherit from EventTarget, which causes inconsistencies in how Zone.js
174 // patches it.
175 const handler = (e) => this._zone.run(() => observer.next(e));
176 mql.addListener(handler);
177 return () => {
178 mql.removeListener(handler);
179 };
180 }).pipe(startWith(mql), map(({ matches }) => ({ query, matches })), takeUntil(this._destroySubject));
181 // Add the MediaQueryList to the set of queries.
182 const output = { observable: queryObservable, mql };
183 this._queries.set(query, output);
184 return output;
185 }
186}
187BreakpointObserver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: BreakpointObserver, deps: [{ token: MediaMatcher }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
188BreakpointObserver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: BreakpointObserver, providedIn: 'root' });
189i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: BreakpointObserver, decorators: [{
190 type: Injectable,
191 args: [{ providedIn: 'root' }]
192 }], ctorParameters: function () { return [{ type: MediaMatcher }, { type: i0.NgZone }]; } });
193/**
194 * Split each query string into separate query strings if two queries are provided as comma
195 * separated.
196 */
197function splitQueries(queries) {
198 return queries
199 .map(query => query.split(','))
200 .reduce((a1, a2) => a1.concat(a2))
201 .map(query => query.trim());
202}
203
204/**
205 * @license
206 * Copyright Google LLC All Rights Reserved.
207 *
208 * Use of this source code is governed by an MIT-style license that can be
209 * found in the LICENSE file at https://angular.io/license
210 */
211// PascalCase is being used as Breakpoints is used like an enum.
212// tslint:disable-next-line:variable-name
213const Breakpoints = {
214 XSmall: '(max-width: 599.98px)',
215 Small: '(min-width: 600px) and (max-width: 959.98px)',
216 Medium: '(min-width: 960px) and (max-width: 1279.98px)',
217 Large: '(min-width: 1280px) and (max-width: 1919.98px)',
218 XLarge: '(min-width: 1920px)',
219 Handset: '(max-width: 599.98px) and (orientation: portrait), ' +
220 '(max-width: 959.98px) and (orientation: landscape)',
221 Tablet: '(min-width: 600px) and (max-width: 839.98px) and (orientation: portrait), ' +
222 '(min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape)',
223 Web: '(min-width: 840px) and (orientation: portrait), ' +
224 '(min-width: 1280px) and (orientation: landscape)',
225 HandsetPortrait: '(max-width: 599.98px) and (orientation: portrait)',
226 TabletPortrait: '(min-width: 600px) and (max-width: 839.98px) and (orientation: portrait)',
227 WebPortrait: '(min-width: 840px) and (orientation: portrait)',
228 HandsetLandscape: '(max-width: 959.98px) and (orientation: landscape)',
229 TabletLandscape: '(min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape)',
230 WebLandscape: '(min-width: 1280px) and (orientation: landscape)',
231};
232
233/**
234 * @license
235 * Copyright Google LLC All Rights Reserved.
236 *
237 * Use of this source code is governed by an MIT-style license that can be
238 * found in the LICENSE file at https://angular.io/license
239 */
240
241/**
242 * @license
243 * Copyright Google LLC All Rights Reserved.
244 *
245 * Use of this source code is governed by an MIT-style license that can be
246 * found in the LICENSE file at https://angular.io/license
247 */
248
249/**
250 * Generated bundle index. Do not edit.
251 */
252
253export { BreakpointObserver, Breakpoints, LayoutModule, MediaMatcher };
254//# sourceMappingURL=layout.mjs.map