@ionic/angular 7.3.4-dev.11699470772.1dad7e66 → 7.3.4-dev.11699991837.1bc64f72

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 (150) hide show
  1. package/README.md +0 -20
  2. package/app-initialize.d.ts +1 -1
  3. package/directives/navigation/ion-back-button.d.ts +16 -6
  4. package/directives/navigation/ion-router-outlet.d.ts +122 -4
  5. package/directives/navigation/ion-tabs.d.ts +64 -4
  6. package/directives/navigation/nav-delegate.d.ts +9 -0
  7. package/directives/navigation/router-link-delegate.d.ts +41 -7
  8. package/{common/directives → directives}/navigation/stack-utils.d.ts +1 -1
  9. package/directives/overlays/modal.d.ts +47 -3
  10. package/directives/overlays/popover.d.ts +43 -3
  11. package/directives/proxies-list.d.ts +1 -1
  12. package/directives/proxies.d.ts +29 -3
  13. package/esm2020/app-initialize.mjs +1 -1
  14. package/esm2020/directives/navigation/ion-back-button.mjs +36 -15
  15. package/esm2020/directives/navigation/ion-router-outlet.mjs +435 -6
  16. package/esm2020/directives/navigation/ion-tabs.mjs +166 -9
  17. package/esm2020/directives/navigation/nav-delegate.mjs +42 -0
  18. package/esm2020/directives/navigation/nav-params.mjs +45 -0
  19. package/esm2020/directives/navigation/router-link-delegate.mjs +92 -11
  20. package/esm2020/directives/navigation/stack-controller.mjs +275 -0
  21. package/esm2020/directives/navigation/stack-utils.mjs +73 -0
  22. package/esm2020/directives/overlays/modal.mjs +88 -8
  23. package/esm2020/directives/overlays/popover.mjs +87 -8
  24. package/esm2020/directives/proxies-list.mjs +3 -1
  25. package/esm2020/directives/proxies.mjs +62 -10
  26. package/esm2020/index.mjs +22 -5
  27. package/esm2020/ionic-core.mjs +6 -0
  28. package/esm2020/ionic-module.mjs +32 -14
  29. package/esm2020/providers/action-sheet-controller.mjs +18 -0
  30. package/esm2020/providers/alert-controller.mjs +18 -0
  31. package/esm2020/providers/angular-delegate.mjs +152 -0
  32. package/esm2020/providers/animation-controller.mjs +37 -0
  33. package/esm2020/providers/config.mjs +44 -0
  34. package/esm2020/providers/dom-controller.mjs +44 -0
  35. package/esm2020/providers/gesture-controller.mjs +31 -0
  36. package/esm2020/providers/loading-controller.mjs +18 -0
  37. package/esm2020/providers/menu-controller.mjs +100 -0
  38. package/esm2020/providers/modal-controller.mjs +25 -0
  39. package/esm2020/providers/nav-controller.mjs +221 -0
  40. package/esm2020/providers/picker-controller.mjs +18 -0
  41. package/esm2020/providers/platform.mjs +246 -0
  42. package/esm2020/providers/popover-controller.mjs +25 -0
  43. package/esm2020/providers/toast-controller.mjs +18 -0
  44. package/esm2020/types/interfaces.mjs +2 -0
  45. package/esm2020/util/ionic-router-reuse-strategy.mjs +55 -0
  46. package/esm2020/util/overlay.mjs +25 -0
  47. package/fesm2015/ionic-angular.mjs +2485 -135
  48. package/fesm2015/ionic-angular.mjs.map +1 -1
  49. package/fesm2020/ionic-angular.mjs +2477 -136
  50. package/fesm2020/ionic-angular.mjs.map +1 -1
  51. package/index.d.ts +20 -4
  52. package/ionic-core.d.ts +2 -0
  53. package/ionic-module.d.ts +2 -2
  54. package/package.json +2 -18
  55. package/{common/providers → providers}/action-sheet-controller.d.ts +2 -2
  56. package/{common/providers → providers}/alert-controller.d.ts +2 -2
  57. package/{common/providers → providers}/angular-delegate.d.ts +1 -1
  58. package/{common/providers → providers}/animation-controller.d.ts +1 -1
  59. package/{common/providers → providers}/config.d.ts +1 -1
  60. package/{common/providers → providers}/gesture-controller.d.ts +1 -1
  61. package/{common/providers → providers}/loading-controller.d.ts +2 -2
  62. package/{common/providers → providers}/modal-controller.d.ts +2 -2
  63. package/{common/providers → providers}/nav-controller.d.ts +2 -2
  64. package/{common/providers → providers}/picker-controller.d.ts +2 -2
  65. package/{common/providers → providers}/platform.d.ts +1 -1
  66. package/{common/providers → providers}/popover-controller.d.ts +2 -2
  67. package/{common/providers → providers}/toast-controller.d.ts +2 -2
  68. package/test/README.md +0 -8
  69. package/{common/types → types}/interfaces.d.ts +4 -0
  70. package/common/directives/navigation/back-button.d.ts +0 -26
  71. package/common/directives/navigation/nav.d.ts +0 -13
  72. package/common/directives/navigation/router-link-delegate.d.ts +0 -50
  73. package/common/directives/navigation/router-outlet.d.ts +0 -103
  74. package/common/directives/navigation/tabs.d.ts +0 -74
  75. package/common/index.d.ts +0 -26
  76. package/common/overlays/modal.d.ts +0 -50
  77. package/common/overlays/popover.d.ts +0 -46
  78. package/common/utils/proxy.d.ts +0 -8
  79. package/directives/navigation/ion-nav.d.ts +0 -8
  80. package/esm2020/common/directives/navigation/back-button.mjs +0 -59
  81. package/esm2020/common/directives/navigation/nav-params.mjs +0 -45
  82. package/esm2020/common/directives/navigation/nav.mjs +0 -47
  83. package/esm2020/common/directives/navigation/router-link-delegate.mjs +0 -111
  84. package/esm2020/common/directives/navigation/router-outlet.mjs +0 -461
  85. package/esm2020/common/directives/navigation/stack-controller.mjs +0 -275
  86. package/esm2020/common/directives/navigation/stack-utils.mjs +0 -73
  87. package/esm2020/common/directives/navigation/tabs.mjs +0 -172
  88. package/esm2020/common/index.mjs +0 -26
  89. package/esm2020/common/ionic-angular-common.mjs +0 -5
  90. package/esm2020/common/overlays/modal.mjs +0 -87
  91. package/esm2020/common/overlays/popover.mjs +0 -79
  92. package/esm2020/common/providers/action-sheet-controller.mjs +0 -18
  93. package/esm2020/common/providers/alert-controller.mjs +0 -18
  94. package/esm2020/common/providers/angular-delegate.mjs +0 -152
  95. package/esm2020/common/providers/animation-controller.mjs +0 -37
  96. package/esm2020/common/providers/config.mjs +0 -44
  97. package/esm2020/common/providers/dom-controller.mjs +0 -44
  98. package/esm2020/common/providers/gesture-controller.mjs +0 -31
  99. package/esm2020/common/providers/loading-controller.mjs +0 -18
  100. package/esm2020/common/providers/menu-controller.mjs +0 -100
  101. package/esm2020/common/providers/modal-controller.mjs +0 -25
  102. package/esm2020/common/providers/nav-controller.mjs +0 -221
  103. package/esm2020/common/providers/picker-controller.mjs +0 -18
  104. package/esm2020/common/providers/platform.mjs +0 -246
  105. package/esm2020/common/providers/popover-controller.mjs +0 -25
  106. package/esm2020/common/providers/toast-controller.mjs +0 -18
  107. package/esm2020/common/types/interfaces.mjs +0 -2
  108. package/esm2020/common/utils/overlay.mjs +0 -25
  109. package/esm2020/common/utils/proxy.mjs +0 -47
  110. package/esm2020/common/utils/routing.mjs +0 -55
  111. package/esm2020/directives/navigation/ion-nav.mjs +0 -21
  112. package/esm2020/standalone/directives/angular-component-lib/utils.mjs +0 -51
  113. package/esm2020/standalone/directives/icon.mjs +0 -33
  114. package/esm2020/standalone/directives/proxies.mjs +0 -2960
  115. package/esm2020/standalone/index.mjs +0 -15
  116. package/esm2020/standalone/ionic-angular-standalone.mjs +0 -5
  117. package/esm2020/standalone/navigation/back-button.mjs +0 -32
  118. package/esm2020/standalone/navigation/nav.mjs +0 -28
  119. package/esm2020/standalone/navigation/router-link-delegate.mjs +0 -30
  120. package/esm2020/standalone/navigation/router-outlet.mjs +0 -23
  121. package/esm2020/standalone/navigation/tabs.mjs +0 -46
  122. package/esm2020/standalone/overlays/modal.mjs +0 -32
  123. package/esm2020/standalone/overlays/popover.mjs +0 -28
  124. package/esm2020/standalone/providers/ionic-angular.mjs +0 -41
  125. package/fesm2015/ionic-angular-common.mjs +0 -2472
  126. package/fesm2015/ionic-angular-common.mjs.map +0 -1
  127. package/fesm2015/ionic-angular-standalone.mjs +0 -3191
  128. package/fesm2015/ionic-angular-standalone.mjs.map +0 -1
  129. package/fesm2020/ionic-angular-common.mjs +0 -2461
  130. package/fesm2020/ionic-angular-common.mjs.map +0 -1
  131. package/fesm2020/ionic-angular-standalone.mjs +0 -3189
  132. package/fesm2020/ionic-angular-standalone.mjs.map +0 -1
  133. package/standalone/directives/angular-component-lib/utils.d.ts +0 -9
  134. package/standalone/directives/icon.d.ts +0 -9
  135. package/standalone/directives/proxies.d.ts +0 -1217
  136. package/standalone/index.d.ts +0 -12
  137. package/standalone/navigation/back-button.d.ts +0 -9
  138. package/standalone/navigation/nav.d.ts +0 -8
  139. package/standalone/navigation/router-link-delegate.d.ts +0 -10
  140. package/standalone/navigation/router-outlet.d.ts +0 -6
  141. package/standalone/navigation/tabs.d.ts +0 -12
  142. package/standalone/overlays/modal.d.ts +0 -6
  143. package/standalone/overlays/popover.d.ts +0 -6
  144. package/standalone/providers/ionic-angular.d.ts +0 -3
  145. /package/{common/directives → directives}/navigation/nav-params.d.ts +0 -0
  146. /package/{common/directives → directives}/navigation/stack-controller.d.ts +0 -0
  147. /package/{common/providers → providers}/dom-controller.d.ts +0 -0
  148. /package/{common/providers → providers}/menu-controller.d.ts +0 -0
  149. /package/{common/utils/routing.d.ts → util/ionic-router-reuse-strategy.d.ts} +0 -0
  150. /package/{common/utils → util}/overlay.d.ts +0 -0
