@angular/router 21.0.0-next.8 → 21.0.0-next.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.
@@ -1,12 +1,12 @@
1
1
  /**
2
- * @license Angular v21.0.0-next.8
2
+ * @license Angular v21.0.0-next.9
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  import { DOCUMENT, Location } from '@angular/common';
8
8
  import * as i0 from '@angular/core';
9
- import { ɵisPromise as _isPromise, ɵRuntimeError as _RuntimeError, Injectable, ɵisNgModule as _isNgModule, isStandalone, createEnvironmentInjector, InjectionToken, EventEmitter, input, inject, ViewContainerRef, ChangeDetectorRef, Directive, Input, Output, reflectComponentType, Component, ɵisInjectable as _isInjectable, runInInjectionContext, makeEnvironmentProviders, Compiler, NgModuleFactory, ɵresolveComponentResources as _resolveComponentResources, afterNextRender, signal, EnvironmentInjector, DestroyRef, untracked, ɵConsole as _Console, ɵPendingTasksInternal as _PendingTasksInternal, ɵINTERNAL_APPLICATION_ERROR_HANDLER as _INTERNAL_APPLICATION_ERROR_HANDLER } from '@angular/core';
9
+ import { ɵisPromise as _isPromise, ɵRuntimeError as _RuntimeError, Injectable, ɵisNgModule as _isNgModule, isStandalone, createEnvironmentInjector, InjectionToken, EventEmitter, input, inject, ViewContainerRef, ChangeDetectorRef, Directive, Input, Output, reflectComponentType, Component, ɵisInjectable as _isInjectable, runInInjectionContext, makeEnvironmentProviders, Compiler, NgModuleFactory, ɵresolveComponentResources as _resolveComponentResources, afterNextRender, signal, EnvironmentInjector, DestroyRef, untracked, ɵConsole as _Console, ɵPendingTasksInternal as _PendingTasksInternal, ɵINTERNAL_APPLICATION_ERROR_HANDLER as _INTERNAL_APPLICATION_ERROR_HANDLER, ɵformatRuntimeError as _formatRuntimeError } from '@angular/core';
10
10
  import { isObservable, from, of, BehaviorSubject, combineLatest, EmptyError, Observable, concat, defer, pipe, throwError, EMPTY, Subject, Subscription } from 'rxjs';
11
11
  import { first, map, switchMap, take, startWith, filter, takeUntil, mergeMap, concatMap, tap, catchError, scan, defaultIfEmpty, last as last$1, takeLast, finalize } from 'rxjs/operators';
12
12
  import * as i1 from '@angular/platform-browser';
@@ -448,10 +448,10 @@ function mapChildrenIntoArray(segment, fn) {
448
448
  * @publicApi
449
449
  */
450
450
  class UrlSerializer {
451
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
452
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() });
451
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
452
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() });
453
453
  }
454
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: UrlSerializer, decorators: [{
454
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: UrlSerializer, decorators: [{
455
455
  type: Injectable,
456
456
  args: [{ providedIn: 'root', useFactory: () => new DefaultUrlSerializer() }]
457
457
  }] });
@@ -752,7 +752,7 @@ class UrlParser {
752
752
  }
753
753
  const children = this.parseChildren();
754
754
  segments[outletName] =
755
- Object.keys(children).length === 1
755
+ Object.keys(children).length === 1 && children[PRIMARY_OUTLET]
756
756
  ? children[PRIMARY_OUTLET]
757
757
  : new UrlSegmentGroup([], children);
758
758
  this.consumeOptional('//');
