@coolon/angular-ui-powerups 0.0.8 → 0.0.10

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 (53) hide show
  1. package/bundles/coolon-angular-ui-powerups.umd.js +592 -167
  2. package/bundles/coolon-angular-ui-powerups.umd.js.map +1 -1
  3. package/bundles/coolon-angular-ui-powerups.umd.min.js +1 -1
  4. package/bundles/coolon-angular-ui-powerups.umd.min.js.map +1 -1
  5. package/coolon-angular-ui-powerups.d.ts +12 -11
  6. package/coolon-angular-ui-powerups.metadata.json +1 -1
  7. package/esm2015/coolon-angular-ui-powerups.js +12 -11
  8. package/esm2015/index.js +2 -2
  9. package/esm2015/lib/animations/slideDownAndUpAnimation.js +2 -1
  10. package/esm2015/lib/components/forms/abstract-input.component.js +22 -12
  11. package/esm2015/lib/directives/command.directive.js +48 -4
  12. package/esm2015/lib/directives/focus-binding.directive.js +30 -14
  13. package/esm2015/lib/interaction/services/dialog-interaction.service.js +3 -1
  14. package/esm2015/lib/place/components/busy-overlay/busy-overlay.component.js +4 -4
  15. package/esm2015/lib/place/components/nav/nav.component.js +31 -0
  16. package/esm2015/lib/place/guards/place-route.guard.js +3 -3
  17. package/esm2015/lib/place/index.js +4 -3
  18. package/esm2015/lib/place/place.module.js +16 -5
  19. package/esm2015/lib/place/route/parameter-decorators.js +98 -2
  20. package/esm2015/lib/place/route/parameter-definition.class.js +4 -2
  21. package/esm2015/lib/place/route/route-parameter-bindings.js +25 -13
  22. package/esm2015/lib/place/route/route-parameter-sanitiser.js +206 -74
  23. package/esm2015/public_api.js +2 -2
  24. package/esm5/coolon-angular-ui-powerups.js +12 -11
  25. package/esm5/index.js +2 -2
  26. package/esm5/lib/animations/slideDownAndUpAnimation.js +2 -1
  27. package/esm5/lib/components/forms/abstract-input.component.js +26 -12
  28. package/esm5/lib/directives/command.directive.js +52 -4
  29. package/esm5/lib/directives/focus-binding.directive.js +34 -14
  30. package/esm5/lib/interaction/services/dialog-interaction.service.js +3 -1
  31. package/esm5/lib/place/components/busy-overlay/busy-overlay.component.js +4 -4
  32. package/esm5/lib/place/components/nav/nav.component.js +36 -0
  33. package/esm5/lib/place/guards/place-route.guard.js +3 -3
  34. package/esm5/lib/place/index.js +4 -3
  35. package/esm5/lib/place/place.module.js +16 -5
  36. package/esm5/lib/place/route/parameter-decorators.js +98 -2
  37. package/esm5/lib/place/route/parameter-definition.class.js +4 -2
  38. package/esm5/lib/place/route/route-parameter-bindings.js +25 -13
  39. package/esm5/lib/place/route/route-parameter-sanitiser.js +284 -92
  40. package/esm5/public_api.js +2 -2
  41. package/fesm2015/coolon-angular-ui-powerups.js +473 -121
  42. package/fesm2015/coolon-angular-ui-powerups.js.map +1 -1
  43. package/fesm5/coolon-angular-ui-powerups.js +562 -139
  44. package/fesm5/coolon-angular-ui-powerups.js.map +1 -1
  45. package/lib/components/forms/abstract-input.component.d.ts +9 -8
  46. package/lib/directives/command.directive.d.ts +6 -3
  47. package/lib/directives/focus-binding.directive.d.ts +1 -0
  48. package/lib/place/components/nav/nav.component.d.ts +7 -0
  49. package/lib/place/index.d.ts +1 -0
  50. package/lib/place/route/parameter-decorators.d.ts +17 -0
  51. package/lib/place/route/parameter-definition.class.d.ts +4 -3
  52. package/lib/place/route/route-parameter-sanitiser.d.ts +33 -6
  53. package/package.json +2 -2
@@ -5,17 +5,20 @@ import { MatDialog, MatButtonModule, MatDialogModule, MatTabsModule, MatProgress
5
5
  import { BrowserModule } from '@angular/platform-browser';
6
6
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
7
7
  import { __decorate, __metadata, __awaiter } from 'tslib';
8
- import { GarbageCollector, MutableListModel, Constant, UseDelegate, MutableValueModel, assert, Dsl, Logger, ListModel, StoreInListModel, EventListenerList, DelegatingValueModel, lang, UseDelegatingValueModel, ValueModel, StoreInValueModel, Trace, OptionsHelper, ValueHolder, TransactionObserver, Binding } from '@coolon/pectin';
8
+ import { GarbageCollector, DelegatingFormValueModel, UseDelegate, ValueModel, assert, UnaryCommand, lang, Dsl, Logger, ListModel, StoreInListModel, EventListenerList, DelegatingValueModel, MutableListModel, StoreInValueModel, Trace, OptionsHelper, ValueHolder, MutableValueModel, TransactionObserver, Binding } from '@coolon/pectin';
9
9
  import { PortalModule } from '@angular/cdk/portal';
10
10
  import { Deferred } from '@coolon/pectin/lib/promise/deferred.class';
11
+ import { assert as assert$1, Klass, Opts } from '@coolon/typescript-utilities';
11
12
  import { MatDialog as MatDialog$1 } from '@angular/material/dialog';
13
+ import { MatListModule } from '@angular/material/list';
14
+ import { MatTabsModule as MatTabsModule$1 } from '@angular/material/tabs';
15
+ import { MatTooltipModule } from '@angular/material/tooltip';
12
16
  import { RouterModule, Router, ActivatedRoute, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
13
17
  import { style, trigger, transition, animate } from '@angular/animations';
14
18
  import ResizeObserver from 'resize-observer-polyfill';
15
19
  import { Memoize } from '@typescript-plus/fast-memoize-decorator';
16
20
  import { isNil } from 'lodash';
17
21
  import 'reflect-metadata';
18
- import { Klass, Opts } from '@coolon/typescript-utilities';
19
22
  import { Memoize as Memoize$1 } from '@typescript-plus/fast-memoize-decorator/dist/src';
20
23
 
21
24
  /**
@@ -35,8 +38,6 @@ class DisposableComponent extends GarbageCollector {
35
38
  * @fileoverview added by tsickle
36
39
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
37
40
  */
38
- /** @type {?} */
39
- const EMPTY_ERRORS = new MutableListModel().readonly;
40
41
  /**
41
42
  * @abstract
42
43
  * @template T
@@ -44,9 +45,15 @@ const EMPTY_ERRORS = new MutableListModel().readonly;
44
45
  class AbstractInputComponent extends DisposableComponent {
45
46
  constructor() {
46
47
  super();
48
+ this.valueModel = new DelegatingFormValueModel();
49
+ // TODO: fix this.
50
+ // tslint:disable-next-line:no-output-native
47
51
  this.focus = new EventEmitter();
52
+ // tslint:disable-next-line:no-output-native
48
53
  this.blur = new EventEmitter();
54
+ // tslint:disable-next-line:no-output-native
49
55
  this.enterKey = new EventEmitter();
56
+ // tslint:disable-next-line:no-output-native
50
57
  this.escapeKey = new EventEmitter();
51
58
  /** @type {?} */
52
59
  const self = this;
@@ -61,6 +68,13 @@ class AbstractInputComponent extends DisposableComponent {
61
68
  }
62
69
  };
63
70
  }
