X Tutup
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions modules/angular2/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export {RouterOutlet} from './src/router/router_outlet';
export {RouterLink} from './src/router/router_link';
export {RouteParams, RouteData} from './src/router/instruction';
export {RouteRegistry} from './src/router/route_registry';
export {PlatformLocation} from './src/router/platform_location';
export {LocationStrategy, APP_BASE_HREF} from './src/router/location_strategy';
export {HashLocationStrategy} from './src/router/hash_location_strategy';
export {PathLocationStrategy} from './src/router/path_location_strategy';
Expand All @@ -20,6 +21,7 @@ export {CanActivate} from './src/router/lifecycle_annotations';
export {Instruction, ComponentInstruction} from './src/router/instruction';
export {OpaqueToken} from 'angular2/core';

import {PlatformLocation} from './src/router/platform_location';
import {LocationStrategy} from './src/router/location_strategy';
import {PathLocationStrategy} from './src/router/path_location_strategy';
import {Router, RootRouter} from './src/router/router';
Expand Down Expand Up @@ -111,6 +113,7 @@ export const ROUTER_DIRECTIVES: any[] = CONST_EXPR([RouterOutlet, RouterLink]);
export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
RouteRegistry,
CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})),
PlatformLocation,
Location,
CONST_EXPR(new Provider(
Router,
Expand Down
51 changes: 27 additions & 24 deletions modules/angular2/src/router/hash_location_strategy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {Injectable} from 'angular2/core';
import {LocationStrategy, normalizeQueryParams} from './location_strategy';
import {EventListener, History, Location} from 'angular2/src/facade/browser';
import {Injectable, Inject, Optional} from 'angular2/core';
import {
LocationStrategy,
joinWithSlash,
APP_BASE_HREF,
normalizeQueryParams
} from './location_strategy';
import {EventListener} from 'angular2/src/facade/browser';
import {isPresent} from 'angular2/src/facade/lang';
import {PlatformLocation} from './platform_location';

/**
* `HashLocationStrategy` is a {@link LocationStrategy} used to configure the
Expand Down Expand Up @@ -43,48 +49,45 @@ import {EventListener, History, Location} from 'angular2/src/facade/browser';
*/
@Injectable()
export class HashLocationStrategy extends LocationStrategy {
private _location: Location;
private _history: History;

constructor() {
private _baseHref: string = '';
constructor(private _platformLocation: PlatformLocation,
@Optional() @Inject(APP_BASE_HREF) _baseHref?: string) {
super();
this._location = DOM.getLocation();
this._history = DOM.getHistory();
if (isPresent(_baseHref)) {
this._baseHref = _baseHref;
}
}

onPopState(fn: EventListener): void {
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
}
onPopState(fn: EventListener): void { this._platformLocation.onPopState(fn); }

getBaseHref(): string { return ''; }
getBaseHref(): string { return this._baseHref; }

path(): string {
// the hash value is always prefixed with a `#`
// and if it is empty then it will stay empty
var path = this._location.hash;
var path = this._platformLocation.hash;

// Dart will complain if a call to substring is
// executed with a position value that extends the
// length of string.
return (path.length > 0 ? path.substring(1) : path) +
normalizeQueryParams(this._location.search);
normalizeQueryParams(this._platformLocation.search);
}

prepareExternalUrl(internal: string): string {
return internal.length > 0 ? ('#' + internal) : internal;
var url = joinWithSlash(this._baseHref, internal);
return url.length > 0 ? ('#' + url) : url;
}

pushState(state: any, title: string, path: string, queryParams: string) {
var url = path + normalizeQueryParams(queryParams);
var url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams));
if (url.length == 0) {
url = this._location.pathname;
} else {
url = this.prepareExternalUrl(url);
url = this._platformLocation.pathname;
}
this._history.pushState(state, title, url);
this._platformLocation.pushState(state, title, url);
}

forward(): void { this._history.forward(); }
forward(): void { this._platformLocation.forward(); }

back(): void { this._history.back(); }
back(): void { this._platformLocation.back(); }
}
23 changes: 23 additions & 0 deletions modules/angular2/src/router/location_strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,26 @@ export const APP_BASE_HREF: OpaqueToken = CONST_EXPR(new OpaqueToken('appBaseHre
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;
}
41 changes: 20 additions & 21 deletions modules/angular2/src/router/path_location_strategy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {Injectable, Inject} from 'angular2/core';
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 {LocationStrategy, APP_BASE_HREF, normalizeQueryParams} from './location_strategy';
import {
LocationStrategy,
APP_BASE_HREF,
normalizeQueryParams,
joinWithSlash
} from './location_strategy';
import {PlatformLocation} from './platform_location';

/**
* `PathLocationStrategy` is a {@link LocationStrategy} used to configure the
Expand Down Expand Up @@ -52,49 +57,43 @@ import {LocationStrategy, APP_BASE_HREF, normalizeQueryParams} from './location_
*/
@Injectable()
export class PathLocationStrategy extends LocationStrategy {
private _location: Location;
private _history: History;
private _baseHref: string;

constructor(@Inject(APP_BASE_HREF) href?: string) {
constructor(private _platformLocation: PlatformLocation,
@Optional() @Inject(APP_BASE_HREF) href?: string) {
super();

if (isBlank(href)) {
href = DOM.getBaseHref();
href = this._platformLocation.getBaseHrefFromDOM();
}

if (isBlank(href)) {
throw new BaseException(
`No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.`);
}

this._location = DOM.getLocation();
this._history = DOM.getHistory();
this._baseHref = href;
}

onPopState(fn: EventListener): void {
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
DOM.getGlobalEventTarget('window').addEventListener('hashchange', fn, false);
this._platformLocation.onPopState(fn);
this._platformLocation.onHashChange(fn);
}

getBaseHref(): string { return this._baseHref; }

prepareExternalUrl(internal: string): string {
if (internal.startsWith('/') && this._baseHref.endsWith('/')) {
return this._baseHref + internal.substring(1);
}
return this._baseHref + internal;
}
prepareExternalUrl(internal: string): string { return joinWithSlash(this._baseHref, internal); }

path(): string { return this._location.pathname + normalizeQueryParams(this._location.search); }
path(): string {
return this._platformLocation.pathname + normalizeQueryParams(this._platformLocation.search);
}

pushState(state: any, title: string, url: string, queryParams: string) {
var externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));
this._history.pushState(state, title, externalUrl);
this._platformLocation.pushState(state, title, externalUrl);
}

forward(): void { this._history.forward(); }
forward(): void { this._platformLocation.forward(); }

back(): void { this._history.back(); }
back(): void { this._platformLocation.back(); }
}
46 changes: 46 additions & 0 deletions modules/angular2/src/router/platform_location.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
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}.
*/
@Injectable()
export class PlatformLocation {
private _location: Location;
private _history: History;

constructor() { 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();
}

getBaseHrefFromDOM(): string { return DOM.getBaseHref(); }

onPopState(fn: EventListener): void {
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
}

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);
}

forward(): void { this._history.forward(); }

back(): void { this._history.back(); }
}
Loading
X Tutup