@@ -843,6 +843,9 @@ function isUrlTree(v) {
843
843
  * @param queryParams The query parameters for the `UrlTree`. `null` if the `UrlTree` does not have
844
844
  * any query parameters.
845
845
  * @param fragment The fragment for the `UrlTree`. `null` if the `UrlTree` does not have a fragment.
846
+ * @param urlSerializer The `UrlSerializer` to use for handling query parameter normalization.
847
+ * You should provide your application's custom `UrlSerializer` if one is configured to parse and
848
+ * serialize query parameter values to and from objects other than strings/string arrays.
846
849
  *
847
850
  * @usageNotes
848
851
  *
@@ -880,9 +883,9 @@ function isUrlTree(v) {
880
883
  * createUrlTreeFromSnapshot(snapshot, ['../../team/44/user/22']);
881
884
  * ```
882
885
  */
883
- function createUrlTreeFromSnapshot(relativeTo, commands, queryParams = null, fragment = null) {
886
+ function createUrlTreeFromSnapshot(relativeTo, commands, queryParams = null, fragment = null, urlSerializer = new DefaultUrlSerializer()) {
884
887
  const relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeTo);
885
- return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, queryParams, fragment);
888
+ return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, queryParams, fragment, urlSerializer);
886
889
  }
887
890
  function createSegmentGroupFromRoute(route) {
888
891
  let targetGroup;
@@ -902,7 +905,7 @@ function createSegmentGroupFromRoute(route) {
902
905
  const rootSegmentGroup = createRoot(rootCandidate);
903
906
  return targetGroup ?? rootSegmentGroup;
904
907
  }
905
- function createUrlTreeFromSegmentGroup(relativeTo, commands, queryParams, fragment) {
908
+ function createUrlTreeFromSegmentGroup(relativeTo, commands, queryParams, fragment, urlSerializer) {
906
909
  let root = relativeTo;
907
910
  while (root.parent) {
908
911
  root = root.parent;
@@ -911,17 +914,17 @@ function createUrlTreeFromSegmentGroup(relativeTo, commands, queryParams, fragme
911
914
  // `UrlSegmentGroup`. All we need to do is update the `queryParams` and `fragment` without
912
915
  // applying any other logic.
913
916
  if (commands.length === 0) {
914
- return tree(root, root, root, queryParams, fragment);
917
+ return tree(root, root, root, queryParams, fragment, urlSerializer);
915
918
  }
916
919
  const nav = computeNavigation(commands);
917
920
  if (nav.toRoot()) {
918
- return tree(root, root, new UrlSegmentGroup([], {}), queryParams, fragment);
921
+ return tree(root, root, new UrlSegmentGroup([], {}), queryParams, fragment, urlSerializer);
919
922
  }
920
923
  const position = findStartingPositionForTargetGroup(nav, root, relativeTo);
921
924
  const newSegmentGroup = position.processChildren
922
925
  ? updateSegmentGroupChildren(position.segmentGroup, position.index, nav.commands)
923
926
  : updateSegmentGroup(position.segmentGroup, position.index, nav.commands);
924
- return tree(root, position.segmentGroup, newSegmentGroup, queryParams, fragment);
927
+ return tree(root, position.segmentGroup, newSegmentGroup, queryParams, fragment, urlSerializer);
925
928
  }
926
929
  function isMatrixParams(command) {
927
930
  return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
@@ -933,12 +936,39 @@ function isMatrixParams(command) {
933
936
  function isCommandWithOutlets(command) {
934
937
  return typeof command === 'object' && command != null && command.outlets;
935
938
  }
936
- function tree(oldRoot, oldSegmentGroup, newSegmentGroup, queryParams, fragment) {
937
- let qp = {};
938
- if (queryParams) {
939
- Object.entries(queryParams).forEach(([name, value]) => {
940
- qp[name] = Array.isArray(value) ? value.map((v) => `${v}`) : `${value}`;
941
- });
939
+ /**
940
+ * Normalizes a query parameter value by using the `UrlSerializer` to serialize then parse the value.
941
+ *
942
+ * This ensures that the value is consistent between parsing a URL in the browser on a fresh page load (or page refresh)
943
+ * and a navigation where the query parameter value is passed directly to the router.
944
+ *
945
+ * This also allows custom `UrlSerializer` implementations to define how query parameter values are represented
946
+ * in a `UrlTree`. Since `UrlSerializer` already has a `parse` that takes a string, it already has control
947
+ * over how a browser URL is parsed into a `UrlTree` on initial load/page refresh.
948
+ */
949
+ function normalizeQueryParams(k, v, urlSerializer) {
950
+ // Hack for empty string query param, which, for whatever reason, happens
951
+ // in a test. Parsing drops empty key params (which might not really be necessary).
952
+ // It's probably really a test issue but I don't have the time to fix it...
953
+ k ||= 'ɵ';
954
+ const tree = new UrlTree();
955
+ tree.queryParams = { [k]: v };
956
+ return urlSerializer.parse(urlSerializer.serialize(tree)).queryParams[k];
957
+ }
958
+ function tree(oldRoot, oldSegmentGroup, newSegmentGroup, queryParams, fragment, urlSerializer) {
959
+ const qp = {};
960
+ for (const [key, value] of Object.entries(queryParams ?? {})) {
961
+ // This retains old behavior where each item in the array was stringified individually This
962
+ // helps remove special-case handling for empty and single-item arrays where the default
963
+ // serializer removes empty arrays when serialized then parsed or converts them to non-arrays
964
+ // for single-item arrays. Changing this could have breaking change implications. Prior code
965
+ // always returned arrays of strings for array inputs so tests, applications, serializers,
966
+ // etc. may only be set up to handle string arrays. We could consider changing this in the
967
+ // future to serialize the entire array as a single value. For now, this feels safer and is
968
+ // at least a step in the right direction.
969
+ qp[key] = Array.isArray(value)
970
+ ? value.map((v) => normalizeQueryParams(key, v, urlSerializer))
971
+ : normalizeQueryParams(key, value, urlSerializer);
942
972
  }
943
973
  let rootCandidate;
944
974
  if (oldRoot === oldSegmentGroup) {
@@ -2135,10 +2165,10 @@ class ChildrenOutletContexts {
2135
2165
  getContext(childName) {
2136
2166
  return this.contexts.get(childName) || null;
2137
2167
  }
2138
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: ChildrenOutletContexts, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable });
2139
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' });
2168
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: ChildrenOutletContexts, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable });
2169
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' });
2140
2170
  }
2141
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: ChildrenOutletContexts, decorators: [{
2171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: ChildrenOutletContexts, decorators: [{
2142
2172
  type: Injectable,
2143
2173
  args: [{ providedIn: 'root' }]
2144
2174
  }], ctorParameters: () => [{ type: i0.EnvironmentInjector }] });
@@ -2925,10 +2955,10 @@ class RouterOutlet {
2925
2955
  this.inputBinder?.bindActivatedRouteToOutletComponent(this);
2926
2956
  this.activateEvents.emit(this.activated.instance);
2927
2957
  }
2928
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2929
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.0-next.8", type: RouterOutlet, isStandalone: true, selector: "router-outlet", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: false, isRequired: false, transformFunction: null }, routerOutletData: { classPropertyName: "routerOutletData", publicName: "routerOutletData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], usesOnChanges: true, ngImport: i0 });
2958
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2959
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.0-next.9", type: RouterOutlet, isStandalone: true, selector: "router-outlet", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: false, isRequired: false, transformFunction: null }, routerOutletData: { classPropertyName: "routerOutletData", publicName: "routerOutletData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], usesOnChanges: true, ngImport: i0 });
2930
2960
  }
2931
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RouterOutlet, decorators: [{
2961
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RouterOutlet, decorators: [{
2932
2962
  type: Directive,
2933
2963
  args: [{
2934
2964
  selector: 'router-outlet',
@@ -3038,10 +3068,10 @@ class RoutedComponentInputBinder {
3038
3068
  });
3039
3069
  this.outletDataSubscriptions.set(outlet, dataSubscription);
3040
3070
  }
3041
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RoutedComponentInputBinder, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3042
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RoutedComponentInputBinder });
3071
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RoutedComponentInputBinder, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3072
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RoutedComponentInputBinder });
3043
3073
  }
3044
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RoutedComponentInputBinder, decorators: [{
3074
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RoutedComponentInputBinder, decorators: [{
3045
3075
  type: Injectable
3046
3076
  }] });
3047
3077
 
@@ -3055,10 +3085,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8",
3055
3085
  * to this `EmptyOutletComponent`.
3056
3086
  */
3057
3087
  class ɵEmptyOutletComponent {
3058
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3059
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.0-next.8", type: ɵEmptyOutletComponent, isStandalone: true, selector: "ng-component", exportAs: ["emptyRouterOutlet"], ngImport: i0, template: `<router-outlet/>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
3088
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3089
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.0-next.9", type: ɵEmptyOutletComponent, isStandalone: true, selector: "ng-component", exportAs: ["emptyRouterOutlet"], ngImport: i0, template: `<router-outlet/>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
3060
3090
  }
3061
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
3091
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
3062
3092
  type: Component,
3063
3093
  args: [{
3064
3094
  template: `<router-outlet/>`,
@@ -4029,9 +4059,9 @@ let Recognizer$1 = class Recognizer {
4029
4059
  const rootNode = new TreeNode(rootSnapshot, children);
4030
4060
  const routeState = new RouterStateSnapshot('', rootNode);
4031
4061
  const tree = createUrlTreeFromSnapshot(rootSnapshot, [], this.urlTree.queryParams, this.urlTree.fragment);
4032
- // https://github.com/angular/angular/issues/47307
4033
4062
  // Creating the tree stringifies the query params
4034
- // We don't want to do this here so reassign them to the original.
4063
+ // We don't want to do this here to preserve pre-existing behavior
4064
+ // so reassign them to the original.
4035
4065
  tree.queryParams = this.urlTree.queryParams;
4036
4066
  routeState.url = this.urlSerializer.serialize(tree);
4037
4067
  return { state: routeState, tree };
@@ -4902,10 +4932,10 @@ class TitleStrategy {
4902
4932
  getResolvedTitleForRoute(snapshot) {
4903
4933
  return snapshot.data[RouteTitleKey];
4904
4934
  }
4905
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4906
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) });
4935
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4936
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) });
4907
4937
  }