71
+ /**
72
+ * @param {?} model
73
+ * @return {?}
74
+ */
75
+ set userValueModel(model) {
76
+ this.valueModel.setDelegate(model);
77
+ }
64
78
  /**
65
79
  * @return {?}
66
80
  */
@@ -101,7 +115,7 @@ class AbstractInputComponent extends DisposableComponent {
101
115
  * @return {?}
102
116
  */
103
117
  safelyInvoke(command) {
104
- if (command && command.isEnabled()) {
118
+ if (command && command.enabled.value) {
105
119
  command.execute();
106
120
  }
107
121
  }
@@ -109,7 +123,6 @@ class AbstractInputComponent extends DisposableComponent {
109
123
  * @return {?}
110
124
  */
111
125
  ngOnInit() {
112
- // this._focused = this.valueModel['focused'] || new ValueHolder();
113
126
  }
114
127
  /**
115
128
  * @return {?}
@@ -121,8 +134,7 @@ class AbstractInputComponent extends DisposableComponent {
121
134
  * @return {?}
122
135
  */
123
136
  get enabled() {
124
- // @ts-ignore
125
- return ((/** @type {?} */ (this.valueModel))).enabled || Constant.TRUE;
137
+ return this.valueModel.enabled;
126
138
  }
127
139
  /**
128
140
  * @return {?}
@@ -134,7 +146,7 @@ class AbstractInputComponent extends DisposableComponent {
134
146
  * @return {?}
135
147
  */
136
148
  get errorList() {
137
- return ((/** @type {?} */ (this.valueModel))).errorList || EMPTY_ERRORS;
149
+ return this.valueModel.errorList;
138
150
  }
139
151
  /**
140
152
  * @return {?}
@@ -144,7 +156,7 @@ class AbstractInputComponent extends DisposableComponent {
144
156
  }
145
157
  }
146
158
  AbstractInputComponent.propDecorators = {
147
- valueModel: [{ type: Input }],
159
+ userValueModel: [{ type: Input, args: ['valueModel',] }],
148
160
  label: [{ type: Input }],
149
161
  floatLabel: [{ type: Input }],
150
162
  hint: [{ type: Input }],
@@ -164,8 +176,9 @@ AbstractInputComponent.propDecorators = {
164
176
  };
165
177
  __decorate([
166
178
  UseDelegate(),
167
- __metadata("design:type", MutableValueModel)
168
- ], AbstractInputComponent.prototype, "valueModel", void 0);
179
+ __metadata("design:type", ValueModel),
180
+ __metadata("design:paramtypes", [ValueModel])
181
+ ], AbstractInputComponent.prototype, "userValueModel", null);
169
182
  if (false) {
170
183
  /** @type {?} */
171
184
  AbstractInputComponent.prototype.valueModel;
@@ -227,6 +240,9 @@ NumberInputComponent.ctorParameters = () => [];
227
240
  * @fileoverview added by tsickle
228
241
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
229
242
  */
243
+ /**
244
+ * @template P
245
+ */
230
246
  class CommandDirective extends GarbageCollector {
231
247
  /**
232
248
  * @param {?} elementRef
@@ -234,12 +250,37 @@ class CommandDirective extends GarbageCollector {
234
250
  constructor(elementRef) {
235
251
  super();
236
252
  this.elementRef = elementRef;
253
+ this._commandParameterProvided = false;
254
+ }
255
+ /**
256
+ * @param {?} value
257
+ * @return {?}
258
+ */
259
+ set commandParameter(value) {
260
+ this._commandParameterProvided = true;
261
+ this._commandParameter = value;
262
+ }
263
+ /**
264
+ * @return {?}
265
+ */
266
+ get commandParameter() {
267
+ return this._commandParameter;
237
268
  }
238
269
  /**
239
270
  * @return {?}
240
271
  */
241
272
  ngOnInit() {
242
273
  assert.notNil(this.pectinCommand);
274
+ if (this.pectinCommand instanceof UnaryCommand) {
275
+ if (!this._commandParameterProvided) {
276
+ lang.illegalState('UnaryCommands required the command parameter to be specified.');
277
+ }
278
+ }
279
+ else {
280
+ if (this._commandParameterProvided) {
281
+ lang.illegalState('command parameters are only supported by UnaryCommands');
282
+ }
283
+ }
243
284
  }
244
285
  /**
245
286
  * @return {?}
@@ -280,8 +321,13 @@ class CommandDirective extends GarbageCollector {
280
321
  notifyClick($event) {
281
322
  $event.preventDefault();
282
323
  $event.stopPropagation();
283
- if (this.pectinCommand.isEnabled()) {
284
- this.pectinCommand.execute({ event: $event });
324
+ if (this.pectinCommand.enabled.value) {
325
+ if (this.pectinCommand instanceof UnaryCommand) {
326
+ this.pectinCommand.withContext({ event: $event }).execute(this.commandParameter);
327
+ }
328
+ else {
329
+ this.pectinCommand.withContext({ event: $event }).execute();
330
+ }
285
331
  }
286
332
  else {
287
333
  console.warn('disabled command clicked, ignoring.');
@@ -300,11 +346,22 @@ CommandDirective.ctorParameters = () => [
300
346
  ];
301
347
  CommandDirective.propDecorators = {
302
348
  pectinCommand: [{ type: Input }],
349
+ commandParameter: [{ type: Input }],
303
350
  notifyClick: [{ type: HostListener, args: ['click', ['$event'],] }]
304
351
  };
305
352
  if (false) {
306
353
  /** @type {?} */
307
354
  CommandDirective.prototype.pectinCommand;
355
+ /**
356
+ * @type {?}
357
+ * @private
358
+ */
359
+ CommandDirective.prototype._commandParameter;
360
+ /**
361
+ * @type {?}
362
+ * @private
363
+ */
364
+ CommandDirective.prototype._commandParameterProvided;
308
365
  /**
309
366
  * @type {?}
310
367
  * @private
@@ -333,13 +390,17 @@ class FocusBindingDirective extends DisposableComponent {
333
390
  * @return {?}
334
391
  */
335
392
  onFocusIn() {
336
- this.pectinFocusBinding.focusCallbacks.notifyFocusIn();
393
+ if (this.hasBinding()) {
394
+ this.pectinFocusBinding.focusContext.notifyFocusIn();
395
+ }
337
396
  }
338
397
  /**
339
398
  * @return {?}
340
399
  */
341
400
  onFocusOut() {
342
- this.pectinFocusBinding.focusCallbacks.notifyFocusOut();
401
+ if (this.hasBinding()) {
402
+ this.pectinFocusBinding.focusContext.notifyFocusOut();
403
+ }
343
404
  }
344
405
  /**
345
406
  * @return {?}
@@ -351,16 +412,28 @@ class FocusBindingDirective extends DisposableComponent {
351
412
  */
352
413
  ngAfterViewInit() {
353
414
  // TODO: Make this also track the current enabled/disabled state.
354
- const { chain } = Dsl.disposeWith(this);
355
- chain.value(this.pectinFocusBinding.focused).subscribe((/**
356
- * @param {?} focused
357
- * @return {?}
358
- */
359
- (focused) => {
360
- if (focused && !this.alreadyHasFocus()) {
361
- this.tryAndFocus();
362
- }
363
- }));
415
+ if (this.hasBinding()) {
416
+ const { chain } = Dsl.disposeWith(this);
417
+ chain.value(this.pectinFocusBinding.focusContext.focused).subscribe((/**
418
+ * @param {?} focused
419
+ * @return {?}
420
+ */
421
+ (focused) => {
422
+ if (focused && !this.alreadyHasFocus()) {
423
+ this.tryAndFocus();
424
+ }
425
+ }));
426
+ }
427
+ else {
428
+ Logger.get(this).warn("pectinFocusBinding was nil");
429
+ }
430
+ }
431
+ /**
432
+ * @private
433
+ * @return {?}
434
+ */
435
+ hasBinding() {
436
+ return !!this.pectinFocusBinding && !!this.pectinFocusBinding.focusContext;
364
437
  }
365
438
  // Hook method for debugging via tracing.
366
439
  /**
@@ -416,7 +489,7 @@ class FocusBindingDirective extends DisposableComponent {
416
489
  * @return {?}
417
490
  */
418
491
  modelShouldStillHaveFocus() {
419
- return this.pectinFocusBinding.focused.value;
492
+ return this.hasBinding() && this.pectinFocusBinding.focusContext.focused.value;
420
493
  }
421
494
  // Hook method for debugging via tracing.
422
495
  /**
@@ -1150,6 +1223,7 @@ class DialogInteractionService extends InteractionContext {
1150
1223
  constructor(dialogService) {
1151
1224
  super();
1152
1225
  this.dialogService = dialogService;
1226
+ assert$1.notNil(dialogService);
1153
1227
  }
1154
1228
  /**
1155
1229
  * @template D, R, E
@@ -1290,7 +1364,7 @@ class BusyOverlayComponent {
1290
1364
  }
1291
1365
  BusyOverlayComponent.decorators = [
1292
1366
  { type: Component, args: [{
1293
- selector: 'aup-busy-overlay',
1367
+ selector: 'angular-ui-powerups-busy-overlay',
1294
1368
  template: "<ng-content></ng-content>\n<div class=\"busy-overlay-backdrop\" *ngIf=\"busyModel.value\">\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"52\"></mat-progress-spinner>\n</div>\n",
1295
1369
  styles: [":host{position:relative}div.busy-overlay-backdrop{position:absolute;background-color:rgba(0,0,0,.2);top:0;left:0;bottom:0;right:0;display:-ms-grid;display:grid;-ms-grid-columns:auto;grid-template-columns:auto;-ms-grid-rows:auto;grid-template-rows:auto;place-content:center}"]
1296
1370
  }] }
@@ -1302,7 +1376,7 @@ BusyOverlayComponent.propDecorators = {
1302
1376
  busy: [{ type: Input }]
1303
1377
  };
1304
1378
  __decorate([
1305
- UseDelegatingValueModel(),
1379
+ UseDelegate(),
1306
1380
  __metadata("design:type", ValueModel)
1307
1381
  ], BusyOverlayComponent.prototype, "busyModel", void 0);
1308
1382
  __decorate([
@@ -1343,6 +1417,36 @@ EmptyStateComponent.decorators = [
1343
1417
  /** @nocollapse */
1344
1418
  EmptyStateComponent.ctorParameters = () => [];
1345
1419
 
1420
+ /**
1421
+ * @fileoverview added by tsickle
1422
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1423
+ */
1424
+ class NavComponent {
1425
+ constructor() {
1426
+ }
1427
+ /**
1428
+ * @return {?}
1429
+ */
1430
+ ngOnInit() {
1431
+ }
1432
+ }
1433
+ NavComponent.decorators = [
1434
+ { type: Component, args: [{
1435
+ selector: 'angular-ui-powerups-nav',
1436
+ template: "<nav mat-tab-nav-bar>\n <a mat-tab-link *ngFor=\"let place of places\" [routerLink]='place.path'\n routerLinkActive #rla=\"routerLinkActive\"\n [active]=\"rla.isActive\"\n [matTooltip]=\"place.title\">{{place.title}}</a>\n</nav>\n\n",
1437
+ styles: [""]
1438
+ }] }
1439
+ ];
1440
+ /** @nocollapse */
1441
+ NavComponent.ctorParameters = () => [];
1442
+ NavComponent.propDecorators = {
1443
+ places: [{ type: Input }]
1444
+ };
1445
+ if (false) {
1446
+ /** @type {?} */
1447
+ NavComponent.prototype.places;
1448
+ }
1449
+
1346
1450
  /**
1347
1451
  * @fileoverview added by tsickle
1348
1452
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
@@ -1460,19 +1564,25 @@ PlaceModule.decorators = [
1460
1564
  { type: NgModule, args: [{
1461
1565
  imports: [
1462
1566
  CommonModule,
1567
+ BrowserAnimationsModule,
1463
1568
  MatProgressSpinnerModule,
1464
- RouterModule
1569
+ RouterModule,
1570
+ MatTabsModule$1,
1571
+ MatListModule,
1572
+ MatTooltipModule
1465
1573
  ],
1466
1574
  declarations: [
1467
1575
  EmptyStateComponent,
1468
1576
  BusyOverlayComponent,
1469
- PlaceOutletComponent
1577
+ PlaceOutletComponent,
1578
+ NavComponent
1470
1579
  ],
1471
1580
  entryComponents: [BusyOverlayComponent],
1472
1581
  exports: [
1473
1582
  BusyOverlayComponent,
1474
1583
  PlaceOutletComponent,
1475
- EmptyStateComponent
1584
+ EmptyStateComponent,
1585
+ NavComponent
1476
1586
  ],
1477
1587
  providers: [
1478
1588
  PlaceService
@@ -1537,6 +1647,7 @@ const defaultHiddenStyleDef = style({
1537
1647
  * @return {?}
1538
1648
  */
1539
1649
  function slideDownAndUpAnimation(triggerName, options) {
1650
+ // SEE to fix this: https://github.com/angular/angular/issues/15587#issuecomment-351510501
1540
1651
  /** @type {?} */
1541
1652
  const duration = OptionsHelper.get(options).getOptional('duration', '100ms');
1542
1653
  /** @type {?} */
@@ -1931,7 +2042,7 @@ function Place(options) {
1931
2042
  function ResolvedParameter() { }
1932
2043
  if (false) {
1933
2044
  /** @type {?} */
1934
- ResolvedParameter.prototype.parameter;
2045
+ ResolvedParameter.prototype.parameterDef;
1935
2046
  /** @type {?} */
1936
2047
  ResolvedParameter.prototype.resolvedValue;
1937
2048
  }
@@ -1953,7 +2064,7 @@ class ResolvedParameters {
1953
2064
  * @param {?} p
1954
2065
  * @return {?}
1955
2066
  */
1956
- p => p.parameter === parameter));
2067
+ p => p.parameterDef === parameter));
1957
2068
  return resolved ? resolved.resolvedValue : null;
1958
2069
  }
1959
2070
  /**
@@ -1967,8 +2078,8 @@ class ResolvedParameters {
1967
2078
  * @param {?} p
1968
2079
  * @return {?}
1969
2080
  */
1970
- p => p.parameter !== parameter)).concat({
1971
- parameter,
2081
+ p => p.parameterDef !== parameter)).concat({
2082
+ parameterDef: parameter,
1972
2083
  resolvedValue: value
1973
2084
  }));
