@coolon/angular-ui-powerups 0.0.7 → 0.0.9

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 (54) hide show
  1. package/bundles/coolon-angular-ui-powerups.umd.js +552 -159
  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/components/forms/abstract-input.component.js +8 -3
  10. package/esm2015/lib/directives/command.directive.js +48 -4
  11. package/esm2015/lib/directives/focus-binding.directive.js +30 -14
  12. package/esm2015/lib/interaction/components/alert-dialog/alert-dialog.component.js +1 -1
  13. package/esm2015/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.js +1 -1
  14. package/esm2015/lib/place/components/empty-state/empty-state.component.js +1 -1
  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 +77 -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/components/forms/abstract-input.component.js +8 -3
  27. package/esm5/lib/directives/command.directive.js +52 -4
  28. package/esm5/lib/directives/focus-binding.directive.js +34 -14
  29. package/esm5/lib/interaction/components/alert-dialog/alert-dialog.component.js +1 -1
  30. package/esm5/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.js +1 -1
  31. package/esm5/lib/place/components/empty-state/empty-state.component.js +1 -1
  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 +77 -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 +436 -112
  42. package/fesm2015/coolon-angular-ui-powerups.js.map +1 -1
  43. package/fesm5/coolon-angular-ui-powerups.js +521 -130
  44. package/fesm5/coolon-angular-ui-powerups.js.map +1 -1
  45. package/lib/components/forms/abstract-input.component.d.ts +7 -7
  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
  54. package/styles/styles.scss +15 -0
@@ -5,10 +5,13 @@ 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, MutableListModel, Constant, UseDelegate, MutableValueModel, assert, UnaryCommand, lang, Dsl, Logger, ListModel, StoreInListModel, EventListenerList, DelegatingValueModel, UseDelegatingValueModel, ValueModel, StoreInValueModel, Trace, OptionsHelper, ValueHolder, 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
11
  import { MatDialog as MatDialog$1 } from '@angular/material/dialog';