4908
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: TitleStrategy, decorators: [{
4938
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: TitleStrategy, decorators: [{
4909
4939
  type: Injectable,
4910
4940
  args: [{ providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }]
4911
4941
  }] });
@@ -4929,10 +4959,10 @@ class DefaultTitleStrategy extends TitleStrategy {
4929
4959
  this.title.setTitle(title);
4930
4960
  }
4931
4961
  }
4932
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
4933
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
4962
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
4963
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
4934
4964
  }
4935
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
4965
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
4936
4966
  type: Injectable,
4937
4967
  args: [{ providedIn: 'root' }]
4938
4968
  }], ctorParameters: () => [{ type: i1.Title }] });
@@ -5017,10 +5047,10 @@ class RouterConfigLoader {
5017
5047
  this.childrenLoaders.set(route, loader);
5018
5048
  return loader;
5019
5049
  }
5020
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RouterConfigLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5021
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' });
5050
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RouterConfigLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5051
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' });
5022
5052
  }
5023
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RouterConfigLoader, decorators: [{
5053
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RouterConfigLoader, decorators: [{
5024
5054
  type: Injectable,
5025
5055
  args: [{ providedIn: 'root' }]
5026
5056
  }] });
@@ -5101,10 +5131,10 @@ function maybeResolveResources(value) {
5101
5131
  * @publicApi
5102
5132
  */
5103
5133
  class UrlHandlingStrategy {
5104
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: UrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5105
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: UrlHandlingStrategy, providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) });
5134
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: UrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5135
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: UrlHandlingStrategy, providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) });
5106
5136
  }
