Commit Graph

563 Commits

Author SHA1 Message Date
Andrew Scott 3c6b653089 feat(router): Option to correctly restore history on failed navigation (#43289)
Exposes implementation from #38884 as a public opt-in option.

From that commit:
> 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.

Resolves #13586

PR Close #43289
2021-09-02 17:46:35 +00:00
Ahmed Ayed c6a93001eb fix(common): synchronise location mock behavior with the navigators (#41730)
* Do not emit url pop on Location.go
* Emit a `popstate` event before each `hashchange` to have the same
behavior of the browser.
* Track the url change in the internal history when calling `simulateHashChange`

The changes to the router tests reflect the goals of the test.
Generally when `Location.go` is used to trigger navigations, it is only
relevant for `HashLocationStrategy` and verifying that the Router picks
up changes from manual URL changes. To do this, we convert those calls
to `simulateHashChange` instead.
Manual URL bar changes to the path when not using the `HashLocationStrategy`
would otherwise trigger a full page refresh so they aren't relevant to
these test scenarios which assert correct behavior during the lifetime
of the router.

[Reference for no `popstate` on `pushState`/`replaceState`](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event)
> Note that just calling history.pushState() or history.replaceState() won't
trigger a popstate event. The popstate event will be triggered by doing a browser
action such as a click on the back or forward button (or calling history.back()
or history.forward() in JavaScript).

[Reference for `popstate` before `hashChange`](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event#when_popstate_is_sent)

>  When the transition occurs, either due to the user triggering the browser's
> "Back" button or otherwise, the popstate event is near the end of the process to transition to the new location
...
> 12. If the value of state changed, the popstate event is sent to the document.
> 13. Any persisted user state is restored, if the browser chooses to do so.
> 14. If the original and new entry's shared the same document, but had different fragments in their URLs, send the hashchange event to the window.

BREAKING CHANGE:

The behavior of the `SpyLocation` used by the `RouterTestingModule` has changed
to match the behavior of browsers. It no longer emits a 'popstate' event
when `Location.go` is called. In addition, `simulateHashChange` now
triggers _both_ a `hashchange` and a `popstate` event.
Tests which use `location.go` and expect the changes to be picked up by
the `Router` should likely change to `simulateHashChange` instead.
Each test is different in what it attempts to assert so there is no
single change that works for all tests. Each test using the `SpyLocation` to
simulate browser URL changes should be evaluated on a case-by-case basis.

fixes #27059

PR Close #41730
2021-09-02 16:53:47 +00:00
Alan Agius 95f3aecc29 fix(router): add more context to Unhandled Navigation Error (#43291)
Previously, the error message was not added to `Unhandled Navigation Error`

Before
```
main.js:1 Unhandled Navigation Errors:
```

After
```
main.js:1 Unhandled Navigation Errors: SecurityError: Failed to execute 'replaceState' on 'History': A history state object with URL 'http://localhost:4200/' cannot be created in a document with origin 'http://127.0.0.1:8080' and URL 'http://127.0.0.1:8080/'.
```

PR Close #43291
2021-09-01 21:15:00 +00:00
anandtiwary faf9f5a3bc feat(router): new output that would notify when link is activated (#43280)
This commit adds a new output to `routerLinkActive` directive.
Whenever, the associated link becomes active or inactive, an
event will be fired on this out with the correct status

PR Close #37284

PR Close #43280
2021-09-01 08:23:15 -07:00
Andrew Scott 78690ee354 docs(router): Fix incorrect name for url match options (#43268)
fixes #43123

PR Close #43268
2021-08-26 10:07:23 -07:00
Andrew Scott ccb09b4558 fix(router): null/undefined routerLink should disable navigation (#43087)
The current behavior of `routerLink` for `null` and `undefined` inputs is to treat
the input the same as `[]`. This creates several unresolvable issues with
correctly disabling the links because `commands = []` does _not_ behave the same
as disabling a link. Instead, it navigates to the current page, but will also
clear any fragment and/or query params.

The new behavior of the `routerLink` input will be to completely disable navigation
for `null` and `undefined` inputs. For HTML Anchor elements, this will also mean
removing the `href` attribute.

Fixes #21457
Fixes #13980
Fixes #31154

BREAKING CHANGE:
Previously `null` and `undefined` inputs for `routerLink` were
equaivalent to empty string and there was no way to disable the link's
navigation.
In addition, the `href` is changed from a property `HostBinding()` to an
attribute binding (`HostBinding('attr.href')`). The effect of this
change is that `DebugElement.properties['href']` will now return the
`href` value returned by the native element which will be the full URL
rather than the internal value of the `RouterLink` `href` property.

PR Close #43087
2021-08-20 12:51:09 -07:00
Andrew Scott 286b2807de fix(router): eagerly update internal state on browser-triggered navigations (#43102)
The management of `browserUrlTree` currently has several problems with
correctly tracking the actual state of the browser.

This change makes the Router eagerly update the `browserUrlTree` when
handling navigations triggered by browser events (i.e., not 'imperative'). This
is because with those types of navigations, the browser URL bar is
_already_ updated. If we do not update the internal tracking of the
`browserUrlTree`, we will be out of sync with the real URL if the
navigation is rejected.

It would be best if we could remove `browserUrlTree` completely, but doing that
would require a lot more investigation and is blocked by #27059 because
the SpyLocation used in tests does not emulate real browser behavior.

fixes #43101

PR Close #43102
2021-08-16 09:33:23 -07:00
Andrew Scott bbad42310b fix(router): ensure check for match options is compatible with property renaming (#43086)
After renaming, 'paths' is not in routerLinkOptions since it's been renamed.

PR Close #43086
2021-08-09 10:26:07 -07:00
Jon Rimmer 784671597e fix(router): Allow question marks in query param values (#31187)
According to the URI spec, question mark characters are valid in query data,
so these should accepted by the param parsing.

See https://tools.ietf.org/html/rfc3986#section-3.4

Fixes #31116

BREAKING CHANGE: The default url serializer would previously drop
everything after and including a question mark in query parameters. That
is, for a navigation to `/path?q=hello?&other=123`, the query
params would be parsed to just `{q: 'hello'}`. This is
incorrect because the URI spec allows for question mark characers in
query data. This change will now correctly parse the params for the
above example to be `{v: 'hello?', other: '123'}`.

PR Close #31187
2021-08-06 10:49:37 -07:00
Kristiyan Kostadinov 9a3cf661a2 refactor(core): update peerDependencies to allow rxjs7 (#42991)
We can't update the framework to rxjs7 until version 13, because it contains breaking changes, but we can allow users to opt into it since all of our code should be compatible.

These changes expand the allowed version range of rxjs and add an integration test to verify that we don't get compilation errors. Note that we also have a test that runs the AIO examples against rxjs 7 already (#42660).

Fixes #41897.

PR Close #42991
2021-08-02 13:55:01 -07:00
Andrew Kushnir 8861d73e7f build: rename shims_for_IE.js -> shims_for_internal_tests.js (#43002)
This commit renames shims_for_IE.js -> shims_for_internal_tests.js, since there are no IE shims there anymore (there are still shims for older Safari and Android versions).

PR Close #43002
2021-08-02 10:38:42 -07:00
Steven Masala 0d81b007e4 fix(router): add missing outlet events to RouterOutletContract (#42431)
Exposes both activateEvents and deactivateEvents as the original outlet interface did.

PR Close #42431
2021-07-27 16:34:24 -07:00
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
Andrew Scott a6c256fcd6 docs: Add import line to router event example for clarification (#42935)
Without the `import {Event} from '@angular/router';`, the filter will
not work because the type is understood as the native `Event`.

Fixes #42920

PR Close #42935
2021-07-23 12:06:34 -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
Paul Gschwendtner abc77a6a39 refactor(router): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `router` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:15 -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
Paul Gschwendtner 9db69a9c9e build: use api-golden tool from dev-infra for testing public API (#42688)
Switches our TS API guardian targets to rather use the new tool from
dev-infra that relies on Microsoft's API extractor.

PR Close #42688
2021-06-30 11:43:48 -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
Andrew Scott 536c3738ba docs: clarify onSameUrlNavigation behavior (#42275)
`onSameUrlNavigation` only affects whether the Angular Router
processes the URL and runs it through the navigation pipeline,
retriggering redirects, guards, and resolvers. The name `reload` is a
little confusing because it does _not_ reload the component. Developers
_also_ need to implement a custom `RouteReuseStrategy` to trigger a
component reload on same URL navigation.

Fixes #21115

PR Close #42275
2021-06-09 09:45:25 -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
Paul Gschwendtner 2d0ff0a5d3 ci: add lint error for files with missing trailing new-line (#42478)
For quite a while it is an unspoken convention to add a trailing
new-line files within the Angular repository. This was never enforced
automatically, but has been frequently raised in pull requests through
manual review. This commit sets up a lint rule so that this is
"officially" enforced and doesn't require manual review.

PR Close #42478
2021-06-04 13:31:03 -07:00
Paul Gschwendtner 25f763cff8 feat(core): support TypeScript 4.3 (#42022)
Switches the repository to TypeScript 4.3 and the latest
version of tslib. This involves updating the peer dependency
ranges on `typescript` for the compiler CLI and for the Bazel
package. Tests for new TypeScript features have been added to
ensure compatibility with Angular's ngtsc compiler.

PR Close #42022
2021-06-04 11:17:09 -07:00
Andrew Scott 6a2e3e2b2c docs: change Navigation from type to interface (#42281)
Navigation type should be interface so it can be documented on aio site.

fixes #37384

PR Close #42281
2021-06-01 14:13:20 -07:00
Igor Minar 184de5048a docs: expand documentation for ROUTES (#42398)
Previously the docs were very minimalistic. The most important thing missing from the docs
was that people should primarily use higher level APIs instead of using ROUTES directly.

It would be nice to holistically overhaul more of the router API docs, but that's out of
scope of this change.

Fixes #39350

PR Close #42398
2021-05-27 16:47:39 -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
Andrew Scott 8228170919 docs: document shallow equality emit for ActivatedRoute (#42280)
fixes #40769

PR Close #42280
2021-05-25 22:15:39 +00:00
Andrew Scott 6da0c97423 docs: add note about redirects after absolute redirect (#42277)
This commit addresses the documentation portion of #19069.

PR Close #42277
2021-05-25 22:13:07 +00:00
Andrew Scott ef33806480 docs: add small clarity around navigationCancel (#42282)
Add small clarity to sentence in documentation for navigation cancel event
to indicate that router guards returning false or urlTree is only one of
several reasons a NavigationCancel event happens.

fixes #26613

PR Close #42282
2021-05-25 17:55:22 +00:00
Joey Perrott 617d3f124f build(router): update supported range of node versions to be less restrictive (#42205)
Update the supported range of node versions for to be less restrictive, no longer causing
yarn or npm to fail engine's checks for future versions of node.

While this change will no longer cause yarn or npm to fail these engine's check, this does
not reflect a change in the officially supported versions of node for Angular.  Angular
continues to maintain support for Active LTS and Maintenance LTS versions of node.

PR Close #42205
2021-05-25 17:48:46 +00:00
Andrew Scott a39169851e docs: clarify pathMatch strategy prefix (#42287)
This commit clarifies the description of the default `pathMatch`
strategy (prefix) to indicate that the path segments must each match to
a config.

fixes #39737

PR Close #42287
2021-05-24 15:43:31 -07:00
Joey Perrott 2dd956421c build: remove publishConfig entry from package.json entries (#42104)
Remove publishConfig property from the package.json entry for each of the entries in
the publish configuration.  Using the wombat proxy is now ensured/managed by the
ng-dev release tooling.

PR Close #42104
2021-05-18 15:41:33 -07:00
David Shevitz 5b9a36cf95 docs: move all existing router documentation into a single location and add two new topics: an overview and a reference (#41972)
PR Close #41972
2021-05-18 15:39:38 -07:00
Julien Marcou 562a782114 docs: fix package name in version.ts files in different packages (#41208)
PR Close #41208
2021-05-10 10:26:34 -04:00
Joey Perrott 961296adf5 fix(router): update supported range of node versions to only include LTS versions (#41822)
Update the supported range of node versions for Angular to only include supported LTS versions.

PR Close #41822
2021-04-26 15:21:13 -07: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:
https://github.com/angular/angular/blob/1d12c50f63f90c91636185b2287e31e9c0291121/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