Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(common): add a LocationUpgradeService to mimic AngularJS functionality #30055

Closed
wants to merge 13 commits into from

Conversation

Projects
None yet
5 participants
@jasonaden
Copy link
Contributor

commented Apr 23, 2019

This PR contains a handful of features related to location services.

Read history.state

Previously there wasn't a way to retrieve history.state from the Location service. The only time the framework exposed this value was in navigation events. This meant if you weren't using the Angular router, there wasn't a way to get access to this history.state value other than going directly to the DOM.

This PR adds an API to retrieve the value of history.state. This will be useful and needed to provide a backwards-compatible Location service that can emulate AngularJS's $location service since we will need to be able to read the state data in order to produce AngularJS location transition events.

This feature will additionally be useful to any application that wants to access state data through Angular rather than going directly to the DOM APIs.

Read URL parts

Without this change, the framework doesn't surface URL parts such as hostname, protocol, and port. This makes it difficult to rebuild a complete URL. This change provides new APIs to read these values.

Location Upgrade ($location)

This PR provides a replacement for $location. The new service is written in Angular, and can be consumed into existing applications by using the downgraded version
of the provider.

Prior to this addition, applications upgrading from AngularJS to Angular could get into a situation where AngularJS wanted to control the URL, and would often parse or serialize the URL in a different way than Angular. Additionally, AngularJS was alerted to URL changes only through the $digest cycle. This provided a buggy feedback loop
from Angular to AngularJS.

With this new LocationUpgradeProvider, the $location methods and events are provided in Angular, and use Angular APIs to make updates to the URL. Additionally, change
s to the URL made by other parts of the Angular framework (such as the Router) will be listened for and will cause events to fire in AngularJS, but will no longer attempt
to update the URL (since it was already updated by the Angular framework).

This centralizes URL reads and writes to Angular and should help provide an easier path to upgrading AngularJS applications to Angular.

jasonaden added some commits Feb 6, 2019

feat(common): add ability to retrieve the state from Location service
Previously there wasn't a way to retrieve `history.state` from the `Location` service. The only time the framework exposed this value was in navigation events. This meant if you weren't using the Angular router, there wasn't a way to get access to this `history.state` value other than going directly to the DOM.

This PR adds an API to retrieve the value of `history.state`. This will be useful and needed to provide a backwards-compatible `Location` service that can emulate AngularJS's `$location` service since we will need to be able to read the state data in order to produce AngularJS location transition events.

This feature will additionally be useful to any application that wants to access state data through Angular rather than going directly to the DOM APIs.
feat(common): add APIs to read component pieces of URL
Without this change, the framework doesn't surface URL parts such as hostname, protocol, and port. This makes it difficult to rebuild a complete URL. This change provides new APIs to read these values.
feat(common): add @angular/common/upgrade package for $location-relat…
…ed APIs

AngularJS's `$location` service doesn't have a direct counterpart in Angular. This is largely because the `Location` service in Angular was pulled out of the `Router`, but was not purpose-built to stand on its own.

This commit adds a new `@angular/common/upgrade` package with the beginnings of a new `LocationUpgradeService`. This service will more closely match the API of AngularJS and provide a way to replace the `$location` service from AngularJS.
feat(common): add MockPlatformLocation to enable more robust testing …
…of Location services

Prior to this change we had a MockLocationStrategy to replace the Path and Hash Location Strategies. However, there wasn't a good way to test the PlatformLocation which is needed for doing things such as setting history.state, using back()/forward(), etc.
feat(common): add ability to track all location changes
This feature adds an `onUrlChange` to Angular's `Location` class. This is useful to track all updates coming from anywhere in the framework. Without this method, it's difficult (or impossible) to track updates run through `location.go()` or `location.replaceState()` as the browser doesn't publish events when `history.pushState()` or `.replaceState()` are run.
fix(common): adjust MockPlatformLocation to set state to new object
When using the `history` API, setting a new `state` and retrieving it does not pass a `===` test to the object used to set the state. In other words, `history.state` is always a copy. This change makes the `MockPlatformLocation` behave in the same way.
feat(common): add UrlCodec type for use with upgrade applications
This abstract class (and AngularJSUrlCodec) are used for serializing and deserializing pieces of a URL string. AngularJS had a different way of doing this than Angular, and using this class in conjunction with the LocationUpgradeService an application can have control over how AngularJS URLs are serialized and deserialized.

@googlebot googlebot added the cla: yes label Apr 23, 2019

@jasonaden jasonaden force-pushed the jasonaden:cleanup_url_uni branch from c54e7f1 to e2ce937 Apr 23, 2019

feat(common): provide replacement for AngularJS $location service
This commit provides a replacement for `$location`. The new service is written in Angular, and can be consumed into existing applications by using the downgraded version
of the provider.