5107
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: UrlHandlingStrategy, decorators: [{
5137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: UrlHandlingStrategy, decorators: [{
5108
5138
  type: Injectable,
5109
5139
  args: [{ providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) }]
5110
5140
  }] });
@@ -5121,10 +5151,10 @@ class DefaultUrlHandlingStrategy {
5121
5151
  merge(newUrlPart, wholeUrl) {
5122
5152
  return newUrlPart;
5123
5153
  }
5124
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultUrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5125
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultUrlHandlingStrategy, providedIn: 'root' });
5154
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultUrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5155
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultUrlHandlingStrategy, providedIn: 'root' });
5126
5156
  }
5127
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultUrlHandlingStrategy, decorators: [{
5157
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultUrlHandlingStrategy, decorators: [{
5128
5158
  type: Injectable,
5129
5159
  args: [{ providedIn: 'root' }]
5130
5160
  }] });
@@ -5421,18 +5451,24 @@ class NavigationTransitions {
5421
5451
  switchTap((t) => {
5422
5452
  const loadComponents = (route) => {
5423
5453
  const loaders = [];
5424
- if (route.routeConfig?.loadComponent) {
5454
+ if (route.routeConfig?._loadedComponent) {
5455
+ route.component = route.routeConfig?._loadedComponent;
5456
+ }
5457
+ else if (route.routeConfig?.loadComponent) {
5425
5458
  const injector = getClosestRouteInjector(route) ?? this.environmentInjector;
5426
- loaders.push(from(this.configLoader.loadComponent(injector, route.routeConfig)).pipe(tap((loadedComponent) => {
5459
+ loaders.push(this.configLoader
5460
+ .loadComponent(injector, route.routeConfig)
5461
+ .then((loadedComponent) => {
5427
5462
  route.component = loadedComponent;
5428
- }), map(() => void 0)));
5463
+ }));
5429
5464
  }
5430
5465
  for (const child of route.children) {
5431
5466
  loaders.push(...loadComponents(child));
5432
5467
  }
5433
5468
  return loaders;
5434
5469
  };
5435
- return combineLatest(loadComponents(t.targetSnapshot.root)).pipe(defaultIfEmpty(null), take(1));
5470
+ const loaders = loadComponents(t.targetSnapshot.root);
5471
+ return loaders.length === 0 ? of(t) : from(Promise.all(loaders).then(() => t));
5436
5472
  }), switchTap(() => this.afterPreactivation()), switchMap(() => {
5437
5473
  const { currentSnapshot, targetSnapshot } = overallTransitionState;
5438
5474
  const viewTransitionStarted = this.createViewTransition?.(this.environmentInjector, currentSnapshot.root, targetSnapshot.root);
@@ -5599,10 +5635,10 @@ class NavigationTransitions {
5599
5635
  return (currentBrowserUrl.toString() !== targetBrowserUrl?.toString() &&
5600
5636
  !currentNavigation?.extras.skipLocationChange);
5601
5637
  }
5602
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: NavigationTransitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5603
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: NavigationTransitions, providedIn: 'root' });
5638
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: NavigationTransitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5639
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: NavigationTransitions, providedIn: 'root' });
5604
5640
  }
