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