refactor(Location): out of router and into platform/common

closes https://github.com/angular/angular/issues/4943

BREAKING CHANGE:

`Location` and other related providers have been moved out of `router` and into `platform/common`. `BrowserPlatformLocation` is not meant to be used directly however advanced configurations may use it via the following import change.

Before:

```
import {
  PlatformLocation,
  Location,
  LocationStrategy,
  HashLocationStrategy,
  PathLocationStrategy,
  APP_BASE_HREF}
from 'angular2/router';

import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';
```

After:

```
import {
  PlatformLocation,
  Location,
  LocationStrategy,
  HashLocationStrategy,
  PathLocationStrategy,
  APP_BASE_HREF}
from 'angular2/platform/common';

import {BrowserPlatformLocation} from 'angular2/src/platform/browser/location/browser_platform_location';
```

Closes #7962
This commit is contained in:
Nathan Walker
2016-04-08 00:31:20 -07:00
parent 30c43521d3
commit b602bd8c83
55 changed files with 187 additions and 178 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
import {Injectable} from 'angular2/src/core/di';
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
import {ListWrapper} from 'angular2/src/facade/collection';
import {Location} from 'angular2/src/router/location/location';
import {Location} from 'angular2/platform/common';
/**
* A spy for {@link Location} that allows tests to fire simulated location events.
@@ -1,6 +1,6 @@
import {Injectable} from 'angular2/src/core/di';
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
import {LocationStrategy} from 'angular2/src/router/location/location_strategy';
import {LocationStrategy} from 'angular2/platform/common';
/**
@@ -1,7 +1,6 @@
import {Injectable} from 'angular2/core';
import {Injectable} from 'angular2/src/core/di/decorators';
import {UrlChangeListener, PlatformLocation} from './platform_location';
import {History, Location} from 'angular2/src/facade/browser';
import {UrlChangeListener} from './platform_location';
import {PlatformLocation} from './platform_location';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
/**
@@ -1,13 +1,8 @@
import {Injectable, Inject, Optional} from 'angular2/core';
import {
LocationStrategy,
joinWithSlash,
APP_BASE_HREF,
normalizeQueryParams
} from './location_strategy';
import {UrlChangeListener} from './platform_location';
import {LocationStrategy, APP_BASE_HREF} from './location_strategy';
import {Location} from './location';
import {UrlChangeListener, PlatformLocation} from './platform_location';
import {isPresent} from 'angular2/src/facade/lang';
import {PlatformLocation} from './platform_location';
/**
* `HashLocationStrategy` is a {@link LocationStrategy} used to configure the
@@ -23,12 +18,14 @@ import {PlatformLocation} from './platform_location';
* ```
* import {Component, provide} from 'angular2/core';
* import {
* ROUTER_DIRECTIVES,
* ROUTER_PROVIDERS,
* RouteConfig,
* Location,
* LocationStrategy,
* HashLocationStrategy
* } from 'angular2/platform/common';
* import {
* ROUTER_DIRECTIVES,
* ROUTER_PROVIDERS,
* RouteConfig
* } from 'angular2/router';
*
* @Component({directives: [ROUTER_DIRECTIVES]})
@@ -78,12 +75,12 @@ export class HashLocationStrategy extends LocationStrategy {
}
prepareExternalUrl(internal: string): string {
var url = joinWithSlash(this._baseHref, internal);
var url = Location.joinWithSlash(this._baseHref, internal);
return url.length > 0 ? ('#' + url) : url;
}
pushState(state: any, title: string, path: string, queryParams: string) {
var url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams));
var url = this.prepareExternalUrl(path + Location.normalizeQueryParams(queryParams));
if (url.length == 0) {
url = this._platformLocation.pathname;
}
@@ -91,7 +88,7 @@ export class HashLocationStrategy extends LocationStrategy {
}
replaceState(state: any, title: string, path: string, queryParams: string) {
var url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams));
var url = this.prepareExternalUrl(path + Location.normalizeQueryParams(queryParams));
if (url.length == 0) {
url = this._platformLocation.pathname;
}
@@ -1,6 +1,6 @@
import {LocationStrategy} from './location_strategy';
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
import {Injectable, Inject} from 'angular2/core';
import {LocationStrategy} from './location_strategy';
/**
* `Location` is a service that applications can use to interact with a browser's URL.
@@ -22,11 +22,11 @@ import {Injectable, Inject} from 'angular2/core';
*
* ```
* import {Component} from 'angular2/core';
* import {Location} from 'angular2/platform/common';
* import {
* ROUTER_DIRECTIVES,
* ROUTER_PROVIDERS,
* RouteConfig,
* Location
* RouteConfig
* } from 'angular2/router';
*
* @Component({directives: [ROUTER_DIRECTIVES]})
@@ -51,7 +51,7 @@ export class Location {
constructor(public platformStrategy: LocationStrategy) {
var browserBaseHref = this.platformStrategy.getBaseHref();
this._baseHref = stripTrailingSlash(stripIndexHtml(browserBaseHref));
this._baseHref = Location.stripTrailingSlash(_stripIndexHtml(browserBaseHref));
this.platformStrategy.onPopState((ev) => {
ObservableWrapper.callEmit(this._subject, {'url': this.path(), 'pop': true, 'type': ev.type});
});
@@ -67,7 +67,7 @@ export class Location {
* trailing slashes
*/
normalize(url: string): string {
return stripTrailingSlash(_stripBaseHref(this._baseHref, stripIndexHtml(url)));
return Location.stripTrailingSlash(_stripBaseHref(this._baseHref, _stripIndexHtml(url)));
}
/**
@@ -117,6 +117,50 @@ export class Location {
onReturn: () => void = null): Object {
return ObservableWrapper.subscribe(this._subject, onNext, onThrow, onReturn);
}
/**
* Given a string of url parameters, prepend with '?' if needed, otherwise return parameters as
* is.
*/
public static normalizeQueryParams(params: string): string {
return (params.length > 0 && params.substring(0, 1) != '?') ? ('?' + params) : params;
}
/**
* Given 2 parts of a url, join them with a slash if needed.
*/
public static joinWithSlash(start: string, end: string): string {
if (start.length == 0) {
return end;
}
if (end.length == 0) {
return start;
}
var slashes = 0;
if (start.endsWith('/')) {
slashes++;
}
if (end.startsWith('/')) {
slashes++;
}
if (slashes == 2) {
return start + end.substring(1);
}
if (slashes == 1) {
return start + end;
}
return start + '/' + end;
}
/**
* If url has a trailing slash, remove it, otherwise return url as is.
*/
public static stripTrailingSlash(url: string): string {
if (/\/$/g.test(url)) {
url = url.substring(0, url.length - 1);
}
return url;
}
}
function _stripBaseHref(baseHref: string, url: string): string {
@@ -126,17 +170,10 @@ function _stripBaseHref(baseHref: string, url: string): string {
return url;
}
function stripIndexHtml(url: string): string {
function _stripIndexHtml(url: string): string {
if (/\/index.html$/g.test(url)) {
// '/index.html'.length == 11
return url.substring(0, url.length - 11);
}
return url;
}
function stripTrailingSlash(url: string): string {
if (/\/$/g.test(url)) {
url = url.substring(0, url.length - 1);
}
return url;
}
@@ -43,6 +43,7 @@ export abstract class LocationStrategy {
* ```
* import {Component} from 'angular2/core';
* import {ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig} from 'angular2/router';
* import {APP_BASE_HREF} from 'angular2/platform/common';
*
* @Component({directives: [ROUTER_DIRECTIVES]})
* @RouteConfig([
@@ -59,30 +60,3 @@ export abstract class LocationStrategy {
* ```
*/
export const APP_BASE_HREF: OpaqueToken = CONST_EXPR(new OpaqueToken('appBaseHref'));
export function normalizeQueryParams(params: string): string {
return (params.length > 0 && params.substring(0, 1) != '?') ? ('?' + params) : params;
}
export function joinWithSlash(start: string, end: string): string {
if (start.length == 0) {
return end;
}
if (end.length == 0) {
return start;
}
var slashes = 0;
if (start.endsWith('/')) {
slashes++;
}
if (end.startsWith('/')) {
slashes++;
}
if (slashes == 2) {
return start + end.substring(1);
}
if (slashes == 1) {
return start + end;
}
return start + '/' + end;
}
@@ -1,13 +1,9 @@
import {Injectable, Inject, Optional} from 'angular2/core';
import {isBlank} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions';
import {
LocationStrategy,
APP_BASE_HREF,
normalizeQueryParams,
joinWithSlash
} from './location_strategy';
import {PlatformLocation, UrlChangeListener} from './platform_location';
import {LocationStrategy, APP_BASE_HREF} from './location_strategy';
import {Location} from './location';
/**
* `PathLocationStrategy` is a {@link LocationStrategy} used to configure the
@@ -30,12 +26,15 @@ import {PlatformLocation, UrlChangeListener} from './platform_location';
*
* ```
* import {Component, provide} from 'angular2/core';
* import {bootstrap} from 'angular2/platform/browser';
* import {
* Location,
* APP_BASE_HREF
* } from 'angular2/platform/common';
* import {
* ROUTER_DIRECTIVES,
* ROUTER_PROVIDERS,
* RouteConfig,
* Location
* RouteConfig
* } from 'angular2/router';
*
* @Component({directives: [ROUTER_DIRECTIVES]})
@@ -81,19 +80,22 @@ export class PathLocationStrategy extends LocationStrategy {
getBaseHref(): string { return this._baseHref; }
prepareExternalUrl(internal: string): string { return joinWithSlash(this._baseHref, internal); }
prepareExternalUrl(internal: string): string {
return Location.joinWithSlash(this._baseHref, internal);
}
path(): string {
return this._platformLocation.pathname + normalizeQueryParams(this._platformLocation.search);
return this._platformLocation.pathname +
Location.normalizeQueryParams(this._platformLocation.search);
}
pushState(state: any, title: string, url: string, queryParams: string) {
var externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));
var externalUrl = this.prepareExternalUrl(url + Location.normalizeQueryParams(queryParams));
this._platformLocation.pushState(state, title, externalUrl);
}
replaceState(state: any, title: string, url: string, queryParams: string) {
var externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));
var externalUrl = this.prepareExternalUrl(url + Location.normalizeQueryParams(queryParams));
this._platformLocation.replaceState(state, title, externalUrl);
}
@@ -0,0 +1,5 @@
export * from './browser/location/platform_location';
export * from './browser/location/location_strategy';
export * from './browser/location/hash_location_strategy';
export * from './browser/location/path_location_strategy';
export * from './browser/location/location';
@@ -36,7 +36,6 @@ import {BrowserDomAdapter} from './browser/browser_adapter';
import {wtfInit} from 'angular2/src/core/profile/wtf_init';
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';
import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
@@ -45,6 +44,9 @@ import {
ClientMessageBrokerFactory,
ClientMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/client_message_broker';
import {
BrowserPlatformLocation
} from 'angular2/src/platform/browser/location/browser_platform_location';
import {Serializer} from 'angular2/src/web_workers/shared/serializer';
import {ON_WEB_WORKER} from 'angular2/src/web_workers/shared/api';
import {RenderStore} from 'angular2/src/web_workers/shared/render_store';
@@ -1,8 +1,8 @@
import {Directive} from 'angular2/core';
import {Location} from 'angular2/platform/common';
import {isString} from 'angular2/src/facade/lang';
import {Router} from '../router';
import {Location} from '../location/location';
import {Instruction} from '../instruction';
/**
+1 -1
View File
@@ -2,6 +2,7 @@ import {PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/faca
import {Map, StringMapWrapper, MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import {isBlank, isString, isPresent, Type, isArray} from 'angular2/src/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
import {Location} from 'angular2/platform/common';
import {Inject, Injectable} from 'angular2/core';
import {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from './route_registry';
@@ -10,7 +11,6 @@ import {
Instruction,
} from './instruction';
import {RouterOutlet} from './directives/router_outlet';
import {Location} from './location/location';
import {getCanActivateHook} from './lifecycle/route_lifecycle_reflector';
import {RouteDefinition} from './route_config/route_config_impl';
@@ -1,8 +1,10 @@
import {ROUTER_PROVIDERS_COMMON} from './router_providers_common';
import {Provider} from 'angular2/core';
import {
BrowserPlatformLocation
} from 'angular2/src/platform/browser/location/browser_platform_location';
import {PlatformLocation} from 'angular2/platform/common';
import {CONST_EXPR} from 'angular2/src/facade/lang';
import {BrowserPlatformLocation} from './location/browser_platform_location';
import {PlatformLocation} from './location/platform_location';
/**
* A list of {@link Provider}s. To use the router, you must add this to your application.
@@ -1,8 +1,6 @@
import {LocationStrategy} from 'angular2/src/router/location/location_strategy';
import {PathLocationStrategy} from 'angular2/src/router/location/path_location_strategy';
import {LocationStrategy, PathLocationStrategy, Location} from 'angular2/platform/common';
import {Router, RootRouter} from 'angular2/src/router/router';
import {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from 'angular2/src/router/route_registry';
import {Location} from 'angular2/src/router/location/location';
import {CONST_EXPR, Type} from 'angular2/src/facade/lang';
import {ApplicationRef, OpaqueToken, Provider} from 'angular2/core';
import {BaseException} from 'angular2/src/facade/exceptions';
@@ -1,4 +1,7 @@
import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';
import {
BrowserPlatformLocation
} from 'angular2/src/platform/browser/location/browser_platform_location';
import {UrlChangeListener} from 'angular2/platform/common';
import {Injectable} from 'angular2/src/core/di';
import {ROUTER_CHANNEL} from 'angular2/src/web_workers/shared/messaging_api';
import {
@@ -10,7 +13,6 @@ import {bind} from './bind';
import {LocationType} from 'angular2/src/web_workers/shared/serialized_types';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
import {EventEmitter, ObservableWrapper, PromiseWrapper} from 'angular2/src/facade/async';
import {UrlChangeListener} from 'angular2/src/router/location/platform_location';
@Injectable()
export class MessageBasedPlatformLocation {
@@ -1,6 +1,8 @@
import {MessageBasedPlatformLocation} from './platform_location';
import {CONST_EXPR} from 'angular2/src/facade/lang';
import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';
import {
BrowserPlatformLocation
} from 'angular2/src/platform/browser/location/browser_platform_location';
import {APP_INITIALIZER, Provider, Injector, NgZone} from 'angular2/core';
export const WORKER_RENDER_ROUTER = CONST_EXPR([
@@ -1,15 +1,11 @@
import {Injectable} from 'angular2/src/core/di';
import {
PlatformLocation,
UrlChangeEvent,
UrlChangeListener
} from 'angular2/src/router/location/platform_location';
import {
FnArg,
UiArguments,
ClientMessageBroker,
ClientMessageBrokerFactory
} from 'angular2/src/web_workers/shared/client_message_broker';
import {PlatformLocation, UrlChangeEvent, UrlChangeListener} from 'angular2/platform/common';
import {ROUTER_CHANNEL} from 'angular2/src/web_workers/shared/messaging_api';
import {LocationType} from 'angular2/src/web_workers/shared/serialized_types';
import {PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
@@ -1,5 +1,5 @@
import {ApplicationRef, Provider, NgZone, APP_INITIALIZER} from 'angular2/core';
import {PlatformLocation} from 'angular2/src/router/location/platform_location';
import {PlatformLocation} from 'angular2/platform/common';
import {WebWorkerPlatformLocation} from './platform_location';
import {ROUTER_PROVIDERS_COMMON} from 'angular2/src/router/router_providers_common';