committed by
Rado Kirov
parent
800c8f196f
commit
8bea667a0b
@@ -0,0 +1,58 @@
|
||||
import {Injectable} from 'angular2/core';
|
||||
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';
|
||||
|
||||
/**
|
||||
* `PlatformLocation` encapsulates all of the direct calls to platform APIs.
|
||||
* This class should not be used directly by an application developer. Instead, use
|
||||
* {@link Location}.
|
||||
*/
|
||||
@Injectable()
|
||||
export class BrowserPlatformLocation extends PlatformLocation {
|
||||
private _location: Location;
|
||||
private _history: History;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._init();
|
||||
}
|
||||
|
||||
// This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
|
||||
/** @internal */
|
||||
_init() {
|
||||
this._location = DOM.getLocation();
|
||||
this._history = DOM.getHistory();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
get location(): Location { return this._location; }
|
||||
|
||||
getBaseHrefFromDOM(): string { return DOM.getBaseHref(); }
|
||||
|
||||
onPopState(fn: UrlChangeListener): void {
|
||||
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
|
||||
}
|
||||
|
||||
onHashChange(fn: UrlChangeListener): void {
|
||||
DOM.getGlobalEventTarget('window').addEventListener('hashchange', fn, false);
|
||||
}
|
||||
|
||||
get pathname(): string { return this._location.pathname; }
|
||||
get search(): string { return this._location.search; }
|
||||
get hash(): string { return this._location.hash; }
|
||||
set pathname(newPath: string) { this._location.pathname = newPath; }
|
||||
|
||||
pushState(state: any, title: string, url: string): void {
|
||||
this._history.pushState(state, title, url);
|
||||
}
|
||||
|
||||
replaceState(state: any, title: string, url: string): void {
|
||||
this._history.replaceState(state, title, url);
|
||||
}
|
||||
|
||||
forward(): void { this._history.forward(); }
|
||||
|
||||
back(): void { this._history.back(); }
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
APP_BASE_HREF,
|
||||
normalizeQueryParams
|
||||
} from './location_strategy';
|
||||
import {EventListener} from 'angular2/src/facade/browser';
|
||||
import {UrlChangeListener} from './platform_location';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {PlatformLocation} from './platform_location';
|
||||
|
||||
@@ -58,7 +58,7 @@ export class HashLocationStrategy extends LocationStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
onPopState(fn: EventListener): void {
|
||||
onPopState(fn: UrlChangeListener): void {
|
||||
this._platformLocation.onPopState(fn);
|
||||
this._platformLocation.onHashChange(fn);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {OpaqueToken} from 'angular2/core';
|
||||
import {UrlChangeListener} from './platform_location';
|
||||
|
||||
/**
|
||||
* `LocationStrategy` is responsible for representing and reading route state
|
||||
@@ -24,7 +25,7 @@ export abstract class LocationStrategy {
|
||||
abstract replaceState(state: any, title: string, url: string, queryParams: string): void;
|
||||
abstract forward(): void;
|
||||
abstract back(): void;
|
||||
abstract onPopState(fn: (_: any) => any): void;
|
||||
abstract onPopState(fn: UrlChangeListener): void;
|
||||
abstract getBaseHref(): string;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {Injectable, Inject, Optional} from 'angular2/core';
|
||||
import {EventListener, History, Location} from 'angular2/src/facade/browser';
|
||||
import {isBlank} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {
|
||||
@@ -8,7 +7,7 @@ import {
|
||||
normalizeQueryParams,
|
||||
joinWithSlash
|
||||
} from './location_strategy';
|
||||
import {PlatformLocation} from './platform_location';
|
||||
import {PlatformLocation, UrlChangeListener} from './platform_location';
|
||||
|
||||
/**
|
||||
* `PathLocationStrategy` is a {@link LocationStrategy} used to configure the
|
||||
@@ -75,7 +74,7 @@ export class PathLocationStrategy extends LocationStrategy {
|
||||
this._baseHref = href;
|
||||
}
|
||||
|
||||
onPopState(fn: EventListener): void {
|
||||
onPopState(fn: UrlChangeListener): void {
|
||||
this._platformLocation.onPopState(fn);
|
||||
this._platformLocation.onHashChange(fn);
|
||||
}
|
||||
|
||||
@@ -1,50 +1,48 @@
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {EventListener, History, Location} from 'angular2/src/facade/browser';
|
||||
|
||||
/**
|
||||
* `PlatformLocation` encapsulates all of the direct calls to platform APIs.
|
||||
* This class should not be used directly by an application developer. Instead, use
|
||||
* {@link Location}.
|
||||
*
|
||||
* `PlatformLocation` encapsulates all calls to DOM apis, which allows the Router to be platform
|
||||
* agnostic.
|
||||
* This means that we can have different implementation of `PlatformLocation` for the different
|
||||
* platforms
|
||||
* that angular supports. For example, the default `PlatformLocation` is {@link
|
||||
* BrowserPlatformLocation},
|
||||
* however when you run your app in a WebWorker you use {@link WebWorkerPlatformLocation}.
|
||||
*
|
||||
* The `PlatformLocation` class is used directly by all implementations of {@link LocationStrategy}
|
||||
* when
|
||||
* they need to interact with the DOM apis like pushState, popState, etc...
|
||||
*
|
||||
* {@link LocationStrategy} in turn is used by the {@link Location} service which is used directly
|
||||
* by
|
||||
* the {@link Router} in order to navigate between routes. Since all interactions between {@link
|
||||
* Router} /
|
||||
* {@link Location} / {@link LocationStrategy} and DOM apis flow through the `PlatformLocation`
|
||||
* class
|
||||
* they are all platform independent.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PlatformLocation {
|
||||
private _location: Location;
|
||||
private _history: History;
|
||||
export abstract class PlatformLocation {
|
||||
abstract getBaseHrefFromDOM(): string;
|
||||
abstract onPopState(fn: UrlChangeListener): void;
|
||||
abstract onHashChange(fn: UrlChangeListener): void;
|
||||
|
||||
constructor() { this._init(); }
|
||||
pathname: string;
|
||||
search: string;
|
||||
hash: string;
|
||||
|
||||
// This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
|
||||
/** @internal */
|
||||
_init() {
|
||||
this._location = DOM.getLocation();
|
||||
this._history = DOM.getHistory();
|
||||
}
|
||||
abstract replaceState(state: any, title: string, url: string): void;
|
||||
|
||||
getBaseHrefFromDOM(): string { return DOM.getBaseHref(); }
|
||||
abstract pushState(state: any, title: string, url: string): void;
|
||||
|
||||
onPopState(fn: EventListener): void {
|
||||
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
|
||||
}
|
||||
abstract forward(): void;
|
||||
|
||||
onHashChange(fn: EventListener): void {
|
||||
DOM.getGlobalEventTarget('window').addEventListener('hashchange', fn, false);
|
||||
}
|
||||
|
||||
get pathname(): string { return this._location.pathname; }
|
||||
get search(): string { return this._location.search; }
|
||||
get hash(): string { return this._location.hash; }
|
||||
set pathname(newPath: string) { this._location.pathname = newPath; }
|
||||
|
||||
pushState(state: any, title: string, url: string): void {
|
||||
this._history.pushState(state, title, url);
|
||||
}
|
||||
|
||||
replaceState(state: any, title: string, url: string): void {
|
||||
this._history.replaceState(state, title, url);
|
||||
}
|
||||
|
||||
forward(): void { this._history.forward(); }
|
||||
|
||||
back(): void { this._history.back(); }
|
||||
abstract back(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A serializable version of the event from onPopState or onHashChange
|
||||
*/
|
||||
export interface UrlChangeEvent { type: string; }
|
||||
|
||||
export interface UrlChangeListener { (e: UrlChangeEvent): any; }
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// import {ROUTER_PROVIDERS_COMMON} from './router_providers_common';
|
||||
import {ROUTER_PROVIDERS_COMMON} from 'angular2/router';
|
||||
import {Provider} from 'angular2/core';
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {BrowserPlatformLocation} from './browser_platform_location';
|
||||
import {PlatformLocation} from './platform_location';
|
||||
|
||||
/**
|
||||
* A list of {@link Provider}s. To use the router, you must add this to your application.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/iRUP8B5OUbxCWQ3AcIDm))
|
||||
*
|
||||
* ```
|
||||
* import {Component} from 'angular2/core';
|
||||
* import {
|
||||
* ROUTER_DIRECTIVES,
|
||||
* ROUTER_PROVIDERS,
|
||||
* RouteConfig
|
||||
* } from 'angular2/router';
|
||||
*
|
||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
||||
* @RouteConfig([
|
||||
* {...},
|
||||
* ])
|
||||
* class AppCmp {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* bootstrap(AppCmp, [ROUTER_PROVIDERS]);
|
||||
* ```
|
||||
*/
|
||||
export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
|
||||
ROUTER_PROVIDERS_COMMON,
|
||||
CONST_EXPR(new Provider(PlatformLocation, {useClass: BrowserPlatformLocation})),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Use {@link ROUTER_PROVIDERS} instead.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const ROUTER_BINDINGS = ROUTER_PROVIDERS;
|
||||
@@ -0,0 +1,40 @@
|
||||
import {LocationStrategy} from 'angular2/src/router/location_strategy';
|
||||
import {PathLocationStrategy} from 'angular2/src/router/path_location_strategy';
|
||||
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';
|
||||
import {CONST_EXPR, Type} from 'angular2/src/facade/lang';
|
||||
import {ApplicationRef, OpaqueToken, Provider} from 'angular2/core';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
/**
|
||||
* The Platform agnostic ROUTER PROVIDERS
|
||||
*/
|
||||
export const ROUTER_PROVIDERS_COMMON: any[] = CONST_EXPR([
|
||||
RouteRegistry,
|
||||
CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})),
|
||||
Location,
|
||||
CONST_EXPR(new Provider(
|
||||
Router,
|
||||
{
|
||||
useFactory: routerFactory,
|
||||
deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT, ApplicationRef])
|
||||
})),
|
||||
CONST_EXPR(new Provider(
|
||||
ROUTER_PRIMARY_COMPONENT,
|
||||
{useFactory: routerPrimaryComponentFactory, deps: CONST_EXPR([ApplicationRef])}))
|
||||
]);
|
||||
|
||||
function routerFactory(registry: RouteRegistry, location: Location, primaryComponent: Type,
|
||||
appRef: ApplicationRef): RootRouter {
|
||||
var rootRouter = new RootRouter(registry, location, primaryComponent);
|
||||
appRef.registerDisposeListener(() => rootRouter.dispose());
|
||||
return rootRouter;
|
||||
}
|
||||
|
||||
function routerPrimaryComponentFactory(app: ApplicationRef): Type {
|
||||
if (app.componentTypes.length == 0) {
|
||||
throw new BaseException("Bootstrap at least one component before injecting Router.");
|
||||
}
|
||||
return app.componentTypes[0];
|
||||
}
|
||||
Reference in New Issue
Block a user