Commit Graph

284 Commits

Author SHA1 Message Date
Dmitrij Kuba dbae00195e feat(router): ability to provide custom route reuse strategy via DI for `RouterTestingModule` (#42434)
For now it's not possible to provide custom route reuse strategy via DI
for `RouterTestingModule`, only imperative instantiation. These changes
makes it possible to provide custom route reuse strategy via DI.

PR Close #42434
2021-07-26 12:02:42 -07:00
Andrew Scott 4b49824236 test(router): move computed state restoration tests to own file (#42933)
To reduce the enormouse size of the integration.spec.ts file, move tests related to the computed
state restoration to their own file.

PR Close #42933
2021-07-23 14:25:06 -07:00
Andrew Scott 9119e1f7bd refactor(router): Ensure computed state restoration works for thrown errors (#42933)
When `canceledNavigationResolution='computed'`, the `Router` needs to
handle the cases where errors are thrown. Previously, the logic was not
updated and would simply do a `replaceState` rather than determining
where in the history we should move to restore the page/url from before
the failed navigation.

PR Close #42933
2021-07-23 14:25:06 -07:00
Paul Gschwendtner b5ab7aff43 refactor: add override keyword to members implementing abstract declarations (#42512)
In combination with the TS `noImplicitOverride` compatibility changes,
we also want to follow the best-practice of adding `override` to
members which are implemented as part of abstract classes. This
commit fixes all instances which will be flagged as part of the
custom `no-implicit-override-abstract` TSLint rule.

PR Close #42512
2021-07-12 13:11:17 -07:00
Andrew Scott 3791ae0c95 refactor(router): Adjust behavior for computed navigation restoration (#42751)
When another navigation is triggered during an in-process navigation and
the `canceledNavigationResolution` is `'computed'`, we should not
attempt to restore the browser history using `history.go`. Doing that
would trigger a third navigation through the router which would conflict
with the new navigation that we were trying to process. Instead, we
treat this as a redirect and skip the history restoration attempt. This
acts similarly to returning `UrlTree` from a guard.

Fixes issue described in https://github.com/angular/angular/pull/38884#issuecomment-863767152

PR Close #42751
2021-07-09 10:19:09 -07:00
George Kalpakas 5aa0138726 refactor(service-worker): switch to the official TypeScript typings (#42736)
Previously, we used custom typings for the ServiceWorker environment.
This was necessary back when the ServiceWorker package was introduced,
since there were no official typings.

Since there are now official typings for Web Workers (including
ServiceWorkers) offered by TypeScript as [lib.webworker.d.ts][1], this
commit gets rid of our custom typings in favor of using the official
ones.

[1]: https://github.com/microsoft/TypeScript/blob/v4.3.4/lib/lib.webworker.d.ts

PR Close #42736
2021-07-08 10:28:22 -07:00
Kristiyan Kostadinov 07c1ddc487 fix(router): error if module is destroyed before location is initialized (#42560)
This is something I ran into while working on a fix for the `TestBed` module teardown behavior for #18831. In the `RouterInitializer.appInitializer` we have a callback to the `LOCATION_INITIALIZED` which has to do some DI lookups. The problem is that if the module is destroyed before the location promise resolves, the `Injector.get` calls will fail. This is unlikely to happen in a real app, but it'll show up in unit tests once the test module teardown behavior is fixed.

PR Close #42560
2021-06-17 18:11:53 +00:00
Ahmed Ayed efb440eb2f refactor(router): compute correct history restoration when navigation is cancelled (#38884)
We can’t determine whether the user actually meant the `back` or
the `forward` using the popstate event (triggered by a browser
back/forward)
so we instead need to store information on the state and compute the
distance the user is traveling withing the browser history.
So by using the `History#go` method,
we can bring the user back to the page where he is supposed to be after
performing the action.

implementation for #13586

PR Close #38884
2021-06-10 14:09:21 -07:00
Sam Severance c44ab4f6da fix(router): fix `serializeQueryParams` logic (#42481)
corrects a bug that resulted in query params such as
`[queryParams]={a: 1, b:[]}` being serialized as 'a=1&'
instead of 'a=1'

resolves #42445

PR Close #42481
2021-06-08 10:43:00 -07:00
Kristiyan Kostadinov a787f78074 test: clean up internal testing utilities (#42177)
We have some internal proxies for all of the Jasmine functions, as well as some other helpers. This code hasn't been touched in more than 5 years, it can lead to confusion and it isn't really necessary since the same can be achieved using Jasmine.

These changes remove most of the code and clean up our existing unit tests.

PR Close #42177
2021-05-26 20:07:25 +00:00
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
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
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
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
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
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
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
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 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 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 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 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
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
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
Adam c4becca0e4 feat(router): add new initialNavigation options to replace legacy (#37480)
As of Angular v4, four of the options for
`ExtraOptions#initialNavigation` have been deprecated. We intend
to remove them in v11. The final state for these options is:
`enabledBlocking`, `enabledNonBlocking`, and `disabled`. We plan
to remove and deprecate the remaining option in the next two
major releases.

New options:
- `enabledNonBlocking`: same as legacy_enabled
- `enabledBlocking`: same as enabled

BREAKING CHANGE:

* The `initialNavigation` property for the options in
  `RouterModule.forRoot` no longer supports `legacy_disabled`,
  `legacy_enabled`, `true`, or `false` as valid values.
  `legacy_enabled` (the old default) is instead `enabledNonBlocking`
* `enabled` is deprecated as a valid value for the
  `RouterModule.forRoot` `initialNavigation` option. `enabledBlocking`
  has been introduced to replace it

PR Close #37480
2020-10-14 11:20:51 -07:00
Joey Perrott 783a5bd7bb fix(router): remove preserveQueryParams symbol (#38762)
Remove preserveQueryParams as it was deprecated for removal in v4, use
queryParamsHandling="preserve" instead.

BREAKING CHANGE: preserveQueryParams has been removed, use
queryParamsHandling="preserve" instead

PR Close #38762
2020-10-14 10:40:55 -07:00
Andrew Kushnir 8fd25d9614 docs: remove IE10 references from comments in the code (#39090)
PR Close #39090
2020-10-13 15:51:49 -07:00
Zack Elliott d8c05347c3 fix(router): properly assign ExtraOptions to Router in RouterTestingModule (#39096)
Previously, RouterTestingModule only assigned two of the options within ExtraOptions to the Router.
Now, it assigns the same options as RouterModule does (with the exception of enableTracing) via a
new shared function assignExtraOptionsToRouter.

Fixes #23347

PR Close #39096
2020-10-05 16:35:14 -07:00
Zack Birkenbuel ea1968317e fix(router): update getRouteGuards to check if the context outlet is activated (#39049)
In certain circumstances (errors during component constructor) the router outlet may not be activated before
redirecting to a new route. If the new route requires running guards and resolvers the current logic will throw
when accessing outlet.component due to an isActivated check within the property getter.  This update brings the
logic inline with deactivateRouterAndItsChildren, namely checking outlet.isActivated before trying to access
outlet.component.

Fixes #39030

PR Close #39049
2020-09-30 14:58:47 -07:00
Mathieu Lemoine 3817e5f1df fix(router): Fix arguments order for call to shouldReuseRoute (#26949)
The `createOrReuseChildren` function calls shouldReuseRoute with the
previous child values use as the future and the future child value used
as the current argument. This is incosistent with the argument order in
`createNode`. This inconsistent order can make it difficult/impossible
to correctly implement the `shouldReuseRoute` function. Usually this
order doesn't matter because simple equality checks are made on the
args and it doesn't matter which is which.

More detail can be found in the bug report: #16192.

Fix #16192

BREAKING CHANGE: This change corrects the argument order when calling
RouteReuseStrategy#shouldReuseRoute. Previously, when evaluating child
routes, they would be called with the future and current arguments would
be swapped. If your RouteReuseStrategy relies specifically on only the future
or current snapshot state, you may need to update the shouldReuseRoute
implementation's use of "future" and "current" ActivateRouteSnapshots.

PR Close #26949
2020-09-15 11:33:52 -07:00
Andrew Scott 281865bbcf refactor(router): Remove `defer` as it's not needed anymore (#38781)
This change contains the test from #38780 and also removes `defer` from
the `apply_redirects` logic because the change that introduced
`concatMap` instead of `map`...`concatAll` makes `defer` unnecessary.

PR Close #38781
2020-09-10 08:55:31 -07:00
Andrew Scott 926ffcd8ac fix(router): support lazy loading for empty path named outlets (#38379)
In general, the router only matches and loads a single Route config tree. However,
named outlets with empty paths are a special case where the router can
and should actually match two different `Route`s and ensure that the
modules are loaded for each match.

This change updates the "ApplyRedirects" stage to ensure that named
outlets with empty paths finish loading their configs before proceeding
to the next stage in the routing pipe. This is necessary because if the
named outlet has `loadChildren` but the associated lazy config is not loaded
before following stages attempt to match and activate relevant `Route`s,
an error will occur.

fixes #12842

PR Close #38379
2020-09-08 10:15:21 -07:00
Misko Hevery 8f24bc9443 Revert "fix(router): support lazy loading for empty path named outlets (#38379)"
This reverts commit 7ad32649c0.
2020-08-19 21:05:31 -07:00
Andrew Scott 7ad32649c0 fix(router): support lazy loading for empty path named outlets (#38379)
In general, the router only matches and loads a single Route config tree. However,
named outlets with empty paths are a special case where the router can
and should actually match two different `Route`s and ensure that the
modules are loaded for each match.

This change updates the "ApplyRedirects" stage to ensure that named
outlets with empty paths finish loading their configs before proceeding
to the next stage in the routing pipe. This is necessary because if the
named outlet has `loadChildren` but the associated lazy config is not loaded
before following stages attempt to match and activate relevant `Route`s,
an error will occur.

fixes #12842

PR Close #38379
2020-08-19 11:36:06 -07:00
Andrew Scott dbfb50e9f4 fix(router): ensure routerLinkActive updates when associated routerLinks change (#38511)
This commit introduces a new subscription in the `routerLinkActive` directive which triggers an update
when any of its associated routerLinks have changes. `RouterLinkActive` not only needs to know when
links are added or removed, but it also needs to know about if a link it already knows about
changes in some way.

Quick note that `from...mergeAll` is used instead of just a simple
`merge` (or `scheduled...mergeAll`) to avoid introducing new rxjs
operators in order to keep bundle size down.

Fixes #18469

PR Close #38511
2020-08-18 10:21:49 -07:00