1974
2085
  }
@@ -1979,7 +2090,7 @@ class ResolvedParameters {
1979
2090
  getFormattedRouteId() {
1980
2091
  /** @type {?} */
1981
2092
  const routeIdParam = this.getRouteIdParam();
1982
- return routeIdParam ? routeIdParam.parameter.type.format(routeIdParam.resolvedValue) : null;
2093
+ return routeIdParam ? routeIdParam.parameterDef.type.format(routeIdParam.resolvedValue) : null;
1983
2094
  }
1984
2095
  /**
1985
2096
  * @private
@@ -1990,7 +2101,7 @@ class ResolvedParameters {
1990
2101
  * @param {?} p
1991
2102
  * @return {?}
1992
2103
  */
1993
- p => p.parameter.isRouteId));
2104
+ p => p.parameterDef.isRouteId));
1994
2105
  }
1995
2106
  /**
1996
2107
  * @protected
@@ -2004,12 +2115,12 @@ class ResolvedParameters {
2004
2115
  * @param {?} p
2005
2116
  * @return {?}
2006
2117
  */
2007
- p => !p.parameter.isRouteId)).forEach((/**
2118
+ p => !p.parameterDef.isRouteId)).forEach((/**
2008
2119
  * @param {?} p
2009
2120
  * @return {?}
2010
2121
  */
2011
2122
  p => {
2012
- params[p.parameter.name] = p.parameter.type.format(p.resolvedValue);
2123
+ params[p.parameterDef.name] = p.parameterDef.type.format(p.resolvedValue);
2013
2124
  }));