@@ -1,2472 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { Injectable, inject, NgZone, ApplicationRef, Injector, createComponent, InjectionToken, EnvironmentInjector, Inject, Optional, TemplateRef, Directive, ContentChild, EventEmitter, ViewContainerRef, Attribute, SkipSelf, Input, Output, reflectComponentType, HostListener, ElementRef, ViewChild } from '@angular/core';
3
- import { actionSheetController, alertController, loadingController, menuController, LIFECYCLE_WILL_ENTER, LIFECYCLE_DID_ENTER, LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_UNLOAD, modalController, pickerController, popoverController, toastController, createAnimation, getTimeGivenProgression, createGesture, isPlatform, getPlatforms, componentOnReady } from '@ionic/core/components';
4
- import { __awaiter, __decorate } from 'tslib';
5
- import * as i3 from '@angular/router';
6
- import { NavigationStart, PRIMARY_OUTLET, ChildrenOutletContexts, ActivatedRoute, Router } from '@angular/router';
7
- import * as i1 from '@angular/common';
8
- import { DOCUMENT } from '@angular/common';
9
- import { Subject, fromEvent, BehaviorSubject, combineLatest, of } from 'rxjs';
10
- import { filter, switchMap, distinctUntilChanged } from 'rxjs/operators';
11
-
12
- // TODO(FW-2827): types
13
- class OverlayBaseController {
14
- constructor(ctrl) {
15
- this.ctrl = ctrl;
16
- }
17
- /**
18
- * Creates a new overlay
19
- */
20
- create(opts) {
21
- return this.ctrl.create((opts || {}));
22
- }
23
- /**
24
- * When `id` is not provided, it dismisses the top overlay.
25
- */
26
- dismiss(data, role, id) {
27
- return this.ctrl.dismiss(data, role, id);
28
- }
29
- /**
30
- * Returns the top overlay.
31
- */
32
- getTop() {
33
- return this.ctrl.getTop();
34
- }
35
- }
36
-
37
- class ActionSheetController extends OverlayBaseController {
38
- constructor() {
39
- super(actionSheetController);
40
- }
41
- }
42
- /** @nocollapse */ ActionSheetController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ActionSheetController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
43
- /** @nocollapse */ ActionSheetController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ActionSheetController, providedIn: 'root' });
44
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ActionSheetController, decorators: [{
45
- type: Injectable,
46
- args: [{
47
- providedIn: 'root',
48
- }]
49
- }], ctorParameters: function () { return []; } });
50
-
51
- class AlertController extends OverlayBaseController {
52
- constructor() {
53
- super(alertController);
54
- }
55
- }
56
- /** @nocollapse */ AlertController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AlertController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
57
- /** @nocollapse */ AlertController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AlertController, providedIn: 'root' });
58
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AlertController, decorators: [{
59
- type: Injectable,
60
- args: [{
61
- providedIn: 'root',
62
- }]
63
- }], ctorParameters: function () { return []; } });
64
-
65
- class LoadingController extends OverlayBaseController {
66
- constructor() {
67
- super(loadingController);
68
- }
69
- }
70
- /** @nocollapse */ LoadingController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: LoadingController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
71
- /** @nocollapse */ LoadingController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: LoadingController, providedIn: 'root' });
72
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: LoadingController, decorators: [{
73
- type: Injectable,
74
- args: [{
75
- providedIn: 'root',
76
- }]
77
- }], ctorParameters: function () { return []; } });
78
-
79
- class MenuController {
80
- /**
81
- * Programmatically open the Menu.
82
- * @param [menuId] Optionally get the menu by its id, or side.
83
- * @return returns a promise when the menu is fully opened
84
- */
85
- open(menuId) {
86
- return menuController.open(menuId);
87
- }
88
- /**
89
- * Programmatically close the Menu. If no `menuId` is given as the first
90
- * argument then it'll close any menu which is open. If a `menuId`
91
- * is given then it'll close that exact menu.
92
- * @param [menuId] Optionally get the menu by its id, or side.
93
- * @return returns a promise when the menu is fully closed
94
- */
95
- close(menuId) {
96
- return menuController.close(menuId);
97
- }
98
- /**
99
- * Toggle the menu. If it's closed, it will open, and if opened, it
100
- * will close.
101
- * @param [menuId] Optionally get the menu by its id, or side.
102
- * @return returns a promise when the menu has been toggled
103
- */
104
- toggle(menuId) {
105
- return menuController.toggle(menuId);
106
- }
107
- /**
108
- * Used to enable or disable a menu. For example, there could be multiple
109
- * left menus, but only one of them should be able to be opened at the same
110
- * time. If there are multiple menus on the same side, then enabling one menu
111
- * will also automatically disable all the others that are on the same side.
112
- * @param [menuId] Optionally get the menu by its id, or side.
113
- * @return Returns the instance of the menu, which is useful for chaining.
114
- */
115
- enable(shouldEnable, menuId) {
116
- return menuController.enable(shouldEnable, menuId);
117
- }
118
- /**
119
- * Used to enable or disable the ability to swipe open the menu.
120
- * @param shouldEnable True if it should be swipe-able, false if not.
121
- * @param [menuId] Optionally get the menu by its id, or side.
122
- * @return Returns the instance of the menu, which is useful for chaining.
123
- */
124
- swipeGesture(shouldEnable, menuId) {
125
- return menuController.swipeGesture(shouldEnable, menuId);
126
- }
127
- /**
128
- * @param [menuId] Optionally get the menu by its id, or side.
129
- * @return Returns true if the specified menu is currently open, otherwise false.
130
- * If the menuId is not specified, it returns true if ANY menu is currenly open.
131
- */
132
- isOpen(menuId) {
133
- return menuController.isOpen(menuId);
134
- }
135
- /**
136
- * @param [menuId] Optionally get the menu by its id, or side.
137
- * @return Returns true if the menu is currently enabled, otherwise false.
138
- */
139
- isEnabled(menuId) {
140
- return menuController.isEnabled(menuId);
141
- }
142
- /**
143
- * Used to get a menu instance. If a `menuId` is not provided then it'll
144
- * return the first menu found. If a `menuId` is `left` or `right`, then
145
- * it'll return the enabled menu on that side. Otherwise, if a `menuId` is
146
- * provided, then it'll try to find the menu using the menu's `id`
147
- * property. If a menu is not found then it'll return `null`.
148
- * @param [menuId] Optionally get the menu by its id, or side.
149
- * @return Returns the instance of the menu if found, otherwise `null`.
150
- */
151
- get(menuId) {
152
- return menuController.get(menuId);
153
- }
154
- /**
155
- * @return Returns the instance of the menu already opened, otherwise `null`.
156
- */
157
- getOpen() {
158
- return menuController.getOpen();
159
- }
160
- /**
161
- * @return Returns an array of all menu instances.
162
- */
163
- getMenus() {
164
- return menuController.getMenus();
165
- }
166
- }
167
- /** @nocollapse */ MenuController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: MenuController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
168
- /** @nocollapse */ MenuController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: MenuController, providedIn: 'root' });
169
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: MenuController, decorators: [{
170
- type: Injectable,
171
- args: [{
172
- providedIn: 'root',
173
- }]
174
- }] });
175
-
176
- /**
177
- * @description
178
- * NavParams are an object that exists on a page and can contain data for that particular view.
179
- * Similar to how data was pass to a view in V1 with `$stateParams`, NavParams offer a much more flexible
180
- * option with a simple `get` method.
181
- *
182
- * @usage
183
- * ```ts
184
- * import { NavParams } from '@ionic/angular';
185
- *
186
- * export class MyClass{
187
- *
188
- * constructor(navParams: NavParams){
189
- * // userParams is an object we have in our nav-parameters
190
- * navParams.get('userParams');
191
- * }
192
- *
193
- * }
194
- * ```
195
- */
196
- class NavParams {
197
- constructor(data = {}) {
198
- this.data = data;
199
- }
200
- /**
201
- * Get the value of a nav-parameter for the current view
202
- *
203
- * ```ts
204
- * import { NavParams } from 'ionic-angular';
205
- *
206
- * export class MyClass{
207
- * constructor(public navParams: NavParams){
208
- * // userParams is an object we have in our nav-parameters
209
- * this.navParams.get('userParams');
210
- * }
211
- * }
212
- * ```
213
- *
214
- * @param param Which param you want to look up
215
- */
216
- get(param) {
217
- return this.data[param];
218
- }
219
- }
220
-
221
- // TODO(FW-2827): types
222
- class AngularDelegate {
223
- constructor() {
224
- this.zone = inject(NgZone);
225
- this.applicationRef = inject(ApplicationRef);
226
- }
227
- create(environmentInjector, injector, elementReferenceKey) {
228
- return new AngularFrameworkDelegate(environmentInjector, injector, this.applicationRef, this.zone, elementReferenceKey);
229
- }
230
- }
231
- /** @nocollapse */ AngularDelegate.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AngularDelegate, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
232
- /** @nocollapse */ AngularDelegate.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AngularDelegate });
233
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AngularDelegate, decorators: [{
234
- type: Injectable
235
- }] });
236
- class AngularFrameworkDelegate {
237
- constructor(environmentInjector, injector, applicationRef, zone, elementReferenceKey) {
238
- this.environmentInjector = environmentInjector;
239
- this.injector = injector;
240
- this.applicationRef = applicationRef;
241
- this.zone = zone;
242
- this.elementReferenceKey = elementReferenceKey;
243
- this.elRefMap = new WeakMap();
244
- this.elEventsMap = new WeakMap();
245
- }
246
- attachViewToDom(container, component, params, cssClasses) {
247
- return this.zone.run(() => {
248
- return new Promise((resolve) => {
249
- const componentProps = Object.assign({}, params);
250
- /**
251
- * Ionic Angular passes a reference to a modal
252
- * or popover that can be accessed using a
253
- * variable in the overlay component. If
254
- * elementReferenceKey is defined, then we should
255
- * pass a reference to the component using
256
- * elementReferenceKey as the key.
257
- */
258
- if (this.elementReferenceKey !== undefined) {
259
- componentProps[this.elementReferenceKey] = container;
260
- }
261
- const el = attachView(this.zone, this.environmentInjector, this.injector, this.applicationRef, this.elRefMap, this.elEventsMap, container, component, componentProps, cssClasses, this.elementReferenceKey);
262
- resolve(el);
263
- });
264
- });
265
- }
266
- removeViewFromDom(_container, component) {
267
- return this.zone.run(() => {
268
- return new Promise((resolve) => {
269
- const componentRef = this.elRefMap.get(component);
270
- if (componentRef) {
271
- componentRef.destroy();
272
- this.elRefMap.delete(component);
273
- const unbindEvents = this.elEventsMap.get(component);
274
- if (unbindEvents) {
275
- unbindEvents();
276
- this.elEventsMap.delete(component);
277
- }
278
- }
279
- resolve();
280
- });
281
- });
282
- }
283
- }
284
- const attachView = (zone, environmentInjector, injector, applicationRef, elRefMap, elEventsMap, container, component, params, cssClasses, elementReferenceKey) => {
285
- /**
286
- * Wraps the injector with a custom injector that
287
- * provides NavParams to the component.
288
- *
289
- * NavParams is a legacy feature from Ionic v3 that allows
290
- * Angular developers to provide data to a component
291
- * and access it by providing NavParams as a dependency
292
- * in the constructor.
293
- *
294
- * The modern approach is to access the data directly
295
- * from the component's class instance.
296
- */
297
- const childInjector = Injector.create({
298
- providers: getProviders(params),
299
- parent: injector,
300
- });
301
- const componentRef = createComponent(component, {
302
- environmentInjector,
303
- elementInjector: childInjector,
304
- });
305
- const instance = componentRef.instance;
306
- const hostElement = componentRef.location.nativeElement;
307
- if (params) {
308
- /**
309
- * For modals and popovers, a reference to the component is
310
- * added to `params` during the call to attachViewToDom. If
311
- * a reference using this name is already set, this means
312
- * the app is trying to use the name as a component prop,
313
- * which will cause collisions.
314
- */
315
- if (elementReferenceKey && instance[elementReferenceKey] !== undefined) {
316
- console.error(`[Ionic Error]: ${elementReferenceKey} is a reserved property when using ${container.tagName.toLowerCase()}. Rename or remove the "${elementReferenceKey}" property from ${component.name}.`);
317
- }
318
- Object.assign(instance, params);
319
- }
320
- if (cssClasses) {
321
- for (const cssClass of cssClasses) {
322
- hostElement.classList.add(cssClass);
323
- }
324
- }
325
- const unbindEvents = bindLifecycleEvents(zone, instance, hostElement);
326
- container.appendChild(hostElement);
327
- applicationRef.attachView(componentRef.hostView);
328
- elRefMap.set(hostElement, componentRef);
329
- elEventsMap.set(hostElement, unbindEvents);
330
- return hostElement;
331
- };
332
- const LIFECYCLES = [
333
- LIFECYCLE_WILL_ENTER,
334
- LIFECYCLE_DID_ENTER,
335
- LIFECYCLE_WILL_LEAVE,
336
- LIFECYCLE_DID_LEAVE,
337
- LIFECYCLE_WILL_UNLOAD,
338
- ];
339
- const bindLifecycleEvents = (zone, instance, element) => {
340
- return zone.run(() => {
341
- const unregisters = LIFECYCLES.filter((eventName) => typeof instance[eventName] === 'function').map((eventName) => {
342
- const handler = (ev) => instance[eventName](ev.detail);
343
- element.addEventListener(eventName, handler);
344
- return () => element.removeEventListener(eventName, handler);
345
- });
346
- return () => unregisters.forEach((fn) => fn());
347
- });
348
- };
349
- const NavParamsToken = new InjectionToken('NavParamsToken');
350
- const getProviders = (params) => {
351
- return [
352
- {
353
- provide: NavParamsToken,
354
- useValue: params,
355
- },
356
- {
357
- provide: NavParams,
358
- useFactory: provideNavParamsInjectable,
359
- deps: [NavParamsToken],
360
- },
361
- ];
362
- };
363
- const provideNavParamsInjectable = (params) => {
364
- return new NavParams(params);
365
- };
366
-
367
- class ModalController extends OverlayBaseController {
368
- constructor() {
369
- super(modalController);
370
- this.angularDelegate = inject(AngularDelegate);
371
- this.injector = inject(Injector);
372
- this.environmentInjector = inject(EnvironmentInjector);
373
- }
374
- create(opts) {
375
- return super.create(Object.assign(Object.assign({}, opts), { delegate: this.angularDelegate.create(this.environmentInjector, this.injector, 'modal') }));
376
- }
377
- }
378
- /** @nocollapse */ ModalController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ModalController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
379
- /** @nocollapse */ ModalController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ModalController });
380
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ModalController, decorators: [{
381
- type: Injectable
382
- }], ctorParameters: function () { return []; } });
383
-
384
- class PickerController extends OverlayBaseController {
385
- constructor() {
386
- super(pickerController);
387
- }
388
- }
389
- /** @nocollapse */ PickerController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PickerController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
390
- /** @nocollapse */ PickerController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PickerController, providedIn: 'root' });
391
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PickerController, decorators: [{
392
- type: Injectable,
393
- args: [{
394
- providedIn: 'root',
395
- }]
396
- }], ctorParameters: function () { return []; } });
397
-
398
- class PopoverController extends OverlayBaseController {
399
- constructor() {
400
- super(popoverController);
401
- this.angularDelegate = inject(AngularDelegate);
402
- this.injector = inject(Injector);
403
- this.environmentInjector = inject(EnvironmentInjector);
404
- }
405
- create(opts) {
406
- return super.create(Object.assign(Object.assign({}, opts), { delegate: this.angularDelegate.create(this.environmentInjector, this.injector, 'popover') }));
407
- }
408
- }
409
- /** @nocollapse */ PopoverController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PopoverController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
410
- /** @nocollapse */ PopoverController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PopoverController });
411
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PopoverController, decorators: [{
412
- type: Injectable
413
- }], ctorParameters: function () { return []; } });
414
-
415
- class ToastController extends OverlayBaseController {
416
- constructor() {
417
- super(toastController);
418
- }
419
- }
420
- /** @nocollapse */ ToastController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ToastController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
421
- /** @nocollapse */ ToastController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ToastController, providedIn: 'root' });
422
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ToastController, decorators: [{
423
- type: Injectable,
424
- args: [{
425
- providedIn: 'root',
426
- }]
427
- }], ctorParameters: function () { return []; } });
428
-
429
- class AnimationController {
430
- /**
431
- * Create a new animation
432
- */
433
- create(animationId) {
434
- return createAnimation(animationId);
435
- }
436
- /**
437
- * EXPERIMENTAL
438
- *
439
- * Given a progression and a cubic bezier function,
440
- * this utility returns the time value(s) at which the
441
- * cubic bezier reaches the given time progression.
442
- *
443
- * If the cubic bezier never reaches the progression
444
- * the result will be an empty array.
445
- *
446
- * This is most useful for switching between easing curves
447
- * when doing a gesture animation (i.e. going from linear easing
448
- * during a drag, to another easing when `progressEnd` is called)
449
- */
450
- easingTime(p0, p1, p2, p3, progression) {
451
- return getTimeGivenProgression(p0, p1, p2, p3, progression);
452
- }
453
- }
454
- /** @nocollapse */ AnimationController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AnimationController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
455
- /** @nocollapse */ AnimationController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AnimationController, providedIn: 'root' });
456
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AnimationController, decorators: [{
457
- type: Injectable,
458
- args: [{
459
- providedIn: 'root',
460
- }]
461
- }] });
462
-
463
- class GestureController {
464
- constructor(zone) {
465
- this.zone = zone;
466
- }
467
- /**
468
- * Create a new gesture
469
- */
470
- create(opts, runInsideAngularZone = false) {
471
- if (runInsideAngularZone) {
472
- Object.getOwnPropertyNames(opts).forEach((key) => {
473
- if (typeof opts[key] === 'function') {
474
- const fn = opts[key];
475
- opts[key] = (...props) => this.zone.run(() => fn(...props));
476
- }
477
- });
478
- }
479
- return createGesture(opts);
480
- }
481
- }
482
- /** @nocollapse */ GestureController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: GestureController, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
483
- /** @nocollapse */ GestureController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: GestureController, providedIn: 'root' });
484
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: GestureController, decorators: [{
485
- type: Injectable,
486
- args: [{
487
- providedIn: 'root',
488
- }]
489
- }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
490
-
491
- class DomController {
492
- /**
493
- * Schedules a task to run during the READ phase of the next frame.
494
- * This task should only read the DOM, but never modify it.
495
- */
496
- read(cb) {
497
- getQueue().read(cb);
498
- }
499
- /**
500
- * Schedules a task to run during the WRITE phase of the next frame.
501
- * This task should write the DOM, but never READ it.
502
- */
503
- write(cb) {
504
- getQueue().write(cb);
505
- }
506
- }
507
- /** @nocollapse */ DomController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DomController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
508
- /** @nocollapse */ DomController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DomController, providedIn: 'root' });
509
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DomController, decorators: [{
510
- type: Injectable,
511
- args: [{
512
- providedIn: 'root',
513
- }]
514
- }] });
515
- const getQueue = () => {
516
- const win = typeof window !== 'undefined' ? window : null;
517
- if (win != null) {
518
- const Ionic = win.Ionic;
519
- if (Ionic === null || Ionic === void 0 ? void 0 : Ionic.queue) {
520
- return Ionic.queue;
521
- }
522
- return {
523
- read: (cb) => win.requestAnimationFrame(cb),
524
- write: (cb) => win.requestAnimationFrame(cb),
525
- };
526
- }
527
- return {
528
- read: (cb) => cb(),
529
- write: (cb) => cb(),
530
- };
531
- };
532
-
533
- class Platform {
534
- constructor(doc, zone) {
535
- this.doc = doc;
536
- /**
537
- * @hidden
538
- */
539
- this.backButton = new Subject();
540
- /**
541
- * The keyboardDidShow event emits when the
542
- * on-screen keyboard is presented.
543
- */
544
- this.keyboardDidShow = new Subject();
545
- /**
546
- * The keyboardDidHide event emits when the
547
- * on-screen keyboard is hidden.
548
- */
549
- this.keyboardDidHide = new Subject();
550
- /**
551
- * The pause event emits when the native platform puts the application
552
- * into the background, typically when the user switches to a different
553
- * application. This event would emit when a Cordova app is put into
554
- * the background, however, it would not fire on a standard web browser.
555
- */
556
- this.pause = new Subject();
557
- /**
558
- * The resume event emits when the native platform pulls the application
559
- * out from the background. This event would emit when a Cordova app comes
560
- * out from the background, however, it would not fire on a standard web browser.
561
- */
562
- this.resume = new Subject();
563
- /**
564
- * The resize event emits when the browser window has changed dimensions. This
565
- * could be from a browser window being physically resized, or from a device
566
- * changing orientation.
567
- */
568
- this.resize = new Subject();
569
- zone.run(() => {
570
- var _a;
571
- this.win = doc.defaultView;
572
- this.backButton.subscribeWithPriority = function (priority, callback) {
573
- return this.subscribe((ev) => {
574
- return ev.register(priority, (processNextHandler) => zone.run(() => callback(processNextHandler)));
575
- });
576
- };
577
- proxyEvent(this.pause, doc, 'pause');
578
- proxyEvent(this.resume, doc, 'resume');
579
- proxyEvent(this.backButton, doc, 'ionBackButton');
580
- proxyEvent(this.resize, this.win, 'resize');
581
- proxyEvent(this.keyboardDidShow, this.win, 'ionKeyboardDidShow');
582
- proxyEvent(this.keyboardDidHide, this.win, 'ionKeyboardDidHide');
583
- let readyResolve;
584
- this._readyPromise = new Promise((res) => {
585
- readyResolve = res;
586
- });
587
- if ((_a = this.win) === null || _a === void 0 ? void 0 : _a['cordova']) {
588
- doc.addEventListener('deviceready', () => {
589
- readyResolve('cordova');
590
- }, { once: true });
591
- }
592
- else {
593
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
594
- readyResolve('dom');
595
- }
596
- });
597
- }
598
- /**
599
- * @returns returns true/false based on platform.
600
- * @description
601
- * Depending on the platform the user is on, `is(platformName)` will
602
- * return `true` or `false`. Note that the same app can return `true`
603
- * for more than one platform name. For example, an app running from
604
- * an iPad would return `true` for the platform names: `mobile`,
605
- * `ios`, `ipad`, and `tablet`. Additionally, if the app was running
606
- * from Cordova then `cordova` would be true, and if it was running
607
- * from a web browser on the iPad then `mobileweb` would be `true`.
608
- *
609
- * ```
610
- * import { Platform } from 'ionic-angular';
611
- *
612
- * @Component({...})
613
- * export MyPage {
614
- * constructor(public platform: Platform) {
615
- * if (this.platform.is('ios')) {
616
- * // This will only print when on iOS
617
- * console.log('I am an iOS device!');
618
- * }
619
- * }
620
- * }
621
- * ```
622
- *
623
- * | Platform Name | Description |
624
- * |-----------------|------------------------------------|
625
- * | android | on a device running Android. |
626
- * | capacitor | on a device running Capacitor. |
627
- * | cordova | on a device running Cordova. |
628
- * | ios | on a device running iOS. |
629
- * | ipad | on an iPad device. |
630
- * | iphone | on an iPhone device. |
631
- * | phablet | on a phablet device. |
632
- * | tablet | on a tablet device. |
633
- * | electron | in Electron on a desktop device. |
634
- * | pwa | as a PWA app. |
635
- * | mobile | on a mobile device. |
636
- * | mobileweb | on a mobile device in a browser. |
637
- * | desktop | on a desktop device. |
638
- * | hybrid | is a cordova or capacitor app. |
639
- *
640
- */
641
- is(platformName) {
642
- return isPlatform(this.win, platformName);
643
- }
644
- /**
645
- * @returns the array of platforms
646
- * @description
647
- * Depending on what device you are on, `platforms` can return multiple values.
648
- * Each possible value is a hierarchy of platforms. For example, on an iPhone,
649
- * it would return `mobile`, `ios`, and `iphone`.
650
- *
651
- * ```
652
- * import { Platform } from 'ionic-angular';
653
- *
654
- * @Component({...})
655
- * export MyPage {
656
- * constructor(public platform: Platform) {
657
- * // This will print an array of the current platforms
658
- * console.log(this.platform.platforms());
659
- * }
660
- * }
661
- * ```
662
- */
663
- platforms() {
664
- return getPlatforms(this.win);
665
- }
666
- /**
667
- * Returns a promise when the platform is ready and native functionality
668
- * can be called. If the app is running from within a web browser, then
669
- * the promise will resolve when the DOM is ready. When the app is running
670
- * from an application engine such as Cordova, then the promise will
671
- * resolve when Cordova triggers the `deviceready` event.
672
- *
673
- * The resolved value is the `readySource`, which states which platform
674
- * ready was used. For example, when Cordova is ready, the resolved ready
675
- * source is `cordova`. The default ready source value will be `dom`. The
676
- * `readySource` is useful if different logic should run depending on the
677
- * platform the app is running from. For example, only Cordova can execute
678
- * the status bar plugin, so the web should not run status bar plugin logic.
679
- *
680
- * ```
681
- * import { Component } from '@angular/core';
682
- * import { Platform } from 'ionic-angular';
683
- *
684
- * @Component({...})
685
- * export MyApp {
686
- * constructor(public platform: Platform) {
687
- * this.platform.ready().then((readySource) => {
688
- * console.log('Platform ready from', readySource);
689
- * // Platform now ready, execute any required native code
690
- * });
691
- * }
692
- * }
693
- * ```
694
- */
695
- ready() {
696
- return this._readyPromise;
697
- }
698
- /**
699
- * Returns if this app is using right-to-left language direction or not.
700
- * We recommend the app's `index.html` file already has the correct `dir`
701
- * attribute value set, such as `<html dir="ltr">` or `<html dir="rtl">`.
702
- * [W3C: Structural markup and right-to-left text in HTML](http://www.w3.org/International/questions/qa-html-dir)
703
- */
704
- get isRTL() {
705
- return this.doc.dir === 'rtl';
706
- }
707
- /**
708
- * Get the query string parameter
709
- */
710
- getQueryParam(key) {
711
- return readQueryParam(this.win.location.href, key);
712
- }
713
- /**
714
- * Returns `true` if the app is in landscape mode.
715
- */
716
- isLandscape() {
717
- return !this.isPortrait();
718
- }
719
- /**
720
- * Returns `true` if the app is in portrait mode.
721
- */
722
- isPortrait() {
723
- var _a, _b;
724
- return (_b = (_a = this.win).matchMedia) === null || _b === void 0 ? void 0 : _b.call(_a, '(orientation: portrait)').matches;
725
- }
726
- testUserAgent(expression) {
727
- const nav = this.win.navigator;
728
- return !!((nav === null || nav === void 0 ? void 0 : nav.userAgent) && nav.userAgent.indexOf(expression) >= 0);
729
- }
730
- /**
731
- * Get the current url.
732
- */
733
- url() {
734
- return this.win.location.href;
735
- }
736
- /**
737
- * Gets the width of the platform's viewport using `window.innerWidth`.
738
- */
739
- width() {
740
- return this.win.innerWidth;
741
- }
742
- /**
743
- * Gets the height of the platform's viewport using `window.innerHeight`.
744
- */
745
- height() {
746
- return this.win.innerHeight;
747
- }
748
- }
749
- /** @nocollapse */ Platform.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Platform, deps: [{ token: DOCUMENT }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
750
- /** @nocollapse */ Platform.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Platform, providedIn: 'root' });
751
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Platform, decorators: [{
752
- type: Injectable,
753
- args: [{
754
- providedIn: 'root',
755
- }]
756
- }], ctorParameters: function () {
757
- return [{ type: undefined, decorators: [{
758
- type: Inject,
759
- args: [DOCUMENT]
760
- }] }, { type: i0.NgZone }];
761
- } });
762
- const readQueryParam = (url, key) => {
763
- key = key.replace(/[[\]\\]/g, '\\$&');
764
- const regex = new RegExp('[\\?&]' + key + '=([^&#]*)');
765
- const results = regex.exec(url);
766
- return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;
767
- };
768
- const proxyEvent = (emitter, el, eventName) => {
769
- if (el) {
770
- el.addEventListener(eventName, (ev) => {
771
- // ?? cordova might emit "null" events
772
- const value = ev != null ? ev.detail : undefined;
773
- emitter.next(value);
774
- });
775
- }
776
- };
777
-
778
- class NavController {
779
- constructor(platform, location, serializer, router) {
780
- this.location = location;
781
- this.serializer = serializer;
782
- this.router = router;
783
- this.direction = DEFAULT_DIRECTION;
784
- this.animated = DEFAULT_ANIMATED;
785
- this.guessDirection = 'forward';
786
- this.lastNavId = -1;
787
- // Subscribe to router events to detect direction
788
- if (router) {
789
- router.events.subscribe((ev) => {
790
- if (ev instanceof NavigationStart) {
791
- const id = ev.restoredState ? ev.restoredState.navigationId : ev.id;
792
- this.guessDirection = id < this.lastNavId ? 'back' : 'forward';
793
- this.guessAnimation = !ev.restoredState ? this.guessDirection : undefined;
794
- this.lastNavId = this.guessDirection === 'forward' ? ev.id : id;
795
- }
796
- });
797
- }
798
- // Subscribe to backButton events
799
- platform.backButton.subscribeWithPriority(0, (processNextHandler) => {
800
- this.pop();
801
- processNextHandler();
802
- });
803
- }
804
- /**
805
- * This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
806
- * it's equivalent to calling `this.router.navigateByUrl()`, but it's explicit about the **direction** of the transition.
807
- *
808
- * Going **forward** means that a new page is going to be pushed to the stack of the outlet (ion-router-outlet),
809
- * and that it will show a "forward" animation by default.
810
- *
811
- * Navigating forward can also be triggered in a declarative manner by using the `[routerDirection]` directive:
812
- *
813
- * ```html
814
- * <a routerLink="/path/to/page" routerDirection="forward">Link</a>
815
- * ```
816
- */
817
- navigateForward(url, options = {}) {
818
- this.setDirection('forward', options.animated, options.animationDirection, options.animation);
819
- return this.navigate(url, options);
820
- }
821
- /**
822
- * This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
823
- * it's equivalent to calling:
824
- *
825
- * ```ts
826
- * this.navController.setDirection('back');
827
- * this.router.navigateByUrl(path);
828
- * ```
829
- *
830
- * Going **back** means that all the pages in the stack until the navigated page is found will be popped,
831
- * and that it will show a "back" animation by default.
832
- *
833
- * Navigating back can also be triggered in a declarative manner by using the `[routerDirection]` directive:
834
- *
835
- * ```html
836
- * <a routerLink="/path/to/page" routerDirection="back">Link</a>
837
- * ```
838
- */
839
- navigateBack(url, options = {}) {
840
- this.setDirection('back', options.animated, options.animationDirection, options.animation);
841
- return this.navigate(url, options);
842
- }
843
- /**
844
- * This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
845
- * it's equivalent to calling:
846
- *
847
- * ```ts
848
- * this.navController.setDirection('root');
849
- * this.router.navigateByUrl(path);
850
- * ```
851
- *
852
- * Going **root** means that all existing pages in the stack will be removed,
853
- * and the navigated page will become the single page in the stack.
854
- *
855
- * Navigating root can also be triggered in a declarative manner by using the `[routerDirection]` directive:
856
- *
857
- * ```html
858
- * <a routerLink="/path/to/page" routerDirection="root">Link</a>
859
- * ```
860
- */
861
- navigateRoot(url, options = {}) {
862
- this.setDirection('root', options.animated, options.animationDirection, options.animation);
863
- return this.navigate(url, options);
864
- }
865
- /**
866
- * Same as [Location](https://angular.io/api/common/Location)'s back() method.
867
- * It will use the standard `window.history.back()` under the hood, but featuring a `back` animation
868
- * by default.
869
- */
870
- back(options = { animated: true, animationDirection: 'back' }) {
871
- this.setDirection('back', options.animated, options.animationDirection, options.animation);
872
- return this.location.back();
873
- }
874
- /**
875
- * This methods goes back in the context of Ionic's stack navigation.
876
- *
877
- * It recursively finds the top active `ion-router-outlet` and calls `pop()`.
878
- * This is the recommended way to go back when you are using `ion-router-outlet`.
879
- *
880
- * Resolves to `true` if it was able to pop.
881
- */
882
- pop() {
883
- return __awaiter(this, void 0, void 0, function* () {
884
- let outlet = this.topOutlet;
885
- while (outlet) {
886
- if (yield outlet.pop()) {
887
- return true;
888
- }
889
- else {
890
- outlet = outlet.parentOutlet;
891
- }
892
- }
893
- return false;
894
- });
895
- }
896
- /**
897
- * This methods specifies the direction of the next navigation performed by the Angular router.
898
- *
899
- * `setDirection()` does not trigger any transition, it just sets some flags to be consumed by `ion-router-outlet`.
900
- *
901
- * It's recommended to use `navigateForward()`, `navigateBack()` and `navigateRoot()` instead of `setDirection()`.
902
- */
903
- setDirection(direction, animated, animationDirection, animationBuilder) {
904
- this.direction = direction;
905
- this.animated = getAnimation(direction, animated, animationDirection);
906
- this.animationBuilder = animationBuilder;
907
- }
908
- /**
909
- * @internal
910
- */
911
- setTopOutlet(outlet) {
912
- this.topOutlet = outlet;
913
- }
914
- /**
915
- * @internal
916
- */
917
- consumeTransition() {
918
- let direction = 'root';
919
- let animation;
920
- const animationBuilder = this.animationBuilder;
921
- if (this.direction === 'auto') {
922
- direction = this.guessDirection;
923
- animation = this.guessAnimation;
924
- }
925
- else {
926
- animation = this.animated;
927
- direction = this.direction;
928
- }
929
- this.direction = DEFAULT_DIRECTION;
930
- this.animated = DEFAULT_ANIMATED;
931
- this.animationBuilder = undefined;
932
- return {
933
- direction,
934
- animation,
935
- animationBuilder,
936
- };
937
- }
938
- navigate(url, options) {
939
- if (Array.isArray(url)) {
940
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
941
- return this.router.navigate(url, options);
942
- }
943
- else {
944
- /**
945
- * navigateByUrl ignores any properties that
946
- * would change the url, so things like queryParams
947
- * would be ignored unless we create a url tree
948
- * More Info: https://github.com/angular/angular/issues/18798
949
- */
950
- const urlTree = this.serializer.parse(url.toString());
951
- if (options.queryParams !== undefined) {
952
- urlTree.queryParams = Object.assign({}, options.queryParams);
953
- }
954
- if (options.fragment !== undefined) {
955
- urlTree.fragment = options.fragment;
956
- }
957
- /**
958
- * `navigateByUrl` will still apply `NavigationExtras` properties
959
- * that do not modify the url, such as `replaceUrl` which is why
960
- * `options` is passed in here.
961
- */
962
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
963
- return this.router.navigateByUrl(urlTree, options);
964
- }
965
- }
966
- }
967
- /** @nocollapse */ NavController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NavController, deps: [{ token: Platform }, { token: i1.Location }, { token: i3.UrlSerializer }, { token: i3.Router, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
968
- /** @nocollapse */ NavController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NavController, providedIn: 'root' });
969
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NavController, decorators: [{
970
- type: Injectable,
971
- args: [{
972
- providedIn: 'root',
973
- }]
974
- }], ctorParameters: function () {
975
- return [{ type: Platform }, { type: i1.Location }, { type: i3.UrlSerializer }, { type: i3.Router, decorators: [{
976
- type: Optional
977
- }] }];
978
- } });
979
- const getAnimation = (direction, animated, animationDirection) => {
980
- if (animated === false) {
981
- return undefined;
982
- }
983
- if (animationDirection !== undefined) {
984
- return animationDirection;
985
- }
986
- if (direction === 'forward' || direction === 'back') {
987
- return direction;
988
- }
989
- else if (direction === 'root' && animated === true) {
990
- return 'forward';
991
- }
992
- return undefined;
993
- };
994
- const DEFAULT_DIRECTION = 'auto';
995
- const DEFAULT_ANIMATED = undefined;
996
-
997
- class Config {
998
- get(key, fallback) {
999
- const c = getConfig();
1000
- if (c) {
1001
- return c.get(key, fallback);
1002
- }
1003
- return null;
1004
- }
1005
- getBoolean(key, fallback) {
1006
- const c = getConfig();
1007
- if (c) {
1008
- return c.getBoolean(key, fallback);
1009
- }
1010
- return false;
1011
- }
1012
- getNumber(key, fallback) {
1013
- const c = getConfig();
1014
- if (c) {
1015
- return c.getNumber(key, fallback);
1016
- }
1017
- return 0;
1018
- }
1019
- }
1020
- /** @nocollapse */ Config.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Config, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1021
- /** @nocollapse */ Config.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Config, providedIn: 'root' });
1022
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Config, decorators: [{
1023
- type: Injectable,
1024
- args: [{
1025
- providedIn: 'root',
1026
- }]
1027
- }] });
1028
- const ConfigToken = new InjectionToken('USERCONFIG');
1029
- const getConfig = () => {
1030
- if (typeof window !== 'undefined') {
1031
- const Ionic = window.Ionic;
1032
- if (Ionic === null || Ionic === void 0 ? void 0 : Ionic.config) {
1033
- return Ionic.config;
1034
- }
1035
- }
1036
- return null;
1037
- };
1038
-
1039
- // TODO: Is there a way we can grab this from angular-component-lib instead?
1040
- const proxyInputs = (Cmp, inputs) => {
1041
- const Prototype = Cmp.prototype;
1042
- inputs.forEach((item) => {
1043
- Object.defineProperty(Prototype, item, {
1044
- get() {
1045
- return this.el[item];
1046
- },
1047
- set(val) {
1048
- this.z.runOutsideAngular(() => (this.el[item] = val));
1049
- },
1050
- });
1051
- });
1052
- };
1053
- const proxyMethods = (Cmp, methods) => {
1054
- const Prototype = Cmp.prototype;
1055
- methods.forEach((methodName) => {
1056
- Prototype[methodName] = function () {
1057
- const args = arguments;
1058
- return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args));
1059
- };
1060
- });
1061
- };
1062
- const proxyOutputs = (instance, el, events) => {
1063
- events.forEach((eventName) => (instance[eventName] = fromEvent(el, eventName)));
1064
- };
1065
- // tslint:disable-next-line: only-arrow-functions
1066
- function ProxyCmp(opts) {
1067
- const decorator = function (cls) {
1068
- const { defineCustomElementFn, inputs, methods } = opts;
1069
- if (defineCustomElementFn !== undefined) {
1070
- defineCustomElementFn();
1071
- }
1072
- if (inputs) {
1073
- proxyInputs(cls, inputs);
1074
- }
1075
- if (methods) {
1076
- proxyMethods(cls, methods);
1077
- }
1078
- return cls;
1079
- };
1080
- return decorator;
1081
- }
1082
-
1083
- const POPOVER_INPUTS = [
1084
- 'alignment',
1085
- 'animated',
1086
- 'arrow',
1087
- 'keepContentsMounted',
1088
- 'backdropDismiss',
1089
- 'cssClass',
1090
- 'dismissOnSelect',
1091
- 'enterAnimation',
1092
- 'event',
1093
- 'isOpen',
1094
- 'keyboardClose',
1095
- 'leaveAnimation',
1096
- 'mode',
1097
- 'showBackdrop',
1098
- 'translucent',
1099
- 'trigger',
1100
- 'triggerAction',
1101
- 'reference',
1102
- 'size',
1103
- 'side',
1104
- ];
1105
- const POPOVER_METHODS = ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'];
1106
- let IonPopover = class IonPopover {
1107
- constructor(c, r, z) {
1108
- this.z = z;
1109
- this.isCmpOpen = false;
1110
- this.el = r.nativeElement;
1111
- this.el.addEventListener('ionMount', () => {
1112
- this.isCmpOpen = true;
1113
- c.detectChanges();
1114
- });
1115
- this.el.addEventListener('didDismiss', () => {
1116
- this.isCmpOpen = false;
1117
- c.detectChanges();
1118
- });
1119
- proxyOutputs(this, this.el, [
1120
- 'ionPopoverDidPresent',
1121
- 'ionPopoverWillPresent',
1122
- 'ionPopoverWillDismiss',
1123
- 'ionPopoverDidDismiss',
1124
- 'didPresent',
1125
- 'willPresent',
1126
- 'willDismiss',
1127
- 'didDismiss',
1128
- ]);
1129
- }
1130
- };
1131
- /** @nocollapse */ IonPopover.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonPopover, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
1132
- /** @nocollapse */ IonPopover.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: IonPopover, selector: "ion-popover", inputs: { alignment: "alignment", animated: "animated", arrow: "arrow", keepContentsMounted: "keepContentsMounted", backdropDismiss: "backdropDismiss", cssClass: "cssClass", dismissOnSelect: "dismissOnSelect", enterAnimation: "enterAnimation", event: "event", isOpen: "isOpen", keyboardClose: "keyboardClose", leaveAnimation: "leaveAnimation", mode: "mode", showBackdrop: "showBackdrop", translucent: "translucent", trigger: "trigger", triggerAction: "triggerAction", reference: "reference", size: "size", side: "side" }, queries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0 });
1133
- IonPopover = __decorate([
1134
- ProxyCmp({
1135
- inputs: POPOVER_INPUTS,
1136
- methods: POPOVER_METHODS,
1137
- })
1138
- /**
1139
- * @Component extends from @Directive
1140
- * so by defining the inputs here we
1141
- * do not need to re-define them for the
1142
- * lazy loaded popover.
1143
- */
1144
- ], IonPopover);
1145
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonPopover, decorators: [{
1146
- type: Directive,
1147
- args: [{
1148
- selector: 'ion-popover',
1149
- // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
1150
- inputs: POPOVER_INPUTS,
1151
- }]
1152
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { template: [{
1153
- type: ContentChild,
1154
- args: [TemplateRef, { static: false }]
1155
- }] } });
1156
-
1157
- const MODAL_INPUTS = [
1158
- 'animated',
1159
- 'keepContentsMounted',
1160
- 'backdropBreakpoint',
1161
- 'backdropDismiss',
1162
- 'breakpoints',
1163
- 'canDismiss',
1164
- 'cssClass',
1165
- 'enterAnimation',
1166
- 'event',
1167
- 'handle',
1168
- 'handleBehavior',
1169
- 'initialBreakpoint',
1170
- 'isOpen',
1171
- 'keyboardClose',
1172
- 'leaveAnimation',
1173
- 'mode',
1174
- 'presentingElement',
1175
- 'showBackdrop',
1176
- 'translucent',
1177
- 'trigger',
1178
- ];
1179
- const MODAL_METHODS = [
1180
- 'present',
1181
- 'dismiss',
1182
- 'onDidDismiss',
1183
- 'onWillDismiss',
1184
- 'setCurrentBreakpoint',
1185
- 'getCurrentBreakpoint',
1186
- ];
1187
- let IonModal = class IonModal {
1188
- constructor(c, r, z) {
1189
- this.z = z;
1190
- this.isCmpOpen = false;
1191
- this.el = r.nativeElement;
1192
- this.el.addEventListener('ionMount', () => {
1193
- this.isCmpOpen = true;
1194
- c.detectChanges();
1195
- });
1196
- this.el.addEventListener('didDismiss', () => {
1197
- this.isCmpOpen = false;
1198
- c.detectChanges();
1199
- });
1200
- proxyOutputs(this, this.el, [
1201
- 'ionModalDidPresent',
1202
- 'ionModalWillPresent',
1203
- 'ionModalWillDismiss',
1204
- 'ionModalDidDismiss',
1205
- 'ionBreakpointDidChange',
1206
- 'didPresent',
1207
- 'willPresent',
1208
- 'willDismiss',
1209
- 'didDismiss',
1210
- ]);
1211
- }
1212
- };
1213
- /** @nocollapse */ IonModal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonModal, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
1214
- /** @nocollapse */ IonModal.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: IonModal, selector: "ion-modal", inputs: { animated: "animated", keepContentsMounted: "keepContentsMounted", backdropBreakpoint: "backdropBreakpoint", backdropDismiss: "backdropDismiss", breakpoints: "breakpoints", canDismiss: "canDismiss", cssClass: "cssClass", enterAnimation: "enterAnimation", event: "event", handle: "handle", handleBehavior: "handleBehavior", initialBreakpoint: "initialBreakpoint", isOpen: "isOpen", keyboardClose: "keyboardClose", leaveAnimation: "leaveAnimation", mode: "mode", presentingElement: "presentingElement", showBackdrop: "showBackdrop", translucent: "translucent", trigger: "trigger" }, queries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0 });
1215
- IonModal = __decorate([
1216
- ProxyCmp({
1217
- inputs: MODAL_INPUTS,
1218
- methods: MODAL_METHODS,
1219
- })
1220
- /**
1221
- * @Component extends from @Directive
1222
- * so by defining the inputs here we
1223
- * do not need to re-define them for the
1224
- * lazy loaded popover.
1225
- */
1226
- ], IonModal);
1227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonModal, decorators: [{
1228
- type: Directive,
1229
- args: [{
1230
- selector: 'ion-modal',
1231
- // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
1232
- inputs: MODAL_INPUTS,
1233
- }]
1234
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { template: [{
1235
- type: ContentChild,
1236
- args: [TemplateRef, { static: false }]
1237
- }] } });
1238
-
1239
- const insertView = (views, view, direction) => {
1240
- if (direction === 'root') {
1241
- return setRoot(views, view);
1242
- }
1243
- else if (direction === 'forward') {
1244
- return setForward(views, view);
1245
- }
1246
- else {
1247
- return setBack(views, view);
1248
- }
1249
- };
1250
- const setRoot = (views, view) => {
1251
- views = views.filter((v) => v.stackId !== view.stackId);
1252
- views.push(view);
1253
- return views;
1254
- };
1255
- const setForward = (views, view) => {
1256
- const index = views.indexOf(view);
1257
- if (index >= 0) {
1258
- views = views.filter((v) => v.stackId !== view.stackId || v.id <= view.id);
1259
- }
1260
- else {
1261
- views.push(view);
1262
- }
1263
- return views;
1264
- };
1265
- const setBack = (views, view) => {
1266
- const index = views.indexOf(view);
1267
- if (index >= 0) {
1268
- return views.filter((v) => v.stackId !== view.stackId || v.id <= view.id);
1269
- }
1270
- else {
1271
- return setRoot(views, view);
1272
- }
1273
- };
1274
- const getUrl = (router, activatedRoute) => {
1275
- const urlTree = router.createUrlTree(['.'], { relativeTo: activatedRoute });
1276
- return router.serializeUrl(urlTree);
1277
- };
1278
- const isTabSwitch = (enteringView, leavingView) => {
1279
- if (!leavingView) {
1280
- return true;
1281
- }
1282
- return enteringView.stackId !== leavingView.stackId;
1283
- };
1284
- const computeStackId = (prefixUrl, url) => {
1285
- if (!prefixUrl) {
1286
- return undefined;
1287
- }
1288
- const segments = toSegments(url);
1289
- for (let i = 0; i < segments.length; i++) {
1290
- if (i >= prefixUrl.length) {
1291
- return segments[i];
1292
- }
1293
- if (segments[i] !== prefixUrl[i]) {
1294
- return undefined;
1295
- }
1296
- }
1297
- return undefined;
1298
- };
1299
- const toSegments = (path) => {
1300
- return path
1301
- .split('/')
1302
- .map((s) => s.trim())
1303
- .filter((s) => s !== '');
1304
- };
1305
- const destroyView = (view) => {
1306
- if (view) {
1307
- view.ref.destroy();
1308
- view.unlistenEvents();
1309
- }
1310
- };
1311
-
1312
- // TODO(FW-2827): types
1313
- class StackController {
1314
- constructor(tabsPrefix, containerEl, router, navCtrl, zone, location) {
1315
- this.containerEl = containerEl;
1316
- this.router = router;
1317
- this.navCtrl = navCtrl;
1318
- this.zone = zone;
1319
- this.location = location;
1320
- this.views = [];
1321
- this.skipTransition = false;
1322
- this.nextId = 0;
1323
- this.tabsPrefix = tabsPrefix !== undefined ? toSegments(tabsPrefix) : undefined;
1324
- }
1325
- createView(ref, activatedRoute) {
1326
- var _a;
1327
- const url = getUrl(this.router, activatedRoute);
1328
- const element = (_a = ref === null || ref === void 0 ? void 0 : ref.location) === null || _a === void 0 ? void 0 : _a.nativeElement;
1329
- const unlistenEvents = bindLifecycleEvents(this.zone, ref.instance, element);
1330
- return {
1331
- id: this.nextId++,
1332
- stackId: computeStackId(this.tabsPrefix, url),
1333
- unlistenEvents,
1334
- element,
1335
- ref,
1336
- url,
1337
- };
1338
- }
1339
- getExistingView(activatedRoute) {
1340
- const activatedUrlKey = getUrl(this.router, activatedRoute);
1341
- const view = this.views.find((vw) => vw.url === activatedUrlKey);
1342
- if (view) {
1343
- view.ref.changeDetectorRef.reattach();
1344
- }
1345
- return view;
1346
- }
1347
- setActive(enteringView) {
1348
- var _a, _b;
1349
- const consumeResult = this.navCtrl.consumeTransition();
1350
- let { direction, animation, animationBuilder } = consumeResult;
1351
- const leavingView = this.activeView;
1352
- const tabSwitch = isTabSwitch(enteringView, leavingView);
1353
- if (tabSwitch) {
1354
- direction = 'back';
1355
- animation = undefined;
1356
- }
1357
- const viewsSnapshot = this.views.slice();
1358
- let currentNavigation;
1359
- const router = this.router;
1360
- // Angular >= 7.2.0
1361
- if (router.getCurrentNavigation) {
1362
- currentNavigation = router.getCurrentNavigation();
1363
- // Angular < 7.2.0
1364
- }
1365
- else if ((_a = router.navigations) === null || _a === void 0 ? void 0 : _a.value) {
1366
- currentNavigation = router.navigations.value;
1367
- }
1368
- /**
1369
- * If the navigation action
1370
- * sets `replaceUrl: true`
1371
- * then we need to make sure
1372
- * we remove the last item
1373
- * from our views stack
1374
- */
1375
- if ((_b = currentNavigation === null || currentNavigation === void 0 ? void 0 : currentNavigation.extras) === null || _b === void 0 ? void 0 : _b.replaceUrl) {
1376
- if (this.views.length > 0) {
1377
- this.views.splice(-1, 1);
1378
- }
1379
- }
1380
- const reused = this.views.includes(enteringView);
1381
- const views = this.insertView(enteringView, direction);
1382
- // Trigger change detection before transition starts
1383
- // This will call ngOnInit() the first time too, just after the view
1384
- // was attached to the dom, but BEFORE the transition starts
1385
- if (!reused) {
1386
- enteringView.ref.changeDetectorRef.detectChanges();
1387
- }
1388
- /**
1389
- * If we are going back from a page that
1390
- * was presented using a custom animation
1391
- * we should default to using that
1392
- * unless the developer explicitly
1393
- * provided another animation.
1394
- */
1395
- const customAnimation = enteringView.animationBuilder;
1396
- if (animationBuilder === undefined && direction === 'back' && !tabSwitch && customAnimation !== undefined) {
1397
- animationBuilder = customAnimation;
1398
- }
1399
- /**
1400
- * Save any custom animation so that navigating
1401
- * back will use this custom animation by default.
1402
- */
1403
- if (leavingView) {
1404
- leavingView.animationBuilder = animationBuilder;
1405
- }
1406
- // Wait until previous transitions finish
1407
- return this.zone.runOutsideAngular(() => {
1408
- return this.wait(() => {
1409
- // disconnect leaving page from change detection to
1410
- // reduce jank during the page transition
1411
- if (leavingView) {
1412
- leavingView.ref.changeDetectorRef.detach();
1413
- }
1414
- // In case the enteringView is the same as the leavingPage we need to reattach()
1415
- enteringView.ref.changeDetectorRef.reattach();
1416
- return this.transition(enteringView, leavingView, animation, this.canGoBack(1), false, animationBuilder)
1417
- .then(() => cleanupAsync(enteringView, views, viewsSnapshot, this.location, this.zone))
1418
- .then(() => ({
1419
- enteringView,
1420
- direction,
1421
- animation,
1422
- tabSwitch,
1423
- }));
1424
- });
1425
- });
1426
- }
1427
- canGoBack(deep, stackId = this.getActiveStackId()) {
1428
- return this.getStack(stackId).length > deep;
1429
- }
1430
- pop(deep, stackId = this.getActiveStackId()) {
1431
- return this.zone.run(() => {
1432
- var _a, _b;
1433
- const views = this.getStack(stackId);
1434
- if (views.length <= deep) {
1435
- return Promise.resolve(false);
1436
- }
1437
- const view = views[views.length - deep - 1];
1438
- let url = view.url;
1439
- const viewSavedData = view.savedData;
1440
- if (viewSavedData) {
1441
- const primaryOutlet = viewSavedData.get('primary');
1442
- if ((_b = (_a = primaryOutlet === null || primaryOutlet === void 0 ? void 0 : primaryOutlet.route) === null || _a === void 0 ? void 0 : _a._routerState) === null || _b === void 0 ? void 0 : _b.snapshot.url) {
1443
- url = primaryOutlet.route._routerState.snapshot.url;
1444
- }
1445
- }
1446
- const { animationBuilder } = this.navCtrl.consumeTransition();
1447
- return this.navCtrl.navigateBack(url, Object.assign(Object.assign({}, view.savedExtras), { animation: animationBuilder })).then(() => true);
1448
- });
1449
- }
1450
- startBackTransition() {
1451
- const leavingView = this.activeView;
1452
- if (leavingView) {
1453
- const views = this.getStack(leavingView.stackId);
1454
- const enteringView = views[views.length - 2];
1455
- const customAnimation = enteringView.animationBuilder;
1456
- return this.wait(() => {
1457
- return this.transition(enteringView, // entering view
1458
- leavingView, // leaving view
1459
- 'back', this.canGoBack(2), true, customAnimation);
1460
- });
1461
- }
1462
- return Promise.resolve();
1463
- }
1464
- endBackTransition(shouldComplete) {
1465
- if (shouldComplete) {
1466
- this.skipTransition = true;
1467
- this.pop(1);
1468
- }
1469
- else if (this.activeView) {
1470
- cleanup(this.activeView, this.views, this.views, this.location, this.zone);
1471
- }
1472
- }
1473
- getLastUrl(stackId) {
1474
- const views = this.getStack(stackId);
1475
- return views.length > 0 ? views[views.length - 1] : undefined;
1476
- }
1477
- /**
1478
- * @internal
1479
- */
1480
- getRootUrl(stackId) {
1481
- const views = this.getStack(stackId);
1482
- return views.length > 0 ? views[0] : undefined;
1483
- }
1484
- getActiveStackId() {
1485
- return this.activeView ? this.activeView.stackId : undefined;
1486
- }
1487
- /**
1488
- * @internal
1489
- */
1490
- getActiveView() {
1491
- return this.activeView;
1492
- }
1493
- hasRunningTask() {
1494
- return this.runningTask !== undefined;
1495
- }
1496
- destroy() {
1497
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1498
- this.containerEl = undefined;
1499
- this.views.forEach(destroyView);
1500
- this.activeView = undefined;
1501
- this.views = [];
1502
- }
1503
- getStack(stackId) {
1504
- return this.views.filter((v) => v.stackId === stackId);
1505
- }
1506
- insertView(enteringView, direction) {
1507
- this.activeView = enteringView;
1508
- this.views = insertView(this.views, enteringView, direction);
1509
- return this.views.slice();
1510
- }
1511
- transition(enteringView, leavingView, direction, showGoBack, progressAnimation, animationBuilder) {
1512
- if (this.skipTransition) {
1513
- this.skipTransition = false;
1514
- return Promise.resolve(false);
1515
- }
1516
- if (leavingView === enteringView) {
1517
- return Promise.resolve(false);
1518
- }
1519
- const enteringEl = enteringView ? enteringView.element : undefined;
1520
- const leavingEl = leavingView ? leavingView.element : undefined;
1521
- const containerEl = this.containerEl;
1522
- if (enteringEl && enteringEl !== leavingEl) {
1523
- enteringEl.classList.add('ion-page');
1524
- enteringEl.classList.add('ion-page-invisible');
1525
- if (enteringEl.parentElement !== containerEl) {
1526
- containerEl.appendChild(enteringEl);
1527
- }
1528
- if (containerEl.commit) {
1529
- return containerEl.commit(enteringEl, leavingEl, {
1530
- duration: direction === undefined ? 0 : undefined,
1531
- direction,
1532
- showGoBack,
1533
- progressAnimation,
1534
- animationBuilder,
1535
- });
1536
- }
1537
- }
1538
- return Promise.resolve(false);
1539
- }
1540
- wait(task) {
1541
- return __awaiter(this, void 0, void 0, function* () {
1542
- if (this.runningTask !== undefined) {
1543
- yield this.runningTask;
1544
- this.runningTask = undefined;
1545
- }
1546
- const promise = (this.runningTask = task());
1547
- promise.finally(() => (this.runningTask = undefined));
1548
- return promise;
1549
- });
1550
- }
1551
- }
1552
- const cleanupAsync = (activeRoute, views, viewsSnapshot, location, zone) => {
1553
- if (typeof requestAnimationFrame === 'function') {
1554
- return new Promise((resolve) => {
1555
- requestAnimationFrame(() => {
1556
- cleanup(activeRoute, views, viewsSnapshot, location, zone);
1557
- resolve();
1558
- });
1559
- });
1560
- }
1561
- return Promise.resolve();
1562
- };
1563
- const cleanup = (activeRoute, views, viewsSnapshot, location, zone) => {
1564
- /**
1565
- * Re-enter the Angular zone when destroying page components. This will allow
1566
- * lifecycle events (`ngOnDestroy`) to be run inside the Angular zone.
1567
- */
1568
- zone.run(() => viewsSnapshot.filter((view) => !views.includes(view)).forEach(destroyView));
1569
- views.forEach((view) => {
1570
- /**
1571
- * In the event that a user navigated multiple
1572
- * times in rapid succession, we want to make sure
1573
- * we don't pre-emptively detach a view while
1574
- * it is in mid-transition.
1575
- *
1576
- * In this instance we also do not care about query
1577
- * params or fragments as it will be the same view regardless
1578
- */
1579
- const locationWithoutParams = location.path().split('?')[0];
1580
- const locationWithoutFragment = locationWithoutParams.split('#')[0];
1581
- if (view !== activeRoute && view.url !== locationWithoutFragment) {
1582
- const element = view.element;
1583
- element.setAttribute('aria-hidden', 'true');
1584
- element.classList.add('ion-page-hidden');
1585
- view.ref.changeDetectorRef.detach();
1586
- }
1587
- });
1588
- };
1589
-
1590
- // TODO(FW-2827): types
1591
- // eslint-disable-next-line @angular-eslint/directive-class-suffix
1592
- class IonRouterOutlet {
1593
- constructor(name, tabs, commonLocation, elementRef, router, zone, activatedRoute, parentOutlet) {
1594
- this.parentOutlet = parentOutlet;
1595
- this.activatedView = null;
1596
- // Maintain map of activated route proxies for each component instance
1597
- this.proxyMap = new WeakMap();
1598
- // Keep the latest activated route in a subject for the proxy routes to switch map to
1599
- this.currentActivatedRoute$ = new BehaviorSubject(null);
1600
- this.activated = null;
1601
- this._activatedRoute = null;
1602
- /**
1603
- * The name of the outlet
1604
- */
1605
- this.name = PRIMARY_OUTLET;
1606
- /** @internal */
1607
- this.stackWillChange = new EventEmitter();
1608
- /** @internal */
1609
- this.stackDidChange = new EventEmitter();
1610
- // eslint-disable-next-line @angular-eslint/no-output-rename
1611
- this.activateEvents = new EventEmitter();
1612
- // eslint-disable-next-line @angular-eslint/no-output-rename
1613
- this.deactivateEvents = new EventEmitter();
1614
- this.parentContexts = inject(ChildrenOutletContexts);
1615
- this.location = inject(ViewContainerRef);
1616
- this.environmentInjector = inject(EnvironmentInjector);
1617
- this.inputBinder = inject(INPUT_BINDER, { optional: true });
1618
- /** @nodoc */
1619
- this.supportsBindingToComponentInputs = true;
1620
- // Ionic providers
1621
- this.config = inject(Config);
1622
- this.navCtrl = inject(NavController);
1623
- this.nativeEl = elementRef.nativeElement;
1624
- this.name = name || PRIMARY_OUTLET;
1625
- this.tabsPrefix = tabs === 'true' ? getUrl(router, activatedRoute) : undefined;
1626
- this.stackCtrl = new StackController(this.tabsPrefix, this.nativeEl, router, this.navCtrl, zone, commonLocation);
1627
- this.parentContexts.onChildOutletCreated(this.name, this);
1628
- }
1629
- /** @internal */
1630
- get activatedComponentRef() {
1631
- return this.activated;
1632
- }
1633
- set animation(animation) {
1634
- this.nativeEl.animation = animation;
1635
- }
1636
- set animated(animated) {
1637
- this.nativeEl.animated = animated;
1638
- }
1639
- set swipeGesture(swipe) {
1640
- this._swipeGesture = swipe;
1641
- this.nativeEl.swipeHandler = swipe
1642
- ? {
1643
- canStart: () => this.stackCtrl.canGoBack(1) && !this.stackCtrl.hasRunningTask(),
1644
- onStart: () => this.stackCtrl.startBackTransition(),
1645
- onEnd: (shouldContinue) => this.stackCtrl.endBackTransition(shouldContinue),
1646
- }
1647
- : undefined;
1648
- }
1649
- ngOnDestroy() {
1650
- var _a;
1651
- this.stackCtrl.destroy();
1652
- (_a = this.inputBinder) === null || _a === void 0 ? void 0 : _a.unsubscribeFromRouteData(this);
1653
- }
1654
- getContext() {
1655
- return this.parentContexts.getContext(this.name);
1656
- }
1657
- ngOnInit() {
1658
- this.initializeOutletWithName();
1659
- }
1660
- // Note: Ionic deviates from the Angular Router implementation here
1661
- initializeOutletWithName() {
1662
- if (!this.activated) {
1663
- // If the outlet was not instantiated at the time the route got activated we need to populate
1664
- // the outlet when it is initialized (ie inside a NgIf)
1665
- const context = this.getContext();
1666
- if (context === null || context === void 0 ? void 0 : context.route) {
1667
- this.activateWith(context.route, context.injector);
1668
- }
1669
- }
1670
- new Promise((resolve) => componentOnReady(this.nativeEl, resolve)).then(() => {
1671
- if (this._swipeGesture === undefined) {
1672
- this.swipeGesture = this.config.getBoolean('swipeBackEnabled', this.nativeEl.mode === 'ios');
1673
- }
1674
- });
1675
- }
1676
- get isActivated() {
1677
- return !!this.activated;
1678
- }
1679
- get component() {
1680
- if (!this.activated) {
1681
- throw new Error('Outlet is not activated');
1682
- }
1683
- return this.activated.instance;
1684
- }
1685
- get activatedRoute() {
1686
- if (!this.activated) {
1687
- throw new Error('Outlet is not activated');
1688
- }
1689
- return this._activatedRoute;
1690
- }
1691
- get activatedRouteData() {
1692
- if (this._activatedRoute) {
1693
- return this._activatedRoute.snapshot.data;
1694
- }
1695
- return {};
1696
- }
1697
- /**
1698
- * Called when the `RouteReuseStrategy` instructs to detach the subtree
1699
- */
1700
- detach() {
1701
- throw new Error('incompatible reuse strategy');
1702
- }
1703
- /**
1704
- * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
1705
- */
1706
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1707
- attach(_ref, _activatedRoute) {
1708
- throw new Error('incompatible reuse strategy');
1709
- }
1710
- deactivate() {
1711
- if (this.activated) {
1712
- if (this.activatedView) {
1713
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1714
- const context = this.getContext();
1715
- this.activatedView.savedData = new Map(context.children['contexts']);
1716
- /**
1717
- * Angular v11.2.10 introduced a change
1718
- * where this route context is cleared out when
1719
- * a router-outlet is deactivated, However,
1720
- * we need this route information in order to
1721
- * return a user back to the correct tab when
1722
- * leaving and then going back to the tab context.
1723
- */
1724
- const primaryOutlet = this.activatedView.savedData.get('primary');
1725
- if (primaryOutlet && context.route) {
1726
- primaryOutlet.route = Object.assign({}, context.route);
1727
- }
1728
- /**
1729
- * Ensure we are saving the NavigationExtras
1730
- * data otherwise it will be lost
1731
- */
1732
- this.activatedView.savedExtras = {};
1733
- if (context.route) {
1734
- const contextSnapshot = context.route.snapshot;
1735
- this.activatedView.savedExtras.queryParams = contextSnapshot.queryParams;
1736
- this.activatedView.savedExtras.fragment = contextSnapshot.fragment;
1737
- }
1738
- }
1739
- const c = this.component;
1740
- this.activatedView = null;
1741
- this.activated = null;
1742
- this._activatedRoute = null;
1743
- this.deactivateEvents.emit(c);
1744
- }
1745
- }
1746
- activateWith(activatedRoute, environmentInjector) {
1747
- var _a, _b;
1748
- if (this.isActivated) {
1749
- throw new Error('Cannot activate an already activated outlet');
1750
- }
1751
- this._activatedRoute = activatedRoute;
1752
- let cmpRef;
1753
- let enteringView = this.stackCtrl.getExistingView(activatedRoute);
1754
- if (enteringView) {
1755
- cmpRef = this.activated = enteringView.ref;
1756
- const saved = enteringView.savedData;
1757
- if (saved) {
1758
- // self-restore
1759
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1760
- const context = this.getContext();
1761
- context.children['contexts'] = saved;
1762
- }
1763
- // Updated activated route proxy for this component
1764
- this.updateActivatedRouteProxy(cmpRef.instance, activatedRoute);
1765
- }
1766
- else {
1767
- const snapshot = activatedRoute._futureSnapshot;
1768
- /**
1769
- * Angular 14 introduces a new `loadComponent` property to the route config.
1770
- * This function will assign a `component` property to the route snapshot.
1771
- * We check for the presence of this property to determine if the route is
1772
- * using standalone components.
1773
- */
1774
- const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
1775
- // We create an activated route proxy object that will maintain future updates for this component
1776
- // over its lifecycle in the stack.
1777
- const component$ = new BehaviorSubject(null);
1778
- const activatedRouteProxy = this.createActivatedRouteProxy(component$, activatedRoute);
1779
- const injector = new OutletInjector(activatedRouteProxy, childContexts, this.location.injector);
1780
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1781
- const component = (_a = snapshot.routeConfig.component) !== null && _a !== void 0 ? _a : snapshot.component;
1782
- cmpRef = this.activated = this.location.createComponent(component, {
1783
- index: this.location.length,
1784
- injector,
1785
- environmentInjector: environmentInjector !== null && environmentInjector !== void 0 ? environmentInjector : this.environmentInjector,
1786
- });
1787
- // Once the component is created we can push it to our local subject supplied to the proxy
1788
- component$.next(cmpRef.instance);
1789
- // Calling `markForCheck` to make sure we will run the change detection when the
1790
- // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
1791
- enteringView = this.stackCtrl.createView(this.activated, activatedRoute);
1792
- // Store references to the proxy by component
1793
- this.proxyMap.set(cmpRef.instance, activatedRouteProxy);
1794
- this.currentActivatedRoute$.next({ component: cmpRef.instance, activatedRoute });
1795
- }
1796
- (_b = this.inputBinder) === null || _b === void 0 ? void 0 : _b.bindActivatedRouteToOutletComponent(this);
1797
- this.activatedView = enteringView;
1798
- /**
1799
- * The top outlet is set prior to the entering view's transition completing,
1800
- * so that when we have nested outlets (e.g. ion-tabs inside an ion-router-outlet),
1801
- * the tabs outlet will be assigned as the top outlet when a view inside tabs is
1802
- * activated.
1803
- *
1804
- * In this scenario, activeWith is called for both the tabs and the root router outlet.
1805
- * To avoid a race condition, we assign the top outlet synchronously.
1806
- */
1807
- this.navCtrl.setTopOutlet(this);
1808
- const leavingView = this.stackCtrl.getActiveView();
1809
- this.stackWillChange.emit({
1810
- enteringView,
1811
- tabSwitch: isTabSwitch(enteringView, leavingView),
1812
- });
1813
- this.stackCtrl.setActive(enteringView).then((data) => {
1814
- this.activateEvents.emit(cmpRef.instance);
1815
- this.stackDidChange.emit(data);
1816
- });
1817
- }
1818
- /**
1819
- * Returns `true` if there are pages in the stack to go back.
1820
- */
1821
- canGoBack(deep = 1, stackId) {
1822
- return this.stackCtrl.canGoBack(deep, stackId);
1823
- }
1824
- /**
1825
- * Resolves to `true` if it the outlet was able to sucessfully pop the last N pages.
1826
- */
1827
- pop(deep = 1, stackId) {
1828
- return this.stackCtrl.pop(deep, stackId);
1829
- }
1830
- /**
1831
- * Returns the URL of the active page of each stack.
1832
- */
1833
- getLastUrl(stackId) {
1834
- const active = this.stackCtrl.getLastUrl(stackId);
1835
- return active ? active.url : undefined;
1836
- }
1837
- /**
1838
- * Returns the RouteView of the active page of each stack.
1839
- * @internal
1840
- */
1841
- getLastRouteView(stackId) {
1842
- return this.stackCtrl.getLastUrl(stackId);
1843
- }
1844
- /**
1845
- * Returns the root view in the tab stack.
1846
- * @internal
1847
- */
1848
- getRootView(stackId) {
1849
- return this.stackCtrl.getRootUrl(stackId);
1850
- }
1851
- /**
1852
- * Returns the active stack ID. In the context of ion-tabs, it means the active tab.
1853
- */
1854
- getActiveStackId() {
1855
- return this.stackCtrl.getActiveStackId();
1856
- }
1857
- /**
1858
- * Since the activated route can change over the life time of a component in an ion router outlet, we create
1859
- * a proxy so that we can update the values over time as a user navigates back to components already in the stack.
1860
- */
1861
- createActivatedRouteProxy(component$, activatedRoute) {
1862
- const proxy = new ActivatedRoute();
1863
- proxy._futureSnapshot = activatedRoute._futureSnapshot;
1864
- proxy._routerState = activatedRoute._routerState;
1865
- proxy.snapshot = activatedRoute.snapshot;
1866
- proxy.outlet = activatedRoute.outlet;
1867
- proxy.component = activatedRoute.component;
1868
- // Setup wrappers for the observables so consumers don't have to worry about switching to new observables as the state updates
1869
- proxy._paramMap = this.proxyObservable(component$, 'paramMap');
1870
- proxy._queryParamMap = this.proxyObservable(component$, 'queryParamMap');
1871
- proxy.url = this.proxyObservable(component$, 'url');
1872
- proxy.params = this.proxyObservable(component$, 'params');
1873
- proxy.queryParams = this.proxyObservable(component$, 'queryParams');
1874
- proxy.fragment = this.proxyObservable(component$, 'fragment');
1875
- proxy.data = this.proxyObservable(component$, 'data');
1876
- return proxy;
1877
- }
1878
- /**
1879
- * Create a wrapped observable that will switch to the latest activated route matched by the given component
1880
- */
1881
- proxyObservable(component$, path) {
1882
- return component$.pipe(
1883
- // First wait until the component instance is pushed
1884
- filter((component) => !!component), switchMap((component) => this.currentActivatedRoute$.pipe(filter((current) => current !== null && current.component === component), switchMap((current) => current && current.activatedRoute[path]), distinctUntilChanged())));
1885
- }
1886
- /**
1887
- * Updates the activated route proxy for the given component to the new incoming router state
1888
- */
1889
- updateActivatedRouteProxy(component, activatedRoute) {
1890
- const proxy = this.proxyMap.get(component);
1891
- if (!proxy) {
1892
- throw new Error(`Could not find activated route proxy for view`);
1893
- }
1894
- proxy._futureSnapshot = activatedRoute._futureSnapshot;
1895
- proxy._routerState = activatedRoute._routerState;
1896
- proxy.snapshot = activatedRoute.snapshot;
1897
- proxy.outlet = activatedRoute.outlet;
1898
- proxy.component = activatedRoute.component;
1899
- this.currentActivatedRoute$.next({ component, activatedRoute });
1900
- }
1901
- }
1902
- /** @nocollapse */ IonRouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonRouterOutlet, deps: [{ token: 'name', attribute: true }, { token: 'tabs', attribute: true, optional: true }, { token: i1.Location }, { token: i0.ElementRef }, { token: i3.Router }, { token: i0.NgZone }, { token: i3.ActivatedRoute }, { token: IonRouterOutlet, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive });
1903
- /** @nocollapse */ IonRouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: IonRouterOutlet, selector: "ion-router-outlet", inputs: { animated: "animated", animation: "animation", mode: "mode", swipeGesture: "swipeGesture", name: "name" }, outputs: { stackWillChange: "stackWillChange", stackDidChange: "stackDidChange", activateEvents: "activate", deactivateEvents: "deactivate" }, exportAs: ["outlet"], ngImport: i0 });
1904
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonRouterOutlet, decorators: [{
1905
- type: Directive,
1906
- args: [{
1907
- selector: 'ion-router-outlet',
1908
- exportAs: 'outlet',
1909
- // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
1910
- inputs: ['animated', 'animation', 'mode', 'swipeGesture'],
1911
- }]
1912
- }], ctorParameters: function () {
1913
- return [{ type: undefined, decorators: [{
1914
- type: Attribute,
1915
- args: ['name']
1916
- }] }, { type: undefined, decorators: [{
1917
- type: Optional
1918
- }, {
1919
- type: Attribute,
1920
- args: ['tabs']
1921
- }] }, { type: i1.Location }, { type: i0.ElementRef }, { type: i3.Router }, { type: i0.NgZone }, { type: i3.ActivatedRoute }, { type: IonRouterOutlet, decorators: [{
1922
- type: SkipSelf
1923
- }, {
1924
- type: Optional
1925
- }] }];
1926
- }, propDecorators: { name: [{
1927
- type: Input
1928
- }], stackWillChange: [{
1929
- type: Output
1930
- }], stackDidChange: [{
1931
- type: Output
1932
- }], activateEvents: [{
1933
- type: Output,
1934
- args: ['activate']
1935
- }], deactivateEvents: [{
1936
- type: Output,
1937
- args: ['deactivate']
1938
- }] } });
1939
- class OutletInjector {
1940
- constructor(route, childContexts, parent) {
1941
- this.route = route;
1942
- this.childContexts = childContexts;
1943
- this.parent = parent;
1944
- }
1945
- get(token, notFoundValue) {
1946
- if (token === ActivatedRoute) {
1947
- return this.route;
1948
- }
1949
- if (token === ChildrenOutletContexts) {
1950
- return this.childContexts;
1951
- }
1952
- return this.parent.get(token, notFoundValue);
1953
- }
1954
- }
1955
- // TODO: FW-4785 - Remove this once Angular 15 support is dropped
1956
- const INPUT_BINDER = new InjectionToken('');
1957
- /**
1958
- * Injectable used as a tree-shakable provider for opting in to binding router data to component
1959
- * inputs.
1960
- *
1961
- * The RouterOutlet registers itself with this service when an `ActivatedRoute` is attached or
1962
- * activated. When this happens, the service subscribes to the `ActivatedRoute` observables (params,
1963
- * queryParams, data) and sets the inputs of the component using `ComponentRef.setInput`.
1964
- * Importantly, when an input does not have an item in the route data with a matching key, this
1965
- * input is set to `undefined`. If it were not done this way, the previous information would be
1966
- * retained if the data got removed from the route (i.e. if a query parameter is removed).
1967
- *
1968
- * The `RouterOutlet` should unregister itself when destroyed via `unsubscribeFromRouteData` so that
1969
- * the subscriptions are cleaned up.
1970
- */
1971
- class RoutedComponentInputBinder {
1972
- constructor() {
1973
- this.outletDataSubscriptions = new Map();
1974
- }
1975
- bindActivatedRouteToOutletComponent(outlet) {
1976
- this.unsubscribeFromRouteData(outlet);
1977
- this.subscribeToRouteData(outlet);
1978
- }
1979
- unsubscribeFromRouteData(outlet) {
1980
- var _a;
1981
- (_a = this.outletDataSubscriptions.get(outlet)) === null || _a === void 0 ? void 0 : _a.unsubscribe();
1982
- this.outletDataSubscriptions.delete(outlet);
1983
- }
1984
- subscribeToRouteData(outlet) {
1985
- const { activatedRoute } = outlet;
1986
- const dataSubscription = combineLatest([activatedRoute.queryParams, activatedRoute.params, activatedRoute.data])
1987
- .pipe(switchMap(([queryParams, params, data], index) => {
1988
- data = Object.assign(Object.assign(Object.assign({}, queryParams), params), data);
1989
- // Get the first result from the data subscription synchronously so it's available to
1990
- // the component as soon as possible (and doesn't require a second change detection).
1991
- if (index === 0) {
1992
- return of(data);
1993
- }
1994
- // Promise.resolve is used to avoid synchronously writing the wrong data when
1995
- // two of the Observables in the `combineLatest` stream emit one after
1996
- // another.
1997
- return Promise.resolve(data);
1998
- }))
1999
- .subscribe((data) => {
2000
- // Outlet may have been deactivated or changed names to be associated with a different
2001
- // route
2002
- if (!outlet.isActivated ||
2003
- !outlet.activatedComponentRef ||
2004
- outlet.activatedRoute !== activatedRoute ||
2005
- activatedRoute.component === null) {
2006
- this.unsubscribeFromRouteData(outlet);
2007
- return;
2008
- }
2009
- const mirror = reflectComponentType(activatedRoute.component);
2010
- if (!mirror) {
2011
- this.unsubscribeFromRouteData(outlet);
2012
- return;
2013
- }
2014
- for (const { templateName } of mirror.inputs) {
2015
- outlet.activatedComponentRef.setInput(templateName, data[templateName]);
2016
- }
2017
- });
2018
- this.outletDataSubscriptions.set(outlet, dataSubscription);
2019
- }
2020
- }
2021
- /** @nocollapse */ RoutedComponentInputBinder.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RoutedComponentInputBinder, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2022
- /** @nocollapse */ RoutedComponentInputBinder.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RoutedComponentInputBinder });
2023
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RoutedComponentInputBinder, decorators: [{
2024
- type: Injectable
2025
- }] });
2026
- const provideComponentInputBinding = () => {
2027
- return {
2028
- provide: INPUT_BINDER,
2029
- useFactory: componentInputBindingFactory,
2030
- deps: [Router],
2031
- };
2032
- };
2033
- function componentInputBindingFactory(router) {
2034
- /**
2035
- * We cast the router to any here, since the componentInputBindingEnabled
2036
- * property is not available until Angular v16.
2037
- */
2038
- if (router === null || router === void 0 ? void 0 : router.componentInputBindingEnabled) {
2039
- return new RoutedComponentInputBinder();
2040
- }
2041
- return null;
2042
- }
2043
-
2044
- const BACK_BUTTON_INPUTS = ['color', 'defaultHref', 'disabled', 'icon', 'mode', 'routerAnimation', 'text', 'type'];
2045
- let IonBackButton = class IonBackButton {
2046
- constructor(routerOutlet, navCtrl, config, r, z, c) {
2047
- this.routerOutlet = routerOutlet;
2048
- this.navCtrl = navCtrl;
2049
- this.config = config;
2050
- this.r = r;
2051
- this.z = z;
2052
- c.detach();
2053
- this.el = this.r.nativeElement;
2054
- }
2055
- /**
2056
- * @internal
2057
- */
2058
- onClick(ev) {
2059
- var _a;
2060
- const defaultHref = this.defaultHref || this.config.get('backButtonDefaultHref');
2061
- if ((_a = this.routerOutlet) === null || _a === void 0 ? void 0 : _a.canGoBack()) {
2062
- this.navCtrl.setDirection('back', undefined, undefined, this.routerAnimation);
2063
- this.routerOutlet.pop();
2064
- ev.preventDefault();
2065
- }
2066
- else if (defaultHref != null) {
2067
- this.navCtrl.navigateBack(defaultHref, { animation: this.routerAnimation });
2068
- ev.preventDefault();
2069
- }
2070
- }
2071
- };
2072
- /** @nocollapse */ IonBackButton.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonBackButton, deps: [{ token: IonRouterOutlet, optional: true }, { token: NavController }, { token: Config }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
2073
- /** @nocollapse */ IonBackButton.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: IonBackButton, inputs: { color: "color", defaultHref: "defaultHref", disabled: "disabled", icon: "icon", mode: "mode", routerAnimation: "routerAnimation", text: "text", type: "type" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
2074
- IonBackButton = __decorate([
2075
- ProxyCmp({
2076
- inputs: BACK_BUTTON_INPUTS,
2077
- })
2078
- ], IonBackButton);
2079
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonBackButton, decorators: [{
2080
- type: Directive,
2081
- args: [{
2082
- // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
2083
- inputs: BACK_BUTTON_INPUTS,
2084
- }]
2085
- }], ctorParameters: function () {
2086
- return [{ type: IonRouterOutlet, decorators: [{
2087
- type: Optional
2088
- }] }, { type: NavController }, { type: Config }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }];
2089
- }, propDecorators: { defaultHref: [{
2090
- type: Input
2091
- }], routerAnimation: [{
2092
- type: Input
2093
- }], onClick: [{
2094
- type: HostListener,
2095
- args: ['click', ['$event']]
2096
- }] } });
2097
-
2098
- /**
2099
- * Adds support for Ionic routing directions and animations to the base Angular router link directive.
2100
- *
2101
- * When the router link is clicked, the directive will assign the direction and
2102
- * animation so that the routing integration will transition correctly.
2103
- */
2104
- class RouterLinkDelegateDirective {
2105
- constructor(locationStrategy, navCtrl, elementRef, router, routerLink) {
2106
- this.locationStrategy = locationStrategy;
2107
- this.navCtrl = navCtrl;
2108
- this.elementRef = elementRef;
2109
- this.router = router;
2110
- this.routerLink = routerLink;
2111
- this.routerDirection = 'forward';
2112
- }
2113
- ngOnInit() {
2114
- this.updateTargetUrlAndHref();
2115
- }
2116
- ngOnChanges() {
2117
- this.updateTargetUrlAndHref();
2118
- }
2119
- updateTargetUrlAndHref() {
2120
- var _a;
2121
- if ((_a = this.routerLink) === null || _a === void 0 ? void 0 : _a.urlTree) {
2122
- const href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.routerLink.urlTree));
2123
- this.elementRef.nativeElement.href = href;
2124
- }
2125
- }
2126
- /**
2127
- * @internal
2128
- */
2129
- onClick(ev) {
2130
- this.navCtrl.setDirection(this.routerDirection, undefined, undefined, this.routerAnimation);
2131
- /**
2132
- * This prevents the browser from
2133
- * performing a page reload when pressing
2134
- * an Ionic component with routerLink.
2135
- * The page reload interferes with routing
2136
- * and causes ion-back-button to disappear
2137
- * since the local history is wiped on reload.
2138
- */
2139
- ev.preventDefault();
2140
- }
2141
- }
2142
- /** @nocollapse */ RouterLinkDelegateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RouterLinkDelegateDirective, deps: [{ token: i1.LocationStrategy }, { token: NavController }, { token: i0.ElementRef }, { token: i3.Router }, { token: i3.RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2143
- /** @nocollapse */ RouterLinkDelegateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: RouterLinkDelegateDirective, selector: ":not(a):not(area)[routerLink]", inputs: { routerDirection: "routerDirection", routerAnimation: "routerAnimation" }, host: { listeners: { "click": "onClick($event)" } }, usesOnChanges: true, ngImport: i0 });
2144
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RouterLinkDelegateDirective, decorators: [{
2145
- type: Directive,
2146
- args: [{
2147
- selector: ':not(a):not(area)[routerLink]',
2148
- }]
2149
- }], ctorParameters: function () {
2150
- return [{ type: i1.LocationStrategy }, { type: NavController }, { type: i0.ElementRef }, { type: i3.Router }, { type: i3.RouterLink, decorators: [{
2151
- type: Optional
2152
- }] }];
2153
- }, propDecorators: { routerDirection: [{
2154
- type: Input
2155
- }], routerAnimation: [{
2156
- type: Input
2157
- }], onClick: [{
2158
- type: HostListener,
2159
- args: ['click', ['$event']]
2160
- }] } });
2161
- class RouterLinkWithHrefDelegateDirective {
2162
- constructor(locationStrategy, navCtrl, elementRef, router, routerLink) {
2163
- this.locationStrategy = locationStrategy;
2164
- this.navCtrl = navCtrl;
2165
- this.elementRef = elementRef;
2166
- this.router = router;
2167
- this.routerLink = routerLink;
2168
- this.routerDirection = 'forward';
2169
- }
2170
- ngOnInit() {
2171
- this.updateTargetUrlAndHref();
2172
- }
2173
- ngOnChanges() {
2174
- this.updateTargetUrlAndHref();
2175
- }
2176
- updateTargetUrlAndHref() {
2177
- var _a;
2178
- if ((_a = this.routerLink) === null || _a === void 0 ? void 0 : _a.urlTree) {
2179
- const href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.routerLink.urlTree));
2180
- this.elementRef.nativeElement.href = href;
2181
- }
2182
- }
2183
- /**
2184
- * @internal
2185
- */
2186
- onClick() {
2187
- this.navCtrl.setDirection(this.routerDirection, undefined, undefined, this.routerAnimation);
2188
- }
2189
- }
2190
- /** @nocollapse */ RouterLinkWithHrefDelegateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RouterLinkWithHrefDelegateDirective, deps: [{ token: i1.LocationStrategy }, { token: NavController }, { token: i0.ElementRef }, { token: i3.Router }, { token: i3.RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2191
- /** @nocollapse */ RouterLinkWithHrefDelegateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: RouterLinkWithHrefDelegateDirective, selector: "a[routerLink],area[routerLink]", inputs: { routerDirection: "routerDirection", routerAnimation: "routerAnimation" }, host: { listeners: { "click": "onClick()" } }, usesOnChanges: true, ngImport: i0 });
2192
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RouterLinkWithHrefDelegateDirective, decorators: [{
2193
- type: Directive,
2194
- args: [{
2195
- selector: 'a[routerLink],area[routerLink]',
2196
- }]
2197
- }], ctorParameters: function () {
2198
- return [{ type: i1.LocationStrategy }, { type: NavController }, { type: i0.ElementRef }, { type: i3.Router }, { type: i3.RouterLink, decorators: [{
2199
- type: Optional
2200
- }] }];
2201
- }, propDecorators: { routerDirection: [{
2202
- type: Input
2203
- }], routerAnimation: [{
2204
- type: Input
2205
- }], onClick: [{
2206
- type: HostListener,
2207
- args: ['click']
2208
- }] } });
2209
-
2210
- const NAV_INPUTS = ['animated', 'animation', 'root', 'rootParams', 'swipeGesture'];
2211
- const NAV_METHODS = [
2212
- 'push',
2213
- 'insert',
2214
- 'insertPages',
2215
- 'pop',
2216
- 'popTo',
2217
- 'popToRoot',
2218
- 'removeIndex',
2219
- 'setRoot',
2220
- 'setPages',
2221
- 'getActive',
2222
- 'getByIndex',
2223
- 'canGoBack',
2224
- 'getPrevious',
2225
- ];
2226
- let IonNav = class IonNav {
2227
- constructor(ref, environmentInjector, injector, angularDelegate, z, c) {
2228
- this.z = z;
2229
- c.detach();
2230
- this.el = ref.nativeElement;
2231
- ref.nativeElement.delegate = angularDelegate.create(environmentInjector, injector);
2232
- proxyOutputs(this, this.el, ['ionNavDidChange', 'ionNavWillChange']);
2233
- }
2234
- };
2235
- /** @nocollapse */ IonNav.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonNav, deps: [{ token: i0.ElementRef }, { token: i0.EnvironmentInjector }, { token: i0.Injector }, { token: AngularDelegate }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
2236
- /** @nocollapse */ IonNav.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: IonNav, inputs: { animated: "animated", animation: "animation", root: "root", rootParams: "rootParams", swipeGesture: "swipeGesture" }, ngImport: i0 });
2237
- IonNav = __decorate([
2238
- ProxyCmp({
2239
- inputs: NAV_INPUTS,
2240
- methods: NAV_METHODS,
2241
- })
2242
- ], IonNav);
2243
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonNav, decorators: [{
2244
- type: Directive,
2245
- args: [{
2246
- // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
2247
- inputs: NAV_INPUTS,
2248
- }]
2249
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.EnvironmentInjector }, { type: i0.Injector }, { type: AngularDelegate }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
2250
-
2251
- // eslint-disable-next-line @angular-eslint/directive-class-suffix
2252
- class IonTabs {
2253
- constructor(navCtrl) {
2254
- this.navCtrl = navCtrl;
2255
- /**
2256
- * Emitted before the tab view is changed.
2257
- */
2258
- this.ionTabsWillChange = new EventEmitter();
2259
- /**
2260
- * Emitted after the tab view is changed.
2261
- */
2262
- this.ionTabsDidChange = new EventEmitter();
2263
- this.tabBarSlot = 'bottom';
2264
- }
2265
- ngAfterContentInit() {
2266
- this.detectSlotChanges();
2267
- }
2268
- ngAfterContentChecked() {
2269
- this.detectSlotChanges();
2270
- }
2271
- /**
2272
- * @internal
2273
- */
2274
- onStackWillChange({ enteringView, tabSwitch }) {
2275
- const stackId = enteringView.stackId;
2276
- if (tabSwitch && stackId !== undefined) {
2277
- this.ionTabsWillChange.emit({ tab: stackId });
2278
- }
2279
- }
2280
- /**
2281
- * @internal
2282
- */
2283
- onStackDidChange({ enteringView, tabSwitch }) {
2284
- const stackId = enteringView.stackId;
2285
- if (tabSwitch && stackId !== undefined) {
2286
- if (this.tabBar) {
2287
- this.tabBar.selectedTab = stackId;
2288
- }
2289
- this.ionTabsDidChange.emit({ tab: stackId });
2290
- }
2291
- }
2292
- /**
2293
- * When a tab button is clicked, there are several scenarios:
2294
- * 1. If the selected tab is currently active (the tab button has been clicked
2295
- * again), then it should go to the root view for that tab.
2296
- *
2297
- * a. Get the saved root view from the router outlet. If the saved root view
2298
- * matches the tabRootUrl, set the route view to this view including the
2299
- * navigation extras.
2300
- * b. If the saved root view from the router outlet does
2301
- * not match, navigate to the tabRootUrl. No navigation extras are
2302
- * included.
2303
- *
2304
- * 2. If the current tab tab is not currently selected, get the last route
2305
- * view from the router outlet.
2306
- *
2307
- * a. If the last route view exists, navigate to that view including any
2308
- * navigation extras
2309
- * b. If the last route view doesn't exist, then navigate
2310
- * to the default tabRootUrl
2311
- */
2312
- select(tabOrEvent) {
2313
- const isTabString = typeof tabOrEvent === 'string';
2314
- const tab = isTabString ? tabOrEvent : tabOrEvent.detail.tab;
2315
- const alreadySelected = this.outlet.getActiveStackId() === tab;
2316
- const tabRootUrl = `${this.outlet.tabsPrefix}/${tab}`;
2317
- /**
2318
- * If this is a nested tab, prevent the event
2319
- * from bubbling otherwise the outer tabs
2320
- * will respond to this event too, causing
2321
- * the app to get directed to the wrong place.
2322
- */
2323
- if (!isTabString) {
2324
- tabOrEvent.stopPropagation();
2325
- }
2326
- if (alreadySelected) {
2327
- const activeStackId = this.outlet.getActiveStackId();
2328
- const activeView = this.outlet.getLastRouteView(activeStackId);
2329
- // If on root tab, do not navigate to root tab again
2330
- if ((activeView === null || activeView === void 0 ? void 0 : activeView.url) === tabRootUrl) {
2331
- return;
2332
- }
2333
- const rootView = this.outlet.getRootView(tab);
2334
- const navigationExtras = rootView && tabRootUrl === rootView.url && rootView.savedExtras;
2335
- return this.navCtrl.navigateRoot(tabRootUrl, Object.assign(Object.assign({}, navigationExtras), { animated: true, animationDirection: 'back' }));
2336
- }
2337
- else {
2338
- const lastRoute = this.outlet.getLastRouteView(tab);
2339
- /**
2340
- * If there is a lastRoute, goto that, otherwise goto the fallback url of the
2341
- * selected tab
2342
- */
2343
- const url = (lastRoute === null || lastRoute === void 0 ? void 0 : lastRoute.url) || tabRootUrl;
2344
- const navigationExtras = lastRoute === null || lastRoute === void 0 ? void 0 : lastRoute.savedExtras;
2345
- return this.navCtrl.navigateRoot(url, Object.assign(Object.assign({}, navigationExtras), { animated: true, animationDirection: 'back' }));
2346
- }
2347
- }
2348
- getSelected() {
2349
- return this.outlet.getActiveStackId();
2350
- }
2351
- /**
2352
- * Detects changes to the slot attribute of the tab bar.
2353
- *
2354
- * If the slot attribute has changed, then the tab bar
2355
- * should be relocated to the new slot position.
2356
- */
2357
- detectSlotChanges() {
2358
- this.tabBars.forEach((tabBar) => {
2359
- // el is a protected attribute from the generated component wrapper
2360
- const currentSlot = tabBar.el.getAttribute('slot');
2361
- if (currentSlot !== this.tabBarSlot) {
2362
- this.tabBarSlot = currentSlot;
2363
- this.relocateTabBar();
2364
- }
2365
- });
2366
- }
2367
- /**
2368
- * Relocates the tab bar to the new slot position.
2369
- */
2370
- relocateTabBar() {
2371
- /**
2372
- * `el` is a protected attribute from the generated component wrapper.
2373
- * To avoid having to manually create the wrapper for tab bar, we
2374
- * cast the tab bar to any and access the protected attribute.
2375
- */
2376
- const tabBar = this.tabBar.el;
2377
- if (this.tabBarSlot === 'top') {
2378
- /**
2379
- * A tab bar with a slot of "top" should be inserted
2380
- * at the top of the container.
2381
- */
2382
- this.tabsInner.nativeElement.before(tabBar);
2383
- }
2384
- else {
2385
- /**
2386
- * A tab bar with a slot of "bottom" or without a slot
2387
- * should be inserted at the end of the container.
2388
- */
2389
- this.tabsInner.nativeElement.after(tabBar);
2390
- }
2391
- }
2392
- }
2393
- /** @nocollapse */ IonTabs.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonTabs, deps: [{ token: NavController }], target: i0.ɵɵFactoryTarget.Directive });
2394
- /** @nocollapse */ IonTabs.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: IonTabs, selector: "ion-tabs", outputs: { ionTabsWillChange: "ionTabsWillChange", ionTabsDidChange: "ionTabsDidChange" }, host: { listeners: { "ionTabButtonClick": "select($event)" } }, viewQueries: [{ propertyName: "tabsInner", first: true, predicate: ["tabsInner"], descendants: true, read: ElementRef, static: true }], ngImport: i0 });
2395
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IonTabs, decorators: [{
2396
- type: Directive,
2397
- args: [{
2398
- selector: 'ion-tabs',
2399
- }]
2400
- }], ctorParameters: function () { return [{ type: NavController }]; }, propDecorators: { tabsInner: [{
2401
- type: ViewChild,
2402
- args: ['tabsInner', { read: ElementRef, static: true }]
2403
- }], ionTabsWillChange: [{
2404
- type: Output
2405
- }], ionTabsDidChange: [{
2406
- type: Output
2407
- }], select: [{
2408
- type: HostListener,
2409
- args: ['ionTabButtonClick', ['$event']]
2410
- }] } });
2411
-
2412
- /**
2413
- * Provides a way to customize when activated routes get reused.
2414
- */
2415
- class IonicRouteStrategy {
2416
- /**
2417
- * Whether the given route should detach for later reuse.
2418
- */
2419
- shouldDetach(_route) {
2420
- return false;
2421
- }
2422
- /**
2423
- * Returns `false`, meaning the route (and its subtree) is never reattached
2424
- */
2425
- shouldAttach(_route) {
2426
- return false;
2427
- }
2428
- /**
2429
- * A no-op; the route is never stored since this strategy never detaches routes for later re-use.
2430
- */
2431
- store(_route, _detachedTree) {
2432
- return;
2433
- }
2434
- /**
2435
- * Returns `null` because this strategy does not store routes for later re-use.
2436
- */
2437
- retrieve(_route) {
2438
- return null;
2439
- }
2440
- /**
2441
- * Determines if a route should be reused.
2442
- * This strategy returns `true` when the future route config and
2443
- * current route config are identical and all route parameters are identical.
2444
- */
2445
- shouldReuseRoute(future, curr) {
2446
- if (future.routeConfig !== curr.routeConfig) {
2447
- return false;
2448
- }
2449
- // checking router params
2450
- const futureParams = future.params;
2451
- const currentParams = curr.params;
2452
- const keysA = Object.keys(futureParams);
2453
- const keysB = Object.keys(currentParams);
2454
- if (keysA.length !== keysB.length) {
2455
- return false;
2456
- }
2457
- // Test for A's keys different from B.
2458
- for (const key of keysA) {
2459
- if (currentParams[key] !== futureParams[key]) {
2460
- return false;
2461
- }
2462
- }
2463
- return true;
2464
- }
2465
- }
2466
-
2467
- /**
2468
- * Generated bundle index. Do not edit.
2469
- */
2470
-
2471
- export { ActionSheetController, AlertController, AngularDelegate, AnimationController, Config, ConfigToken, DomController, GestureController, IonBackButton, IonModal, IonNav, IonPopover, IonRouterOutlet, IonTabs, IonicRouteStrategy, LoadingController, MenuController, ModalController, NavController, NavParams, PickerController, Platform, PopoverController, ProxyCmp, RouterLinkDelegateDirective, RouterLinkWithHrefDelegateDirective, ToastController, bindLifecycleEvents, provideComponentInputBinding };
2472
- //# sourceMappingURL=ionic-angular-common.mjs.map