5605
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: NavigationTransitions, decorators: [{
5641
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: NavigationTransitions, decorators: [{
5606
5642
  type: Injectable,
5607
5643
  args: [{ providedIn: 'root' }]
5608
5644
  }], ctorParameters: () => [] });
@@ -5618,10 +5654,10 @@ function isBrowserTriggeredNavigation(source) {
5618
5654
  * @publicApi
5619
5655
  */
5620
5656
  class RouteReuseStrategy {
5621
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RouteReuseStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5622
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RouteReuseStrategy, providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) });
5657
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RouteReuseStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5658
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RouteReuseStrategy, providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) });
5623
5659
  }
5624
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: RouteReuseStrategy, decorators: [{
5660
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: RouteReuseStrategy, decorators: [{
5625
5661
  type: Injectable,
5626
5662
  args: [{ providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) }]
5627
5663
  }] });
@@ -5672,10 +5708,10 @@ class BaseRouteReuseStrategy {
5672
5708
  }
5673
5709
  }
5674
5710
  class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
5675
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultRouteReuseStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
5676
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultRouteReuseStrategy, providedIn: 'root' });
5711
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultRouteReuseStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
5712
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultRouteReuseStrategy, providedIn: 'root' });
5677
5713
  }
5678
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: DefaultRouteReuseStrategy, decorators: [{
5714
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: DefaultRouteReuseStrategy, decorators: [{
5679
5715
  type: Injectable,
5680
5716
  args: [{ providedIn: 'root' }]
5681
5717
  }] });
