Commit Graph

524 Commits

Author SHA1 Message Date
Dmitrij Kuba 6bceb709df fix(router): Only retrieve stored route when reuse strategy indicates it should reattach (#30263)
When creating the router state, the `RouteReuseStrategy#retrieve` should
only be called when `RouteReuseStrategy#shouldAttach` returns `true`.
That is, we should only retrieve a stored route when the reuse strategy
indicates that there is one stored and that it should be reattached.

This now matches the behavior in the route activation:
1d12c50f63/packages/router/src/operators/activate_routes.ts (L170-L172)

Fixes #23162

PR Close #30263
2021-04-15 11:32:59 -07:00
Martin Sikora 0d55d4557f test(router): add Router regression test for hash location strategy (#40409)
This situation can probably happen only when using
`HashLocationStrategy` and by manually changing hash that triggers a route
guard that returns a new `UrlTree`. Then hash in the browser might not
match the current route because navigation was canceled, while hash in
the URL remained set by the user.

Related to #37048

PR Close #40409
2021-04-14 18:48:26 -07:00
Andrew Scott a1b2718b92 fix(router): recursively merge empty path matches (#41584)
When recognizing routes, the router merges nodes which map to the same
empty path config. This is because auxiliary outlets under empty path
parents need to match the parent config. This would result in two
outlet matches for that parent which need to be combined into a single
node: The regular 'primary' match and the match for the auxiliary outlet.
In addition, the children of the merged nodes should also be merged to
account for multiple levels of empty path parents.

Fixes #41481

PR Close #41584
2021-04-14 15:47:07 -07:00
Joey Perrott c30b171d20 feat(router): update supported range of node versions (#41544)
Update the supported range of node versions for Angular.  Angular now
supports node >=12.14.1 to <16.0.0, dropping support for Node v10.

PR Close #41544
2021-04-14 09:40:18 -07:00
Andrew Scott 44a7fae00f fix(router): handle new navigations from a NavigationEnd event (#41262)
This commit removes the line to set `currentNavigation` to `null` in the
navigation transitions subscription of the router. This logic is
already handled in the `finalize` stage of the transition pipe and has
been found to cause issues if a new navigation is triggered from a
subscription to the `NavigationEnd` event.

fixes #37460

PR Close #41262
2021-04-08 10:23:04 -07:00
Andrew Scott d28a391385 fix(router): Remove information about attached component when deactivating route (#41381)
When we deactivate a child route, we deactivate its outlet as well as
its children. We also need to clear the stored information about the
route and the associated component.
If we do not, the context will keep these references and can result in
reactivating an outlet that was deactivated by the previous navigation.

Fixes #41379

PR Close #41381
2021-04-07 13:55:31 -07:00
josemontespg 575f537473 docs(router): make getCurrentNavigation() jsdoc more explicit (#41417)
Add additional clarification to the documentation for
`getCurrentNavigation`.

PR Close #41417
2021-04-06 10:05:17 -07:00
Ahmed Ayed e05a6f3bb3 feat(common): add `historyGo` method to `Location` service (#38890)
Add new method `historyGo`, that will let
the user navigate to a specific page from session history identified by its
relative position to the current page.

We add some tests to `location_spec.ts` to validate the behavior of the
`historyGo` and `forward` methods.

Add more tests for `location_spec` to test `location.historyGo(0)`, `location.historyGo()`,
`location.historyGo(100)` and `location.historyGo(-100)`. We also add new tests for
`Integration` spec to validate the navigation when we using
`location#historyGo`.

Update the `historyGo` function docs

Note that this was made an optional function in the abstract classes to
avoid a breaking change. Because our location classes use `implements PlatformLocation`
rather than `extends PlatformLocation`, simply adding a default
implementation was not sufficient to make this a non-breaking change.
While we could fix the classes internal to Angular, this would still have been
a breaking change for any external developers who may have followed our
implementations as an example.

PR Close #38890
2021-04-06 09:25:58 -07:00
Matthias Kunnen b5551609fe fix(router): fragment can be null (#37336)
ActivatedRoute.fragment was typed as Observable<string> but could emit
both null and undefined due to incorrect non-null assertion. These
non-null assertions have been removed and fragment has been retyped to
string | null.

BREAKING CHANGE:
Strict null checks will report on fragment potentially being null.
Migration path: add null check.

Fixes #23894, fixes #34197.

PR Close #37336
2021-03-22 10:02:39 -07:00
Kristiyan Kostadinov 59ef40988e feat(core): support TypeScript 4.2 (#41158)
Updates the repo to TypeScript 4.2 and tslib 2.1.0.

PR Close #41158
2021-03-17 09:10:25 -07:00
Kristiyan Kostadinov 3c66b100dd perf(common): remove unused methods from DomAdapter (#41102)
The `DomAdapter` is present in all Angular apps and its methods aren't tree shakeable.
These changes remove the methods that either aren't being used anymore or were only
used by our own tests. Note that these changes aren't breaking, because the adapter
is an internal API.

The following methods were removed:
* `getProperty` - only used within our own tests.
* `log` - Guaranteed to be defined on `console`.
* `logGroup` and `logGroupEnd` - Only used in one place. It was in the DomAdapter for built-in null checking.
* `logGroupEnd` - Only used in one place. It was placed in the DomAdapter for built in null checking.
* `performanceNow` - Only used in one place that has to be invoked through the browser console.
* `supportsCookies` - Unused.
* `getCookie` - Unused.
* `getLocation` and `getHistory` - Only used in one place which appears to have access to the DOM
already, because it had direct accesses to `window`. Furthermore, even if this was being used
in a non-browser context already, the `DominoAdapter` was set up to throw an error.

The following APIs were changed to be more compact:
* `supportsDOMEvents` - Changed to a readonly property.
* `remove` - No longer returns the removed node.

PR Close #41102
2021-03-10 11:48:24 -08:00
arturovt 38524c4d29 fix(common): cleanup location change listeners when the root view is removed (#40867)
In the new behavior Angular cleanups `popstate` and `hashchange` event listeners
when the root view gets destroyed, thus event handlers are not added twice
when the application is bootstrapped again.

BREAKING CHANGE:

Methods of the `PlatformLocation` class, namely `onPopState` and `onHashChange`,
used to return `void`. Now those methods return functions that can be called
to remove event handlers.

PR Close #31546

PR Close #40867
2021-03-04 13:09:04 -08:00
abarghoud ca721c2972 feat(core): more precise type for `APP_INITIALIZER` token (#40986)
This commit updates the type of the `APP_INITIALIZER` injection token to
better document the expected types of values that Angular handles. Only
Promises and Observables are awaited and other types of values are ignored,
so the type of `APP_INITIALIZER` has been updated to
`Promise<unknown> | Observable<unknown> | void` to reflect this behavior.

BREAKING CHANGE:

The type of the `APP_INITIALIZER` token has been changed to more accurately
reflect the types of return values that are handled by Angular. Previously,
each initializer callback was typed to return `any`, this is now
`Promise<unknown> | Observable<unknown> | void`. In the unlikely event that
your application uses the `Injector.get` or `TestBed.inject` API to inject
the `APP_INITIALIZER` token, you may need to update the code to account for
the stricter type.

Additionally, TypeScript may report the TS2742 error if the `APP_INITIALIZER`
token is used in an expression of which its inferred type has to be emitted
into a .d.ts file. To workaround this, an explicit type annotation is needed,
which would typically be `Provider` or `Provider[]`.

Closes #40729

PR Close #40986
2021-03-04 12:01:07 -08:00
pavlenko 9ae0faa00a docs(router): fix typo for the equivalent `exactMatchOptions` value (#41075)
When `Router.isActive` is called with `true` the `exactMatchOptions` value is set for this case.

PR Close #41075
2021-03-04 10:58:30 -08:00
Andrew Scott 6c05c80f19 feat(router): Add more find-tuned control in `routerLinkActiveOptions` (#40303)
This commit adds more configurability to the `Router#isActive` method
and `RouterLinkActive#routerLinkActiveOptions`.
It allows tuning individual match options for query params and the url
tree, which were either both partial or both exact matches in the past.
Additionally, it also allows matching against the fragment and matrix
parameters.

fixes #13205

BREAKING CHANGE:
The type of the `RouterLinkActive.routerLinkActiveOptions` input was
expanded to allow more fine-tuned control. Code that previously read
this property may need to be updated to account for the new type.

PR Close #40303
2021-02-24 15:32:05 -08:00
Andrew Scott a82fddf1ce feat(router): Allow for custom router outlet implementations (#40827)
This PR formalizes, documents, and makes public the router outlet contract.

The set of `RouterOutlet` methods used by the `Router` has not changed
in over 4 years, since the introduction of route reuse strategies.

Creation of custom router outlets is already possible and is used by the
Ionic framework
(https://github.com/ionic-team/ionic-framework/blob/master/angular/src/directives/navigation/ion-router-outlet.ts).
There is a small "hack" that is needed to make this work, which is that
outlets must register with `ChildrenOutletContexts`, but it currently
only accepts our `RouterOutlet`.

By exposing the interface the `Router` uses to activate and deactivate
routes through outlets, we allow for developers to more easily and safely
extend the `Router` and have fine-tuned control over navigation and component
activation that fits project requirements.

PR Close #40827
2021-02-19 09:13:17 -08:00
Paul Gammans 95ad452e54 fix(router): fix load interaction of navigation and preload strategies (#40389)
Fix router to ensure that a route module is only loaded once especially
in relation to the use of preload strategies with delayed or partial
loading.

Add test to check the interaction of PreloadingStrategy and normal
router navigation under differing scenarios.
Checking:
 * Prevention of duplicate loading of modules.
   related to #26557
 * Prevention of duplicate RouteConfigLoad(Start|End) events
   related to #22842
 * Ensuring preload strategy remains active for submodules if needed
   The selected preload strategy should still decide when to load submodules
 * Possibility of memory leak with unfinished preload subscription
   related to #26557
 * Ensure that the stored loader promise is cleared so that subsequent
   load will try the fetch again.
 * Add error handle error from loadChildren
 * Ensure we handle error from with NgModule create

Fixes #26557 #22842 #26557

PR Close #40389
2021-02-16 11:28:50 -08:00
Joey Perrott 267c566baf Revert "fix(router): fix load interaction of navigation and preload strategies (#40389)" (#40806)
This reverts commit e9a19a6152.

PR Close #40806
2021-02-11 11:59:10 -08:00
Paul Gammans e9a19a6152 fix(router): fix load interaction of navigation and preload strategies (#40389)
Fix router to ensure that a route module is only loaded once especially
in relation to the use of preload strategies with delayed or partial
loading.

Add test to check the interaction of PreloadingStrategy and normal
router navigation under differing scenarios.
Checking:
 * Prevention of duplicate loading of modules.
   related to #26557
 * Prevention of duplicate RouteConfigLoad(Start|End) events
   related to #22842
 * Ensuring preload strategy remains active for submodules if needed
   The selected preload strategy should still decide when to load submodules
 * Possibility of memory leak with unfinished preload subscription
   related to #26557
 * Ensure that the stored loader promise is cleared so that subsequent
   load will try the fetch again.
 * Add error handle error from loadChildren
 * Ensure we handle error from with NgModule create

Fixes #26557 #22842 #26557

PR Close #40389
2021-02-11 09:15:09 -08:00
Joey Perrott 350dadab73 fix(router): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:43 -08:00
Kristiyan Kostadinov 00070376ed fix(router): stop emitting to event observable on destroy (#40638)
No longer emits to `Router.events` after the router has been destroyed. Also
returns a resolved promise to the navigation methods.

Fixes #40502.

PR Close #40638
2021-02-04 10:46:46 -08:00
JiaLiPassion 4b3106ed8a refactor(router): fix several typos in router spec (#40626)
Fix a couple typos in router tests.

PR Close #40626
2021-01-29 11:14:35 -08:00
Alison Gale f0733d109e fix(router): Fix occasional error when creating url tree in IE 11 and Edge (#40488)
For the Google Cloud Console within Google we observed errors in the
shallowEqual function for users in IE and Edge. This patch was made within
Google and the errors went away. This commit upstreams the change into Angular.

PR Close #40488
2021-01-21 12:25:16 -08:00
Alex Mokin 3cf4e3c7c5 fix(router): always stringify matrix parameters (#25095)
Fix a case where matrix parameters weren't stringified when they are passed as a first command
when creating a url tree. Fix return type in parseMatrixParams method
because it always returns {[key: string]: string}

Closes #23165

PR Close #25095
2021-01-20 16:19:45 -08:00
Martin Sikora b37a9eba1a fix(router): lazy loaded modules without RouterModule.forChild() won't cause an infinite loop (#36605)
When loading a module that doesn't provide `RouterModule.forChild()` preloader will get stuck
in an infinite loop and throw `ERROR Error: Maximum call stack size exceeded.`
The issue is that child module's `Injector` will look to its parent `Injector` when it doesn't
find any `ROUTES` so it will return routes for it's parent module instead. This will load the
child again that returns its parent's routes and so on.

Closes #29164

PR Close #36605
2021-01-15 10:39:55 -08:00
Alexey Elin cf02cf1e18 docs: remove duplicated the (#40434)
PR Close #40434
2021-01-14 11:33:57 -08:00
Martin Sikora 9105005192 refactor(router): refactor and simplify router RxJS chains (#40290)
Refactor and simplifiy RxJS usage in the router package
in order to reduce its size and increase performance.

PR Close #40290
2021-01-11 15:30:55 -08:00
markostanimirovic 4a7a649852 docs(router): clarify the description of legacy relativeLinkResolution (#40384)
PR Close #40384
2021-01-11 14:09:40 -08:00
Trotyl 76954688b1 fix(router): better ngZone checking for warning (#25839)
Do not warn that navigation was triggered outside Angular zone if the
Router was created outside Angular zone in the first place.

Closes #25837

PR Close #25839
2021-01-11 10:49:44 -08:00
Andrew Scott 74175f84ea fix(router): Remove usage of `Object.values` to avoid the need for a polyfill (#40370)
`Object.values` is not supported in IE11 without a polyfill. The quickest,
most straightfoward fix for this is to simply use `Object.keys` instead.
We may want to consider including the polyfill in the CLI in the future
or just wait until IE11 support is dropped before using
`Object.values`.

PR Close #40370
2021-01-09 16:36:21 -08:00
Andrew Scott b36bece17c docs(router): Clearly document how to retrieve all params in the router tree (#40306)
This commit documents how to add a helper function which combines all the params
in the router state tree into a single object. It provides a starting point for
developers to reference if they require a more fine-tuned approach.

Fixes #11023

PR Close #40306
2021-01-08 11:47:47 -08:00
Andrew Scott 2028a43580 fix(router): Remove usage of `Object.entries` to avoid the need for a polyfill (#40340)
`Object.entries` is not supported in IE11 without a polyfill. The quickest,
most straightfoward fix for this is to simply use `Object.keys` instead.
We may want to consider including the polyfill in the CLI in the future
or just wait until IE11 support is dropped before using
`Object.entries`.

PR Close #40340
2021-01-07 11:45:58 -08:00
Andrew Scott 13020f904f fix(router): correctly deactivate children with componentless parent (#40196)
During route activation, a componentless route will not have a context created
for it, but the logic continues to recurse so that children are still
activated. This can be seen here:
362f45c4bf/packages/router/src/operators/activate_routes.ts (L151-L158)

The current deactivation logic does not currently account for componentless routes.

This commit adjusts the deactivation logic so that if a context cannot
be retrieved for a given route (because it is componentless), we
continue to recurse and deactivate the children using the same
`parentContexts` in the same way that activation does.

Fixes #20694

PR Close #40196
2021-01-06 13:49:30 -08:00
Andrew Scott 605775398f docs(router): Clarify 'parent' for params inheritance (#40304)
When talking about parameter inheritance, one might think that matrix
parameters can be inherited from the "parent" segment, or the segment
which appears immediately to the left. In reality, when we talk about
a "parent" in the `Router`, we mean the parent `Route` config. This
config may contain more than one segment and matrix parameters must
appear at the end or they do not "belong" to any config.

PR Close #40304
2021-01-05 13:54:41 -08:00
Andrew Scott e43f7e26fe fix(router): apply redirects should match named outlets with empty path parents (#40029)
There are two parts to this commit:
1. Revert the changes from #38379. This change had an incomplete view of
how things worked and also diverged the implementations of
`applyRedirects` and `recognize` even more.
2. Apply the fixes from the `recognize` algorithm to ensure that named
outlets with empty path parents can be matched. This change also passes
all the tests that were added in #38379 with the added benefit of being
a more complete fix that stays in-line with the `recognize` algorithm.
This was made possible by using the same approach for `split` by
always creating segments for empty path matches (previously, this was
only done in `applyRedirects` if there was a `redirectTo` value). At the
end of the expansions, we need to squash all empty segments so that
serializing the final `UrlTree` returns the same result as before.

Fixes #39952
Fixes #10726
Closes #30410

PR Close #40029
2021-01-05 12:43:47 -08:00
Andrew Scott 5842467134 refactor(router): Extract common functions for config matching (#40029)
The `applyRedirects` and `recognize` algorithms have the same overall goal:
match a `UrlTree` with the application's `Routes` config. There are a
few key functions in these algorithms which can be shared rather than
duplicated between the two. This also makes it easier to see how the two
are similar and where they diverge.

PR Close #40029
2021-01-05 12:43:47 -08:00
Andrew Scott 3966bcc5d9 fix(router): Ensure named outlets with empty path parents are recognized (#40029)
This commit updates the `recognize` algorithm to work with named outlets
which have empty path parents. For example, given the following config

```
  const routes = [
    {
      path: '',
      children: [
        {path: 'a', outlet: 'aux', component: AuxComponent}
    ]}
  ];
```

The url `/(aux:a)` should match this config. In order to do so, we need
to allow the children of `UrlSegmentGroup`s to match a `Route` config
for a different outlet (in this example, the `primary`) when it's an
empty path. This should also *only* happen if we were unable to find a
match for the outlet in the level above. That is, the matching strategy
is to find the first `Route` in the list which _matches the given
outlet_. If we are unable to do that, then we allow empty paths from
other outlets to match and try to find some child there whose outlet
matches our segment.

PR Close #40029
2021-01-05 12:43:47 -08:00
Andrew Scott a9f8deb173 refactor(router): make `recognize` synchronous (#40029)
To make the tests suite easier to follow, `Recognize#apply` can be made
into a synchronous function rather than one that return an `Observable`.

Also, as a chore, remove as many `any` types as possible.

PR Close #40029
2021-01-05 12:43:47 -08:00
Andrew Scott 6f1609e092 refactor(router): Update `recognize` to return `null` when there is no match (#40029)
This commit updates the `recognize` algorithm to return `null` when a
segment does not match a given config rather than throwing an error.
This makes the code much easier to follow because the "no match" result
has to be explicitly handled rather than catching the error in very
specific places.

PR Close #40029
2021-01-05 12:43:47 -08:00
Andrew Scott 77f47da016 refactor(router): Use for...of rather than `mapChildrenIntoArray` helper (#40029)
When stepping through the `recognize` algorithm, it is much easier to
follow when using a simple `for...of` rather than the helper
`mapChildrenIntoArray` with the passed closure. The only special thing that
`mapChildrenIntoArray` does is ensure the primary route appears first.
This change will have no affect on the result because `processChildren` later calls
`sortActivatedRouteSnapshots`, which does the same thing.

PR Close #40029
2021-01-05 12:43:47 -08:00
Andrew Scott df85f3727f refactor(router): Produce error message when canActivate is used with redirectTo (#40067)
Redirects in the router are processed before activations. This means that a canActivate will
never execute if a route has a redirect. Rather than silently ignoring
the invalid config, developers should be notified so they know why it
doesn't work.

Closes #18605
The feature request for a function/class redirect is covered in #13373.

PR Close #40067
2021-01-05 10:09:27 -08:00
Howard Jing c22d00547a docs(router): fix typo (#40244)
Replace the word Angualr with Angular.

PR Close #40244
2020-12-23 10:05:31 -08:00
Miloš Lapiš 19b9ec8e4b docs(router): Correct equivalent for 'enabled' initial navigation (#40061)
With regard to the code in `router_module.ts`, the correct equivalent for `enabled`
should be` enabledBlocking` and not `enabledNonBlocking`.

PR Close #40061
2020-12-10 14:07:42 -08:00
Andrew Scott 112324a614 feat(router): add `relativeTo` as an input to `routerLink` (#39720)
Allow configuration of `relativeTo` in the `routerLink` directive. This
is related to the clearing of auxiliary routes, where you need to use
`relativeTo: route.parent` in order to clear it from the activated
auxiliary component itself. This is because `relativeTo: route` will
consume the segment that we're trying to clear, so there is really no
way to do this with routerLink at the moment.

Related issue: #13523
Related (internal link): https://yaqs.corp.google.com/eng/q/5999443644645376

PR Close #39720
2020-12-10 11:21:00 -08:00
Marcono1234 3e1e5a15ba docs: update links to use HTTPS as protocol (#39718)
PR Close #39718
2020-11-20 12:52:16 -08:00
Andrew Scott c33a8235d9 fix(router): correctly handle string command in outlets (#39728)
There are many places where examples use just a string for the command
in outlets. When using nested outlets, we do not correctly handle
this case, as the types and algorithm always expect an array.
This PR updates the `createUrlTree` algorithm to account for the
possibility of a string literal as the command for an outlet.

Fixes #18928

PR Close #39728
2020-11-20 08:38:31 -08:00
cexbrayat 5fa767363d fix(router): remove duplicated getOutlet function (#39764)
The codebase currently contains two `getOutlet` functions,
and they can end up in the bundle of an application.
A recent commit 6fbe21941d tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated functions.

This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `router/src/utils/config`.

PR Close #39764
2020-11-20 08:31:14 -08:00
WilliamKoza b1d300dc26 fix(common): Prefer to use pageXOffset / pageYOffset instance of scrollX / scrollY (#28262)
This fix ensures a better cross-browser compatibility.
This fix has been used for angular.io.

PR Close #28262
2020-11-19 12:22:03 -08:00
Andrew Scott 3af585c004 fix(router): Ensure all outlets are used when commands have a prefix (#39456)
When there is a primary outlet present in the outlets map and the object is also prefixed
with some other commands, the current logic only uses the primary outlet and ignores
the others. This change ensures that all outlets are respected at the
segment level when prefixed with other commands.

PR Close #39456
2020-10-30 16:23:03 -07:00
Andrew Scott ff7a62ee21 refactor(router): Small refactor of createUrlTree and extra tests (#39456)
This commit has a small refactor of some methods in create_url_tree.ts
and adds some test cases, including two that will fail at the moment but
should pass. A follow-up commit will make use of the refactorings to fix
the test with minimal changes.

PR Close #39456
2020-10-30 16:23:03 -07:00