12
+ import { MatListModule } from '@angular/material/list';
13
+ import { MatTabsModule as MatTabsModule$1 } from '@angular/material/tabs';
14
+ import { MatTooltipModule } from '@angular/material/tooltip';
12
15
  import { RouterModule, Router, ActivatedRoute, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
13
16
  import { style, trigger, transition, animate } from '@angular/animations';
14
17
  import ResizeObserver from 'resize-observer-polyfill';
@@ -44,9 +47,14 @@ const EMPTY_ERRORS = new MutableListModel().readonly;
44
47
  class AbstractInputComponent extends DisposableComponent {
45
48
  constructor() {
46
49
  super();
50
+ // TODO: fix this.
51
+ // tslint:disable-next-line:no-output-native
47
52
  this.focus = new EventEmitter();
53
+ // tslint:disable-next-line:no-output-native
48
54
  this.blur = new EventEmitter();
55
+ // tslint:disable-next-line:no-output-native
49
56
  this.enterKey = new EventEmitter();
57
+ // tslint:disable-next-line:no-output-native
50
58
  this.escapeKey = new EventEmitter();
51
59
  /** @type {?} */
52
60
  const self = this;
@@ -101,7 +109,7 @@ class AbstractInputComponent extends DisposableComponent {
101
109
  * @return {?}
102
110
  */
103
111
  safelyInvoke(command) {
104
- if (command && command.isEnabled()) {
112
+ if (command && command.enabled.value) {
105
113
  command.execute();
106
114
  }
107
115
  }
@@ -227,6 +235,9 @@ NumberInputComponent.ctorParameters = () => [];
227
235
  * @fileoverview added by tsickle
228
236
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
229
237
  */
238
+ /**
239
+ * @template P
240
+ */
230
241
  class CommandDirective extends GarbageCollector {
231
242
  /**
232
243
  * @param {?} elementRef
@@ -234,12 +245,37 @@ class CommandDirective extends GarbageCollector {
234
245
  constructor(elementRef) {
235
246
  super();
236
247
  this.elementRef = elementRef;
248
+ this._commandParameterProvided = false;
249
+ }
250
+ /**
251
+ * @param {?} value
252
+ * @return {?}
253
+ */
254
+ set commandParameter(value) {
255
+ this._commandParameterProvided = true;
256
+ this._commandParameter = value;
257
+ }
258
+ /**
259
+ * @return {?}
260
+ */
261
+ get commandParameter() {
262
+ return this._commandParameter;
237
263
  }
238
264
  /**
239
265
  * @return {?}
240
266
  */
241
267
  ngOnInit() {
242
268
  assert.notNil(this.pectinCommand);
269
+ if (this.pectinCommand instanceof UnaryCommand) {
270
+ if (!this._commandParameterProvided) {
271
+ lang.illegalState('UnaryCommands required the command parameter to be specified.');
272
+ }
273
+ }
274
+ else {
275
+ if (this._commandParameterProvided) {
276
+ lang.illegalState('command parameters are only supported by UnaryCommands');
277
+ }
278
+ }
243
279
  }
244
280
  /**
245
281
  * @return {?}
@@ -280,8 +316,13 @@ class CommandDirective extends GarbageCollector {
280
316
  notifyClick($event) {
281
317
  $event.preventDefault();
282
318
  $event.stopPropagation();
283
- if (this.pectinCommand.isEnabled()) {
284
- this.pectinCommand.execute({ event: $event });
319
+ if (this.pectinCommand.enabled.value) {
320
+ if (this.pectinCommand instanceof UnaryCommand) {
321
+ this.pectinCommand.withContext({ event: $event }).execute(this.commandParameter);
322
+ }
323
+ else {
324
+ this.pectinCommand.withContext({ event: $event }).execute();
325
+ }
285
326
  }
286
327
  else {
287
328
  console.warn('disabled command clicked, ignoring.');
@@ -300,11 +341,22 @@ CommandDirective.ctorParameters = () => [
300
341
  ];
301
342
  CommandDirective.propDecorators = {
302
343
  pectinCommand: [{ type: Input }],
344
+ commandParameter: [{ type: Input }],
303
345
  notifyClick: [{ type: HostListener, args: ['click', ['$event'],] }]
304
346
  };
305
347
  if (false) {
306
348
  /** @type {?} */
307
349
  CommandDirective.prototype.pectinCommand;
350
+ /**
351
+ * @type {?}
352
+ * @private
353
+ */
354
+ CommandDirective.prototype._commandParameter;
355
+ /**
356
+ * @type {?}
357
+ * @private
358
+ */
359
+ CommandDirective.prototype._commandParameterProvided;
308
360
  /**
309
361
  * @type {?}
310
362
  * @private
@@ -333,13 +385,17 @@ class FocusBindingDirective extends DisposableComponent {
333
385
  * @return {?}
334
386
  */
335
387
  onFocusIn() {
336
- this.pectinFocusBinding.focusCallbacks.notifyFocusIn();
388
+ if (this.hasBinding()) {
389
+ this.pectinFocusBinding.focusCallbacks.notifyFocusIn();
390
+ }
337
391
  }
338
392
  /**
339
393
  * @return {?}
340
394
  */
341
395
  onFocusOut() {
342
- this.pectinFocusBinding.focusCallbacks.notifyFocusOut();
396
+ if (this.hasBinding()) {
397
+ this.pectinFocusBinding.focusCallbacks.notifyFocusOut();
398
+ }
343
399
  }
344
400
  /**
345
401
  * @return {?}
@@ -351,16 +407,28 @@ class FocusBindingDirective extends DisposableComponent {
351
407
  */
352
408
  ngAfterViewInit() {
353
409
  // 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
- }));
410
+ if (this.hasBinding()) {
411
+ const { chain } = Dsl.disposeWith(this);
412
+ chain.value(this.pectinFocusBinding.focused).subscribe((/**
413
+ * @param {?} focused
414
+ * @return {?}
415
+ */
416
+ (focused) => {
417
+ if (focused && !this.alreadyHasFocus()) {
418
+ this.tryAndFocus();
419
+ }
420
+ }));
421
+ }
422
+ else {
423
+ Logger.get(this).warn("pectinFocusBinding was nil");
424
+ }
425
+ }
426
+ /**
427
+ * @private
428
+ * @return {?}
429
+ */
430
+ hasBinding() {
431
+ return this.pectinFocusBinding && this.pectinFocusBinding.focused;
364
432
  }
365
433
  // Hook method for debugging via tracing.
366
434
  /**
@@ -416,7 +484,7 @@ class FocusBindingDirective extends DisposableComponent {
416
484
  * @return {?}
417
485
  */
418
486
  modelShouldStillHaveFocus() {
419
- return this.pectinFocusBinding.focused.value;
487
+ return this.hasBinding() && this.pectinFocusBinding.focused.value;
420
488
  }
421
489
  // Hook method for debugging via tracing.
422
490
  /**
@@ -784,7 +852,7 @@ AlertDialogComponent.decorators = [
784
852
  { type: Component, args: [{
785
853
  selector: 'angular-ui-powerups-alert-dialog',
786
854
  template: "<h3 matDialogTitle *ngIf=\"alert.title\">{{alert.title()}}</h3>\n<div matDialogContent>\n <p *ngFor=\"let line of alert.content()\">{{line}}</p>\n</div>\n<p matDialogActions>\n <button mat-raised-button color=\"primary\" (click)=\"done()\">{{alert.ok()}}</button>\n</p>\n",
787
- styles: [":host{display:block;padding:var(--default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
855
+ styles: [":host{display:block;padding:var(--angular-ui-powerups-default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
788
856
  }] }
789
857
  ];
790
858
  /** @nocollapse */
@@ -826,7 +894,7 @@ ConfirmationDialogComponent.decorators = [
826
894
  { type: Component, args: [{
827
895
  selector: 'angular-ui-powerups-confirmation-dialog',
828
896
  template: "<h3 matDialogTitle *ngIf=\"confirm.title\">{{confirm.title()}}</h3>\n<div matDialogContent>\n <p *ngFor=\"let line of confirm.content()\">{{line}}</p>\n</div>\n<p matDialogActions>\n <button mat-button (click)=\"cancel()\">{{confirm.cancel()}}</button>\n <button mat-raised-button [color]=\"isDestructive() ? 'warn' : 'primary'\" (click)=\"done(true)\">{{confirm.ok()}}</button>\n</p>\n\n",
829
- styles: [":host{display:block;padding:var(--default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
897
+ styles: [":host{display:block;padding:var(--angular-ui-powerups-default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
830
898
  }] }
831
899
  ];
832
900
  /** @nocollapse */
@@ -1337,12 +1405,42 @@ EmptyStateComponent.decorators = [
1337
1405
  <ng-content></ng-content>
1338
1406
  </div>
1339
1407
  `,
1340
- styles: [":host{display:flex;flex-direction:column;justify-content:center;align-items:center}.container{padding:var(--default-padding);border:2px dashed rgba(0,0,0,.2);border-radius:5px;font-size:14px;font-weight:300}"]
1408
+ styles: [":host{display:flex;flex-direction:column;justify-content:center;align-items:center}.container{padding:var(--angular-ui-powerups-default-padding);border:2px dashed rgba(0,0,0,.2);border-radius:5px;font-size:14px;font-weight:300}"]
1341
1409
  }] }
1342
1410
  ];
1343
1411
  /** @nocollapse */
1344
1412
  EmptyStateComponent.ctorParameters = () => [];
1345
1413
 
1414
+ /**
1415
+ * @fileoverview added by tsickle
1416
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1417
+ */
1418
+ class NavComponent {
1419
+ constructor() {
1420
+ }
1421
+ /**
1422
+ * @return {?}
1423
+ */
1424
+ ngOnInit() {
1425
+ }
1426
+ }
1427
+ NavComponent.decorators = [
1428
+ { type: Component, args: [{
1429
+ selector: 'angular-ui-powerups-nav',
1430
+ 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",
1431
+ styles: [""]
1432
+ }] }
1433
+ ];
1434
+ /** @nocollapse */
1435
+ NavComponent.ctorParameters = () => [];
1436
+ NavComponent.propDecorators = {
1437
+ places: [{ type: Input }]
1438
+ };
1439
+ if (false) {
1440
+ /** @type {?} */
1441
+ NavComponent.prototype.places;
1442
+ }
1443
+
1346
1444
  /**
1347
1445
  * @fileoverview added by tsickle
1348
1446
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
@@ -1460,19 +1558,25 @@ PlaceModule.decorators = [
1460
1558
  { type: NgModule, args: [{
1461
1559
  imports: [
1462
1560
  CommonModule,
1561
+ BrowserAnimationsModule,
1463
1562
  MatProgressSpinnerModule,
1464
- RouterModule
1563
+ RouterModule,
1564
+ MatTabsModule$1,
1565
+ MatListModule,
1566
+ MatTooltipModule
1465
1567
  ],
1466
1568
  declarations: [
1467
1569
  EmptyStateComponent,
1468
1570
  BusyOverlayComponent,
1469
- PlaceOutletComponent
1571
+ PlaceOutletComponent,
1572
+ NavComponent
1470
1573
  ],
1471
1574
  entryComponents: [BusyOverlayComponent],
1472
1575
  exports: [
1473
1576
  BusyOverlayComponent,
1474
1577
  PlaceOutletComponent,
1475
- EmptyStateComponent
1578
+ EmptyStateComponent,
1579
+ NavComponent
1476
1580
  ],
1477
1581
  providers: [
1478
1582
  PlaceService
@@ -1931,7 +2035,7 @@ function Place(options) {
1931
2035
  function ResolvedParameter() { }
1932
2036
  if (false) {
1933
2037
  /** @type {?} */
1934
- ResolvedParameter.prototype.parameter;
2038
+ ResolvedParameter.prototype.parameterDef;
1935
2039
  /** @type {?} */
1936
2040
  ResolvedParameter.prototype.resolvedValue;
1937
2041
  }
@@ -1953,7 +2057,7 @@ class ResolvedParameters {
1953
2057
  * @param {?} p
1954
2058
  * @return {?}
1955
2059
  */
1956
- p => p.parameter === parameter));
2060
+ p => p.parameterDef === parameter));
1957
2061
  return resolved ? resolved.resolvedValue : null;
1958
2062
  }
1959
2063
  /**
@@ -1967,8 +2071,8 @@ class ResolvedParameters {
1967
2071
  * @param {?} p
1968
2072
  * @return {?}
1969
2073
  */
1970
- p => p.parameter !== parameter)).concat({
1971
- parameter,
2074
+ p => p.parameterDef !== parameter)).concat({
2075
+ parameterDef: parameter,
1972
2076
  resolvedValue: value
1973
2077
  }));
1974
2078
  }
@@ -1979,7 +2083,7 @@ class ResolvedParameters {
1979
2083
  getFormattedRouteId() {
1980
2084
  /** @type {?} */
1981
2085
  const routeIdParam = this.getRouteIdParam();
1982
- return routeIdParam ? routeIdParam.parameter.type.format(routeIdParam.resolvedValue) : null;
2086
+ return routeIdParam ? routeIdParam.parameterDef.type.format(routeIdParam.resolvedValue) : null;
1983
2087
  }
1984
2088
  /**
1985
2089
  * @private
@@ -1990,7 +2094,7 @@ class ResolvedParameters {
1990
2094
  * @param {?} p
1991
2095
  * @return {?}
1992
2096
  */
1993
- p => p.parameter.isRouteId));
2097
+ p => p.parameterDef.isRouteId));
1994
2098
  }
1995
2099
  /**
1996
2100
  * @protected
@@ -2004,12 +2108,12 @@ class ResolvedParameters {
2004
2108
  * @param {?} p
2005
2109
  * @return {?}
2006
2110
  */
2007
- p => !p.parameter.isRouteId)).forEach((/**
2111
+ p => !p.parameterDef.isRouteId)).forEach((/**
2008
2112
  * @param {?} p
2009
2113
  * @return {?}
2010
2114
  */
2011
2115
  p => {
2012
- params[p.parameter.name] = p.parameter.type.format(p.resolvedValue);
2116
+ params[p.parameterDef.name] = p.parameterDef.type.format(p.resolvedValue);
2013
2117
  }));
2014
2118
  return params;
2015
2119
  }
@@ -2033,7 +2137,7 @@ class ResolvedParameters {
2033
2137
  /** @type {?} */
2034
2138
  const path = routeId ? [relativePath, routeId, this.getFormattedParameters()] : [relativePath, this.getFormattedParameters()];
2035
2139
  router.navigate(path, {
2036
- relativeTo: activatedRoute,
2140
+ relativeTo: activatedRoute
2037
2141
  });
2038
2142
  }
2039
2143
  }
@@ -2093,11 +2197,23 @@ class RouteParameterBindings extends GarbageCollector {
2093
2197
  /** @type {?} */
2094
2198
  const result = [];
2095
2199
  routeParameterDefs.forEach((/**
2096
- * @param {?} parameter
2200
+ * @param {?} parameterDef
2097
2201
  * @return {?}
2098
2202
  */
2099
- parameter => {
2100
- result.push({ parameter, resolvedValue: parameter.type.parse(params.get(parameter.name)) });
2203
+ parameterDef => {
2204
+ /** @type {?} */
2205
+ let resolvedValue;
2206
+ if (parameterDef.isArray) {
2207
+ resolvedValue = params.getAll(parameterDef.name).map((/**
2208
+ * @param {?} v
2209
+ * @return {?}
2210
+ */
2211
+ v => parameterDef.type.parse(v)));
2212
+ }
2213
+ else {
2214
+ resolvedValue = parameterDef.type.parse(params.get(parameterDef.name));
2215
+ }
2216
+ result.push({ parameterDef: parameterDef, resolvedValue: resolvedValue });
2101
2217
  }));
2102
2218
  return new ResolvedParameters(result);
2103
2219
  }));
@@ -2320,70 +2436,147 @@ if (false) {
2320
2436
  * @fileoverview added by tsickle
2321
2437
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2322
2438
  */
2439
+ /**
2440
+ * @abstract
2441
+ * @template T, S
2442
+ */
2443
+ class Sanitiser {
2444
+ /**
2445
+ * @param {?} parameterDef
2446
+ * @param {?} snapshot
2447
+ * @param {?} sanitiser
2448
+ */
2449
+ constructor(parameterDef, snapshot, sanitiser) {
2450
+ this.parameterDef = parameterDef;
2451
+ this.snapshot = snapshot;
2452
+ this.sanitiser = sanitiser;
2453
+ }
2454
+ /**
2455
+ * @return {?}
2456
+ */
2457
+ isRouteId() {
2458
+ return this.parameterDef.isRouteId;
2459
+ }
2460
+ /**
2461
+ * @return {?}
2462
+ */
2463
+ get valueChanged() {
2464
+ return !isNil(this.initialValue) && this.hasChanged(this.initialValue, this.sanitisedValue);
2465
+ }
2466
+ /**
2467
+ * @return {?}
2468
+ */
2469
+ get sanitisedValue() {
2470
+ return this._sanitisedValue;
2471
+ }
2472
+ /**
2473
+ * @return {?}
2474
+ */
2475
+ sanitize() {
2476
+ return __awaiter(this, void 0, void 0, function* () {
2477
+ if (this.sanitiser) {
2478
+ this.initialValue = this.readFrom(this.snapshot);
2479
+ this._sanitisedValue = yield this.sanitiser.sanitise(this.initialValue);
2480
+ if (this.initialValue !== this._sanitisedValue) {
2481
+ return false;
2482
+ }
2483
+ }
2484
+ return true;
2485
+ });
2486
+ }
2487
+ }
2488
+ if (false) {
2489
+ /**
2490
+ * @type {?}
2491
+ * @private
2492
+ */
2493
+ Sanitiser.prototype.initialValue;
2494
+ /**
2495
+ * @type {?}
2496
+ * @private
2497
+ */
2498
+ Sanitiser.prototype._sanitisedValue;
2499
+ /** @type {?} */
2500
+ Sanitiser.prototype.parameterDef;
2501
+ /** @type {?} */
2502
+ Sanitiser.prototype.snapshot;
2503
+ /** @type {?} */
2504
+ Sanitiser.prototype.sanitiser;
2505
+ /**
2506
+ * @abstract
2507
+ * @protected
2508
+ * @param {?} snapshot
2509
+ * @return {?}
2510
+ */
2511
+ Sanitiser.prototype.readFrom = function (snapshot) { };
2512
+ /**
2513
+ * @abstract
2514
+ * @protected
2515
+ * @param {?} initialValue
2516
+ * @param {?} sanitisedValue
2517
+ * @return {?}
2518
+ */
2519
+ Sanitiser.prototype.hasChanged = function (initialValue, sanitisedValue) { };
2520
+ /**
2521
+ * @abstract
2522
+ * @param {?} dest
2523
+ * @return {?}
2524
+ */
2525
+ Sanitiser.prototype.injectRouteParam = function (dest) { };
2526
+ }
2323
2527
  class RouteParameterSanitiser {
2324
2528
  /**
2325
2529
  * @param {?} parameterDefs
2530
+ * @param {?} snapshot
2326
2531
  * @param {?} injector
2327
2532
  */
2328
- constructor(parameterDefs, injector) {
2533
+ constructor(parameterDefs, snapshot, injector) {
2329
2534
  this.parameterDefs = parameterDefs;
2535
+ this.snapshot = snapshot;
2330
2536
  this.injector = injector;
2331
- this.sanitisedParameters = [];
2332
- this.routeParameter = parameterDefs.find((/**
2537
+ this.parameterSanitisers = [];
2538
+ /** @type {?} */
2539
+ const sanitisers = parameterDefs.map((/**
2540
+ * @param {?} def
2541
+ * @return {?}
2542
+ */
2543
+ def => {
2544
+ return def.isArray ?
2545
+ new Sanitiser.Array(def, snapshot, this.getSanitiser(def)) :
2546
+ new Sanitiser.Value(def, snapshot, this.getSanitiser(def));
2547
+ }));
2548
+ this.routeIdSanitiser = sanitisers.find((/**
2333
2549
  * @param {?} p
2334
2550
  * @return {?}
2335
2551
  */
2336
- p => p.isRouteId));
2337
- this.queryParameters = parameterDefs.filter((/**
2552
+ p => p.isRouteId()));
2553
+ this.parameterSanitisers = sanitisers.filter((/**
2338
2554
  * @param {?} p
2339
2555
  * @return {?}
2340
2556
  */
2341
- p => !p.isRouteId));
2557
+ p => !p.isRouteId()));
2342
2558
  }
2343
2559
  /**
2344
- * @param {?} snapshot
2345
2560
  * @return {?}
2346
2561
  */
2347
- sanitise(snapshot) {
2562
+ sanitise() {
2348
2563
  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) {
2564
+ if (this.routeIdSanitiser) {
2565
+ yield this.routeIdSanitiser.sanitize();
2566
+ if (this.routeIdSanitiser.valueChanged) {
2353
2567
  // if the route id isn't ok we redirect immediately as the query params may need to be sanitised in the
2354
2568
  // context of the route id.
2355
2569
  return false;
2356
2570
  }
2357
2571
  }
2358
- for (const param of this.queryParameters) {
2359
- yield this.sanitiseParameter(param, snapshot.queryParamMap.get(param.name));
2360
- }
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
- }
2572
+ for (const sanitiser of this.parameterSanitisers) {
2573
+ yield sanitiser.sanitize();
2385
2574
  }
2386
- return true;
2575
+ return !this.parameterSanitisers.find((/**
2576
+ * @param {?} s
2577
+ * @return {?}
2578
+ */
2579
+ s => s.valueChanged));
2387
2580
  });
2388
2581
  }
2389
2582
  /**
@@ -2391,35 +2584,24 @@ class RouteParameterSanitiser {
2391
2584
  * @return {?}
2392
2585
  */
2393
2586
  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]);
2587
+ assert.isTruthy(this.parameterSanitisers.length !== 0);
2588
+ if (this.routeIdSanitiser.valueChanged) {
2589
+ return router.navigate(['..', this.routeIdSanitiser.sanitisedValue]);
2403
2590
  }
2404
2591
  else {
2405
2592
  /** @type {?} */
2406
- const queryParams = this.sanitisedParameters.filter((/**
2593
+ const routeParams = {};
2594
+ this.parameterSanitisers.forEach((/**
2407
2595
  * @param {?} s
2408
2596
  * @return {?}
2409
2597
  */
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]);
2598
+ s => s.injectRouteParam(routeParams)));
2599
+ return router.navigate(['.', routeParams]);
2418
2600
  }
2419
2601
  }
2420
2602
  /**
2421
2603
  * @private
2422
- * @template T
2604
+ * @template T, S
2423
2605
  * @param {?} def
2424
2606
  * @return {?}
2425
2607
  */
@@ -2427,12 +2609,6 @@ class RouteParameterSanitiser {
2427
2609
  return def.sanitiser ? this.injector.get(def.sanitiser, new def.sanitiser()) : null;
2428
2610
  }
2429
2611
  }
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
2612
  __decorate([
2437
2613
  Memoize$1(),
2438
2614
  __metadata("design:type", Function),
@@ -2444,22 +2620,93 @@ if (false) {
2444
2620
  * @type {?}
2445
2621
  * @private
2446
2622
  */
2447
- RouteParameterSanitiser.prototype.routeParameter;
2623
+ RouteParameterSanitiser.prototype.routeIdSanitiser;
2448
2624
  /**
2449
2625
  * @type {?}
2450
2626
  * @private
2451
2627
  */
2452
- RouteParameterSanitiser.prototype.queryParameters;
2453
- /**
2454
- * @type {?}
2455
- * @private
2456
- */
2457
- RouteParameterSanitiser.prototype.sanitisedParameters;
2628
+ RouteParameterSanitiser.prototype.parameterSanitisers;
2458
2629
  /** @type {?} */
2459
2630
  RouteParameterSanitiser.prototype.parameterDefs;
2460
2631
  /** @type {?} */
2632
+ RouteParameterSanitiser.prototype.snapshot;
2633
+ /** @type {?} */
2461
2634
  RouteParameterSanitiser.prototype.injector;
2462
2635
  }
2636
+ (function (Sanitiser) {
2637
+ /**
2638
+ * @template T
2639
+ */
2640
+ class Value extends Sanitiser {
2641
+ /**
2642
+ * @param {?} snapshot
2643
+ * @return {?}
2644
+ */
2645
+ readFrom(snapshot) {
2646
+ /** @type {?} */
2647
+ const rawValue = this.parameterDef.isRouteId ?
2648
+ snapshot.paramMap.get(this.parameterDef.name) :
2649
+ snapshot.queryParamMap.get(this.parameterDef.name);
2650
+ return this.parameterDef.type.parse(rawValue);
2651
+ }
2652
+ /**
2653
+ * @protected
2654
+ * @param {?} initialValue
2655
+ * @param {?} sanitisedValue
2656
+ * @return {?}
2657
+ */
2658
+ hasChanged(initialValue, sanitisedValue) {
2659
+ return initialValue !== sanitisedValue;
2660
+ }
2661
+ /**
2662
+ * @param {?} dest
2663
+ * @return {?}
2664
+ */
2665
+ injectRouteParam(dest) {
2666
+ dest[this.parameterDef.name] = this.parameterDef.type.format(this.sanitisedValue);
2667
+ }
2668
+ }
2669
+ Sanitiser.Value = Value;
2670
+ /**
2671
+ * @template T
2672
+ */
2673
+ class Array extends Sanitiser {
2674
+ /**
2675
+ * @param {?} snapshot
2676
+ * @return {?}
2677
+ */
2678
+ readFrom(snapshot) {
2679
+ /** @type {?} */
2680
+ const rawValues = snapshot.queryParamMap.getAll(this.parameterDef.name);
2681
+ return rawValues.map((/**
2682
+ * @param {?} value
2683
+ * @return {?}
2684
+ */
2685
+ value => this.parameterDef.type.parse(value)));
2686
+ }
2687
+ /**
2688
+ * @protected
2689
+ * @param {?} initialValue
2690
+ * @param {?} sanitisedValue
2691
+ * @return {?}
2692
+ */
2693
+ hasChanged(initialValue, sanitisedValue) {
2694
+ return initialValue !== sanitisedValue;
2695
+ }
2696
+ /**
2697
+ * @param {?} dest
2698
+ * @return {?}
2699
+ */
2700
+ injectRouteParam(dest) {
2701
+ dest[this.parameterDef.name] = this.sanitisedValue.map((/**
2702
+ * @param {?} v
2703
+ * @return {?}
2704
+ */
2705
+ v => this.parameterDef.type.format(v)));
2706
+ }
2707
+ }
2708
+ Sanitiser.Array = Array;
2709
+ })(Sanitiser || (Sanitiser = {}));
2463
2710
 
2464
2711
  /**
2465
2712
  * @fileoverview added by tsickle
@@ -2483,8 +2730,8 @@ class PlaceRouteGuard {
2483
2730
  /** @type {?} */
2484
2731
  const routeParameters = Klass.get(route.component).getMetadataList(RouteParameterBindings.ROUTE_PARAMETER_LIST_KEY);
2485
2732
  /** @type {?} */
2486
- const sanitiser = new RouteParameterSanitiser(routeParameters, this.injector);
2487
- return sanitiser.sanitise(route).then((/**
2733
+ const sanitiser = new RouteParameterSanitiser(routeParameters, route, this.injector);
2734
+ return sanitiser.sanitise().then((/**
2488
2735
  * @param {?} proceed
2489
2736
  * @return {?}
2490
2737
  */
@@ -2554,6 +2801,17 @@ if (false) {
2554
2801
  /** @type {?|undefined} */
2555
2802
  ParameterOptions.prototype.sanitiser;
2556
2803
  }
2804
+ /**
2805
+ * @record
2806
+ * @template T
2807
+ */
2808
+ function ListParameterOptions() { }
2809
+ if (false) {
2810
+ /** @type {?|undefined} */
2811
+ ListParameterOptions.prototype.as;
2812
+ /** @type {?|undefined} */
2813
+ ListParameterOptions.prototype.listSanitiser;
2814
+ }
2557
2815
  /**
2558
2816
  * @template T
2559
2817
  * @param {?} type
@@ -2575,12 +2833,22 @@ function RouteId(type, options) {
2575
2833
  });
2576
2834
  }
2577
2835
  /**
2836
+ * @deprecated use RouteParameter instead.
2578
2837
  * @template T
2579
2838
  * @param {?} type
2580
2839
  * @param {?=} options
2581
2840
  * @return {?}
2582
2841
  */
2583
2842
  function QueryParameter(type, options) {
2843
+ return RouteParameter(type, options);
2844
+ }
2845
+ /**
2846
+ * @template T
2847
+ * @param {?} type
2848
+ * @param {?=} options
2849
+ * @return {?}
2850
+ */
2851
+ function RouteParameter(type, options) {
2584
2852
  // assert.isTruthy(type.isValid());
2585
2853
  return (/**
2586
2854
  * @param {?} prototype
@@ -2594,6 +2862,36 @@ function QueryParameter(type, options) {
2594
2862
  UseDelegate()(prototype, propertyKey);
2595
2863
  });
2596
2864
  }
2865
+ /**
2866
+ * @deprecated use RouteParameterList instead
2867
+ * @template E
2868
+ * @param {?} elementType
2869
+ * @param {?=} options
2870
+ * @return {?}
2871
+ */
2872
+ function QueryParameterList(elementType, options) {
2873
+ return RouteParameterList(elementType, options);
2874
+ }
2875
+ /**
2876
+ * @template E
2877
+ * @param {?} elementType
2878
+ * @param {?=} options
2879
+ * @return {?}
2880
+ */
2881
+ function RouteParameterList(elementType, options) {
2882
+ // assert.isTruthy(type.isValid());
2883
+ return (/**
2884
+ * @param {?} prototype
2885
+ * @param {?} propertyKey
2886
+ * @return {?}
2887
+ */
2888
+ (prototype, propertyKey) => {
2889
+ /** @type {?} */
2890
+ const param = createArrayDefinition(propertyKey, elementType, options);
2891
+ Klass.get(prototype).addToOwnMetadataList(RouteParameterBindings.ROUTE_PARAMETER_LIST_KEY, param);
2892
+ UseDelegate()(prototype, propertyKey);
2893
+ });
2894
+ }
2597
2895
  /**
2598
2896
  * @template T
2599
2897
  * @param {?} propertyName
@@ -2613,7 +2911,31 @@ function createDefinition(propertyName, type, options, routeId) {
2613
2911
  propertyName: propertyNameAsString,
2614
2912
  type: assert.notNil(type),
2615
2913
  sanitiser: opts.getOptional('sanitiser', null),
2616
- isRouteId: routeId
2914
+ isRouteId: routeId,
2915
+ isArray: false
2916
+ };
2917
+ return def;
2918
+ }
2919
+ /**
2920
+ * @template T
2921
+ * @param {?} propertyName
2922
+ * @param {?} type
2923
+ * @param {?} options
2924
+ * @return {?}
2925
+ */
2926
+ function createArrayDefinition(propertyName, type, options) {
2927
+ /** @type {?} */
2928
+ const opts = Opts.get(options);
2929
+ /** @type {?} */
2930
+ const propertyNameAsString = assert.notNil(propertyName).toString();
2931
+ /** @type {?} */
2932
+ const def = {
2933
+ name: opts.getOptional('as', propertyNameAsString),
2934
+ propertyName: propertyNameAsString,
2935
+ type: assert.notNil(type),
2936
+ sanitiser: opts.getOptional('listSanitiser', null),
2937
+ isRouteId: false,
2938
+ isArray: true
2617
2939
  };
2618
2940
  return def;
2619
2941
  }
@@ -2624,7 +2946,7 @@ function createDefinition(propertyName, type, options, routeId) {
2624
2946
  */
2625
2947
  /**
2626
2948
  * @record
2627
- * @template T
2949
+ * @template E, S
2628
2950
  */
2629
2951
  function ParameterDefinition() { }
2630
2952
  if (false) {
@@ -2638,6 +2960,8 @@ if (false) {
2638
2960
  ParameterDefinition.prototype.sanitiser;
2639
2961
  /** @type {?} */
2640
2962
  ParameterDefinition.prototype.isRouteId;
2963
+ /** @type {?} */
2964
+ ParameterDefinition.prototype.isArray;
2641
2965
  }
2642
2966
 
2643
2967
  /**
@@ -2720,5 +3044,5 @@ var ParameterType;
2720
3044
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2721
3045
  */
2722
3046
 
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 };
3047
+ 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
3048
  //# sourceMappingURL=coolon-angular-ui-powerups.js.map