2014
2125
  return params;
2015
2126
  }
@@ -2033,7 +2144,7 @@ class ResolvedParameters {
2033
2144
  /** @type {?} */
2034
2145
  const path = routeId ? [relativePath, routeId, this.getFormattedParameters()] : [relativePath, this.getFormattedParameters()];
2035
2146
  router.navigate(path, {
2036
- relativeTo: activatedRoute,
2147
+ relativeTo: activatedRoute
2037
2148
  });
2038
2149
  }
2039
2150
  }
@@ -2093,11 +2204,23 @@ class RouteParameterBindings extends GarbageCollector {
2093
2204
  /** @type {?} */
2094
2205
  const result = [];
2095
2206
  routeParameterDefs.forEach((/**
2096
- * @param {?} parameter
2207
+ * @param {?} parameterDef
2097
2208
  * @return {?}
2098
2209
  */
2099
- parameter => {
2100
- result.push({ parameter, resolvedValue: parameter.type.parse(params.get(parameter.name)) });
2210
+ parameterDef => {
2211
+ /** @type {?} */
2212
+ let resolvedValue;
2213
+ if (parameterDef.isArray) {
2214
+ resolvedValue = params.getAll(parameterDef.name).map((/**
2215
+ * @param {?} v
2216
+ * @return {?}
2217
+ */
2218
+ v => parameterDef.type.parse(v)));
2219
+ }
2220
+ else {
2221
+ resolvedValue = parameterDef.type.parse(params.get(parameterDef.name));
2222
+ }
2223
+ result.push({ parameterDef: parameterDef, resolvedValue: resolvedValue });
2101
2224
  }));
2102
2225
  return new ResolvedParameters(result);
2103
2226
  }));