Prior to this addition, applications upgrading from AngularJS to Angular could get into a situation where AngularJS wanted to control the URL, and would often parse or se
rialize the URL in a different way than Angular. Additionally, AngularJS was alerted to URL changes only through the `$digest` cycle. This provided a buggy feedback loop
from Angular to AngularJS.

With this new `LocationUpgradeProvider`, the `$location` methods and events are provided in Angular, and use Angular APIs to make updates to the URL. Additionally, change
s to the URL made by other parts of the Angular framework (such as the Router) will be listened for and will cause events to fire in AngularJS, but will no longer attempt
 to update the URL (since it was already updated by the Angular framework).

This centralizes URL reads and writes to Angular and should help provide an easier path to upgrading AngularJS applications to Angular.

@jasonaden jasonaden force-pushed the jasonaden:cleanup_url_uni branch from e2ce937 to d3a87d8 Apr 23, 2019

@ngbot ngbot bot added this to the needsTriage milestone Apr 23, 2019

Show resolved Hide resolved packages/common/test/location/location_spec.ts Outdated
Show resolved Hide resolved packages/common/upgrade/rollup.config.js Outdated
Show resolved Hide resolved packages/common/testing/src/mock_platform_location.ts
Show resolved Hide resolved packages/common/testing/src/mock_platform_location.ts Outdated
Show resolved Hide resolved packages/common/src/location/location.ts Outdated
Show resolved Hide resolved packages/common/testing/tsconfig-build.json
Show resolved Hide resolved packages/common/upgrade/src/params.ts
Show resolved Hide resolved packages/common/upgrade/BUILD.bazel
private initalizing = true;
private updateBrowser = false;
private $$absUrl: string = '';
private $$url: string = '';

This comment has been minimized.

Copy link
@alxhub

alxhub Apr 23, 2019

Contributor

Given that we intentionally provide these $$ fields because people read from them (and so technically they're here to be interface compatible with AngularJS), I would go ahead and make them public API. We want our public API guard to ensure they're not changed without consideration.

This comment has been minimized.

Copy link
@jasonaden

jasonaden Apr 23, 2019

Author Contributor

I'll have this discussion with Igor to see what he thinks. I'm inclined to leave it out because if people are already using TypeScript from Definitely Typed, they will not have these and would have to do casting anyway. See type definition here.

This comment has been minimized.

Copy link
@alxhub

alxhub Apr 24, 2019

Contributor

That makes sense. I was more thinking that we want to make sure we don't inadvertently change any of this API, but maybe having the documentation in place that the class mirrors AngularJS's interface is enough.

Show resolved Hide resolved packages/common/upgrade/src/$location.ts Outdated

@jasonaden jasonaden force-pushed the jasonaden:cleanup_url_uni branch from 1d48209 to bac2e8c Apr 23, 2019

@jasonaden jasonaden force-pushed the jasonaden:cleanup_url_uni branch from bac2e8c to bbb4752 Apr 23, 2019

@jasonaden jasonaden marked this pull request as ready for review Apr 23, 2019

@jasonaden jasonaden requested review from angular/fw-core as code owners Apr 23, 2019

@jasonaden

This comment has been minimized.

Copy link
Contributor Author

commented Apr 24, 2019

@IgorMinar
Copy link
Member

left a comment

let's rename some of the symbols and remove the $locationProvider and peerDep on @angular/upgrade. the rest lgtm from the api perspective.

Show resolved Hide resolved tools/public_api_guard/common/upgrade.d.ts Outdated
Show resolved Hide resolved tools/public_api_guard/common/upgrade.d.ts Outdated
Show resolved Hide resolved tools/public_api_guard/common/upgrade.d.ts Outdated
html5Mode(mode?: any): void;
}

