fix(router): set correct redirect/default URL from hashchange

Currently, hashchange events outside of Angular that cause navigation
do not take into account cases where the initial route URL changes
due to a redirect or a default route.

Closes #5590

Closes #5683
This commit is contained in:
Brian Ford
2015-12-07 16:05:57 -08:00
parent fb4f1e8dc9
commit aa85856e1c
9 changed files with 139 additions and 12 deletions

View File

@ -21,7 +21,16 @@ export class SpyLocation implements Location {
path(): string { return this._path; }
simulateUrlPop(pathname: string) { ObservableWrapper.callEmit(this._subject, {'url': pathname}); }
simulateUrlPop(pathname: string) {
ObservableWrapper.callEmit(this._subject, {'url': pathname, 'pop': true});
}
simulateHashChange(pathname: string) {
// Because we don't prevent the native event, the browser will independently update the path
this.setInitialPath(pathname);
this.urlChanges.push('hash: ' + pathname);
ObservableWrapper.callEmit(this._subject, {'url': pathname, 'pop': true, 'type': 'hashchange'});
}
prepareExternalUrl(url: string): string {
if (url.length > 0 && !url.startsWith('/')) {
@ -42,6 +51,15 @@ export class SpyLocation implements Location {
this.urlChanges.push(url);
}
replaceState(path: string, query: string = '') {
path = this.prepareExternalUrl(path);
this._path = path;
this._query = query;
var url = path + (query.length > 0 ? ('?' + query) : '');
this.urlChanges.push('replace: ' + url);
}
forward() {
// TODO
}

View File

@ -15,7 +15,7 @@ export class MockLocationStrategy extends LocationStrategy {
simulatePopState(url: string): void {
this.internalPath = url;
ObservableWrapper.callEmit(this._subject, null);
ObservableWrapper.callEmit(this._subject, new MockPopStateEvent(this.path()));
}
path(): string { return this.internalPath; }
@ -27,10 +27,6 @@ export class MockLocationStrategy extends LocationStrategy {
return this.internalBaseHref + internal;
}
simulateUrlPop(pathname: string): void {
ObservableWrapper.callEmit(this._subject, {'url': pathname});
}
pushState(ctx: any, title: string, path: string, query: string): void {
this.internalTitle = title;
@ -41,6 +37,16 @@ export class MockLocationStrategy extends LocationStrategy {
this.urlChanges.push(externalUrl);
}
replaceState(ctx: any, title: string, path: string, query: string): void {
this.internalTitle = title;
var url = path + (query.length > 0 ? ('?' + query) : '');
this.internalPath = url;
var externalUrl = this.prepareExternalUrl(url);
this.urlChanges.push('replace: ' + externalUrl);
}
onPopState(fn: (value: any) => void): void { ObservableWrapper.subscribe(this._subject, fn); }
getBaseHref(): string { return this.internalBaseHref; }
@ -55,3 +61,9 @@ export class MockLocationStrategy extends LocationStrategy {
forward(): void { throw 'not implemented'; }
}
class MockPopStateEvent {
pop: boolean = true;
type: string = 'popstate';
constructor(public newUrl: string) {}
}