@@ -2320,70 +2443,147 @@ if (false) {
2320
2443
  * @fileoverview added by tsickle
2321
2444
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2322
2445
  */
2446
+ /**
2447
+ * @abstract
2448
+ * @template T, S
2449
+ */
2450
+ class Sanitiser {
2451
+ /**
2452
+ * @param {?} parameterDef
2453
+ * @param {?} snapshot
2454
+ * @param {?} sanitiser
2455
+ */
2456
+ constructor(parameterDef, snapshot, sanitiser) {
2457
+ this.parameterDef = parameterDef;
2458
+ this.snapshot = snapshot;
2459
+ this.sanitiser = sanitiser;
2460
+ }
2461
+ /**
2462
+ * @return {?}
2463
+ */
2464
+ isRouteId() {
2465
+ return this.parameterDef.isRouteId;
2466
+ }
2467
+ /**
2468
+ * @return {?}
2469
+ */
2470
+ get valueChanged() {
2471
+ return !isNil(this.initialValue) && this.hasChanged(this.initialValue, this.sanitisedValue);
2472
+ }
2473
+ /**
2474
+ * @return {?}
2475
+ */
2476
+ get sanitisedValue() {
2477
+ return this._sanitisedValue;
2478
+ }
2479
+ /**
2480
+ * @return {?}
2481
+ */
2482
+ sanitize() {
2483
+ return __awaiter(this, void 0, void 0, function* () {
2484
+ if (this.sanitiser) {
2485
+ this.initialValue = this.readFrom(this.snapshot);
2486
+ this._sanitisedValue = yield this.sanitiser.sanitise(this.initialValue);
2487
+ if (this.initialValue !== this._sanitisedValue) {
2488
+ return false;
2489
+ }
2490
+ }
2491
+ return true;
2492
+ });
2493
+ }
2494
+ }
2495
+ if (false) {
2496
+ /**
2497
+ * @type {?}
2498
+ * @private
2499
+ */
2500
+ Sanitiser.prototype.initialValue;
2501
+ /**
2502
+ * @type {?}
2503
+ * @private
2504
+ */
2505
+ Sanitiser.prototype._sanitisedValue;
2506
+ /** @type {?} */
2507
+ Sanitiser.prototype.parameterDef;
2508
+ /** @type {?} */
2509
+ Sanitiser.prototype.snapshot;
2510
+ /** @type {?} */
2511
+ Sanitiser.prototype.sanitiser;
2512
+ /**
2513
+ * @abstract
2514
+ * @protected
2515
+ * @param {?} snapshot
2516
+ * @return {?}
2517
+ */
2518
+ Sanitiser.prototype.readFrom = function (snapshot) { };
2519
+ /**
2520
+ * @abstract
2521
+ * @protected
2522
+ * @param {?} initialValue
2523
+ * @param {?} sanitisedValue
2524
+ * @return {?}
2525
+ */
2526
+ Sanitiser.prototype.hasChanged = function (initialValue, sanitisedValue) { };
2527
+ /**
2528
+ * @abstract
2529
+ * @param {?} dest
2530
+ * @return {?}
2531
+ */
2532
+ Sanitiser.prototype.injectRouteParam = function (dest) { };
2533
+ }
2323
2534
  class RouteParameterSanitiser {
2324
2535
  /**
2325
2536
  * @param {?} parameterDefs
2537
+ * @param {?} snapshot
2326
2538
  * @param {?} injector
2327
2539
  */
2328
- constructor(parameterDefs, injector) {
2540
+ constructor(parameterDefs, snapshot, injector) {
2329
2541
  this.parameterDefs = parameterDefs;
2542
+ this.snapshot = snapshot;
2330
2543
  this.injector = injector;
2331
- this.sanitisedParameters = [];
2332
- this.routeParameter = parameterDefs.find((/**
2544
+ this.parameterSanitisers = [];
2545
+ /** @type {?} */
2546
+ const sanitisers = parameterDefs.map((/**
2547
+ * @param {?} def
2548
+ * @return {?}
2549
+ */
2550
+ def => {
2551
+ return def.isArray ?
2552
+ new Sanitiser.Array(def, snapshot, this.getSanitiser(def)) :
2553
+ new Sanitiser.Value(def, snapshot, this.getSanitiser(def));
2554
+ }));
2555
+ this.routeIdSanitiser = sanitisers.find((/**
2333
2556
  * @param {?} p
2334
2557
  * @return {?}
2335
2558
  */
2336
- p => p.isRouteId));
2337
- this.queryParameters = parameterDefs.filter((/**
2559
+ p => p.isRouteId()));
2560
+ this.parameterSanitisers = sanitisers.filter((/**
2338
2561
  * @param {?} p
2339
2562
  * @return {?}
2340
2563
  */
2341
- p => !p.isRouteId));
2564
+ p => !p.isRouteId()));
2342
2565
  }
2343
2566
  /**
2344
- * @param {?} snapshot
2345
2567
  * @return {?}
2346
2568
  */
2347
- sanitise(snapshot) {
2569
+ sanitise() {
2348
2570
  return __awaiter(this, void 0, void 0, function* () {
2349
- if (this.routeParameter) {
2350
- /** @type {?} */
2351
- const routeOk = yield this.sanitiseParameter(this.routeParameter, snapshot.paramMap.get(this.routeParameter.name));
2352
- if (!routeOk) {
2571
+ if (this.routeIdSanitiser) {
2572
+ yield this.routeIdSanitiser.sanitize();
2573
+ if (this.routeIdSanitiser.valueChanged) {
2353
2574
  // if the route id isn't ok we redirect immediately as the query params may need to be sanitised in the
2354
2575
  // context of the route id.
2355
2576
  return false;
2356
2577
  }
2357
2578
  }
2358
- for (const param of this.queryParameters) {
2359
- yield this.sanitiseParameter(param, snapshot.queryParamMap.get(param.name));
2579
+ for (const sanitiser of this.parameterSanitisers) {
2580
+ yield sanitiser.sanitize();
2360
2581
  }
2361
- return this.sanitisedParameters.length === 0;
2362
- });
2363
- }
2364
- /**
2365
- * @template T
2366
- * @param {?} def
2367
- * @param {?} formattedInitialValue
2368
- * @return {?}
2369
- */
2370
- sanitiseParameter(def, formattedInitialValue) {
2371
- return __awaiter(this, void 0, void 0, function* () {
2372
- if (def) {
2373
- /** @type {?} */
2374
- const sanitiser = this.getSanitiser(def);
2375
- if (sanitiser) {
2376
- /** @type {?} */
2377
- const initialValue = def.type.parse(formattedInitialValue);
2378
- /** @type {?} */
2379
- const sanitisedValue = yield sanitiser.sanitise(initialValue);
2380
- if (initialValue !== sanitisedValue) {
2381
- this.sanitisedParameters.push({ def, value: def.type.format(sanitisedValue) });
2382
- return false;
2383
- }
2384
- }
2385
- }
2386
- return true;
2582
+ return !this.parameterSanitisers.find((/**
2583
+ * @param {?} s
2584
+ * @return {?}
2585
+ */
2586
+ s => s.valueChanged));
2387
2587
  });
2388
2588
  }
2389
2589
  /**
@@ -2391,35 +2591,24 @@ class RouteParameterSanitiser {
2391
2591
  * @return {?}
2392
2592
  */
2393
2593
  redirect(router) {
2394
- assert.isTruthy(this.sanitisedParameters.length !== 0);
2395
- /** @type {?} */
2396
- const sanitisedRouteId = this.sanitisedParameters.find((/**
2397
- * @param {?} s
2398
- * @return {?}
2399
- */
2400
- s => s.def === this.routeParameter));
2401
- if (sanitisedRouteId) {
2402
- return router.navigate(['..', sanitisedRouteId.value]);
2594
+ assert.isTruthy(this.parameterSanitisers.length !== 0);
2595
+ if (this.routeIdSanitiser.valueChanged) {
2596
+ return router.navigate(['..', this.routeIdSanitiser.sanitisedValue]);
2403
2597
  }
2404
2598
  else {
2405
2599
  /** @type {?} */
2406
- const queryParams = this.sanitisedParameters.filter((/**
2600
+ const routeParams = {};
2601
+ this.parameterSanitisers.forEach((/**
2407
2602
  * @param {?} s
2408
2603
  * @return {?}
2409
2604
  */
2410
- s => s.def !== this.routeParameter))
2411
- .reduce((/**
2412
- * @param {?} params
2413
- * @param {?} item
2414
- * @return {?}
2415
- */
2416
- (params, item) => (Object.assign({}, params, { [item.def.name]: item.value }))), {});
2417
- return router.navigate(['.', queryParams]);
2605
+ s => s.injectRouteParam(routeParams)));
2606
+ return router.navigate(['.', routeParams]);
2418
2607
  }
2419
2608
  }
2420
2609
  /**
2421
2610
  * @private
2422
- * @template T
2611
+ * @template T, S
2423
2612
  * @param {?} def
2424
2613
  * @return {?}
2425
2614
  */
@@ -2427,12 +2616,6 @@ class RouteParameterSanitiser {
2427
2616
  return def.sanitiser ? this.injector.get(def.sanitiser, new def.sanitiser()) : null;
2428
2617
  }
2429
2618
  }
2430
- __decorate([
2431
- Trace(),
2432
- __metadata("design:type", Function),
2433
- __metadata("design:paramtypes", [Object, String]),
2434
- __metadata("design:returntype", Promise)
2435
- ], RouteParameterSanitiser.prototype, "sanitiseParameter", null);
2436
2619
  __decorate([
2437
2620
  Memoize$1(),
2438
2621
  __metadata("design:type", Function),
@@ -2444,22 +2627,93 @@ if (false) {
2444
2627
  * @type {?}
2445
2628
  * @private
2446
2629
  */
2447
- RouteParameterSanitiser.prototype.routeParameter;
2448
- /**
2449
- * @type {?}
2450
- * @private
2451
- */
2452
- RouteParameterSanitiser.prototype.queryParameters;
2630
+ RouteParameterSanitiser.prototype.routeIdSanitiser;
2453
2631
  /**
2454
2632
  * @type {?}
2455
2633
  * @private
2456
2634
  */
2457
- RouteParameterSanitiser.prototype.sanitisedParameters;
2635
+ RouteParameterSanitiser.prototype.parameterSanitisers;
2458
2636
  /** @type {?} */
2459
2637
  RouteParameterSanitiser.prototype.parameterDefs;
2460
2638
  /** @type {?} */
2639
+ RouteParameterSanitiser.prototype.snapshot;
2640
+ /** @type {?} */
2461
2641
  RouteParameterSanitiser.prototype.injector;
2462
2642
  }
2643
+ (function (Sanitiser) {
2644
+ /**
2645
+ * @template T
2646
+ */
2647
+ class Value extends Sanitiser {
2648
+ /**
2649
+ * @param {?} snapshot
2650
+ * @return {?}
2651
+ */
2652
+ readFrom(snapshot) {
2653
+ /** @type {?} */
2654
+ const rawValue = this.parameterDef.isRouteId ?
2655
+ snapshot.paramMap.get(this.parameterDef.name) :
2656
+ snapshot.queryParamMap.get(this.parameterDef.name);
2657
+ return this.parameterDef.type.parse(rawValue);
2658
+ }
2659
+ /**
2660
+ * @protected
2661
+ * @param {?} initialValue
2662
+ * @param {?} sanitisedValue
2663
+ * @return {?}
2664
+ */
2665
+ hasChanged(initialValue, sanitisedValue) {
2666
+ return initialValue !== sanitisedValue;
2667
+ }
2668
+ /**
2669
+ * @param {?} dest
2670
+ * @return {?}
2671
+ */
2672
+ injectRouteParam(dest) {
2673
+ dest[this.parameterDef.name] = this.parameterDef.type.format(this.sanitisedValue);
2674
+ }
2675
+ }
2676
+ Sanitiser.Value = Value;
2677
+ /**
2678
+ * @template T
2679
+ */
2680
+ class Array extends Sanitiser {
2681
+ /**
2682
+ * @param {?} snapshot
2683
+ * @return {?}
2684
+ */
2685
+ readFrom(snapshot) {
2686
+ /** @type {?} */
2687
+ const rawValues = snapshot.queryParamMap.getAll(this.parameterDef.name);
2688
+ return rawValues.map((/**
2689
+ * @param {?} value
2690
+ * @return {?}
2691
+ */
2692
+ value => this.parameterDef.type.parse(value)));
2693
+ }
2694
+ /**
2695
+ * @protected
2696
+ * @param {?} initialValue
2697
+ * @param {?} sanitisedValue
2698
+ * @return {?}
2699
+ */
2700
+ hasChanged(initialValue, sanitisedValue) {
2701
+ return initialValue !== sanitisedValue;
2702
+ }
2703
+ /**
2704
+ * @param {?} dest
2705
+ * @return {?}
2706
+ */
2707
+ injectRouteParam(dest) {
2708
+ dest[this.parameterDef.name] = this.sanitisedValue.map((/**
2709
+ * @param {?} v
2710
+ * @return {?}
2711
+ */
2712
+ v => this.parameterDef.type.format(v)));
2713
+ }
2714
+ }
2715
+ Sanitiser.Array = Array;
2716
+ })(Sanitiser || (Sanitiser = {}));
2463
2717
 
2464
2718
  /**
2465
2719
  * @fileoverview added by tsickle
@@ -2483,8 +2737,8 @@ class PlaceRouteGuard {
2483
2737
  /** @type {?} */
2484
2738
  const routeParameters = Klass.get(route.component).getMetadataList(RouteParameterBindings.ROUTE_PARAMETER_LIST_KEY);
2485
2739
  /** @type {?} */
2486
- const sanitiser = new RouteParameterSanitiser(routeParameters, this.injector);
2487
- return sanitiser.sanitise(route).then((/**
2740
+ const sanitiser = new RouteParameterSanitiser(routeParameters, route, this.injector);
2741
+ return sanitiser.sanitise().then((/**
2488
2742
  * @param {?} proceed
2489
2743
  * @return {?}
2490
2744
  */
@@ -2554,6 +2808,17 @@ if (false) {
2554
2808
  /** @type {?|undefined} */
2555
2809
  ParameterOptions.prototype.sanitiser;
2556
2810
  }
2811
+ /**
2812
+ * @record
2813
+ * @template T
2814
+ */
2815
+ function ListParameterOptions() { }
2816
+ if (false) {
2817
+ /** @type {?|undefined} */
2818
+ ListParameterOptions.prototype.as;
2819
+ /** @type {?|undefined} */
2820
+ ListParameterOptions.prototype.listSanitiser;
2821
+ }
2557
2822
  /**
2558
2823
  * @template T
2559
2824
  * @param {?} type
@@ -2575,12 +2840,32 @@ function RouteId(type, options) {
2575
2840
  });
2576
2841
  }
2577
2842
  /**
2843
+ * @deprecated use RouteParameter instead.
2578
2844
  * @template T
2579
2845
  * @param {?} type
2580
2846
  * @param {?=} options
2581
2847
  * @return {?}
2582
2848
  */
2583
2849
  function QueryParameter(type, options) {
2850
+ return (/**
2851
+ * @param {?} prototype
2852
+ * @param {?} propertyKey
2853
+ * @return {?}
2854
+ */
2855
+ (prototype, propertyKey) => {
2856
+ /** @type {?} */
2857
+ const param = createDefinition(propertyKey, type, options, false);
2858
+ Klass.get(prototype).addToOwnMetadataList(RouteParameterBindings.ROUTE_PARAMETER_LIST_KEY, param);
2859
+ UseDelegate()(prototype, propertyKey);
2860
+ });
2861
+ }
2862
+ /**
2863
+ * @template T
2864
+ * @param {?} type
2865
+ * @param {?=} options
2866
+ * @return {?}
2867
+ */
2868
+ function RouteParameter(type, options) {
2584
2869
  // assert.isTruthy(type.isValid());
2585
2870
  return (/**
2586
2871
  * @param {?} prototype
@@ -2594,6 +2879,47 @@ function QueryParameter(type, options) {
2594
2879
  UseDelegate()(prototype, propertyKey);
2595
2880
  });
2596
2881
  }
2882
+ /**
2883
+ * @deprecated use RouteParameterList instead
2884
+ * @template E
2885
+ * @param {?} elementType
2886
+ * @param {?=} options
2887
+ * @return {?}
2888
+ */
2889
+ function QueryParameterList(elementType, options) {
2890
+ // assert.isTruthy(type.isValid());
2891
+ return (/**
2892
+ * @param {?} prototype
2893
+ * @param {?} propertyKey
2894
+ * @return {?}
2895
+ */
2896
+ (prototype, propertyKey) => {
2897
+ /** @type {?} */
2898
+ const param = createArrayDefinition(propertyKey, elementType, options);
2899
+ Klass.get(prototype).addToOwnMetadataList(RouteParameterBindings.ROUTE_PARAMETER_LIST_KEY, param);
2900
+ UseDelegate()(prototype, propertyKey);
2901
+ });
2902
+ }
2903
+ /**
2904
+ * @template E
2905
+ * @param {?} elementType
2906
+ * @param {?=} options
2907
+ * @return {?}
2908
+ */
2909
+ function RouteParameterList(elementType, options) {
2910
+ // assert.isTruthy(type.isValid());
2911
+ return (/**
2912
+ * @param {?} prototype
2913
+ * @param {?} propertyKey
2914
+ * @return {?}
2915
+ */
2916
+ (prototype, propertyKey) => {
2917
+ /** @type {?} */
2918
+ const param = createArrayDefinition(propertyKey, elementType, options);
2919
+ Klass.get(prototype).addToOwnMetadataList(RouteParameterBindings.ROUTE_PARAMETER_LIST_KEY, param);
2920
+ UseDelegate()(prototype, propertyKey);
2921
+ });
2922
+ }
2597
2923
  /**
2598
2924
  * @template T
2599
2925
  * @param {?} propertyName
@@ -2613,7 +2939,31 @@ function createDefinition(propertyName, type, options, routeId) {
2613
2939
  propertyName: propertyNameAsString,
2614
2940
  type: assert.notNil(type),
2615
2941
  sanitiser: opts.getOptional('sanitiser', null),
2616
- isRouteId: routeId
2942
+ isRouteId: routeId,
2943
+ isArray: false
2944
+ };
2945
+ return def;
2946
+ }
2947
+ /**
2948
+ * @template T
2949
+ * @param {?} propertyName
2950
+ * @param {?} type
2951
+ * @param {?} options
2952
+ * @return {?}
2953
+ */
2954
+ function createArrayDefinition(propertyName, type, options) {
2955
+ /** @type {?} */
2956
+ const opts = Opts.get(options);
2957
+ /** @type {?} */
2958
+ const propertyNameAsString = assert.notNil(propertyName).toString();
2959
+ /** @type {?} */
2960
+ const def = {
2961
+ name: opts.getOptional('as', propertyNameAsString),
2962
+ propertyName: propertyNameAsString,
2963
+ type: assert.notNil(type),
2964
+ sanitiser: opts.getOptional('listSanitiser', null),
2965
+ isRouteId: false,
2966
+ isArray: true
2617
2967
  };
2618
2968
  return def;
2619
2969
  }
@@ -2624,7 +2974,7 @@ function createDefinition(propertyName, type, options, routeId) {
2624
2974
  */
2625
2975
  /**
2626
2976
  * @record
2627
- * @template T
2977
+ * @template E, S
2628
2978
  */
2629
2979
  function ParameterDefinition() { }
2630
2980
  if (false) {
@@ -2638,6 +2988,8 @@ if (false) {
2638
2988
  ParameterDefinition.prototype.sanitiser;
2639
2989
  /** @type {?} */
2640
2990
  ParameterDefinition.prototype.isRouteId;
2991
+ /** @type {?} */
2992
+ ParameterDefinition.prototype.isArray;
2641
2993
  }
2642
2994
 
2643
2995
  /**
@@ -2720,5 +3072,5 @@ var ParameterType;
2720
3072
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2721
3073
  */
2722
3074
 
2723
- export { ACTIVITY_DATA, AbstractActivity, AbstractInputComponent, AbstractPlaceComponent, ActivityContainerComponent, ActivityOutletComponent, AlertDialogComponent, AngularUiPowerupsModule, Bounds, BusyOverlayComponent, CommandDirective, ConfirmationDialogComponent, DialogInteractionService, Dimension, DisposableComponent, EmptyStateComponent, FocusBindingDirective, INTERACTION_CONTEXT, InteractionContext, InteractionModule, LeavePlaceGuard, NumberInputComponent, ParameterType, PasswordInputComponent, Place, PlaceModule, PlaceOutletComponent, PlaceRouteGuard, PlaceService, Point, QueryParameter, ResizeAwareComponent, RouteId, RouteParameterBindings, RouteParameterSanitiser, SelectInputComponent, StringInputComponent, slideDownAndUpAnimation, CommandDirective as ɵa, FocusBindingDirective as ɵb, DisposableComponent as ɵc, NumberInputComponent as ɵd, AbstractInputComponent as ɵe, StringInputComponent as ɵf, PasswordInputComponent as ɵg, SelectInputComponent as ɵh, PlaceModule as ɵi, EmptyStateComponent as ɵj, BusyOverlayComponent as ɵk, PlaceOutletComponent as ɵl, PlaceService as ɵm, InteractionModule as ɵn, ActivityContainerComponent as ɵo, ConfirmationDialogComponent as ɵp, AbstractActivity as ɵq, ACTIVITY_DATA as ɵr, AlertDialogComponent as ɵt, ActivityOutletComponent as ɵv, DialogInteractionService as ɵw, InteractionContext as ɵx };
3075
+ export { ACTIVITY_DATA, AbstractActivity, AbstractInputComponent, AbstractPlaceComponent, ActivityContainerComponent, ActivityOutletComponent, AlertDialogComponent, AngularUiPowerupsModule, Bounds, BusyOverlayComponent, CommandDirective, ConfirmationDialogComponent, DialogInteractionService, Dimension, DisposableComponent, EmptyStateComponent, FocusBindingDirective, INTERACTION_CONTEXT, InteractionContext, InteractionModule, LeavePlaceGuard, NavComponent, NumberInputComponent, ParameterType, PasswordInputComponent, Place, PlaceModule, PlaceOutletComponent, PlaceRouteGuard, PlaceService, Point, QueryParameter, QueryParameterList, ResizeAwareComponent, RouteId, RouteParameter, RouteParameterBindings, RouteParameterList, RouteParameterSanitiser, Sanitiser, SelectInputComponent, StringInputComponent, slideDownAndUpAnimation, CommandDirective as ɵa, FocusBindingDirective as ɵb, DisposableComponent as ɵc, NumberInputComponent as ɵd, AbstractInputComponent as ɵe, StringInputComponent as ɵf, PasswordInputComponent as ɵg, SelectInputComponent as ɵh, PlaceModule as ɵi, EmptyStateComponent as ɵj, BusyOverlayComponent as ɵk, PlaceOutletComponent as ɵl, PlaceService as ɵm, NavComponent as ɵn, InteractionModule as ɵo, ActivityContainerComponent as ɵp, ConfirmationDialogComponent as ɵq, AbstractActivity as ɵr, ACTIVITY_DATA as ɵs, AlertDialogComponent as ɵu, ActivityOutletComponent as ɵw, DialogInteractionService as ɵx, InteractionContext as ɵy };
2724
3076
  //# sourceMappingURL=coolon-angular-ui-powerups.js.map