export declare class LocationUpgradeService {

This comment has been minimized.

Copy link
@IgorMinar

@jasonaden jasonaden force-pushed the jasonaden:cleanup_url_uni branch from 0c8d8cf to 768038d Apr 24, 2019

@jasonaden jasonaden force-pushed the jasonaden:cleanup_url_uni branch from 768038d to fb54256 Apr 24, 2019

@IgorMinar IgorMinar modified the milestones: needsTriage, version 8 Apr 24, 2019

@benlesh benlesh closed this in d0672c2 Apr 24, 2019

benlesh added a commit that referenced this pull request Apr 24, 2019

feat(common): add ability to retrieve the state from Location service (
…#30055)

Previously there wasn't a way to retrieve `history.state` from the `Location` service. The only time the framework exposed this value was in navigation events. This meant if you weren't using the Angular router, there wasn't a way to get access to this `history.state` value other than going directly to the DOM.

This PR adds an API to retrieve the value of `history.state`. This will be useful and needed to provide a backwards-compatible `Location` service that can emulate AngularJS's `$location` service since we will need to be able to read the state data in order to produce AngularJS location transition events.

This feature will additionally be useful to any application that wants to access state data through Angular rather than going directly to the DOM APIs.

PR Close #30055

benlesh added a commit that referenced this pull request Apr 24, 2019

feat(common): add APIs to read component pieces of URL (#30055)
Without this change, the framework doesn't surface URL parts such as hostname, protocol, and port. This makes it difficult to rebuild a complete URL. This change provides new APIs to read these values.

PR Close #30055

benlesh added a commit that referenced this pull request Apr 24, 2019

feat(common): add @angular/common/upgrade package for $location-relat…
…ed APIs (#30055)

AngularJS's `$location` service doesn't have a direct counterpart in Angular. This is largely because the `Location` service in Angular was pulled out of the `Router`, but was not purpose-built to stand on its own.

This commit adds a new `@angular/common/upgrade` package with the beginnings of a new `LocationUpgradeService`. This service will more closely match the API of AngularJS and provide a way to replace the `$location` service from AngularJS.

PR Close #30055

benlesh added a commit that referenced this pull request Apr 24, 2019

feat(common): add ability to track all location changes (#30055)
This feature adds an `onUrlChange` to Angular's `Location` class. This is useful to track all updates coming from anywhere in the framework. Without this method, it's difficult (or impossible) to track updates run through `location.go()` or `location.replaceState()` as the browser doesn't publish events when `history.pushState()` or `.replaceState()` are run.

PR Close #30055

benlesh added a commit that referenced this pull request Apr 24, 2019

fix(common): adjust MockPlatformLocation to set state to new object (#…
…30055)

When using the `history` API, setting a new `state` and retrieving it does not pass a `===` test to the object used to set the state. In other words, `history.state` is always a copy. This change makes the `MockPlatformLocation` behave in the same way.

PR Close #30055

benlesh added a commit that referenced this pull request Apr 24, 2019

feat(common): add UrlCodec type for use with upgrade applications (#3…
…0055)

This abstract class (and AngularJSUrlCodec) are used for serializing and deserializing pieces of a URL string. AngularJS had a different way of doing this than Angular, and using this class in conjunction with the LocationUpgradeService an application can have control over how AngularJS URLs are serialized and deserialized.

PR Close #30055

benlesh added a commit that referenced this pull request Apr 24, 2019

feat(common): provide replacement for AngularJS $location service (#3…
…0055)

This commit provides a replacement for `$location`. The new service is written in Angular, and can be consumed into existing applications by using the downgraded version
of the provider.

Prior to this addition, applications upgrading from AngularJS to Angular could get into a situation where AngularJS wanted to control the URL, and would often parse or se
rialize the URL in a different way than Angular. Additionally, AngularJS was alerted to URL changes only through the `$digest` cycle. This provided a buggy feedback loop
from Angular to AngularJS.

With this new `LocationUpgradeProvider`, the `$location` methods and events are provided in Angular, and use Angular APIs to make updates to the URL. Additionally, change
s to the URL made by other parts of the Angular framework (such as the Router) will be listened for and will cause events to fire in AngularJS, but will no longer attempt
 to update the URL (since it was already updated by the Angular framework).

This centralizes URL reads and writes to Angular and should help provide an easier path to upgrading AngularJS applications to Angular.

PR Close #30055

benlesh added a commit that referenced this pull request Apr 24, 2019

benlesh added a commit that referenced this pull request Apr 24, 2019

brandonroberts added a commit to brandonroberts/angular that referenced this pull request Apr 25, 2019

fix(common): add upgrade sub-package to ng_package rule for @angular/…
…common

Follow-up to angular#30055 to include @angular/common/upgrade in the npm package

Closes angular#30116

brandonroberts added a commit to brandonroberts/angular that referenced this pull request Apr 25, 2019

fix(common): add upgrade sub-package to ng_package rule for @angular/…
…common

Follow-up to angular#30055 to include @angular/common/upgrade in the npm package

Closes angular#30116

brandonroberts added a commit to brandonroberts/angular that referenced this pull request Apr 25, 2019

fix(common): add upgrade sub-package to ng_package rule for @angular/…
…common

Follow-up to angular#30055 to include @angular/common/upgrade in the npm package

Closes angular#30116

brandonroberts added a commit to brandonroberts/angular that referenced this pull request Apr 25, 2019

fix(common): add upgrade sub-package to ng_package rule for @angular/…
…common

Follow-up to angular#30055 to include @angular/common/upgrade in the npm package

Closes angular#30116

AndrewKushnir added a commit that referenced this pull request Apr 25, 2019

fix(common): add upgrade sub-package to ng_package rule for @angular/…
…common (#30117)

Follow-up to #30055 to include @angular/common/upgrade in the npm package

Closes #30116

PR Close #30117
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.