@@ -5774,10 +5810,10 @@ class StateManager {
5774
5810
  // when merging, such as the query params so they are not lost on a refresh.
5775
5811
  this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, finalUrl ?? this.rawUrlTree);
5776
5812
  }
5777
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: StateManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5778
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: StateManager, providedIn: 'root', useFactory: () => inject(HistoryStateManager) });
5813
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: StateManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5814
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: StateManager, providedIn: 'root', useFactory: () => inject(HistoryStateManager) });
5779
5815
  }
5780
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: StateManager, decorators: [{
5816
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: StateManager, decorators: [{
5781
5817
  type: Injectable,
5782
5818
  args: [{ providedIn: 'root', useFactory: () => inject(HistoryStateManager) }]
5783
5819
  }] });
@@ -5909,10 +5945,10 @@ class HistoryStateManager extends StateManager {
5909
5945
  }
5910
5946
  return { navigationId };
5911
5947
  }
5912
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: HistoryStateManager, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
5913
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: HistoryStateManager, providedIn: 'root' });
5948
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HistoryStateManager, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
5949
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HistoryStateManager, providedIn: 'root' });
5914
5950
  }
5915
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: HistoryStateManager, decorators: [{
5951
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HistoryStateManager, decorators: [{
5916
5952
  type: Injectable,
5917
5953
  args: [{ providedIn: 'root' }]
5918
5954
  }] });
@@ -6336,7 +6372,7 @@ class Router {
6336
6372
  }
6337
6373
  relativeToUrlSegmentGroup = this.currentUrlTree.root;
6338
6374
  }
6339
- return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, q, f ?? null);
6375
+ return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, q, f ?? null, this.urlSerializer);
6340
6376
  }
6341
6377
  /**
6342
6378
  * Navigates to a view using an absolute route path.
@@ -6412,7 +6448,8 @@ class Router {
6412
6448
  try {
6413
6449
  return this.urlSerializer.parse(url);
6414
6450
  }
6415
- catch {
6451
+ catch (e) {
6452
+ this.console.warn(_formatRuntimeError(4018 /* RuntimeErrorCode.ERROR_PARSING_URL */, ngDevMode && `Error parsing URL ${url}. Falling back to '/' instead. \n` + e));
6416
6453
  return this.urlSerializer.parse('/');
6417
6454
  }
6418
6455
  }
@@ -6485,10 +6522,10 @@ class Router {
6485
6522
  return Promise.reject(e);
6486
6523
  });
6487
6524
  }
6488
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: Router, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6489
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: Router, providedIn: 'root' });
6525
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: Router, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6526
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: Router, providedIn: 'root' });
6490
6527
  }
6491
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.8", ngImport: i0, type: Router, decorators: [{
6528
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: Router, decorators: [{
6492
6529
  type: Injectable,
6493
6530
  args: [{ providedIn: 'root' }]
6494
6531
  }], ctorParameters: () => [] });