@dugararchit/flex-layout 13.0.0-dugararchit
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/_private-utils/angular-flex-layout-_private-utils.d.ts +5 -0
- package/_private-utils/auto-prefixer.d.ts +24 -0
- package/_private-utils/index.d.ts +10 -0
- package/_private-utils/layout-validator.d.ts +32 -0
- package/_private-utils/object-extend.d.ts +15 -0
- package/_private-utils/package.json +10 -0
- package/_private-utils/testing/angular-flex-layout-_private-utils-testing.d.ts +5 -0
- package/_private-utils/testing/custom-matchers.d.ts +65 -0
- package/_private-utils/testing/dom-tools.d.ts +47 -0
- package/_private-utils/testing/helpers.d.ts +24 -0
- package/_private-utils/testing/index.d.ts +10 -0
- package/_private-utils/testing/package.json +10 -0
- package/angular-flex-layout-13.0.0-beta.38.tgz +0 -0
- package/angular-flex-layout.d.ts +5 -0
- package/core/README.md +25 -0
- package/core/add-alias.d.ts +14 -0
- package/core/angular-flex-layout-core.d.ts +5 -0
- package/core/base/base2.d.ts +60 -0
- package/core/base/index.d.ts +8 -0
- package/core/basis-validator/basis-validator.d.ts +13 -0
- package/core/breakpoints/break-point-registry.d.ts +42 -0
- package/core/breakpoints/break-point.d.ts +14 -0
- package/core/breakpoints/break-points-token.d.ts +14 -0
- package/core/breakpoints/breakpoint-tools.d.ts +19 -0
- package/core/breakpoints/data/break-points.d.ts +12 -0
- package/core/breakpoints/data/orientation-break-points.d.ts +23 -0
- package/core/breakpoints/index.d.ts +12 -0
- package/core/browser-provider.d.ts +24 -0
- package/core/match-media/index.d.ts +9 -0
- package/core/match-media/match-media.d.ts +59 -0
- package/core/match-media/mock/mock-match-media.d.ts +92 -0
- package/core/media-change.d.ts +30 -0
- package/core/media-marshaller/media-marshaller.d.ts +123 -0
- package/core/media-marshaller/print-hook.d.ts +95 -0
- package/core/media-observer/index.d.ts +8 -0
- package/core/media-observer/media-observer.d.ts +115 -0
- package/core/media-trigger/index.d.ts +8 -0
- package/core/media-trigger/media-trigger.d.ts +73 -0
- package/core/module.d.ts +11 -0
- package/core/multiply/multiplier.d.ts +5 -0
- package/core/package.json +10 -0
- package/core/public-api.d.ts +25 -0
- package/core/sass/_layout-bp.scss +76 -0
- package/core/style-builder/style-builder.d.ts +21 -0
- package/core/style-utils/style-utils.d.ts +53 -0
- package/core/stylesheet-map/index.d.ts +8 -0
- package/core/stylesheet-map/stylesheet-map.d.ts +24 -0
- package/core/tokens/breakpoint-token.d.ts +10 -0
- package/core/tokens/index.d.ts +10 -0
- package/core/tokens/library-config.d.ts +26 -0
- package/core/tokens/server-token.d.ts +15 -0
- package/core/utils/array.d.ts +9 -0
- package/core/utils/index.d.ts +9 -0
- package/core/utils/sort.d.ts +15 -0
- package/esm2020/_private-utils/angular-flex-layout-_private-utils.mjs +5 -0
- package/esm2020/_private-utils/auto-prefixer.mjs +65 -0
- package/esm2020/_private-utils/index.mjs +11 -0
- package/esm2020/_private-utils/layout-validator.mjs +83 -0
- package/esm2020/_private-utils/object-extend.mjs +30 -0
- package/esm2020/_private-utils/testing/angular-flex-layout-_private-utils-testing.mjs +5 -0
- package/esm2020/_private-utils/testing/custom-matchers.mjs +201 -0
- package/esm2020/_private-utils/testing/dom-tools.mjs +101 -0
- package/esm2020/_private-utils/testing/helpers.mjs +43 -0
- package/esm2020/_private-utils/testing/index.mjs +11 -0
- package/esm2020/angular-flex-layout.mjs +5 -0
- package/esm2020/core/add-alias.mjs +23 -0
- package/esm2020/core/angular-flex-layout-core.mjs +5 -0
- package/esm2020/core/base/base2.mjs +131 -0
- package/esm2020/core/base/index.mjs +9 -0
- package/esm2020/core/basis-validator/basis-validator.mjs +48 -0
- package/esm2020/core/breakpoints/break-point-registry.mjs +76 -0
- package/esm2020/core/breakpoints/break-point.mjs +2 -0
- package/esm2020/core/breakpoints/break-points-token.mjs +30 -0
- package/esm2020/core/breakpoints/breakpoint-tools.mjs +53 -0
- package/esm2020/core/breakpoints/data/break-points.mjs +78 -0
- package/esm2020/core/breakpoints/data/orientation-break-points.mjs +40 -0
- package/esm2020/core/breakpoints/index.mjs +13 -0
- package/esm2020/core/browser-provider.mjs +41 -0
- package/esm2020/core/match-media/index.mjs +10 -0
- package/esm2020/core/match-media/match-media.mjs +186 -0
- package/esm2020/core/match-media/mock/mock-match-media.mjs +224 -0
- package/esm2020/core/media-change.mjs +25 -0
- package/esm2020/core/media-marshaller/media-marshaller.mjs +317 -0
- package/esm2020/core/media-marshaller/print-hook.mjs +265 -0
- package/esm2020/core/media-observer/index.mjs +9 -0
- package/esm2020/core/media-observer/media-observer.mjs +195 -0
- package/esm2020/core/media-trigger/index.mjs +9 -0
- package/esm2020/core/media-trigger/media-trigger.mjs +188 -0
- package/esm2020/core/module.mjs +27 -0
- package/esm2020/core/multiply/multiplier.mjs +16 -0
- package/esm2020/core/public-api.mjs +26 -0
- package/esm2020/core/style-builder/style-builder.mjs +15 -0
- package/esm2020/core/style-utils/style-utils.mjs +174 -0
- package/esm2020/core/stylesheet-map/index.mjs +9 -0
- package/esm2020/core/stylesheet-map/stylesheet-map.mjs +59 -0
- package/esm2020/core/tokens/breakpoint-token.mjs +13 -0
- package/esm2020/core/tokens/index.mjs +11 -0
- package/esm2020/core/tokens/library-config.mjs +30 -0
- package/esm2020/core/tokens/server-token.mjs +19 -0
- package/esm2020/core/utils/array.mjs +12 -0
- package/esm2020/core/utils/index.mjs +10 -0
- package/esm2020/core/utils/sort.mjs +20 -0
- package/esm2020/extended/angular-flex-layout-extended.mjs +5 -0
- package/esm2020/extended/class/class.mjs +88 -0
- package/esm2020/extended/img-src/img-src.mjs +106 -0
- package/esm2020/extended/module.mjs +45 -0
- package/esm2020/extended/public-api.mjs +13 -0
- package/esm2020/extended/show-hide/show-hide.mjs +176 -0
- package/esm2020/extended/style/style-transforms.mjs +76 -0
- package/esm2020/extended/style/style.mjs +130 -0
- package/esm2020/flex/angular-flex-layout-flex.mjs +5 -0
- package/esm2020/flex/flex/flex.mjs +291 -0
- package/esm2020/flex/flex-align/flex-align.mjs +80 -0
- package/esm2020/flex/flex-fill/flex-fill.mjs +50 -0
- package/esm2020/flex/flex-offset/flex-offset.mjs +121 -0
- package/esm2020/flex/flex-order/flex-order.mjs +66 -0
- package/esm2020/flex/layout/layout.mjs +86 -0
- package/esm2020/flex/layout-align/layout-align.mjs +194 -0
- package/esm2020/flex/layout-gap/layout-gap.mjs +282 -0
- package/esm2020/flex/module.mjs +62 -0
- package/esm2020/flex/public-api.mjs +17 -0
- package/esm2020/grid/align-columns/align-columns.mjs +137 -0
- package/esm2020/grid/align-rows/align-rows.mjs +119 -0
- package/esm2020/grid/angular-flex-layout-grid.mjs +5 -0
- package/esm2020/grid/area/area.mjs +67 -0
- package/esm2020/grid/areas/areas.mjs +86 -0
- package/esm2020/grid/auto/auto.mjs +89 -0
- package/esm2020/grid/column/column.mjs +67 -0
- package/esm2020/grid/columns/columns.mjs +96 -0
- package/esm2020/grid/gap/gap.mjs +85 -0
- package/esm2020/grid/grid-align/grid-align.mjs +111 -0
- package/esm2020/grid/module.mjs +73 -0
- package/esm2020/grid/public-api.mjs +20 -0
- package/esm2020/grid/row/row.mjs +67 -0
- package/esm2020/grid/rows/rows.mjs +96 -0
- package/esm2020/module.mjs +64 -0
- package/esm2020/public-api.mjs +20 -0
- package/esm2020/server/angular-flex-layout-server.mjs +5 -0
- package/esm2020/server/module.mjs +22 -0
- package/esm2020/server/public-api.mjs +10 -0
- package/esm2020/server/server-match-media.mjs +151 -0
- package/esm2020/server/server-provider.mjs +140 -0
- package/esm2020/version.mjs +11 -0
- package/extended/README.md +18 -0
- package/extended/angular-flex-layout-extended.d.ts +5 -0
- package/extended/class/class.d.ts +38 -0
- package/extended/img-src/img-src.d.ts +51 -0
- package/extended/module.d.ts +16 -0
- package/extended/package.json +10 -0
- package/extended/public-api.d.ts +12 -0
- package/extended/show-hide/show-hide.d.ts +61 -0
- package/extended/style/style-transforms.d.ts +36 -0
- package/extended/style/style.d.ts +45 -0
- package/fesm2015/angular-flex-layout-_private-utils-testing.mjs +357 -0
- package/fesm2015/angular-flex-layout-_private-utils-testing.mjs.map +1 -0
- package/fesm2015/angular-flex-layout-_private-utils.mjs +193 -0
- package/fesm2015/angular-flex-layout-_private-utils.mjs.map +1 -0
- package/fesm2015/angular-flex-layout-core.mjs +2331 -0
- package/fesm2015/angular-flex-layout-core.mjs.map +1 -0
- package/fesm2015/angular-flex-layout-extended.mjs +621 -0
- package/fesm2015/angular-flex-layout-extended.mjs.map +1 -0
- package/fesm2015/angular-flex-layout-flex.mjs +1206 -0
- package/fesm2015/angular-flex-layout-flex.mjs.map +1 -0
- package/fesm2015/angular-flex-layout-grid.mjs +1047 -0
- package/fesm2015/angular-flex-layout-grid.mjs.map +1 -0
- package/fesm2015/angular-flex-layout-server.mjs +324 -0
- package/fesm2015/angular-flex-layout-server.mjs.map +1 -0
- package/fesm2015/angular-flex-layout.mjs +94 -0
- package/fesm2015/angular-flex-layout.mjs.map +1 -0
- package/fesm2020/angular-flex-layout-_private-utils-testing.mjs +357 -0
- package/fesm2020/angular-flex-layout-_private-utils-testing.mjs.map +1 -0
- package/fesm2020/angular-flex-layout-_private-utils.mjs +192 -0
- package/fesm2020/angular-flex-layout-_private-utils.mjs.map +1 -0
- package/fesm2020/angular-flex-layout-core.mjs +2304 -0
- package/fesm2020/angular-flex-layout-core.mjs.map +1 -0
- package/fesm2020/angular-flex-layout-extended.mjs +612 -0
- package/fesm2020/angular-flex-layout-extended.mjs.map +1 -0
- package/fesm2020/angular-flex-layout-flex.mjs +1198 -0
- package/fesm2020/angular-flex-layout-flex.mjs.map +1 -0
- package/fesm2020/angular-flex-layout-grid.mjs +1047 -0
- package/fesm2020/angular-flex-layout-grid.mjs.map +1 -0
- package/fesm2020/angular-flex-layout-server.mjs +322 -0
- package/fesm2020/angular-flex-layout-server.mjs.map +1 -0
- package/fesm2020/angular-flex-layout.mjs +92 -0
- package/fesm2020/angular-flex-layout.mjs.map +1 -0
- package/flex/README.md +19 -0
- package/flex/angular-flex-layout-flex.d.ts +5 -0
- package/flex/flex/flex.d.ts +59 -0
- package/flex/flex-align/flex-align.d.ts +32 -0
- package/flex/flex-fill/flex-fill.d.ts +33 -0
- package/flex/flex-offset/flex-offset.d.ts +44 -0
- package/flex/flex-order/flex-order.d.ts +34 -0
- package/flex/layout/layout.d.ts +43 -0
- package/flex/layout-align/layout-align.d.ts +49 -0
- package/flex/layout-gap/layout-gap.d.ts +65 -0
- package/flex/module.d.ts +21 -0
- package/flex/package.json +10 -0
- package/flex/public-api.d.ts +16 -0
- package/grid/README.md +19 -0
- package/grid/align-columns/align-columns.d.ts +39 -0
- package/grid/align-rows/align-rows.d.ts +39 -0
- package/grid/angular-flex-layout-grid.d.ts +5 -0
- package/grid/area/area.d.ts +34 -0
- package/grid/areas/areas.d.ts +41 -0
- package/grid/auto/auto.d.ts +41 -0
- package/grid/column/column.d.ts +34 -0
- package/grid/columns/columns.d.ts +43 -0
- package/grid/gap/gap.d.ts +42 -0
- package/grid/grid-align/grid-align.d.ts +37 -0
- package/grid/module.d.ts +23 -0
- package/grid/package.json +10 -0
- package/grid/public-api.d.ts +19 -0
- package/grid/row/row.d.ts +34 -0
- package/grid/rows/rows.d.ts +43 -0
- package/module.d.ts +30 -0
- package/package.json +100 -0
- package/public-api.d.ts +18 -0
- package/server/README.md +23 -0
- package/server/angular-flex-layout-server.d.ts +5 -0
- package/server/module.d.ts +6 -0
- package/server/package.json +10 -0
- package/server/public-api.d.ts +9 -0
- package/server/server-match-media.d.ts +61 -0
- package/server/server-provider.d.ts +44 -0
- package/version.d.ts +10 -0
|
@@ -0,0 +1,2331 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { APP_BOOTSTRAP_LISTENER, PLATFORM_ID, NgModule, Injectable, InjectionToken, Inject, inject, Directive } from '@angular/core';
|
|
3
|
+
import { isPlatformBrowser, DOCUMENT, isPlatformServer } from '@angular/common';
|
|
4
|
+
import { BehaviorSubject, Observable, merge, Subject, asapScheduler, of, fromEvent } from 'rxjs';
|
|
5
|
+
import { applyCssPrefixes, extendObject, buildLayoutCSS } from '@angular/flex-layout/_private-utils';
|
|
6
|
+
import { filter, tap, map, debounceTime, switchMap, distinctUntilChanged, takeUntil, take } from 'rxjs/operators';
|
|
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
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Find all of the server-generated stylings, if any, and remove them
|
|
17
|
+
* This will be in the form of inline classes and the style block in the
|
|
18
|
+
* head of the DOM
|
|
19
|
+
*/
|
|
20
|
+
function removeStyles(_document, platformId) {
|
|
21
|
+
return () => {
|
|
22
|
+
if (isPlatformBrowser(platformId)) {
|
|
23
|
+
const elements = Array.from(_document.querySelectorAll(`[class*=${CLASS_NAME}]`));
|
|
24
|
+
// RegExp constructor should only be used if passing a variable to the constructor.
|
|
25
|
+
// When using static regular expression it is more performant to use reg exp literal.
|
|
26
|
+
// This is also needed to provide Safari 9 compatibility, please see
|
|
27
|
+
// https://stackoverflow.com/questions/37919802 for more discussion.
|
|
28
|
+
const classRegex = /\bflex-layout-.+?\b/g;
|
|
29
|
+
elements.forEach(el => {
|
|
30
|
+
el.classList.contains(`${CLASS_NAME}ssr`) && el.parentNode ?
|
|
31
|
+
el.parentNode.removeChild(el) : el.className.replace(classRegex, '');
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Provider to remove SSR styles on the browser
|
|
38
|
+
*/
|
|
39
|
+
const BROWSER_PROVIDER = {
|
|
40
|
+
provide: APP_BOOTSTRAP_LISTENER,
|
|
41
|
+
useFactory: removeStyles,
|
|
42
|
+
deps: [DOCUMENT, PLATFORM_ID],
|
|
43
|
+
multi: true
|
|
44
|
+
};
|
|
45
|
+
const CLASS_NAME = 'flex-layout-';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @license
|
|
49
|
+
* Copyright Google LLC All Rights Reserved.
|
|
50
|
+
*
|
|
51
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
52
|
+
* found in the LICENSE file at https://angular.io/license
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* *****************************************************************
|
|
56
|
+
* Define module for common Angular Layout utilities
|
|
57
|
+
* *****************************************************************
|
|
58
|
+
*/
|
|
59
|
+
class CoreModule {
|
|
60
|
+
}
|
|
61
|
+
CoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: CoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
62
|
+
CoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: CoreModule });
|
|
63
|
+
CoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: CoreModule, providers: [BROWSER_PROVIDER] });
|
|
64
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: CoreModule, decorators: [{
|
|
65
|
+
type: NgModule,
|
|
66
|
+
args: [{
|
|
67
|
+
providers: [BROWSER_PROVIDER]
|
|
68
|
+
}]
|
|
69
|
+
}] });
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Class instances emitted [to observers] for each mql notification
|
|
73
|
+
*/
|
|
74
|
+
class MediaChange {
|
|
75
|
+
/**
|
|
76
|
+
* @param matches whether the mediaQuery is currently activated
|
|
77
|
+
* @param mediaQuery e.g. (min-width: 600px) and (max-width: 959px)
|
|
78
|
+
* @param mqAlias e.g. gt-sm, md, gt-lg
|
|
79
|
+
* @param suffix e.g. GtSM, Md, GtLg
|
|
80
|
+
* @param priority the priority of activation for the given breakpoint
|
|
81
|
+
*/
|
|
82
|
+
constructor(matches = false, mediaQuery = 'all', mqAlias = '', suffix = '', priority = 0) {
|
|
83
|
+
this.matches = matches;
|
|
84
|
+
this.mediaQuery = mediaQuery;
|
|
85
|
+
this.mqAlias = mqAlias;
|
|
86
|
+
this.suffix = suffix;
|
|
87
|
+
this.priority = priority;
|
|
88
|
+
this.property = '';
|
|
89
|
+
}
|
|
90
|
+
/** Create an exact copy of the MediaChange */
|
|
91
|
+
clone() {
|
|
92
|
+
return new MediaChange(this.matches, this.mediaQuery, this.mqAlias, this.suffix);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @license
|
|
98
|
+
* Copyright Google LLC All Rights Reserved.
|
|
99
|
+
*
|
|
100
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
101
|
+
* found in the LICENSE file at https://angular.io/license
|
|
102
|
+
*/
|
|
103
|
+
/**
|
|
104
|
+
* Utility to emulate a CSS stylesheet
|
|
105
|
+
*
|
|
106
|
+
* This utility class stores all of the styles for a given HTML element
|
|
107
|
+
* as a readonly `stylesheet` map.
|
|
108
|
+
*/
|
|
109
|
+
class StylesheetMap {
|
|
110
|
+
constructor() {
|
|
111
|
+
this.stylesheet = new Map();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Add an individual style to an HTML element
|
|
115
|
+
*/
|
|
116
|
+
addStyleToElement(element, style, value) {
|
|
117
|
+
const stylesheet = this.stylesheet.get(element);
|
|
118
|
+
if (stylesheet) {
|
|
119
|
+
stylesheet.set(style, value);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
this.stylesheet.set(element, new Map([[style, value]]));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Clear the virtual stylesheet
|
|
127
|
+
*/
|
|
128
|
+
clearStyles() {
|
|
129
|
+
this.stylesheet.clear();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Retrieve a given style for an HTML element
|
|
133
|
+
*/
|
|
134
|
+
getStyleForElement(el, styleName) {
|
|
135
|
+
const styles = this.stylesheet.get(el);
|
|
136
|
+
let value = '';
|
|
137
|
+
if (styles) {
|
|
138
|
+
const style = styles.get(styleName);
|
|
139
|
+
if (typeof style === 'number' || typeof style === 'string') {
|
|
140
|
+
value = style + '';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return value;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
StylesheetMap.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: StylesheetMap, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
147
|
+
StylesheetMap.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: StylesheetMap, providedIn: 'root' });
|
|
148
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: StylesheetMap, decorators: [{
|
|
149
|
+
type: Injectable,
|
|
150
|
+
args: [{ providedIn: 'root' }]
|
|
151
|
+
}] });
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @license
|
|
155
|
+
* Copyright Google LLC All Rights Reserved.
|
|
156
|
+
*
|
|
157
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
158
|
+
* found in the LICENSE file at https://angular.io/license
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @license
|
|
163
|
+
* Copyright Google LLC All Rights Reserved.
|
|
164
|
+
*
|
|
165
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
166
|
+
* found in the LICENSE file at https://angular.io/license
|
|
167
|
+
*/
|
|
168
|
+
const DEFAULT_CONFIG = {
|
|
169
|
+
addFlexToParent: true,
|
|
170
|
+
addOrientationBps: false,
|
|
171
|
+
disableDefaultBps: false,
|
|
172
|
+
disableVendorPrefixes: false,
|
|
173
|
+
serverLoaded: false,
|
|
174
|
+
useColumnBasisZero: true,
|
|
175
|
+
printWithBreakpoints: [],
|
|
176
|
+
mediaTriggerAutoRestore: true,
|
|
177
|
+
ssrObserveBreakpoints: [],
|
|
178
|
+
// This is disabled by default because otherwise the multiplier would
|
|
179
|
+
// run for all users, regardless of whether they're using this feature.
|
|
180
|
+
// Instead, we disable it by default, which requires this ugly cast.
|
|
181
|
+
multiplier: undefined,
|
|
182
|
+
defaultUnit: 'px',
|
|
183
|
+
detectLayoutDisplay: false,
|
|
184
|
+
};
|
|
185
|
+
const LAYOUT_CONFIG = new InjectionToken('Flex Layout token, config options for the library', {
|
|
186
|
+
providedIn: 'root',
|
|
187
|
+
factory: () => DEFAULT_CONFIG
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @license
|
|
192
|
+
* Copyright Google LLC All Rights Reserved.
|
|
193
|
+
*
|
|
194
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
195
|
+
* found in the LICENSE file at https://angular.io/license
|
|
196
|
+
*/
|
|
197
|
+
/**
|
|
198
|
+
* Token that is provided to tell whether the FlexLayoutServerModule
|
|
199
|
+
* has been included in the bundle
|
|
200
|
+
*
|
|
201
|
+
* NOTE: This can be manually provided to disable styles when using SSR
|
|
202
|
+
*/
|
|
203
|
+
const SERVER_TOKEN = new InjectionToken('FlexLayoutServerLoaded', {
|
|
204
|
+
providedIn: 'root',
|
|
205
|
+
factory: () => false
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @license
|
|
210
|
+
* Copyright Google LLC All Rights Reserved.
|
|
211
|
+
*
|
|
212
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
213
|
+
* found in the LICENSE file at https://angular.io/license
|
|
214
|
+
*/
|
|
215
|
+
const BREAKPOINT = new InjectionToken('Flex Layout token, collect all breakpoints into one provider', {
|
|
216
|
+
providedIn: 'root',
|
|
217
|
+
factory: () => null
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @license
|
|
222
|
+
* Copyright Google LLC All Rights Reserved.
|
|
223
|
+
*
|
|
224
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
225
|
+
* found in the LICENSE file at https://angular.io/license
|
|
226
|
+
*/
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @license
|
|
230
|
+
* Copyright Google LLC All Rights Reserved.
|
|
231
|
+
*
|
|
232
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
233
|
+
* found in the LICENSE file at https://angular.io/license
|
|
234
|
+
*/
|
|
235
|
+
/**
|
|
236
|
+
* For the specified MediaChange, make sure it contains the breakpoint alias
|
|
237
|
+
* and suffix (if available).
|
|
238
|
+
*/
|
|
239
|
+
function mergeAlias(dest, source) {
|
|
240
|
+
dest = dest ? dest.clone() : new MediaChange();
|
|
241
|
+
if (source) {
|
|
242
|
+
dest.mqAlias = source.alias;
|
|
243
|
+
dest.mediaQuery = source.mediaQuery;
|
|
244
|
+
dest.suffix = source.suffix;
|
|
245
|
+
dest.priority = source.priority;
|
|
246
|
+
}
|
|
247
|
+
return dest;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** A class that encapsulates CSS style generation for common directives */
|
|
251
|
+
class StyleBuilder {
|
|
252
|
+
constructor() {
|
|
253
|
+
/** Whether to cache the generated output styles */
|
|
254
|
+
this.shouldCache = true;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Run a side effect computation given the input string and the computed styles
|
|
258
|
+
* from the build task and the host configuration object
|
|
259
|
+
* NOTE: This should be a no-op unless an algorithm is provided in a subclass
|
|
260
|
+
*/
|
|
261
|
+
sideEffect(_input, _styles, _parent) {
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* @license
|
|
267
|
+
* Copyright Google LLC All Rights Reserved.
|
|
268
|
+
*
|
|
269
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
270
|
+
* found in the LICENSE file at https://angular.io/license
|
|
271
|
+
*/
|
|
272
|
+
class StyleUtils {
|
|
273
|
+
constructor(_serverStylesheet, _serverModuleLoaded, _platformId, layoutConfig) {
|
|
274
|
+
this._serverStylesheet = _serverStylesheet;
|
|
275
|
+
this._serverModuleLoaded = _serverModuleLoaded;
|
|
276
|
+
this._platformId = _platformId;
|
|
277
|
+
this.layoutConfig = layoutConfig;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Applies styles given via string pair or object map to the directive element
|
|
281
|
+
*/
|
|
282
|
+
applyStyleToElement(element, style, value = null) {
|
|
283
|
+
let styles = {};
|
|
284
|
+
if (typeof style === 'string') {
|
|
285
|
+
styles[style] = value;
|
|
286
|
+
style = styles;
|
|
287
|
+
}
|
|
288
|
+
styles = this.layoutConfig.disableVendorPrefixes ? style : applyCssPrefixes(style);
|
|
289
|
+
this._applyMultiValueStyleToElement(styles, element);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Applies styles given via string pair or object map to the directive's element
|
|
293
|
+
*/
|
|
294
|
+
applyStyleToElements(style, elements = []) {
|
|
295
|
+
const styles = this.layoutConfig.disableVendorPrefixes ? style : applyCssPrefixes(style);
|
|
296
|
+
elements.forEach(el => {
|
|
297
|
+
this._applyMultiValueStyleToElement(styles, el);
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Determine the DOM element's Flexbox flow (flex-direction)
|
|
302
|
+
*
|
|
303
|
+
* Check inline style first then check computed (stylesheet) style
|
|
304
|
+
*/
|
|
305
|
+
getFlowDirection(target) {
|
|
306
|
+
const query = 'flex-direction';
|
|
307
|
+
let value = this.lookupStyle(target, query);
|
|
308
|
+
const hasInlineValue = this.lookupInlineStyle(target, query) ||
|
|
309
|
+
(isPlatformServer(this._platformId) && this._serverModuleLoaded) ? value : '';
|
|
310
|
+
return [value || 'row', hasInlineValue];
|
|
311
|
+
}
|
|
312
|
+
hasWrap(target) {
|
|
313
|
+
const query = 'flex-wrap';
|
|
314
|
+
return this.lookupStyle(target, query) === 'wrap';
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Find the DOM element's raw attribute value (if any)
|
|
318
|
+
*/
|
|
319
|
+
lookupAttributeValue(element, attribute) {
|
|
320
|
+
var _a;
|
|
321
|
+
return (_a = element.getAttribute(attribute)) !== null && _a !== void 0 ? _a : '';
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Find the DOM element's inline style value (if any)
|
|
325
|
+
*/
|
|
326
|
+
lookupInlineStyle(element, styleName) {
|
|
327
|
+
return isPlatformBrowser(this._platformId) ?
|
|
328
|
+
element.style.getPropertyValue(styleName) : getServerStyle(element, styleName);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Determine the inline or inherited CSS style
|
|
332
|
+
* NOTE: platform-server has no implementation for getComputedStyle
|
|
333
|
+
*/
|
|
334
|
+
lookupStyle(element, styleName, inlineOnly = false) {
|
|
335
|
+
let value = '';
|
|
336
|
+
if (element) {
|
|
337
|
+
let immediateValue = value = this.lookupInlineStyle(element, styleName);
|
|
338
|
+
if (!immediateValue) {
|
|
339
|
+
if (isPlatformBrowser(this._platformId)) {
|
|
340
|
+
if (!inlineOnly) {
|
|
341
|
+
value = getComputedStyle(element).getPropertyValue(styleName);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
if (this._serverModuleLoaded) {
|
|
346
|
+
value = this._serverStylesheet.getStyleForElement(element, styleName);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// Note: 'inline' is the default of all elements, unless UA stylesheet overrides;
|
|
352
|
+
// in which case getComputedStyle() should determine a valid value.
|
|
353
|
+
return value ? value.trim() : '';
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Applies the styles to the element. The styles object map may contain an array of values
|
|
357
|
+
* Each value will be added as element style
|
|
358
|
+
* Keys are sorted to add prefixed styles (like -webkit-x) first, before the standard ones
|
|
359
|
+
*/
|
|
360
|
+
_applyMultiValueStyleToElement(styles, element) {
|
|
361
|
+
Object.keys(styles).sort().forEach(key => {
|
|
362
|
+
const el = styles[key];
|
|
363
|
+
const values = Array.isArray(el) ? el : [el];
|
|
364
|
+
values.sort();
|
|
365
|
+
for (let value of values) {
|
|
366
|
+
value = value ? value + '' : '';
|
|
367
|
+
if (isPlatformBrowser(this._platformId) || !this._serverModuleLoaded) {
|
|
368
|
+
isPlatformBrowser(this._platformId) ?
|
|
369
|
+
element.style.setProperty(key, value) : setServerStyle(element, key, value);
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
this._serverStylesheet.addStyleToElement(element, key, value);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
StyleUtils.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: StyleUtils, deps: [{ token: StylesheetMap }, { token: SERVER_TOKEN }, { token: PLATFORM_ID }, { token: LAYOUT_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
379
|
+
StyleUtils.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: StyleUtils, providedIn: 'root' });
|
|
380
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: StyleUtils, decorators: [{
|
|
381
|
+
type: Injectable,
|
|
382
|
+
args: [{ providedIn: 'root' }]
|
|
383
|
+
}], ctorParameters: function () {
|
|
384
|
+
return [{ type: StylesheetMap }, { type: undefined, decorators: [{
|
|
385
|
+
type: Inject,
|
|
386
|
+
args: [SERVER_TOKEN]
|
|
387
|
+
}] }, { type: Object, decorators: [{
|
|
388
|
+
type: Inject,
|
|
389
|
+
args: [PLATFORM_ID]
|
|
390
|
+
}] }, { type: undefined, decorators: [{
|
|
391
|
+
type: Inject,
|
|
392
|
+
args: [LAYOUT_CONFIG]
|
|
393
|
+
}] }];
|
|
394
|
+
} });
|
|
395
|
+
function getServerStyle(element, styleName) {
|
|
396
|
+
var _a;
|
|
397
|
+
const styleMap = readStyleAttribute(element);
|
|
398
|
+
return (_a = styleMap[styleName]) !== null && _a !== void 0 ? _a : '';
|
|
399
|
+
}
|
|
400
|
+
function setServerStyle(element, styleName, styleValue) {
|
|
401
|
+
styleName = styleName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
402
|
+
const styleMap = readStyleAttribute(element);
|
|
403
|
+
styleMap[styleName] = styleValue !== null && styleValue !== void 0 ? styleValue : '';
|
|
404
|
+
writeStyleAttribute(element, styleMap);
|
|
405
|
+
}
|
|
406
|
+
function writeStyleAttribute(element, styleMap) {
|
|
407
|
+
let styleAttrValue = '';
|
|
408
|
+
for (const key in styleMap) {
|
|
409
|
+
const newValue = styleMap[key];
|
|
410
|
+
if (newValue) {
|
|
411
|
+
styleAttrValue += `${key}:${styleMap[key]};`;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
element.setAttribute('style', styleAttrValue);
|
|
415
|
+
}
|
|
416
|
+
function readStyleAttribute(element) {
|
|
417
|
+
const styleMap = {};
|
|
418
|
+
const styleAttribute = element.getAttribute('style');
|
|
419
|
+
if (styleAttribute) {
|
|
420
|
+
const styleList = styleAttribute.split(/;+/g);
|
|
421
|
+
for (let i = 0; i < styleList.length; i++) {
|
|
422
|
+
const style = styleList[i].trim();
|
|
423
|
+
if (style.length > 0) {
|
|
424
|
+
const colonIndex = style.indexOf(':');
|
|
425
|
+
if (colonIndex === -1) {
|
|
426
|
+
throw new Error(`Invalid CSS style: ${style}`);
|
|
427
|
+
}
|
|
428
|
+
const name = style.substr(0, colonIndex).trim();
|
|
429
|
+
styleMap[name] = style.substr(colonIndex + 1).trim();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return styleMap;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* @license
|
|
438
|
+
* Copyright Google LLC All Rights Reserved.
|
|
439
|
+
*
|
|
440
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
441
|
+
* found in the LICENSE file at https://angular.io/license
|
|
442
|
+
*/
|
|
443
|
+
/** HOF to sort the breakpoints by descending priority */
|
|
444
|
+
function sortDescendingPriority(a, b) {
|
|
445
|
+
const priorityA = a ? a.priority || 0 : 0;
|
|
446
|
+
const priorityB = b ? b.priority || 0 : 0;
|
|
447
|
+
return priorityB - priorityA;
|
|
448
|
+
}
|
|
449
|
+
/** HOF to sort the breakpoints by ascending priority */
|
|
450
|
+
function sortAscendingPriority(a, b) {
|
|
451
|
+
const pA = a.priority || 0;
|
|
452
|
+
const pB = b.priority || 0;
|
|
453
|
+
return pA - pB;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* @license
|
|
458
|
+
* Copyright Google LLC All Rights Reserved.
|
|
459
|
+
*
|
|
460
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
461
|
+
* found in the LICENSE file at https://angular.io/license
|
|
462
|
+
*/
|
|
463
|
+
/**
|
|
464
|
+
* MediaMonitor configures listeners to mediaQuery changes and publishes an Observable facade to
|
|
465
|
+
* convert mediaQuery change callbacks to subscriber notifications. These notifications will be
|
|
466
|
+
* performed within the ng Zone to trigger change detections and component updates.
|
|
467
|
+
*
|
|
468
|
+
* NOTE: both mediaQuery activations and de-activations are announced in notifications
|
|
469
|
+
*/
|
|
470
|
+
class MatchMedia {
|
|
471
|
+
constructor(_zone, _platformId, _document) {
|
|
472
|
+
this._zone = _zone;
|
|
473
|
+
this._platformId = _platformId;
|
|
474
|
+
this._document = _document;
|
|
475
|
+
/** Initialize source with 'all' so all non-responsive APIs trigger style updates */
|
|
476
|
+
this.source = new BehaviorSubject(new MediaChange(true));
|
|
477
|
+
this.registry = new Map();
|
|
478
|
+
this.pendingRemoveListenerFns = [];
|
|
479
|
+
this._observable$ = this.source.asObservable();
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Publish list of all current activations
|
|
483
|
+
*/
|
|
484
|
+
get activations() {
|
|
485
|
+
const results = [];
|
|
486
|
+
this.registry.forEach((mql, key) => {
|
|
487
|
+
if (mql.matches) {
|
|
488
|
+
results.push(key);
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
return results;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* For the specified mediaQuery?
|
|
495
|
+
*/
|
|
496
|
+
isActive(mediaQuery) {
|
|
497
|
+
var _a;
|
|
498
|
+
const mql = this.registry.get(mediaQuery);
|
|
499
|
+
return (_a = mql === null || mql === void 0 ? void 0 : mql.matches) !== null && _a !== void 0 ? _a : this.registerQuery(mediaQuery).some(m => m.matches);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* External observers can watch for all (or a specific) mql changes.
|
|
503
|
+
* Typically used by the MediaQueryAdaptor; optionally available to components
|
|
504
|
+
* who wish to use the MediaMonitor as mediaMonitor$ observable service.
|
|
505
|
+
*
|
|
506
|
+
* Use deferred registration process to register breakpoints only on subscription
|
|
507
|
+
* This logic also enforces logic to register all mediaQueries BEFORE notify
|
|
508
|
+
* subscribers of notifications.
|
|
509
|
+
*/
|
|
510
|
+
observe(mqList, filterOthers = false) {
|
|
511
|
+
if (mqList && mqList.length) {
|
|
512
|
+
const matchMedia$ = this._observable$.pipe(filter((change) => !filterOthers ? true : (mqList.indexOf(change.mediaQuery) > -1)));
|
|
513
|
+
const registration$ = new Observable((observer) => {
|
|
514
|
+
const matches = this.registerQuery(mqList);
|
|
515
|
+
if (matches.length) {
|
|
516
|
+
const lastChange = matches.pop();
|
|
517
|
+
matches.forEach((e) => {
|
|
518
|
+
observer.next(e);
|
|
519
|
+
});
|
|
520
|
+
this.source.next(lastChange); // last match is cached
|
|
521
|
+
}
|
|
522
|
+
observer.complete();
|
|
523
|
+
});
|
|
524
|
+
return merge(registration$, matchMedia$);
|
|
525
|
+
}
|
|
526
|
+
return this._observable$;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Based on the BreakPointRegistry provider, register internal listeners for each unique
|
|
530
|
+
* mediaQuery. Each listener emits specific MediaChange data to observers
|
|
531
|
+
*/
|
|
532
|
+
registerQuery(mediaQuery) {
|
|
533
|
+
const list = Array.isArray(mediaQuery) ? mediaQuery : [mediaQuery];
|
|
534
|
+
const matches = [];
|
|
535
|
+
buildQueryCss(list, this._document);
|
|
536
|
+
list.forEach((query) => {
|
|
537
|
+
const onMQLEvent = (e) => {
|
|
538
|
+
this._zone.run(() => this.source.next(new MediaChange(e.matches, query)));
|
|
539
|
+
};
|
|
540
|
+
let mql = this.registry.get(query);
|
|
541
|
+
if (!mql) {
|
|
542
|
+
mql = this.buildMQL(query);
|
|
543
|
+
mql.addListener(onMQLEvent);
|
|
544
|
+
this.pendingRemoveListenerFns.push(() => mql.removeListener(onMQLEvent));
|
|
545
|
+
this.registry.set(query, mql);
|
|
546
|
+
}
|
|
547
|
+
if (mql.matches) {
|
|
548
|
+
matches.push(new MediaChange(true, query));
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
return matches;
|
|
552
|
+
}
|
|
553
|
+
ngOnDestroy() {
|
|
554
|
+
let fn;
|
|
555
|
+
while (fn = this.pendingRemoveListenerFns.pop()) {
|
|
556
|
+
fn();
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Call window.matchMedia() to build a MediaQueryList; which
|
|
561
|
+
* supports 0..n listeners for activation/deactivation
|
|
562
|
+
*/
|
|
563
|
+
buildMQL(query) {
|
|
564
|
+
return constructMql(query, isPlatformBrowser(this._platformId));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
MatchMedia.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MatchMedia, deps: [{ token: i0.NgZone }, { token: PLATFORM_ID }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
568
|
+
MatchMedia.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MatchMedia, providedIn: 'root' });
|
|
569
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MatchMedia, decorators: [{
|
|
570
|
+
type: Injectable,
|
|
571
|
+
args: [{ providedIn: 'root' }]
|
|
572
|
+
}], ctorParameters: function () {
|
|
573
|
+
return [{ type: i0.NgZone }, { type: Object, decorators: [{
|
|
574
|
+
type: Inject,
|
|
575
|
+
args: [PLATFORM_ID]
|
|
576
|
+
}] }, { type: undefined, decorators: [{
|
|
577
|
+
type: Inject,
|
|
578
|
+
args: [DOCUMENT]
|
|
579
|
+
}] }];
|
|
580
|
+
} });
|
|
581
|
+
/**
|
|
582
|
+
* Private global registry for all dynamically-created, injected style tags
|
|
583
|
+
* @see prepare(query)
|
|
584
|
+
*/
|
|
585
|
+
const ALL_STYLES = {};
|
|
586
|
+
/**
|
|
587
|
+
* For Webkit engines that only trigger the MediaQueryList Listener
|
|
588
|
+
* when there is at least one CSS selector for the respective media query.
|
|
589
|
+
*
|
|
590
|
+
* @param mediaQueries
|
|
591
|
+
* @param _document
|
|
592
|
+
*/
|
|
593
|
+
function buildQueryCss(mediaQueries, _document) {
|
|
594
|
+
const list = mediaQueries.filter(it => !ALL_STYLES[it]);
|
|
595
|
+
if (list.length > 0) {
|
|
596
|
+
const query = list.join(', ');
|
|
597
|
+
try {
|
|
598
|
+
const styleEl = _document.createElement('style');
|
|
599
|
+
styleEl.setAttribute('type', 'text/css');
|
|
600
|
+
if (!styleEl.styleSheet) {
|
|
601
|
+
const cssText = `
|
|
602
|
+
/*
|
|
603
|
+
@angular/flex-layout - workaround for possible browser quirk with mediaQuery listeners
|
|
604
|
+
see http://bit.ly/2sd4HMP
|
|
605
|
+
*/
|
|
606
|
+
@media ${query} {.fx-query-test{ }}
|
|
607
|
+
`;
|
|
608
|
+
styleEl.appendChild(_document.createTextNode(cssText));
|
|
609
|
+
}
|
|
610
|
+
_document.head.appendChild(styleEl);
|
|
611
|
+
// Store in private global registry
|
|
612
|
+
list.forEach(mq => ALL_STYLES[mq] = styleEl);
|
|
613
|
+
}
|
|
614
|
+
catch (e) {
|
|
615
|
+
console.error(e);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
function constructMql(query, isBrowser) {
|
|
620
|
+
const canListen = isBrowser && !!window.matchMedia('all').addListener;
|
|
621
|
+
return canListen ? window.matchMedia(query) : {
|
|
622
|
+
matches: query === 'all' || query === '',
|
|
623
|
+
media: query,
|
|
624
|
+
addListener: () => {
|
|
625
|
+
},
|
|
626
|
+
removeListener: () => {
|
|
627
|
+
},
|
|
628
|
+
onchange: null,
|
|
629
|
+
addEventListener() {
|
|
630
|
+
},
|
|
631
|
+
removeEventListener() {
|
|
632
|
+
},
|
|
633
|
+
dispatchEvent() {
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* NOTE: Smaller ranges have HIGHER priority since the match is more specific
|
|
641
|
+
*/
|
|
642
|
+
const DEFAULT_BREAKPOINTS = [
|
|
643
|
+
{
|
|
644
|
+
alias: 'xs',
|
|
645
|
+
mediaQuery: 'screen and (min-width: 0px) and (max-width: 599.98px)',
|
|
646
|
+
priority: 1000,
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
alias: 'sm',
|
|
650
|
+
mediaQuery: 'screen and (min-width: 600px) and (max-width: 959.98px)',
|
|
651
|
+
priority: 900,
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
alias: 'md',
|
|
655
|
+
mediaQuery: 'screen and (min-width: 960px) and (max-width: 1279.98px)',
|
|
656
|
+
priority: 800,
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
alias: 'lg',
|
|
660
|
+
mediaQuery: 'screen and (min-width: 1280px) and (max-width: 1919.98px)',
|
|
661
|
+
priority: 700,
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
alias: 'xl',
|
|
665
|
+
mediaQuery: 'screen and (min-width: 1920px) and (max-width: 4999.98px)',
|
|
666
|
+
priority: 600,
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
alias: 'lt-sm',
|
|
670
|
+
overlapping: true,
|
|
671
|
+
mediaQuery: 'screen and (max-width: 599.98px)',
|
|
672
|
+
priority: 950,
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
alias: 'lt-md',
|
|
676
|
+
overlapping: true,
|
|
677
|
+
mediaQuery: 'screen and (max-width: 959.98px)',
|
|
678
|
+
priority: 850,
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
alias: 'lt-lg',
|
|
682
|
+
overlapping: true,
|
|
683
|
+
mediaQuery: 'screen and (max-width: 1279.98px)',
|
|
684
|
+
priority: 750,
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
alias: 'lt-xl',
|
|
688
|
+
overlapping: true,
|
|
689
|
+
priority: 650,
|
|
690
|
+
mediaQuery: 'screen and (max-width: 1919.98px)',
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
alias: 'gt-xs',
|
|
694
|
+
overlapping: true,
|
|
695
|
+
mediaQuery: 'screen and (min-width: 600px)',
|
|
696
|
+
priority: -950,
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
alias: 'gt-sm',
|
|
700
|
+
overlapping: true,
|
|
701
|
+
mediaQuery: 'screen and (min-width: 960px)',
|
|
702
|
+
priority: -850,
|
|
703
|
+
}, {
|
|
704
|
+
alias: 'gt-md',
|
|
705
|
+
overlapping: true,
|
|
706
|
+
mediaQuery: 'screen and (min-width: 1280px)',
|
|
707
|
+
priority: -750,
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
alias: 'gt-lg',
|
|
711
|
+
overlapping: true,
|
|
712
|
+
mediaQuery: 'screen and (min-width: 1920px)',
|
|
713
|
+
priority: -650,
|
|
714
|
+
}
|
|
715
|
+
];
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* @license
|
|
719
|
+
* Copyright Google LLC All Rights Reserved.
|
|
720
|
+
*
|
|
721
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
722
|
+
* found in the LICENSE file at https://angular.io/license
|
|
723
|
+
*/
|
|
724
|
+
/* tslint:disable */
|
|
725
|
+
const HANDSET_PORTRAIT = '(orientation: portrait) and (max-width: 599.98px)';
|
|
726
|
+
const HANDSET_LANDSCAPE = '(orientation: landscape) and (max-width: 959.98px)';
|
|
727
|
+
const TABLET_PORTRAIT = '(orientation: portrait) and (min-width: 600px) and (max-width: 839.98px)';
|
|
728
|
+
const TABLET_LANDSCAPE = '(orientation: landscape) and (min-width: 960px) and (max-width: 1279.98px)';
|
|
729
|
+
const WEB_PORTRAIT = '(orientation: portrait) and (min-width: 840px)';
|
|
730
|
+
const WEB_LANDSCAPE = '(orientation: landscape) and (min-width: 1280px)';
|
|
731
|
+
const ScreenTypes = {
|
|
732
|
+
'HANDSET': `${HANDSET_PORTRAIT}, ${HANDSET_LANDSCAPE}`,
|
|
733
|
+
'TABLET': `${TABLET_PORTRAIT} , ${TABLET_LANDSCAPE}`,
|
|
734
|
+
'WEB': `${WEB_PORTRAIT}, ${WEB_LANDSCAPE} `,
|
|
735
|
+
'HANDSET_PORTRAIT': `${HANDSET_PORTRAIT}`,
|
|
736
|
+
'TABLET_PORTRAIT': `${TABLET_PORTRAIT} `,
|
|
737
|
+
'WEB_PORTRAIT': `${WEB_PORTRAIT}`,
|
|
738
|
+
'HANDSET_LANDSCAPE': `${HANDSET_LANDSCAPE}`,
|
|
739
|
+
'TABLET_LANDSCAPE': `${TABLET_LANDSCAPE}`,
|
|
740
|
+
'WEB_LANDSCAPE': `${WEB_LANDSCAPE}`
|
|
741
|
+
};
|
|
742
|
+
/**
|
|
743
|
+
* Extended Breakpoints for handset/tablets with landscape or portrait orientations
|
|
744
|
+
*/
|
|
745
|
+
const ORIENTATION_BREAKPOINTS = [
|
|
746
|
+
{ 'alias': 'handset', priority: 2000, 'mediaQuery': ScreenTypes.HANDSET },
|
|
747
|
+
{ 'alias': 'handset.landscape', priority: 2000, 'mediaQuery': ScreenTypes.HANDSET_LANDSCAPE },
|
|
748
|
+
{ 'alias': 'handset.portrait', priority: 2000, 'mediaQuery': ScreenTypes.HANDSET_PORTRAIT },
|
|
749
|
+
{ 'alias': 'tablet', priority: 2100, 'mediaQuery': ScreenTypes.TABLET },
|
|
750
|
+
{ 'alias': 'tablet.landscape', priority: 2100, 'mediaQuery': ScreenTypes.TABLET_LANDSCAPE },
|
|
751
|
+
{ 'alias': 'tablet.portrait', priority: 2100, 'mediaQuery': ScreenTypes.TABLET_PORTRAIT },
|
|
752
|
+
{ 'alias': 'web', priority: 2200, 'mediaQuery': ScreenTypes.WEB, overlapping: true },
|
|
753
|
+
{ 'alias': 'web.landscape', priority: 2200, 'mediaQuery': ScreenTypes.WEB_LANDSCAPE, overlapping: true },
|
|
754
|
+
{ 'alias': 'web.portrait', priority: 2200, 'mediaQuery': ScreenTypes.WEB_PORTRAIT, overlapping: true }
|
|
755
|
+
];
|
|
756
|
+
|
|
757
|
+
const ALIAS_DELIMITERS = /(\.|-|_)/g;
|
|
758
|
+
function firstUpperCase(part) {
|
|
759
|
+
let first = part.length > 0 ? part.charAt(0) : '';
|
|
760
|
+
let remainder = (part.length > 1) ? part.slice(1) : '';
|
|
761
|
+
return first.toUpperCase() + remainder;
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Converts snake-case to SnakeCase.
|
|
765
|
+
* @param name Text to UpperCamelCase
|
|
766
|
+
*/
|
|
767
|
+
function camelCase(name) {
|
|
768
|
+
return name
|
|
769
|
+
.replace(ALIAS_DELIMITERS, '|')
|
|
770
|
+
.split('|')
|
|
771
|
+
.map(firstUpperCase)
|
|
772
|
+
.join('');
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* For each breakpoint, ensure that a Suffix is defined;
|
|
776
|
+
* fallback to UpperCamelCase the unique Alias value
|
|
777
|
+
*/
|
|
778
|
+
function validateSuffixes(list) {
|
|
779
|
+
list.forEach((bp) => {
|
|
780
|
+
if (!bp.suffix) {
|
|
781
|
+
bp.suffix = camelCase(bp.alias); // create Suffix value based on alias
|
|
782
|
+
bp.overlapping = !!bp.overlapping; // ensure default value
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
return list;
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Merge a custom breakpoint list with the default list based on unique alias values
|
|
789
|
+
* - Items are added if the alias is not in the default list
|
|
790
|
+
* - Items are merged with the custom override if the alias exists in the default list
|
|
791
|
+
*/
|
|
792
|
+
function mergeByAlias(defaults, custom = []) {
|
|
793
|
+
const dict = {};
|
|
794
|
+
defaults.forEach(bp => {
|
|
795
|
+
dict[bp.alias] = bp;
|
|
796
|
+
});
|
|
797
|
+
// Merge custom breakpoints
|
|
798
|
+
custom.forEach((bp) => {
|
|
799
|
+
if (dict[bp.alias]) {
|
|
800
|
+
extendObject(dict[bp.alias], bp);
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
dict[bp.alias] = bp;
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
return validateSuffixes(Object.keys(dict).map(k => dict[k]));
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* @license
|
|
811
|
+
* Copyright Google LLC All Rights Reserved.
|
|
812
|
+
*
|
|
813
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
814
|
+
* found in the LICENSE file at https://angular.io/license
|
|
815
|
+
*/
|
|
816
|
+
/**
|
|
817
|
+
* Injection token unique to the flex-layout library.
|
|
818
|
+
* Use this token when build a custom provider (see below).
|
|
819
|
+
*/
|
|
820
|
+
const BREAKPOINTS = new InjectionToken('Token (@angular/flex-layout) Breakpoints', {
|
|
821
|
+
providedIn: 'root',
|
|
822
|
+
factory: () => {
|
|
823
|
+
const breakpoints = inject(BREAKPOINT);
|
|
824
|
+
const layoutConfig = inject(LAYOUT_CONFIG);
|
|
825
|
+
const bpFlattenArray = [].concat.apply([], (breakpoints || [])
|
|
826
|
+
.map((v) => Array.isArray(v) ? v : [v]));
|
|
827
|
+
const builtIns = (layoutConfig.disableDefaultBps ? [] : DEFAULT_BREAKPOINTS)
|
|
828
|
+
.concat(layoutConfig.addOrientationBps ? ORIENTATION_BREAKPOINTS : []);
|
|
829
|
+
return mergeByAlias(builtIns, bpFlattenArray);
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* @license
|
|
835
|
+
* Copyright Google LLC All Rights Reserved.
|
|
836
|
+
*
|
|
837
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
838
|
+
* found in the LICENSE file at https://angular.io/license
|
|
839
|
+
*/
|
|
840
|
+
/**
|
|
841
|
+
* Registry of 1..n MediaQuery breakpoint ranges
|
|
842
|
+
* This is published as a provider and may be overridden from custom, application-specific ranges
|
|
843
|
+
*
|
|
844
|
+
*/
|
|
845
|
+
class BreakPointRegistry {
|
|
846
|
+
constructor(list) {
|
|
847
|
+
/**
|
|
848
|
+
* Memoized BreakPoint Lookups
|
|
849
|
+
*/
|
|
850
|
+
this.findByMap = new Map();
|
|
851
|
+
this.items = [...list].sort(sortAscendingPriority);
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Search breakpoints by alias (e.g. gt-xs)
|
|
855
|
+
*/
|
|
856
|
+
findByAlias(alias) {
|
|
857
|
+
return !alias ? null : this.findWithPredicate(alias, (bp) => bp.alias === alias);
|
|
858
|
+
}
|
|
859
|
+
findByQuery(query) {
|
|
860
|
+
return this.findWithPredicate(query, (bp) => bp.mediaQuery === query);
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* Get all the breakpoints whose ranges could overlapping `normal` ranges;
|
|
864
|
+
* e.g. gt-sm overlaps md, lg, and xl
|
|
865
|
+
*/
|
|
866
|
+
get overlappings() {
|
|
867
|
+
return this.items.filter(it => it.overlapping);
|
|
868
|
+
}
|
|
869
|
+
/**
|
|
870
|
+
* Get list of all registered (non-empty) breakpoint aliases
|
|
871
|
+
*/
|
|
872
|
+
get aliases() {
|
|
873
|
+
return this.items.map(it => it.alias);
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Aliases are mapped to properties using suffixes
|
|
877
|
+
* e.g. 'gt-sm' for property 'layout' uses suffix 'GtSm'
|
|
878
|
+
* for property layoutGtSM.
|
|
879
|
+
*/
|
|
880
|
+
get suffixes() {
|
|
881
|
+
return this.items.map(it => { var _a; return (_a = it === null || it === void 0 ? void 0 : it.suffix) !== null && _a !== void 0 ? _a : ''; });
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Memoized lookup using custom predicate function
|
|
885
|
+
*/
|
|
886
|
+
findWithPredicate(key, searchFn) {
|
|
887
|
+
var _a;
|
|
888
|
+
let response = this.findByMap.get(key);
|
|
889
|
+
if (!response) {
|
|
890
|
+
response = (_a = this.items.find(searchFn)) !== null && _a !== void 0 ? _a : null;
|
|
891
|
+
this.findByMap.set(key, response);
|
|
892
|
+
}
|
|
893
|
+
return response !== null && response !== void 0 ? response : null;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
BreakPointRegistry.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: BreakPointRegistry, deps: [{ token: BREAKPOINTS }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
897
|
+
BreakPointRegistry.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: BreakPointRegistry, providedIn: 'root' });
|
|
898
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: BreakPointRegistry, decorators: [{
|
|
899
|
+
type: Injectable,
|
|
900
|
+
args: [{ providedIn: 'root' }]
|
|
901
|
+
}], ctorParameters: function () {
|
|
902
|
+
return [{ type: undefined, decorators: [{
|
|
903
|
+
type: Inject,
|
|
904
|
+
args: [BREAKPOINTS]
|
|
905
|
+
}] }];
|
|
906
|
+
} });
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* @license
|
|
910
|
+
* Copyright Google LLC All Rights Reserved.
|
|
911
|
+
*
|
|
912
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
913
|
+
* found in the LICENSE file at https://angular.io/license
|
|
914
|
+
*/
|
|
915
|
+
const PRINT = 'print';
|
|
916
|
+
const BREAKPOINT_PRINT = {
|
|
917
|
+
alias: PRINT,
|
|
918
|
+
mediaQuery: PRINT,
|
|
919
|
+
priority: 1000
|
|
920
|
+
};
|
|
921
|
+
/**
|
|
922
|
+
* PrintHook - Use to intercept print MediaQuery activations and force
|
|
923
|
+
* layouts to render with the specified print alias/breakpoint
|
|
924
|
+
*
|
|
925
|
+
* Used in MediaMarshaller and MediaObserver
|
|
926
|
+
*/
|
|
927
|
+
class PrintHook {
|
|
928
|
+
constructor(breakpoints, layoutConfig, _document) {
|
|
929
|
+
this.breakpoints = breakpoints;
|
|
930
|
+
this.layoutConfig = layoutConfig;
|
|
931
|
+
this._document = _document;
|
|
932
|
+
// registeredBeforeAfterPrintHooks tracks if we registered the `beforeprint`
|
|
933
|
+
// and `afterprint` event listeners.
|
|
934
|
+
this.registeredBeforeAfterPrintHooks = false;
|
|
935
|
+
// isPrintingBeforeAfterEvent is used to track if we are printing from within
|
|
936
|
+
// a `beforeprint` event handler. This prevents the typical `stopPrinting`
|
|
937
|
+
// form `interceptEvents` so that printing is not stopped while the dialog
|
|
938
|
+
// is still open. This is an extension of the `isPrinting` property on
|
|
939
|
+
// browsers which support `beforeprint` and `afterprint` events.
|
|
940
|
+
this.isPrintingBeforeAfterEvent = false;
|
|
941
|
+
this.beforePrintEventListeners = [];
|
|
942
|
+
this.afterPrintEventListeners = [];
|
|
943
|
+
this.formerActivations = null;
|
|
944
|
+
// Is this service currently in print mode
|
|
945
|
+
this.isPrinting = false;
|
|
946
|
+
this.queue = new PrintQueue();
|
|
947
|
+
this.deactivations = [];
|
|
948
|
+
}
|
|
949
|
+
/** Add 'print' mediaQuery: to listen for matchMedia activations */
|
|
950
|
+
withPrintQuery(queries) {
|
|
951
|
+
return [...queries, PRINT];
|
|
952
|
+
}
|
|
953
|
+
/** Is the MediaChange event for any 'print' @media */
|
|
954
|
+
isPrintEvent(e) {
|
|
955
|
+
return e.mediaQuery.startsWith(PRINT);
|
|
956
|
+
}
|
|
957
|
+
/** What is the desired mqAlias to use while printing? */
|
|
958
|
+
get printAlias() {
|
|
959
|
+
var _a;
|
|
960
|
+
return [...((_a = this.layoutConfig.printWithBreakpoints) !== null && _a !== void 0 ? _a : [])];
|
|
961
|
+
}
|
|
962
|
+
/** Lookup breakpoints associated with print aliases. */
|
|
963
|
+
get printBreakPoints() {
|
|
964
|
+
return this.printAlias
|
|
965
|
+
.map(alias => this.breakpoints.findByAlias(alias))
|
|
966
|
+
.filter(bp => bp !== null);
|
|
967
|
+
}
|
|
968
|
+
/** Lookup breakpoint associated with mediaQuery */
|
|
969
|
+
getEventBreakpoints({ mediaQuery }) {
|
|
970
|
+
const bp = this.breakpoints.findByQuery(mediaQuery);
|
|
971
|
+
const list = bp ? [...this.printBreakPoints, bp] : this.printBreakPoints;
|
|
972
|
+
return list.sort(sortDescendingPriority);
|
|
973
|
+
}
|
|
974
|
+
/** Update event with printAlias mediaQuery information */
|
|
975
|
+
updateEvent(event) {
|
|
976
|
+
var _a;
|
|
977
|
+
let bp = this.breakpoints.findByQuery(event.mediaQuery);
|
|
978
|
+
if (this.isPrintEvent(event)) {
|
|
979
|
+
// Reset from 'print' to first (highest priority) print breakpoint
|
|
980
|
+
bp = this.getEventBreakpoints(event)[0];
|
|
981
|
+
event.mediaQuery = (_a = bp === null || bp === void 0 ? void 0 : bp.mediaQuery) !== null && _a !== void 0 ? _a : '';
|
|
982
|
+
}
|
|
983
|
+
return mergeAlias(event, bp);
|
|
984
|
+
}
|
|
985
|
+
// registerBeforeAfterPrintHooks registers a `beforeprint` event hook so we can
|
|
986
|
+
// trigger print styles synchronously and apply proper layout styles.
|
|
987
|
+
// It is a noop if the hooks have already been registered or if the document's
|
|
988
|
+
// `defaultView` is not available.
|
|
989
|
+
registerBeforeAfterPrintHooks(target) {
|
|
990
|
+
// `defaultView` may be null when rendering on the server or in other contexts.
|
|
991
|
+
if (!this._document.defaultView || this.registeredBeforeAfterPrintHooks) {
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
this.registeredBeforeAfterPrintHooks = true;
|
|
995
|
+
const beforePrintListener = () => {
|
|
996
|
+
// If we aren't already printing, start printing and update the styles as
|
|
997
|
+
// if there was a regular print `MediaChange`(from matchMedia).
|
|
998
|
+
if (!this.isPrinting) {
|
|
999
|
+
this.isPrintingBeforeAfterEvent = true;
|
|
1000
|
+
this.startPrinting(target, this.getEventBreakpoints(new MediaChange(true, PRINT)));
|
|
1001
|
+
target.updateStyles();
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
const afterPrintListener = () => {
|
|
1005
|
+
// If we aren't already printing, start printing and update the styles as
|
|
1006
|
+
// if there was a regular print `MediaChange`(from matchMedia).
|
|
1007
|
+
this.isPrintingBeforeAfterEvent = false;
|
|
1008
|
+
if (this.isPrinting) {
|
|
1009
|
+
this.stopPrinting(target);
|
|
1010
|
+
target.updateStyles();
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
// Could we have teardown logic to remove if there are no print listeners being used?
|
|
1014
|
+
this._document.defaultView.addEventListener('beforeprint', beforePrintListener);
|
|
1015
|
+
this._document.defaultView.addEventListener('afterprint', afterPrintListener);
|
|
1016
|
+
this.beforePrintEventListeners.push(beforePrintListener);
|
|
1017
|
+
this.afterPrintEventListeners.push(afterPrintListener);
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Prepare RxJS tap operator with partial application
|
|
1021
|
+
* @return pipeable tap predicate
|
|
1022
|
+
*/
|
|
1023
|
+
interceptEvents(target) {
|
|
1024
|
+
return (event) => {
|
|
1025
|
+
if (this.isPrintEvent(event)) {
|
|
1026
|
+
if (event.matches && !this.isPrinting) {
|
|
1027
|
+
this.startPrinting(target, this.getEventBreakpoints(event));
|
|
1028
|
+
target.updateStyles();
|
|
1029
|
+
}
|
|
1030
|
+
else if (!event.matches && this.isPrinting && !this.isPrintingBeforeAfterEvent) {
|
|
1031
|
+
this.stopPrinting(target);
|
|
1032
|
+
target.updateStyles();
|
|
1033
|
+
}
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
this.collectActivations(target, event);
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
/** Stop mediaChange event propagation in event streams */
|
|
1040
|
+
blockPropagation() {
|
|
1041
|
+
return (event) => {
|
|
1042
|
+
return !(this.isPrinting || this.isPrintEvent(event));
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
/**
|
|
1046
|
+
* Save current activateBreakpoints (for later restore)
|
|
1047
|
+
* and substitute only the printAlias breakpoint
|
|
1048
|
+
*/
|
|
1049
|
+
startPrinting(target, bpList) {
|
|
1050
|
+
this.isPrinting = true;
|
|
1051
|
+
this.formerActivations = target.activatedBreakpoints;
|
|
1052
|
+
target.activatedBreakpoints = this.queue.addPrintBreakpoints(bpList);
|
|
1053
|
+
}
|
|
1054
|
+
/** For any print de-activations, reset the entire print queue */
|
|
1055
|
+
stopPrinting(target) {
|
|
1056
|
+
target.activatedBreakpoints = this.deactivations;
|
|
1057
|
+
this.deactivations = [];
|
|
1058
|
+
this.formerActivations = null;
|
|
1059
|
+
this.queue.clear();
|
|
1060
|
+
this.isPrinting = false;
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* To restore pre-Print Activations, we must capture the proper
|
|
1064
|
+
* list of breakpoint activations BEFORE print starts. OnBeforePrint()
|
|
1065
|
+
* is supported; so 'print' mediaQuery activations are used as a fallback
|
|
1066
|
+
* in browsers without `beforeprint` support.
|
|
1067
|
+
*
|
|
1068
|
+
* > But activated breakpoints are deactivated BEFORE 'print' activation.
|
|
1069
|
+
*
|
|
1070
|
+
* Let's capture all de-activations using the following logic:
|
|
1071
|
+
*
|
|
1072
|
+
* When not printing:
|
|
1073
|
+
* - clear cache when activating non-print breakpoint
|
|
1074
|
+
* - update cache (and sort) when deactivating
|
|
1075
|
+
*
|
|
1076
|
+
* When printing:
|
|
1077
|
+
* - sort and save when starting print
|
|
1078
|
+
* - restore as activatedTargets and clear when stop printing
|
|
1079
|
+
*/
|
|
1080
|
+
collectActivations(target, event) {
|
|
1081
|
+
if (!this.isPrinting || this.isPrintingBeforeAfterEvent) {
|
|
1082
|
+
if (!this.isPrintingBeforeAfterEvent) {
|
|
1083
|
+
// Only clear deactivations if we aren't printing from a `beforeprint` event.
|
|
1084
|
+
// Otherwise, this will clear before `stopPrinting()` is called to restore
|
|
1085
|
+
// the pre-Print Activations.
|
|
1086
|
+
this.deactivations = [];
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
if (!event.matches) {
|
|
1090
|
+
const bp = this.breakpoints.findByQuery(event.mediaQuery);
|
|
1091
|
+
// Deactivating a breakpoint
|
|
1092
|
+
if (bp) {
|
|
1093
|
+
const hasFormerBp = this.formerActivations && this.formerActivations.includes(bp);
|
|
1094
|
+
const wasActivated = !this.formerActivations && target.activatedBreakpoints.includes(bp);
|
|
1095
|
+
const shouldDeactivate = hasFormerBp || wasActivated;
|
|
1096
|
+
if (shouldDeactivate) {
|
|
1097
|
+
this.deactivations.push(bp);
|
|
1098
|
+
this.deactivations.sort(sortDescendingPriority);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
/** Teardown logic for the service. */
|
|
1105
|
+
ngOnDestroy() {
|
|
1106
|
+
if (this._document.defaultView) {
|
|
1107
|
+
this.beforePrintEventListeners.forEach(l => this._document.defaultView.removeEventListener('beforeprint', l));
|
|
1108
|
+
this.afterPrintEventListeners.forEach(l => this._document.defaultView.removeEventListener('afterprint', l));
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
PrintHook.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: PrintHook, deps: [{ token: BreakPointRegistry }, { token: LAYOUT_CONFIG }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1113
|
+
PrintHook.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: PrintHook, providedIn: 'root' });
|
|
1114
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: PrintHook, decorators: [{
|
|
1115
|
+
type: Injectable,
|
|
1116
|
+
args: [{ providedIn: 'root' }]
|
|
1117
|
+
}], ctorParameters: function () {
|
|
1118
|
+
return [{ type: BreakPointRegistry }, { type: undefined, decorators: [{
|
|
1119
|
+
type: Inject,
|
|
1120
|
+
args: [LAYOUT_CONFIG]
|
|
1121
|
+
}] }, { type: undefined, decorators: [{
|
|
1122
|
+
type: Inject,
|
|
1123
|
+
args: [DOCUMENT]
|
|
1124
|
+
}] }];
|
|
1125
|
+
} });
|
|
1126
|
+
// ************************************************************************
|
|
1127
|
+
// Internal Utility class 'PrintQueue'
|
|
1128
|
+
// ************************************************************************
|
|
1129
|
+
/**
|
|
1130
|
+
* Utility class to manage print breakpoints + activatedBreakpoints
|
|
1131
|
+
* with correct sorting WHILE printing
|
|
1132
|
+
*/
|
|
1133
|
+
class PrintQueue {
|
|
1134
|
+
constructor() {
|
|
1135
|
+
/** Sorted queue with prioritized print breakpoints */
|
|
1136
|
+
this.printBreakpoints = [];
|
|
1137
|
+
}
|
|
1138
|
+
addPrintBreakpoints(bpList) {
|
|
1139
|
+
bpList.push(BREAKPOINT_PRINT);
|
|
1140
|
+
bpList.sort(sortDescendingPriority);
|
|
1141
|
+
bpList.forEach(bp => this.addBreakpoint(bp));
|
|
1142
|
+
return this.printBreakpoints;
|
|
1143
|
+
}
|
|
1144
|
+
/** Add Print breakpoint to queue */
|
|
1145
|
+
addBreakpoint(bp) {
|
|
1146
|
+
if (!!bp) {
|
|
1147
|
+
const bpInList = this.printBreakpoints.find(it => it.mediaQuery === bp.mediaQuery);
|
|
1148
|
+
if (bpInList === undefined) {
|
|
1149
|
+
// If this is a `printAlias` breakpoint, then append. If a true 'print' breakpoint,
|
|
1150
|
+
// register as highest priority in the queue
|
|
1151
|
+
this.printBreakpoints = isPrintBreakPoint(bp) ? [bp, ...this.printBreakpoints]
|
|
1152
|
+
: [...this.printBreakpoints, bp];
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
/** Restore original activated breakpoints and clear internal caches */
|
|
1157
|
+
clear() {
|
|
1158
|
+
this.printBreakpoints = [];
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
// ************************************************************************
|
|
1162
|
+
// Internal Utility methods
|
|
1163
|
+
// ************************************************************************
|
|
1164
|
+
/** Only support intercept queueing if the Breakpoint is a print @media query */
|
|
1165
|
+
function isPrintBreakPoint(bp) {
|
|
1166
|
+
var _a;
|
|
1167
|
+
return (_a = bp === null || bp === void 0 ? void 0 : bp.mediaQuery.startsWith(PRINT)) !== null && _a !== void 0 ? _a : false;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
/**
|
|
1171
|
+
* @license
|
|
1172
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1173
|
+
*
|
|
1174
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1175
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1176
|
+
*/
|
|
1177
|
+
/**
|
|
1178
|
+
* MediaMarshaller - register responsive values from directives and
|
|
1179
|
+
* trigger them based on media query events
|
|
1180
|
+
*/
|
|
1181
|
+
class MediaMarshaller {
|
|
1182
|
+
constructor(matchMedia, breakpoints, hook) {
|
|
1183
|
+
this.matchMedia = matchMedia;
|
|
1184
|
+
this.breakpoints = breakpoints;
|
|
1185
|
+
this.hook = hook;
|
|
1186
|
+
this._useFallbacks = true;
|
|
1187
|
+
this._activatedBreakpoints = [];
|
|
1188
|
+
this.elementMap = new Map();
|
|
1189
|
+
this.elementKeyMap = new WeakMap();
|
|
1190
|
+
this.watcherMap = new WeakMap(); // special triggers to update elements
|
|
1191
|
+
this.updateMap = new WeakMap(); // callback functions to update styles
|
|
1192
|
+
this.clearMap = new WeakMap(); // callback functions to clear styles
|
|
1193
|
+
this.subject = new Subject();
|
|
1194
|
+
this.observeActivations();
|
|
1195
|
+
}
|
|
1196
|
+
get activatedAlias() {
|
|
1197
|
+
var _a, _b;
|
|
1198
|
+
return (_b = (_a = this.activatedBreakpoints[0]) === null || _a === void 0 ? void 0 : _a.alias) !== null && _b !== void 0 ? _b : '';
|
|
1199
|
+
}
|
|
1200
|
+
set activatedBreakpoints(bps) {
|
|
1201
|
+
this._activatedBreakpoints = [...bps];
|
|
1202
|
+
}
|
|
1203
|
+
get activatedBreakpoints() {
|
|
1204
|
+
return [...this._activatedBreakpoints];
|
|
1205
|
+
}
|
|
1206
|
+
set useFallbacks(value) {
|
|
1207
|
+
this._useFallbacks = value;
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Update styles on breakpoint activates or deactivates
|
|
1211
|
+
* @param mc
|
|
1212
|
+
*/
|
|
1213
|
+
onMediaChange(mc) {
|
|
1214
|
+
const bp = this.findByQuery(mc.mediaQuery);
|
|
1215
|
+
if (bp) {
|
|
1216
|
+
mc = mergeAlias(mc, bp);
|
|
1217
|
+
const bpIndex = this.activatedBreakpoints.indexOf(bp);
|
|
1218
|
+
if (mc.matches && bpIndex === -1) {
|
|
1219
|
+
this._activatedBreakpoints.push(bp);
|
|
1220
|
+
this._activatedBreakpoints.sort(sortDescendingPriority);
|
|
1221
|
+
this.updateStyles();
|
|
1222
|
+
}
|
|
1223
|
+
else if (!mc.matches && bpIndex !== -1) {
|
|
1224
|
+
// Remove the breakpoint when it's deactivated
|
|
1225
|
+
this._activatedBreakpoints.splice(bpIndex, 1);
|
|
1226
|
+
this._activatedBreakpoints.sort(sortDescendingPriority);
|
|
1227
|
+
this.updateStyles();
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* initialize the marshaller with necessary elements for delegation on an element
|
|
1233
|
+
* @param element
|
|
1234
|
+
* @param key
|
|
1235
|
+
* @param updateFn optional callback so that custom bp directives don't have to re-provide this
|
|
1236
|
+
* @param clearFn optional callback so that custom bp directives don't have to re-provide this
|
|
1237
|
+
* @param extraTriggers other triggers to force style updates (e.g. layout, directionality, etc)
|
|
1238
|
+
*/
|
|
1239
|
+
init(element, key, updateFn, clearFn, extraTriggers = []) {
|
|
1240
|
+
initBuilderMap(this.updateMap, element, key, updateFn);
|
|
1241
|
+
initBuilderMap(this.clearMap, element, key, clearFn);
|
|
1242
|
+
this.buildElementKeyMap(element, key);
|
|
1243
|
+
this.watchExtraTriggers(element, key, extraTriggers);
|
|
1244
|
+
}
|
|
1245
|
+
/**
|
|
1246
|
+
* get the value for an element and key and optionally a given breakpoint
|
|
1247
|
+
* @param element
|
|
1248
|
+
* @param key
|
|
1249
|
+
* @param bp
|
|
1250
|
+
*/
|
|
1251
|
+
getValue(element, key, bp) {
|
|
1252
|
+
const bpMap = this.elementMap.get(element);
|
|
1253
|
+
if (bpMap) {
|
|
1254
|
+
const values = bp !== undefined ? bpMap.get(bp) : this.getActivatedValues(bpMap, key);
|
|
1255
|
+
if (values) {
|
|
1256
|
+
return values.get(key);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
return undefined;
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* whether the element has values for a given key
|
|
1263
|
+
* @param element
|
|
1264
|
+
* @param key
|
|
1265
|
+
*/
|
|
1266
|
+
hasValue(element, key) {
|
|
1267
|
+
const bpMap = this.elementMap.get(element);
|
|
1268
|
+
if (bpMap) {
|
|
1269
|
+
const values = this.getActivatedValues(bpMap, key);
|
|
1270
|
+
if (values) {
|
|
1271
|
+
return values.get(key) !== undefined || false;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
return false;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* Set the value for an input on a directive
|
|
1278
|
+
* @param element the element in question
|
|
1279
|
+
* @param key the type of the directive (e.g. flex, layout-gap, etc)
|
|
1280
|
+
* @param bp the breakpoint suffix (empty string = default)
|
|
1281
|
+
* @param val the value for the breakpoint
|
|
1282
|
+
*/
|
|
1283
|
+
setValue(element, key, val, bp) {
|
|
1284
|
+
var _a;
|
|
1285
|
+
let bpMap = this.elementMap.get(element);
|
|
1286
|
+
if (!bpMap) {
|
|
1287
|
+
bpMap = new Map().set(bp, new Map().set(key, val));
|
|
1288
|
+
this.elementMap.set(element, bpMap);
|
|
1289
|
+
}
|
|
1290
|
+
else {
|
|
1291
|
+
const values = ((_a = bpMap.get(bp)) !== null && _a !== void 0 ? _a : new Map()).set(key, val);
|
|
1292
|
+
bpMap.set(bp, values);
|
|
1293
|
+
this.elementMap.set(element, bpMap);
|
|
1294
|
+
}
|
|
1295
|
+
const value = this.getValue(element, key);
|
|
1296
|
+
if (value !== undefined) {
|
|
1297
|
+
this.updateElement(element, key, value);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
/** Track element value changes for a specific key */
|
|
1301
|
+
trackValue(element, key) {
|
|
1302
|
+
return this.subject
|
|
1303
|
+
.asObservable()
|
|
1304
|
+
.pipe(filter(v => v.element === element && v.key === key));
|
|
1305
|
+
}
|
|
1306
|
+
/** update all styles for all elements on the current breakpoint */
|
|
1307
|
+
updateStyles() {
|
|
1308
|
+
this.elementMap.forEach((bpMap, el) => {
|
|
1309
|
+
const keyMap = new Set(this.elementKeyMap.get(el));
|
|
1310
|
+
let valueMap = this.getActivatedValues(bpMap);
|
|
1311
|
+
if (valueMap) {
|
|
1312
|
+
valueMap.forEach((v, k) => {
|
|
1313
|
+
this.updateElement(el, k, v);
|
|
1314
|
+
keyMap.delete(k);
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
keyMap.forEach(k => {
|
|
1318
|
+
valueMap = this.getActivatedValues(bpMap, k);
|
|
1319
|
+
if (valueMap) {
|
|
1320
|
+
const value = valueMap.get(k);
|
|
1321
|
+
this.updateElement(el, k, value);
|
|
1322
|
+
}
|
|
1323
|
+
else {
|
|
1324
|
+
this.clearElement(el, k);
|
|
1325
|
+
}
|
|
1326
|
+
});
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* clear the styles for a given element
|
|
1331
|
+
* @param element
|
|
1332
|
+
* @param key
|
|
1333
|
+
*/
|
|
1334
|
+
clearElement(element, key) {
|
|
1335
|
+
const builders = this.clearMap.get(element);
|
|
1336
|
+
if (builders) {
|
|
1337
|
+
const clearFn = builders.get(key);
|
|
1338
|
+
if (!!clearFn) {
|
|
1339
|
+
clearFn();
|
|
1340
|
+
this.subject.next({ element, key, value: '' });
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
/**
|
|
1345
|
+
* update a given element with the activated values for a given key
|
|
1346
|
+
* @param element
|
|
1347
|
+
* @param key
|
|
1348
|
+
* @param value
|
|
1349
|
+
*/
|
|
1350
|
+
updateElement(element, key, value) {
|
|
1351
|
+
const builders = this.updateMap.get(element);
|
|
1352
|
+
if (builders) {
|
|
1353
|
+
const updateFn = builders.get(key);
|
|
1354
|
+
if (!!updateFn) {
|
|
1355
|
+
updateFn(value);
|
|
1356
|
+
this.subject.next({ element, key, value });
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
/**
|
|
1361
|
+
* release all references to a given element
|
|
1362
|
+
* @param element
|
|
1363
|
+
*/
|
|
1364
|
+
releaseElement(element) {
|
|
1365
|
+
const watcherMap = this.watcherMap.get(element);
|
|
1366
|
+
if (watcherMap) {
|
|
1367
|
+
watcherMap.forEach(s => s.unsubscribe());
|
|
1368
|
+
this.watcherMap.delete(element);
|
|
1369
|
+
}
|
|
1370
|
+
const elementMap = this.elementMap.get(element);
|
|
1371
|
+
if (elementMap) {
|
|
1372
|
+
elementMap.forEach((_, s) => elementMap.delete(s));
|
|
1373
|
+
this.elementMap.delete(element);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
/**
|
|
1377
|
+
* trigger an update for a given element and key (e.g. layout)
|
|
1378
|
+
* @param element
|
|
1379
|
+
* @param key
|
|
1380
|
+
*/
|
|
1381
|
+
triggerUpdate(element, key) {
|
|
1382
|
+
const bpMap = this.elementMap.get(element);
|
|
1383
|
+
if (bpMap) {
|
|
1384
|
+
const valueMap = this.getActivatedValues(bpMap, key);
|
|
1385
|
+
if (valueMap) {
|
|
1386
|
+
if (key) {
|
|
1387
|
+
this.updateElement(element, key, valueMap.get(key));
|
|
1388
|
+
}
|
|
1389
|
+
else {
|
|
1390
|
+
valueMap.forEach((v, k) => this.updateElement(element, k, v));
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
/** Cross-reference for HTMLElement with directive key */
|
|
1396
|
+
buildElementKeyMap(element, key) {
|
|
1397
|
+
let keyMap = this.elementKeyMap.get(element);
|
|
1398
|
+
if (!keyMap) {
|
|
1399
|
+
keyMap = new Set();
|
|
1400
|
+
this.elementKeyMap.set(element, keyMap);
|
|
1401
|
+
}
|
|
1402
|
+
keyMap.add(key);
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* Other triggers that should force style updates:
|
|
1406
|
+
* - directionality
|
|
1407
|
+
* - layout changes
|
|
1408
|
+
* - mutationobserver updates
|
|
1409
|
+
*/
|
|
1410
|
+
watchExtraTriggers(element, key, triggers) {
|
|
1411
|
+
if (triggers && triggers.length) {
|
|
1412
|
+
let watchers = this.watcherMap.get(element);
|
|
1413
|
+
if (!watchers) {
|
|
1414
|
+
watchers = new Map();
|
|
1415
|
+
this.watcherMap.set(element, watchers);
|
|
1416
|
+
}
|
|
1417
|
+
const subscription = watchers.get(key);
|
|
1418
|
+
if (!subscription) {
|
|
1419
|
+
const newSubscription = merge(...triggers).subscribe(() => {
|
|
1420
|
+
const currentValue = this.getValue(element, key);
|
|
1421
|
+
this.updateElement(element, key, currentValue);
|
|
1422
|
+
});
|
|
1423
|
+
watchers.set(key, newSubscription);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
/** Breakpoint locator by mediaQuery */
|
|
1428
|
+
findByQuery(query) {
|
|
1429
|
+
return this.breakpoints.findByQuery(query);
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* get the fallback breakpoint for a given element, starting with the current breakpoint
|
|
1433
|
+
* @param bpMap
|
|
1434
|
+
* @param key
|
|
1435
|
+
*/
|
|
1436
|
+
getActivatedValues(bpMap, key) {
|
|
1437
|
+
for (let i = 0; i < this.activatedBreakpoints.length; i++) {
|
|
1438
|
+
const activatedBp = this.activatedBreakpoints[i];
|
|
1439
|
+
const valueMap = bpMap.get(activatedBp.alias);
|
|
1440
|
+
if (valueMap) {
|
|
1441
|
+
if (key === undefined || (valueMap.has(key) && valueMap.get(key) != null)) {
|
|
1442
|
+
return valueMap;
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
// On the server, we explicitly have an "all" section filled in to begin with.
|
|
1447
|
+
// So we don't need to aggressively find a fallback if no explicit value exists.
|
|
1448
|
+
if (!this._useFallbacks) {
|
|
1449
|
+
return undefined;
|
|
1450
|
+
}
|
|
1451
|
+
const lastHope = bpMap.get('');
|
|
1452
|
+
return (key === undefined || lastHope && lastHope.has(key)) ? lastHope : undefined;
|
|
1453
|
+
}
|
|
1454
|
+
/**
|
|
1455
|
+
* Watch for mediaQuery breakpoint activations
|
|
1456
|
+
*/
|
|
1457
|
+
observeActivations() {
|
|
1458
|
+
const queries = this.breakpoints.items.map(bp => bp.mediaQuery);
|
|
1459
|
+
this.hook.registerBeforeAfterPrintHooks(this);
|
|
1460
|
+
this.matchMedia
|
|
1461
|
+
.observe(this.hook.withPrintQuery(queries))
|
|
1462
|
+
.pipe(tap(this.hook.interceptEvents(this)), filter(this.hook.blockPropagation()))
|
|
1463
|
+
.subscribe(this.onMediaChange.bind(this));
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
MediaMarshaller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaMarshaller, deps: [{ token: MatchMedia }, { token: BreakPointRegistry }, { token: PrintHook }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1467
|
+
MediaMarshaller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaMarshaller, providedIn: 'root' });
|
|
1468
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaMarshaller, decorators: [{
|
|
1469
|
+
type: Injectable,
|
|
1470
|
+
args: [{ providedIn: 'root' }]
|
|
1471
|
+
}], ctorParameters: function () { return [{ type: MatchMedia }, { type: BreakPointRegistry }, { type: PrintHook }]; } });
|
|
1472
|
+
function initBuilderMap(map, element, key, input) {
|
|
1473
|
+
var _a;
|
|
1474
|
+
if (input !== undefined) {
|
|
1475
|
+
const oldMap = (_a = map.get(element)) !== null && _a !== void 0 ? _a : new Map();
|
|
1476
|
+
oldMap.set(key, input);
|
|
1477
|
+
map.set(element, oldMap);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
/**
|
|
1482
|
+
* @license
|
|
1483
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1484
|
+
*
|
|
1485
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1486
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1487
|
+
*/
|
|
1488
|
+
class BaseDirective2 {
|
|
1489
|
+
constructor(elementRef, styleBuilder, styler, marshal) {
|
|
1490
|
+
this.elementRef = elementRef;
|
|
1491
|
+
this.styleBuilder = styleBuilder;
|
|
1492
|
+
this.styler = styler;
|
|
1493
|
+
this.marshal = marshal;
|
|
1494
|
+
this.DIRECTIVE_KEY = '';
|
|
1495
|
+
this.inputs = [];
|
|
1496
|
+
/** The most recently used styles for the builder */
|
|
1497
|
+
this.mru = {};
|
|
1498
|
+
this.destroySubject = new Subject();
|
|
1499
|
+
/** Cache map for style computation */
|
|
1500
|
+
this.styleCache = new Map();
|
|
1501
|
+
}
|
|
1502
|
+
/** Access to host element's parent DOM node */
|
|
1503
|
+
get parentElement() {
|
|
1504
|
+
return this.elementRef.nativeElement.parentElement;
|
|
1505
|
+
}
|
|
1506
|
+
/** Access to the HTMLElement for the directive */
|
|
1507
|
+
get nativeElement() {
|
|
1508
|
+
return this.elementRef.nativeElement;
|
|
1509
|
+
}
|
|
1510
|
+
/** Access to the activated value for the directive */
|
|
1511
|
+
get activatedValue() {
|
|
1512
|
+
return this.marshal.getValue(this.nativeElement, this.DIRECTIVE_KEY);
|
|
1513
|
+
}
|
|
1514
|
+
set activatedValue(value) {
|
|
1515
|
+
this.marshal.setValue(this.nativeElement, this.DIRECTIVE_KEY, value, this.marshal.activatedAlias);
|
|
1516
|
+
}
|
|
1517
|
+
/** For @Input changes */
|
|
1518
|
+
ngOnChanges(changes) {
|
|
1519
|
+
Object.keys(changes).forEach(key => {
|
|
1520
|
+
if (this.inputs.indexOf(key) !== -1) {
|
|
1521
|
+
const bp = key.split('.').slice(1).join('.');
|
|
1522
|
+
const val = changes[key].currentValue;
|
|
1523
|
+
this.setValue(val, bp);
|
|
1524
|
+
}
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
ngOnDestroy() {
|
|
1528
|
+
this.destroySubject.next();
|
|
1529
|
+
this.destroySubject.complete();
|
|
1530
|
+
this.marshal.releaseElement(this.nativeElement);
|
|
1531
|
+
}
|
|
1532
|
+
/** Register with central marshaller service */
|
|
1533
|
+
init(extraTriggers = []) {
|
|
1534
|
+
this.marshal.init(this.elementRef.nativeElement, this.DIRECTIVE_KEY, this.updateWithValue.bind(this), this.clearStyles.bind(this), extraTriggers);
|
|
1535
|
+
}
|
|
1536
|
+
/** Add styles to the element using predefined style builder */
|
|
1537
|
+
addStyles(input, parent) {
|
|
1538
|
+
const builder = this.styleBuilder;
|
|
1539
|
+
const useCache = builder.shouldCache;
|
|
1540
|
+
let genStyles = this.styleCache.get(input);
|
|
1541
|
+
if (!genStyles || !useCache) {
|
|
1542
|
+
genStyles = builder.buildStyles(input, parent);
|
|
1543
|
+
if (useCache) {
|
|
1544
|
+
this.styleCache.set(input, genStyles);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
this.mru = Object.assign({}, genStyles);
|
|
1548
|
+
this.applyStyleToElement(genStyles);
|
|
1549
|
+
builder.sideEffect(input, genStyles, parent);
|
|
1550
|
+
}
|
|
1551
|
+
/** Remove generated styles from an element using predefined style builder */
|
|
1552
|
+
clearStyles() {
|
|
1553
|
+
Object.keys(this.mru).forEach(k => {
|
|
1554
|
+
this.mru[k] = '';
|
|
1555
|
+
});
|
|
1556
|
+
this.applyStyleToElement(this.mru);
|
|
1557
|
+
this.mru = {};
|
|
1558
|
+
this.currentValue = undefined;
|
|
1559
|
+
}
|
|
1560
|
+
/** Force trigger style updates on DOM element */
|
|
1561
|
+
triggerUpdate() {
|
|
1562
|
+
this.marshal.triggerUpdate(this.nativeElement, this.DIRECTIVE_KEY);
|
|
1563
|
+
}
|
|
1564
|
+
/**
|
|
1565
|
+
* Determine the DOM element's Flexbox flow (flex-direction).
|
|
1566
|
+
*
|
|
1567
|
+
* Check inline style first then check computed (stylesheet) style.
|
|
1568
|
+
* And optionally add the flow value to element's inline style.
|
|
1569
|
+
*/
|
|
1570
|
+
getFlexFlowDirection(target, addIfMissing = false) {
|
|
1571
|
+
if (target) {
|
|
1572
|
+
const [value, hasInlineValue] = this.styler.getFlowDirection(target);
|
|
1573
|
+
if (!hasInlineValue && addIfMissing) {
|
|
1574
|
+
const style = buildLayoutCSS(value);
|
|
1575
|
+
const elements = [target];
|
|
1576
|
+
this.styler.applyStyleToElements(style, elements);
|
|
1577
|
+
}
|
|
1578
|
+
return value.trim();
|
|
1579
|
+
}
|
|
1580
|
+
return 'row';
|
|
1581
|
+
}
|
|
1582
|
+
hasWrap(target) {
|
|
1583
|
+
return this.styler.hasWrap(target);
|
|
1584
|
+
}
|
|
1585
|
+
/** Applies styles given via string pair or object map to the directive element */
|
|
1586
|
+
applyStyleToElement(style, value, element = this.nativeElement) {
|
|
1587
|
+
this.styler.applyStyleToElement(element, style, value);
|
|
1588
|
+
}
|
|
1589
|
+
setValue(val, bp) {
|
|
1590
|
+
this.marshal.setValue(this.nativeElement, this.DIRECTIVE_KEY, val, bp);
|
|
1591
|
+
}
|
|
1592
|
+
updateWithValue(input) {
|
|
1593
|
+
if (this.currentValue !== input) {
|
|
1594
|
+
this.addStyles(input);
|
|
1595
|
+
this.currentValue = input;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
BaseDirective2.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: BaseDirective2, deps: [{ token: i0.ElementRef }, { token: StyleBuilder }, { token: StyleUtils }, { token: MediaMarshaller }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1600
|
+
BaseDirective2.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.0.2", type: BaseDirective2, usesOnChanges: true, ngImport: i0 });
|
|
1601
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: BaseDirective2, decorators: [{
|
|
1602
|
+
type: Directive
|
|
1603
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: StyleBuilder }, { type: StyleUtils }, { type: MediaMarshaller }]; } });
|
|
1604
|
+
|
|
1605
|
+
/**
|
|
1606
|
+
* @license
|
|
1607
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1608
|
+
*
|
|
1609
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1610
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1611
|
+
*/
|
|
1612
|
+
|
|
1613
|
+
/**
|
|
1614
|
+
* @license
|
|
1615
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1616
|
+
*
|
|
1617
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1618
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1619
|
+
*/
|
|
1620
|
+
|
|
1621
|
+
/**
|
|
1622
|
+
* @license
|
|
1623
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1624
|
+
*
|
|
1625
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1626
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1627
|
+
*/
|
|
1628
|
+
/**
|
|
1629
|
+
* MockMatchMedia mocks calls to the Window API matchMedia with a build of a simulated
|
|
1630
|
+
* MockMediaQueryListener. Methods are available to simulate an activation of a mediaQuery
|
|
1631
|
+
* range and to clearAll mediaQuery listeners.
|
|
1632
|
+
*/
|
|
1633
|
+
class MockMatchMedia extends MatchMedia {
|
|
1634
|
+
constructor(_zone, _platformId, _document, _breakpoints) {
|
|
1635
|
+
super(_zone, _platformId, _document);
|
|
1636
|
+
this._breakpoints = _breakpoints;
|
|
1637
|
+
this.autoRegisterQueries = true; // Used for testing BreakPoint registrations
|
|
1638
|
+
this.useOverlaps = false; // Allow fallback to overlapping mediaQueries
|
|
1639
|
+
}
|
|
1640
|
+
/** Easy method to clear all listeners for all mediaQueries */
|
|
1641
|
+
clearAll() {
|
|
1642
|
+
this.registry.forEach((mql) => {
|
|
1643
|
+
mql.destroy();
|
|
1644
|
+
});
|
|
1645
|
+
this.registry.clear();
|
|
1646
|
+
this.useOverlaps = false;
|
|
1647
|
+
}
|
|
1648
|
+
/** Feature to support manual, simulated activation of a mediaQuery. */
|
|
1649
|
+
activate(mediaQuery, useOverlaps = this.useOverlaps) {
|
|
1650
|
+
mediaQuery = this._validateQuery(mediaQuery);
|
|
1651
|
+
if (useOverlaps || !this.isActive(mediaQuery)) {
|
|
1652
|
+
this._deactivateAll();
|
|
1653
|
+
this._registerMediaQuery(mediaQuery);
|
|
1654
|
+
this._activateWithOverlaps(mediaQuery, useOverlaps);
|
|
1655
|
+
}
|
|
1656
|
+
return this.hasActivated;
|
|
1657
|
+
}
|
|
1658
|
+
/** Converts an optional mediaQuery alias to a specific, valid mediaQuery */
|
|
1659
|
+
_validateQuery(queryOrAlias) {
|
|
1660
|
+
var _a;
|
|
1661
|
+
const bp = this._breakpoints.findByAlias(queryOrAlias);
|
|
1662
|
+
return (_a = bp === null || bp === void 0 ? void 0 : bp.mediaQuery) !== null && _a !== void 0 ? _a : queryOrAlias;
|
|
1663
|
+
}
|
|
1664
|
+
/**
|
|
1665
|
+
* Manually onMediaChange any overlapping mediaQueries to simulate
|
|
1666
|
+
* similar functionality in the window.matchMedia()
|
|
1667
|
+
*/
|
|
1668
|
+
_activateWithOverlaps(mediaQuery, useOverlaps) {
|
|
1669
|
+
var _a;
|
|
1670
|
+
if (useOverlaps) {
|
|
1671
|
+
const bp = this._breakpoints.findByQuery(mediaQuery);
|
|
1672
|
+
const alias = (_a = bp === null || bp === void 0 ? void 0 : bp.alias) !== null && _a !== void 0 ? _a : 'unknown';
|
|
1673
|
+
// Simulate activation of overlapping lt-<XXX> ranges
|
|
1674
|
+
switch (alias) {
|
|
1675
|
+
case 'lg':
|
|
1676
|
+
this._activateByAlias(['lt-xl']);
|
|
1677
|
+
break;
|
|
1678
|
+
case 'md':
|
|
1679
|
+
this._activateByAlias(['lt-xl', 'lt-lg']);
|
|
1680
|
+
break;
|
|
1681
|
+
case 'sm':
|
|
1682
|
+
this._activateByAlias(['lt-xl', 'lt-lg', 'lt-md']);
|
|
1683
|
+
break;
|
|
1684
|
+
case 'xs':
|
|
1685
|
+
this._activateByAlias(['lt-xl', 'lt-lg', 'lt-md', 'lt-sm']);
|
|
1686
|
+
break;
|
|
1687
|
+
}
|
|
1688
|
+
// Simulate activation of overlapping gt-<xxxx> mediaQuery ranges
|
|
1689
|
+
switch (alias) {
|
|
1690
|
+
case 'xl':
|
|
1691
|
+
this._activateByAlias(['gt-lg', 'gt-md', 'gt-sm', 'gt-xs']);
|
|
1692
|
+
break;
|
|
1693
|
+
case 'lg':
|
|
1694
|
+
this._activateByAlias(['gt-md', 'gt-sm', 'gt-xs']);
|
|
1695
|
+
break;
|
|
1696
|
+
case 'md':
|
|
1697
|
+
this._activateByAlias(['gt-sm', 'gt-xs']);
|
|
1698
|
+
break;
|
|
1699
|
+
case 'sm':
|
|
1700
|
+
this._activateByAlias(['gt-xs']);
|
|
1701
|
+
break;
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
// Activate last since the responsiveActivation is watching *this* mediaQuery
|
|
1705
|
+
return this._activateByQuery(mediaQuery);
|
|
1706
|
+
}
|
|
1707
|
+
/**
|
|
1708
|
+
*
|
|
1709
|
+
*/
|
|
1710
|
+
_activateByAlias(aliases) {
|
|
1711
|
+
const activate = (alias) => {
|
|
1712
|
+
var _a;
|
|
1713
|
+
const bp = this._breakpoints.findByAlias(alias);
|
|
1714
|
+
this._activateByQuery((_a = bp === null || bp === void 0 ? void 0 : bp.mediaQuery) !== null && _a !== void 0 ? _a : alias);
|
|
1715
|
+
};
|
|
1716
|
+
aliases.forEach(activate);
|
|
1717
|
+
}
|
|
1718
|
+
/**
|
|
1719
|
+
*
|
|
1720
|
+
*/
|
|
1721
|
+
_activateByQuery(mediaQuery) {
|
|
1722
|
+
if (!this.registry.has(mediaQuery) && this.autoRegisterQueries) {
|
|
1723
|
+
this._registerMediaQuery(mediaQuery);
|
|
1724
|
+
}
|
|
1725
|
+
const mql = this.registry.get(mediaQuery);
|
|
1726
|
+
if (mql && !this.isActive(mediaQuery)) {
|
|
1727
|
+
this.registry.set(mediaQuery, mql.activate());
|
|
1728
|
+
}
|
|
1729
|
+
return this.hasActivated;
|
|
1730
|
+
}
|
|
1731
|
+
/** Deactivate all current MQLs and reset the buffer */
|
|
1732
|
+
_deactivateAll() {
|
|
1733
|
+
this.registry.forEach((it) => {
|
|
1734
|
+
it.deactivate();
|
|
1735
|
+
});
|
|
1736
|
+
return this;
|
|
1737
|
+
}
|
|
1738
|
+
/** Insure the mediaQuery is registered with MatchMedia */
|
|
1739
|
+
_registerMediaQuery(mediaQuery) {
|
|
1740
|
+
if (!this.registry.has(mediaQuery) && this.autoRegisterQueries) {
|
|
1741
|
+
this.registerQuery(mediaQuery);
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Call window.matchMedia() to build a MediaQueryList; which
|
|
1746
|
+
* supports 0..n listeners for activation/deactivation
|
|
1747
|
+
*/
|
|
1748
|
+
buildMQL(query) {
|
|
1749
|
+
return new MockMediaQueryList(query);
|
|
1750
|
+
}
|
|
1751
|
+
get hasActivated() {
|
|
1752
|
+
return this.activations.length > 0;
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
MockMatchMedia.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MockMatchMedia, deps: [{ token: i0.NgZone }, { token: PLATFORM_ID }, { token: DOCUMENT }, { token: BreakPointRegistry }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1756
|
+
MockMatchMedia.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MockMatchMedia });
|
|
1757
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MockMatchMedia, decorators: [{
|
|
1758
|
+
type: Injectable
|
|
1759
|
+
}], ctorParameters: function () {
|
|
1760
|
+
return [{ type: i0.NgZone }, { type: Object, decorators: [{
|
|
1761
|
+
type: Inject,
|
|
1762
|
+
args: [PLATFORM_ID]
|
|
1763
|
+
}] }, { type: undefined, decorators: [{
|
|
1764
|
+
type: Inject,
|
|
1765
|
+
args: [DOCUMENT]
|
|
1766
|
+
}] }, { type: BreakPointRegistry }];
|
|
1767
|
+
} });
|
|
1768
|
+
/**
|
|
1769
|
+
* Special internal class to simulate a MediaQueryList and
|
|
1770
|
+
* - supports manual activation to simulate mediaQuery matching
|
|
1771
|
+
* - manages listeners
|
|
1772
|
+
*/
|
|
1773
|
+
class MockMediaQueryList {
|
|
1774
|
+
constructor(_mediaQuery) {
|
|
1775
|
+
this._mediaQuery = _mediaQuery;
|
|
1776
|
+
this._isActive = false;
|
|
1777
|
+
this._listeners = [];
|
|
1778
|
+
this.onchange = null;
|
|
1779
|
+
}
|
|
1780
|
+
get matches() {
|
|
1781
|
+
return this._isActive;
|
|
1782
|
+
}
|
|
1783
|
+
get media() {
|
|
1784
|
+
return this._mediaQuery;
|
|
1785
|
+
}
|
|
1786
|
+
/**
|
|
1787
|
+
* Destroy the current list by deactivating the
|
|
1788
|
+
* listeners and clearing the internal list
|
|
1789
|
+
*/
|
|
1790
|
+
destroy() {
|
|
1791
|
+
this.deactivate();
|
|
1792
|
+
this._listeners = [];
|
|
1793
|
+
}
|
|
1794
|
+
/** Notify all listeners that 'matches === TRUE' */
|
|
1795
|
+
activate() {
|
|
1796
|
+
if (!this._isActive) {
|
|
1797
|
+
this._isActive = true;
|
|
1798
|
+
this._listeners.forEach((callback) => {
|
|
1799
|
+
const cb = callback;
|
|
1800
|
+
cb.call(this, { matches: this.matches, media: this.media });
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
return this;
|
|
1804
|
+
}
|
|
1805
|
+
/** Notify all listeners that 'matches === false' */
|
|
1806
|
+
deactivate() {
|
|
1807
|
+
if (this._isActive) {
|
|
1808
|
+
this._isActive = false;
|
|
1809
|
+
this._listeners.forEach((callback) => {
|
|
1810
|
+
const cb = callback;
|
|
1811
|
+
cb.call(this, { matches: this.matches, media: this.media });
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1814
|
+
return this;
|
|
1815
|
+
}
|
|
1816
|
+
/** Add a listener to our internal list to activate later */
|
|
1817
|
+
addListener(listener) {
|
|
1818
|
+
if (this._listeners.indexOf(listener) === -1) {
|
|
1819
|
+
this._listeners.push(listener);
|
|
1820
|
+
}
|
|
1821
|
+
if (this._isActive) {
|
|
1822
|
+
const cb = listener;
|
|
1823
|
+
cb.call(this, { matches: this.matches, media: this.media });
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
/** Don't need to remove listeners in the testing environment */
|
|
1827
|
+
removeListener(_) {
|
|
1828
|
+
}
|
|
1829
|
+
addEventListener(_, __, ___) {
|
|
1830
|
+
}
|
|
1831
|
+
removeEventListener(_, __, ___) {
|
|
1832
|
+
}
|
|
1833
|
+
dispatchEvent(_) {
|
|
1834
|
+
return false;
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
/**
|
|
1838
|
+
* Pre-configured provider for MockMatchMedia
|
|
1839
|
+
*/
|
|
1840
|
+
const MockMatchMediaProvider = {
|
|
1841
|
+
provide: MatchMedia,
|
|
1842
|
+
useClass: MockMatchMedia
|
|
1843
|
+
};
|
|
1844
|
+
|
|
1845
|
+
/**
|
|
1846
|
+
* @license
|
|
1847
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1848
|
+
*
|
|
1849
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1850
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1851
|
+
*/
|
|
1852
|
+
|
|
1853
|
+
/**
|
|
1854
|
+
* @license
|
|
1855
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1856
|
+
*
|
|
1857
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1858
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1859
|
+
*/
|
|
1860
|
+
/** Wraps the provided value in an array, unless the provided value is an array. */
|
|
1861
|
+
function coerceArray(value) {
|
|
1862
|
+
return Array.isArray(value) ? value : [value];
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
/**
|
|
1866
|
+
* @license
|
|
1867
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1868
|
+
*
|
|
1869
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1870
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1871
|
+
*/
|
|
1872
|
+
/**
|
|
1873
|
+
* MediaObserver enables applications to listen for 1..n mediaQuery activations and to determine
|
|
1874
|
+
* if a mediaQuery is currently activated.
|
|
1875
|
+
*
|
|
1876
|
+
* Since a breakpoint change will first deactivate 1...n mediaQueries and then possibly activate
|
|
1877
|
+
* 1..n mediaQueries, the MediaObserver will debounce notifications and report ALL *activations*
|
|
1878
|
+
* in 1 event notification. The reported activations will be sorted in descending priority order.
|
|
1879
|
+
*
|
|
1880
|
+
* This class uses the BreakPoint Registry to inject alias information into the raw MediaChange
|
|
1881
|
+
* notification. For custom mediaQuery notifications, alias information will not be injected and
|
|
1882
|
+
* those fields will be ''.
|
|
1883
|
+
*
|
|
1884
|
+
* Note: Developers should note that only mediaChange activations (not de-activations)
|
|
1885
|
+
* are announced by the MediaObserver.
|
|
1886
|
+
*
|
|
1887
|
+
* @usage
|
|
1888
|
+
*
|
|
1889
|
+
* // RxJS
|
|
1890
|
+
* import { filter } from 'rxjs/operators';
|
|
1891
|
+
* import { MediaObserver } from '@angular/flex-layout';
|
|
1892
|
+
*
|
|
1893
|
+
* @Component({ ... })
|
|
1894
|
+
* export class AppComponent {
|
|
1895
|
+
* status: string = '';
|
|
1896
|
+
*
|
|
1897
|
+
* constructor(mediaObserver: MediaObserver) {
|
|
1898
|
+
* const media$ = mediaObserver.asObservable().pipe(
|
|
1899
|
+
* filter((changes: MediaChange[]) => true) // silly noop filter
|
|
1900
|
+
* );
|
|
1901
|
+
*
|
|
1902
|
+
* media$.subscribe((changes: MediaChange[]) => {
|
|
1903
|
+
* let status = '';
|
|
1904
|
+
* changes.forEach( change => {
|
|
1905
|
+
* status += `'${change.mqAlias}' = (${change.mediaQuery}) <br/>` ;
|
|
1906
|
+
* });
|
|
1907
|
+
* this.status = status;
|
|
1908
|
+
* });
|
|
1909
|
+
*
|
|
1910
|
+
* }
|
|
1911
|
+
* }
|
|
1912
|
+
*/
|
|
1913
|
+
class MediaObserver {
|
|
1914
|
+
constructor(breakpoints, matchMedia, hook) {
|
|
1915
|
+
this.breakpoints = breakpoints;
|
|
1916
|
+
this.matchMedia = matchMedia;
|
|
1917
|
+
this.hook = hook;
|
|
1918
|
+
/** Filter MediaChange notifications for overlapping breakpoints */
|
|
1919
|
+
this.filterOverlaps = false;
|
|
1920
|
+
this.destroyed$ = new Subject();
|
|
1921
|
+
this._media$ = this.watchActivations();
|
|
1922
|
+
this.media$ = this._media$.pipe(filter((changes) => changes.length > 0), map((changes) => changes[0]));
|
|
1923
|
+
}
|
|
1924
|
+
/**
|
|
1925
|
+
* Completes the active subject, signalling to all complete for all
|
|
1926
|
+
* MediaObserver subscribers
|
|
1927
|
+
*/
|
|
1928
|
+
ngOnDestroy() {
|
|
1929
|
+
this.destroyed$.next();
|
|
1930
|
+
this.destroyed$.complete();
|
|
1931
|
+
}
|
|
1932
|
+
// ************************************************
|
|
1933
|
+
// Public Methods
|
|
1934
|
+
// ************************************************
|
|
1935
|
+
/**
|
|
1936
|
+
* Observe changes to current activation 'list'
|
|
1937
|
+
*/
|
|
1938
|
+
asObservable() {
|
|
1939
|
+
return this._media$;
|
|
1940
|
+
}
|
|
1941
|
+
/**
|
|
1942
|
+
* Allow programmatic query to determine if one or more media query/alias match
|
|
1943
|
+
* the current viewport size.
|
|
1944
|
+
* @param value One or more media queries (or aliases) to check.
|
|
1945
|
+
* @returns Whether any of the media queries match.
|
|
1946
|
+
*/
|
|
1947
|
+
isActive(value) {
|
|
1948
|
+
const aliases = splitQueries(coerceArray(value));
|
|
1949
|
+
return aliases.some(alias => {
|
|
1950
|
+
const query = toMediaQuery(alias, this.breakpoints);
|
|
1951
|
+
return query !== null && this.matchMedia.isActive(query);
|
|
1952
|
+
});
|
|
1953
|
+
}
|
|
1954
|
+
// ************************************************
|
|
1955
|
+
// Internal Methods
|
|
1956
|
+
// ************************************************
|
|
1957
|
+
/**
|
|
1958
|
+
* Register all the mediaQueries registered in the BreakPointRegistry
|
|
1959
|
+
* This is needed so subscribers can be auto-notified of all standard, registered
|
|
1960
|
+
* mediaQuery activations
|
|
1961
|
+
*/
|
|
1962
|
+
watchActivations() {
|
|
1963
|
+
const queries = this.breakpoints.items.map(bp => bp.mediaQuery);
|
|
1964
|
+
return this.buildObservable(queries);
|
|
1965
|
+
}
|
|
1966
|
+
/**
|
|
1967
|
+
* Only pass/announce activations (not de-activations)
|
|
1968
|
+
*
|
|
1969
|
+
* Since multiple-mediaQueries can be activation in a cycle,
|
|
1970
|
+
* gather all current activations into a single list of changes to observers
|
|
1971
|
+
*
|
|
1972
|
+
* Inject associated (if any) alias information into the MediaChange event
|
|
1973
|
+
* - Exclude mediaQuery activations for overlapping mQs. List bounded mQ ranges only
|
|
1974
|
+
* - Exclude print activations that do not have an associated mediaQuery
|
|
1975
|
+
*
|
|
1976
|
+
* NOTE: the raw MediaChange events [from MatchMedia] do not
|
|
1977
|
+
* contain important alias information; as such this info
|
|
1978
|
+
* must be injected into the MediaChange
|
|
1979
|
+
*/
|
|
1980
|
+
buildObservable(mqList) {
|
|
1981
|
+
const hasChanges = (changes) => {
|
|
1982
|
+
const isValidQuery = (change) => (change.mediaQuery.length > 0);
|
|
1983
|
+
return (changes.filter(isValidQuery).length > 0);
|
|
1984
|
+
};
|
|
1985
|
+
const excludeOverlaps = (changes) => {
|
|
1986
|
+
return !this.filterOverlaps ? changes : changes.filter(change => {
|
|
1987
|
+
var _a;
|
|
1988
|
+
const bp = this.breakpoints.findByQuery(change.mediaQuery);
|
|
1989
|
+
return (_a = bp === null || bp === void 0 ? void 0 : bp.overlapping) !== null && _a !== void 0 ? _a : true;
|
|
1990
|
+
});
|
|
1991
|
+
};
|
|
1992
|
+
const ignoreDuplicates = (previous, current) => {
|
|
1993
|
+
if (previous.length !== current.length) {
|
|
1994
|
+
return false;
|
|
1995
|
+
}
|
|
1996
|
+
const previousMqs = previous.map(mc => mc.mediaQuery);
|
|
1997
|
+
const currentMqs = new Set(current.map(mc => mc.mediaQuery));
|
|
1998
|
+
const difference = new Set(previousMqs.filter(mq => !currentMqs.has(mq)));
|
|
1999
|
+
return difference.size === 0;
|
|
2000
|
+
};
|
|
2001
|
+
/**
|
|
2002
|
+
*/
|
|
2003
|
+
return this.matchMedia
|
|
2004
|
+
.observe(this.hook.withPrintQuery(mqList))
|
|
2005
|
+
.pipe(filter((change) => change.matches), debounceTime(0, asapScheduler), switchMap(_ => of(this.findAllActivations())), map(excludeOverlaps), filter(hasChanges), distinctUntilChanged(ignoreDuplicates), takeUntil(this.destroyed$));
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* Find all current activations and prepare single list of activations
|
|
2009
|
+
* sorted by descending priority.
|
|
2010
|
+
*/
|
|
2011
|
+
findAllActivations() {
|
|
2012
|
+
const mergeMQAlias = (change) => {
|
|
2013
|
+
const bp = this.breakpoints.findByQuery(change.mediaQuery);
|
|
2014
|
+
return mergeAlias(change, bp);
|
|
2015
|
+
};
|
|
2016
|
+
const replaceWithPrintAlias = (change) => {
|
|
2017
|
+
return this.hook.isPrintEvent(change) ? this.hook.updateEvent(change) : change;
|
|
2018
|
+
};
|
|
2019
|
+
return this.matchMedia
|
|
2020
|
+
.activations
|
|
2021
|
+
.map(query => new MediaChange(true, query))
|
|
2022
|
+
.map(replaceWithPrintAlias)
|
|
2023
|
+
.map(mergeMQAlias)
|
|
2024
|
+
.sort(sortDescendingPriority);
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
MediaObserver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaObserver, deps: [{ token: BreakPointRegistry }, { token: MatchMedia }, { token: PrintHook }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2028
|
+
MediaObserver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaObserver, providedIn: 'root' });
|
|
2029
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaObserver, decorators: [{
|
|
2030
|
+
type: Injectable,
|
|
2031
|
+
args: [{ providedIn: 'root' }]
|
|
2032
|
+
}], ctorParameters: function () { return [{ type: BreakPointRegistry }, { type: MatchMedia }, { type: PrintHook }]; } });
|
|
2033
|
+
/**
|
|
2034
|
+
* Find associated breakpoint (if any)
|
|
2035
|
+
*/
|
|
2036
|
+
function toMediaQuery(query, locator) {
|
|
2037
|
+
var _a, _b;
|
|
2038
|
+
const bp = (_a = locator.findByAlias(query)) !== null && _a !== void 0 ? _a : locator.findByQuery(query);
|
|
2039
|
+
return (_b = bp === null || bp === void 0 ? void 0 : bp.mediaQuery) !== null && _b !== void 0 ? _b : null;
|
|
2040
|
+
}
|
|
2041
|
+
/**
|
|
2042
|
+
* Split each query string into separate query strings if two queries are provided as comma
|
|
2043
|
+
* separated.
|
|
2044
|
+
*/
|
|
2045
|
+
function splitQueries(queries) {
|
|
2046
|
+
return queries.map((query) => query.split(','))
|
|
2047
|
+
.reduce((a1, a2) => a1.concat(a2))
|
|
2048
|
+
.map(query => query.trim());
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
/**
|
|
2052
|
+
* @license
|
|
2053
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2054
|
+
*
|
|
2055
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2056
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2057
|
+
*/
|
|
2058
|
+
|
|
2059
|
+
/**
|
|
2060
|
+
* @license
|
|
2061
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2062
|
+
*
|
|
2063
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2064
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2065
|
+
*/
|
|
2066
|
+
/**
|
|
2067
|
+
* Class
|
|
2068
|
+
*/
|
|
2069
|
+
class MediaTrigger {
|
|
2070
|
+
constructor(breakpoints, matchMedia, layoutConfig, _platformId, _document) {
|
|
2071
|
+
this.breakpoints = breakpoints;
|
|
2072
|
+
this.matchMedia = matchMedia;
|
|
2073
|
+
this.layoutConfig = layoutConfig;
|
|
2074
|
+
this._platformId = _platformId;
|
|
2075
|
+
this._document = _document;
|
|
2076
|
+
this.hasCachedRegistryMatches = false;
|
|
2077
|
+
this.originalActivations = [];
|
|
2078
|
+
this.originalRegistry = new Map();
|
|
2079
|
+
}
|
|
2080
|
+
/**
|
|
2081
|
+
* Manually activate range of breakpoints
|
|
2082
|
+
* @param list array of mediaQuery or alias strings
|
|
2083
|
+
*/
|
|
2084
|
+
activate(list) {
|
|
2085
|
+
list = list.map(it => it.trim()); // trim queries
|
|
2086
|
+
this.saveActivations();
|
|
2087
|
+
this.deactivateAll();
|
|
2088
|
+
this.setActivations(list);
|
|
2089
|
+
this.prepareAutoRestore();
|
|
2090
|
+
}
|
|
2091
|
+
/**
|
|
2092
|
+
* Restore original, 'real' breakpoints and emit events
|
|
2093
|
+
* to trigger stream notification
|
|
2094
|
+
*/
|
|
2095
|
+
restore() {
|
|
2096
|
+
if (this.hasCachedRegistryMatches) {
|
|
2097
|
+
const extractQuery = (change) => change.mediaQuery;
|
|
2098
|
+
const list = this.originalActivations.map(extractQuery);
|
|
2099
|
+
try {
|
|
2100
|
+
this.deactivateAll();
|
|
2101
|
+
this.restoreRegistryMatches();
|
|
2102
|
+
this.setActivations(list);
|
|
2103
|
+
}
|
|
2104
|
+
finally {
|
|
2105
|
+
this.originalActivations = [];
|
|
2106
|
+
if (this.resizeSubscription) {
|
|
2107
|
+
this.resizeSubscription.unsubscribe();
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
// ************************************************
|
|
2113
|
+
// Internal Methods
|
|
2114
|
+
// ************************************************
|
|
2115
|
+
/**
|
|
2116
|
+
* Whenever window resizes, immediately auto-restore original
|
|
2117
|
+
* activations (if we are simulating activations)
|
|
2118
|
+
*/
|
|
2119
|
+
prepareAutoRestore() {
|
|
2120
|
+
const isBrowser = isPlatformBrowser(this._platformId) && this._document;
|
|
2121
|
+
const enableAutoRestore = isBrowser && this.layoutConfig.mediaTriggerAutoRestore;
|
|
2122
|
+
if (enableAutoRestore) {
|
|
2123
|
+
const resize$ = fromEvent(window, 'resize').pipe(take(1));
|
|
2124
|
+
this.resizeSubscription = resize$.subscribe(this.restore.bind(this));
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
/**
|
|
2128
|
+
* Notify all matchMedia subscribers of de-activations
|
|
2129
|
+
*
|
|
2130
|
+
* Note: we must force 'matches' updates for
|
|
2131
|
+
* future matchMedia::activation lookups
|
|
2132
|
+
*/
|
|
2133
|
+
deactivateAll() {
|
|
2134
|
+
const list = this.currentActivations;
|
|
2135
|
+
this.forceRegistryMatches(list, false);
|
|
2136
|
+
this.simulateMediaChanges(list, false);
|
|
2137
|
+
}
|
|
2138
|
+
/**
|
|
2139
|
+
* Cache current activations as sorted, prioritized list of MediaChanges
|
|
2140
|
+
*/
|
|
2141
|
+
saveActivations() {
|
|
2142
|
+
if (!this.hasCachedRegistryMatches) {
|
|
2143
|
+
const toMediaChange = (query) => new MediaChange(true, query);
|
|
2144
|
+
const mergeMQAlias = (change) => {
|
|
2145
|
+
const bp = this.breakpoints.findByQuery(change.mediaQuery);
|
|
2146
|
+
return mergeAlias(change, bp);
|
|
2147
|
+
};
|
|
2148
|
+
this.originalActivations = this.currentActivations
|
|
2149
|
+
.map(toMediaChange)
|
|
2150
|
+
.map(mergeMQAlias)
|
|
2151
|
+
.sort(sortDescendingPriority);
|
|
2152
|
+
this.cacheRegistryMatches();
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
/**
|
|
2156
|
+
* Force set manual activations for specified mediaQuery list
|
|
2157
|
+
*/
|
|
2158
|
+
setActivations(list) {
|
|
2159
|
+
if (!!this.originalRegistry) {
|
|
2160
|
+
this.forceRegistryMatches(list, true);
|
|
2161
|
+
}
|
|
2162
|
+
this.simulateMediaChanges(list);
|
|
2163
|
+
}
|
|
2164
|
+
/**
|
|
2165
|
+
* For specified mediaQuery list manually simulate activations or deactivations
|
|
2166
|
+
*/
|
|
2167
|
+
simulateMediaChanges(queries, matches = true) {
|
|
2168
|
+
const toMediaQuery = (query) => {
|
|
2169
|
+
const locator = this.breakpoints;
|
|
2170
|
+
const bp = locator.findByAlias(query) || locator.findByQuery(query);
|
|
2171
|
+
return bp ? bp.mediaQuery : query;
|
|
2172
|
+
};
|
|
2173
|
+
const emitChangeEvent = (query) => this.emitChangeEvent(matches, query);
|
|
2174
|
+
queries.map(toMediaQuery).forEach(emitChangeEvent);
|
|
2175
|
+
}
|
|
2176
|
+
/**
|
|
2177
|
+
* Replace current registry with simulated registry...
|
|
2178
|
+
* Note: this is required since MediaQueryList::matches is 'readOnly'
|
|
2179
|
+
*/
|
|
2180
|
+
forceRegistryMatches(queries, matches) {
|
|
2181
|
+
const registry = new Map();
|
|
2182
|
+
queries.forEach(query => {
|
|
2183
|
+
registry.set(query, { matches });
|
|
2184
|
+
});
|
|
2185
|
+
this.matchMedia.registry = registry;
|
|
2186
|
+
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Save current MatchMedia::registry items.
|
|
2189
|
+
*/
|
|
2190
|
+
cacheRegistryMatches() {
|
|
2191
|
+
const target = this.originalRegistry;
|
|
2192
|
+
target.clear();
|
|
2193
|
+
this.matchMedia.registry.forEach((value, key) => {
|
|
2194
|
+
target.set(key, value);
|
|
2195
|
+
});
|
|
2196
|
+
this.hasCachedRegistryMatches = true;
|
|
2197
|
+
}
|
|
2198
|
+
/**
|
|
2199
|
+
* Restore original, 'true' registry
|
|
2200
|
+
*/
|
|
2201
|
+
restoreRegistryMatches() {
|
|
2202
|
+
const target = this.matchMedia.registry;
|
|
2203
|
+
target.clear();
|
|
2204
|
+
this.originalRegistry.forEach((value, key) => {
|
|
2205
|
+
target.set(key, value);
|
|
2206
|
+
});
|
|
2207
|
+
this.originalRegistry.clear();
|
|
2208
|
+
this.hasCachedRegistryMatches = false;
|
|
2209
|
+
}
|
|
2210
|
+
/**
|
|
2211
|
+
* Manually emit a MediaChange event via the MatchMedia to MediaMarshaller and MediaObserver
|
|
2212
|
+
*/
|
|
2213
|
+
emitChangeEvent(matches, query) {
|
|
2214
|
+
this.matchMedia.source.next(new MediaChange(matches, query));
|
|
2215
|
+
}
|
|
2216
|
+
get currentActivations() {
|
|
2217
|
+
return this.matchMedia.activations;
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
MediaTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaTrigger, deps: [{ token: BreakPointRegistry }, { token: MatchMedia }, { token: LAYOUT_CONFIG }, { token: PLATFORM_ID }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2221
|
+
MediaTrigger.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaTrigger, providedIn: 'root' });
|
|
2222
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: MediaTrigger, decorators: [{
|
|
2223
|
+
type: Injectable,
|
|
2224
|
+
args: [{ providedIn: 'root' }]
|
|
2225
|
+
}], ctorParameters: function () {
|
|
2226
|
+
return [{ type: BreakPointRegistry }, { type: MatchMedia }, { type: undefined, decorators: [{
|
|
2227
|
+
type: Inject,
|
|
2228
|
+
args: [LAYOUT_CONFIG]
|
|
2229
|
+
}] }, { type: Object, decorators: [{
|
|
2230
|
+
type: Inject,
|
|
2231
|
+
args: [PLATFORM_ID]
|
|
2232
|
+
}] }, { type: undefined, decorators: [{
|
|
2233
|
+
type: Inject,
|
|
2234
|
+
args: [DOCUMENT]
|
|
2235
|
+
}] }];
|
|
2236
|
+
} });
|
|
2237
|
+
|
|
2238
|
+
/**
|
|
2239
|
+
* @license
|
|
2240
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2241
|
+
*
|
|
2242
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2243
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2244
|
+
*/
|
|
2245
|
+
|
|
2246
|
+
/**
|
|
2247
|
+
* @license
|
|
2248
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2249
|
+
*
|
|
2250
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2251
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2252
|
+
*/
|
|
2253
|
+
|
|
2254
|
+
/**
|
|
2255
|
+
* @license
|
|
2256
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2257
|
+
*
|
|
2258
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2259
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2260
|
+
*/
|
|
2261
|
+
/**
|
|
2262
|
+
* The flex API permits 3 or 1 parts of the value:
|
|
2263
|
+
* - `flex-grow flex-shrink flex-basis`, or
|
|
2264
|
+
* - `flex-basis`
|
|
2265
|
+
*/
|
|
2266
|
+
function validateBasis(basis, grow = '1', shrink = '1') {
|
|
2267
|
+
let parts = [grow, shrink, basis];
|
|
2268
|
+
let j = basis.indexOf('calc');
|
|
2269
|
+
if (j > 0) {
|
|
2270
|
+
parts[2] = _validateCalcValue(basis.substring(j).trim());
|
|
2271
|
+
let matches = basis.substr(0, j).trim().split(' ');
|
|
2272
|
+
if (matches.length == 2) {
|
|
2273
|
+
parts[0] = matches[0];
|
|
2274
|
+
parts[1] = matches[1];
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
else if (j == 0) {
|
|
2278
|
+
parts[2] = _validateCalcValue(basis.trim());
|
|
2279
|
+
}
|
|
2280
|
+
else {
|
|
2281
|
+
let matches = basis.split(' ');
|
|
2282
|
+
parts = (matches.length === 3) ? matches : [
|
|
2283
|
+
grow, shrink, basis
|
|
2284
|
+
];
|
|
2285
|
+
}
|
|
2286
|
+
return parts;
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Calc expressions require whitespace before & after any expression operators
|
|
2290
|
+
* This is a simple, crude whitespace padding solution.
|
|
2291
|
+
* - '3 3 calc(15em + 20px)'
|
|
2292
|
+
* - calc(100% / 7 * 2)
|
|
2293
|
+
* - 'calc(15em + 20px)'
|
|
2294
|
+
* - 'calc(15em+20px)'
|
|
2295
|
+
* - '37px'
|
|
2296
|
+
* = '43%'
|
|
2297
|
+
*/
|
|
2298
|
+
function _validateCalcValue(calc) {
|
|
2299
|
+
return calc.replace(/[\s]/g, '').replace(/[\/\*\+\-]/g, ' $& ');
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
const MULTIPLIER_SUFFIX = 'x';
|
|
2303
|
+
function multiply(value, multiplier) {
|
|
2304
|
+
if (multiplier === undefined) {
|
|
2305
|
+
return value;
|
|
2306
|
+
}
|
|
2307
|
+
const transformValue = (possibleValue) => {
|
|
2308
|
+
const numberValue = +(possibleValue.slice(0, -MULTIPLIER_SUFFIX.length));
|
|
2309
|
+
if (value.endsWith(MULTIPLIER_SUFFIX) && !isNaN(numberValue)) {
|
|
2310
|
+
return `${numberValue * multiplier.value}${multiplier.unit}`;
|
|
2311
|
+
}
|
|
2312
|
+
return value;
|
|
2313
|
+
};
|
|
2314
|
+
return value.includes(' ') ?
|
|
2315
|
+
value.split(' ').map(transformValue).join(' ') : transformValue(value);
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2318
|
+
/**
|
|
2319
|
+
* @license
|
|
2320
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2321
|
+
*
|
|
2322
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2323
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2324
|
+
*/
|
|
2325
|
+
|
|
2326
|
+
/**
|
|
2327
|
+
* Generated bundle index. Do not edit.
|
|
2328
|
+
*/
|
|
2329
|
+
|
|
2330
|
+
export { BREAKPOINT, BREAKPOINTS, BREAKPOINT_PRINT, BROWSER_PROVIDER, BaseDirective2, BreakPointRegistry, CLASS_NAME, CoreModule, DEFAULT_BREAKPOINTS, DEFAULT_CONFIG, LAYOUT_CONFIG, MediaChange, MediaMarshaller, MediaObserver, MediaTrigger, ORIENTATION_BREAKPOINTS, PrintHook, SERVER_TOKEN, ScreenTypes, StyleBuilder, StyleUtils, StylesheetMap, coerceArray, mergeAlias, removeStyles, sortAscendingPriority, sortDescendingPriority, validateBasis, MatchMedia as ɵMatchMedia, MockMatchMedia as ɵMockMatchMedia, MockMatchMediaProvider as ɵMockMatchMediaProvider, multiply as ɵmultiply };
|
|
2331
|
+
//# sourceMappingURL=angular-flex-layout-core.mjs.map
|