@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.
Files changed (226) hide show
  1. package/README.md +7 -0
  2. package/_private-utils/angular-flex-layout-_private-utils.d.ts +5 -0
  3. package/_private-utils/auto-prefixer.d.ts +24 -0
  4. package/_private-utils/index.d.ts +10 -0
  5. package/_private-utils/layout-validator.d.ts +32 -0
  6. package/_private-utils/object-extend.d.ts +15 -0
  7. package/_private-utils/package.json +10 -0
  8. package/_private-utils/testing/angular-flex-layout-_private-utils-testing.d.ts +5 -0
  9. package/_private-utils/testing/custom-matchers.d.ts +65 -0
  10. package/_private-utils/testing/dom-tools.d.ts +47 -0
  11. package/_private-utils/testing/helpers.d.ts +24 -0
  12. package/_private-utils/testing/index.d.ts +10 -0
  13. package/_private-utils/testing/package.json +10 -0
  14. package/angular-flex-layout-13.0.0-beta.38.tgz +0 -0
  15. package/angular-flex-layout.d.ts +5 -0
  16. package/core/README.md +25 -0
  17. package/core/add-alias.d.ts +14 -0
  18. package/core/angular-flex-layout-core.d.ts +5 -0
  19. package/core/base/base2.d.ts +60 -0
  20. package/core/base/index.d.ts +8 -0
  21. package/core/basis-validator/basis-validator.d.ts +13 -0
  22. package/core/breakpoints/break-point-registry.d.ts +42 -0
  23. package/core/breakpoints/break-point.d.ts +14 -0
  24. package/core/breakpoints/break-points-token.d.ts +14 -0
  25. package/core/breakpoints/breakpoint-tools.d.ts +19 -0
  26. package/core/breakpoints/data/break-points.d.ts +12 -0
  27. package/core/breakpoints/data/orientation-break-points.d.ts +23 -0
  28. package/core/breakpoints/index.d.ts +12 -0
  29. package/core/browser-provider.d.ts +24 -0
  30. package/core/match-media/index.d.ts +9 -0
  31. package/core/match-media/match-media.d.ts +59 -0
  32. package/core/match-media/mock/mock-match-media.d.ts +92 -0
  33. package/core/media-change.d.ts +30 -0
  34. package/core/media-marshaller/media-marshaller.d.ts +123 -0
  35. package/core/media-marshaller/print-hook.d.ts +95 -0
  36. package/core/media-observer/index.d.ts +8 -0
  37. package/core/media-observer/media-observer.d.ts +115 -0
  38. package/core/media-trigger/index.d.ts +8 -0
  39. package/core/media-trigger/media-trigger.d.ts +73 -0
  40. package/core/module.d.ts +11 -0
  41. package/core/multiply/multiplier.d.ts +5 -0
  42. package/core/package.json +10 -0
  43. package/core/public-api.d.ts +25 -0
  44. package/core/sass/_layout-bp.scss +76 -0
  45. package/core/style-builder/style-builder.d.ts +21 -0
  46. package/core/style-utils/style-utils.d.ts +53 -0
  47. package/core/stylesheet-map/index.d.ts +8 -0
  48. package/core/stylesheet-map/stylesheet-map.d.ts +24 -0
  49. package/core/tokens/breakpoint-token.d.ts +10 -0
  50. package/core/tokens/index.d.ts +10 -0
  51. package/core/tokens/library-config.d.ts +26 -0
  52. package/core/tokens/server-token.d.ts +15 -0
  53. package/core/utils/array.d.ts +9 -0
  54. package/core/utils/index.d.ts +9 -0
  55. package/core/utils/sort.d.ts +15 -0
  56. package/esm2020/_private-utils/angular-flex-layout-_private-utils.mjs +5 -0
  57. package/esm2020/_private-utils/auto-prefixer.mjs +65 -0
  58. package/esm2020/_private-utils/index.mjs +11 -0
  59. package/esm2020/_private-utils/layout-validator.mjs +83 -0
  60. package/esm2020/_private-utils/object-extend.mjs +30 -0
  61. package/esm2020/_private-utils/testing/angular-flex-layout-_private-utils-testing.mjs +5 -0
  62. package/esm2020/_private-utils/testing/custom-matchers.mjs +201 -0
  63. package/esm2020/_private-utils/testing/dom-tools.mjs +101 -0
  64. package/esm2020/_private-utils/testing/helpers.mjs +43 -0
  65. package/esm2020/_private-utils/testing/index.mjs +11 -0
  66. package/esm2020/angular-flex-layout.mjs +5 -0
  67. package/esm2020/core/add-alias.mjs +23 -0
  68. package/esm2020/core/angular-flex-layout-core.mjs +5 -0
  69. package/esm2020/core/base/base2.mjs +131 -0
  70. package/esm2020/core/base/index.mjs +9 -0
  71. package/esm2020/core/basis-validator/basis-validator.mjs +48 -0
  72. package/esm2020/core/breakpoints/break-point-registry.mjs +76 -0
  73. package/esm2020/core/breakpoints/break-point.mjs +2 -0
  74. package/esm2020/core/breakpoints/break-points-token.mjs +30 -0
  75. package/esm2020/core/breakpoints/breakpoint-tools.mjs +53 -0
  76. package/esm2020/core/breakpoints/data/break-points.mjs +78 -0
  77. package/esm2020/core/breakpoints/data/orientation-break-points.mjs +40 -0
  78. package/esm2020/core/breakpoints/index.mjs +13 -0
  79. package/esm2020/core/browser-provider.mjs +41 -0
  80. package/esm2020/core/match-media/index.mjs +10 -0
  81. package/esm2020/core/match-media/match-media.mjs +186 -0
  82. package/esm2020/core/match-media/mock/mock-match-media.mjs +224 -0
  83. package/esm2020/core/media-change.mjs +25 -0
  84. package/esm2020/core/media-marshaller/media-marshaller.mjs +317 -0
  85. package/esm2020/core/media-marshaller/print-hook.mjs +265 -0
  86. package/esm2020/core/media-observer/index.mjs +9 -0
  87. package/esm2020/core/media-observer/media-observer.mjs +195 -0
  88. package/esm2020/core/media-trigger/index.mjs +9 -0
  89. package/esm2020/core/media-trigger/media-trigger.mjs +188 -0
  90. package/esm2020/core/module.mjs +27 -0
  91. package/esm2020/core/multiply/multiplier.mjs +16 -0
  92. package/esm2020/core/public-api.mjs +26 -0
  93. package/esm2020/core/style-builder/style-builder.mjs +15 -0
  94. package/esm2020/core/style-utils/style-utils.mjs +174 -0
  95. package/esm2020/core/stylesheet-map/index.mjs +9 -0
  96. package/esm2020/core/stylesheet-map/stylesheet-map.mjs +59 -0
  97. package/esm2020/core/tokens/breakpoint-token.mjs +13 -0
  98. package/esm2020/core/tokens/index.mjs +11 -0
  99. package/esm2020/core/tokens/library-config.mjs +30 -0
  100. package/esm2020/core/tokens/server-token.mjs +19 -0
  101. package/esm2020/core/utils/array.mjs +12 -0
  102. package/esm2020/core/utils/index.mjs +10 -0
  103. package/esm2020/core/utils/sort.mjs +20 -0
  104. package/esm2020/extended/angular-flex-layout-extended.mjs +5 -0
  105. package/esm2020/extended/class/class.mjs +88 -0
  106. package/esm2020/extended/img-src/img-src.mjs +106 -0
  107. package/esm2020/extended/module.mjs +45 -0
  108. package/esm2020/extended/public-api.mjs +13 -0
  109. package/esm2020/extended/show-hide/show-hide.mjs +176 -0
  110. package/esm2020/extended/style/style-transforms.mjs +76 -0
  111. package/esm2020/extended/style/style.mjs +130 -0
  112. package/esm2020/flex/angular-flex-layout-flex.mjs +5 -0
  113. package/esm2020/flex/flex/flex.mjs +291 -0
  114. package/esm2020/flex/flex-align/flex-align.mjs +80 -0
  115. package/esm2020/flex/flex-fill/flex-fill.mjs +50 -0
  116. package/esm2020/flex/flex-offset/flex-offset.mjs +121 -0
  117. package/esm2020/flex/flex-order/flex-order.mjs +66 -0
  118. package/esm2020/flex/layout/layout.mjs +86 -0
  119. package/esm2020/flex/layout-align/layout-align.mjs +194 -0
  120. package/esm2020/flex/layout-gap/layout-gap.mjs +282 -0
  121. package/esm2020/flex/module.mjs +62 -0
  122. package/esm2020/flex/public-api.mjs +17 -0
  123. package/esm2020/grid/align-columns/align-columns.mjs +137 -0
  124. package/esm2020/grid/align-rows/align-rows.mjs +119 -0
  125. package/esm2020/grid/angular-flex-layout-grid.mjs +5 -0
  126. package/esm2020/grid/area/area.mjs +67 -0
  127. package/esm2020/grid/areas/areas.mjs +86 -0
  128. package/esm2020/grid/auto/auto.mjs +89 -0
  129. package/esm2020/grid/column/column.mjs +67 -0
  130. package/esm2020/grid/columns/columns.mjs +96 -0
  131. package/esm2020/grid/gap/gap.mjs +85 -0
  132. package/esm2020/grid/grid-align/grid-align.mjs +111 -0
  133. package/esm2020/grid/module.mjs +73 -0
  134. package/esm2020/grid/public-api.mjs +20 -0
  135. package/esm2020/grid/row/row.mjs +67 -0
  136. package/esm2020/grid/rows/rows.mjs +96 -0
  137. package/esm2020/module.mjs +64 -0
  138. package/esm2020/public-api.mjs +20 -0
  139. package/esm2020/server/angular-flex-layout-server.mjs +5 -0
  140. package/esm2020/server/module.mjs +22 -0
  141. package/esm2020/server/public-api.mjs +10 -0
  142. package/esm2020/server/server-match-media.mjs +151 -0
  143. package/esm2020/server/server-provider.mjs +140 -0
  144. package/esm2020/version.mjs +11 -0
  145. package/extended/README.md +18 -0
  146. package/extended/angular-flex-layout-extended.d.ts +5 -0
  147. package/extended/class/class.d.ts +38 -0
  148. package/extended/img-src/img-src.d.ts +51 -0
  149. package/extended/module.d.ts +16 -0
  150. package/extended/package.json +10 -0
  151. package/extended/public-api.d.ts +12 -0
  152. package/extended/show-hide/show-hide.d.ts +61 -0
  153. package/extended/style/style-transforms.d.ts +36 -0
  154. package/extended/style/style.d.ts +45 -0
  155. package/fesm2015/angular-flex-layout-_private-utils-testing.mjs +357 -0
  156. package/fesm2015/angular-flex-layout-_private-utils-testing.mjs.map +1 -0
  157. package/fesm2015/angular-flex-layout-_private-utils.mjs +193 -0
  158. package/fesm2015/angular-flex-layout-_private-utils.mjs.map +1 -0
  159. package/fesm2015/angular-flex-layout-core.mjs +2331 -0
  160. package/fesm2015/angular-flex-layout-core.mjs.map +1 -0
  161. package/fesm2015/angular-flex-layout-extended.mjs +621 -0
  162. package/fesm2015/angular-flex-layout-extended.mjs.map +1 -0
  163. package/fesm2015/angular-flex-layout-flex.mjs +1206 -0
  164. package/fesm2015/angular-flex-layout-flex.mjs.map +1 -0
  165. package/fesm2015/angular-flex-layout-grid.mjs +1047 -0
  166. package/fesm2015/angular-flex-layout-grid.mjs.map +1 -0
  167. package/fesm2015/angular-flex-layout-server.mjs +324 -0
  168. package/fesm2015/angular-flex-layout-server.mjs.map +1 -0
  169. package/fesm2015/angular-flex-layout.mjs +94 -0
  170. package/fesm2015/angular-flex-layout.mjs.map +1 -0
  171. package/fesm2020/angular-flex-layout-_private-utils-testing.mjs +357 -0
  172. package/fesm2020/angular-flex-layout-_private-utils-testing.mjs.map +1 -0
  173. package/fesm2020/angular-flex-layout-_private-utils.mjs +192 -0
  174. package/fesm2020/angular-flex-layout-_private-utils.mjs.map +1 -0
  175. package/fesm2020/angular-flex-layout-core.mjs +2304 -0
  176. package/fesm2020/angular-flex-layout-core.mjs.map +1 -0
  177. package/fesm2020/angular-flex-layout-extended.mjs +612 -0
  178. package/fesm2020/angular-flex-layout-extended.mjs.map +1 -0
  179. package/fesm2020/angular-flex-layout-flex.mjs +1198 -0
  180. package/fesm2020/angular-flex-layout-flex.mjs.map +1 -0
  181. package/fesm2020/angular-flex-layout-grid.mjs +1047 -0
  182. package/fesm2020/angular-flex-layout-grid.mjs.map +1 -0
  183. package/fesm2020/angular-flex-layout-server.mjs +322 -0
  184. package/fesm2020/angular-flex-layout-server.mjs.map +1 -0
  185. package/fesm2020/angular-flex-layout.mjs +92 -0
  186. package/fesm2020/angular-flex-layout.mjs.map +1 -0
  187. package/flex/README.md +19 -0
  188. package/flex/angular-flex-layout-flex.d.ts +5 -0
  189. package/flex/flex/flex.d.ts +59 -0
  190. package/flex/flex-align/flex-align.d.ts +32 -0
  191. package/flex/flex-fill/flex-fill.d.ts +33 -0
  192. package/flex/flex-offset/flex-offset.d.ts +44 -0
  193. package/flex/flex-order/flex-order.d.ts +34 -0
  194. package/flex/layout/layout.d.ts +43 -0
  195. package/flex/layout-align/layout-align.d.ts +49 -0
  196. package/flex/layout-gap/layout-gap.d.ts +65 -0
  197. package/flex/module.d.ts +21 -0
  198. package/flex/package.json +10 -0
  199. package/flex/public-api.d.ts +16 -0
  200. package/grid/README.md +19 -0
  201. package/grid/align-columns/align-columns.d.ts +39 -0
  202. package/grid/align-rows/align-rows.d.ts +39 -0
  203. package/grid/angular-flex-layout-grid.d.ts +5 -0
  204. package/grid/area/area.d.ts +34 -0
  205. package/grid/areas/areas.d.ts +41 -0
  206. package/grid/auto/auto.d.ts +41 -0
  207. package/grid/column/column.d.ts +34 -0
  208. package/grid/columns/columns.d.ts +43 -0
  209. package/grid/gap/gap.d.ts +42 -0
  210. package/grid/grid-align/grid-align.d.ts +37 -0
  211. package/grid/module.d.ts +23 -0
  212. package/grid/package.json +10 -0
  213. package/grid/public-api.d.ts +19 -0
  214. package/grid/row/row.d.ts +34 -0
  215. package/grid/rows/rows.d.ts +43 -0
  216. package/module.d.ts +30 -0
  217. package/package.json +100 -0
  218. package/public-api.d.ts +18 -0
  219. package/server/README.md +23 -0
  220. package/server/angular-flex-layout-server.d.ts +5 -0
  221. package/server/module.d.ts +6 -0
  222. package/server/package.json +10 -0
  223. package/server/public-api.d.ts +9 -0
  224. package/server/server-match-media.d.ts +61 -0
  225. package/server/server-provider.d.ts +44 -0
  226. 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