diff --git a/modules/angular2/src/mock/location_mock.js b/modules/angular2/src/mock/location_mock.js index 9297b8aaa4..3425b42d88 100644 --- a/modules/angular2/src/mock/location_mock.js +++ b/modules/angular2/src/mock/location_mock.js @@ -12,18 +12,24 @@ export class SpyLocation extends SpyObject { urlChanges:List; _path:string; _subject:EventEmitter; + _baseHref:string; constructor() { super(); this._path = '/'; this.urlChanges = ListWrapper.create(); this._subject = new EventEmitter(); + this._baseHref = ''; } setInitialPath(url:string) { this._path = url; } + setBaseHref(url:string) { + this._baseHref = url; + } + path():string { return this._path; } @@ -34,6 +40,10 @@ export class SpyLocation extends SpyObject { }); } + normalizeAbsolutely(url) { + return this._baseHref + url; + } + go(url:string) { if (this._path === url) { return; diff --git a/modules/angular2/src/router/location.js b/modules/angular2/src/router/location.js index 2786c182f2..741fad9d98 100644 --- a/modules/angular2/src/router/location.js +++ b/modules/angular2/src/router/location.js @@ -27,6 +27,13 @@ export class Location { return this._stripBaseHref(stripIndexHtml(url)); } + normalizeAbsolutely(url) { + if (url[0] != '/') { + url = '/' + url; + } + return this._addBaseHref(url); + } + _stripBaseHref(url) { if (this._baseHref.length > 0 && StringWrapper.startsWith(url, this._baseHref)) { return StringWrapper.substring(url, this._baseHref.length); @@ -34,8 +41,15 @@ export class Location { return url; } + _addBaseHref(url) { + if (!StringWrapper.startsWith(url, this._baseHref)) { + return this._baseHref + url; + } + return url; + } + go(url:string) { - var finalUrl = url[0] == '/' ? url : this._baseHref + '/' + url; + var finalUrl = this.normalizeAbsolutely(url); this._browserLocation.pushState(null, '', finalUrl); } diff --git a/modules/angular2/src/router/router_link.js b/modules/angular2/src/router/router_link.js index b959133214..e49fcf9a63 100644 --- a/modules/angular2/src/router/router_link.js +++ b/modules/angular2/src/router/router_link.js @@ -6,6 +6,7 @@ import {isPresent} from 'angular2/src/facade/lang'; import {DOM} from 'angular2/src/dom/dom_adapter'; import {Router} from './router'; +import {Location} from './location'; /** * The RouterLink directive lets you link to specific parts of your app. @@ -41,11 +42,13 @@ export class RouterLink { _route:string; _params:any; _router:Router; + _location:Location; _href:string; - constructor(elementRef:ElementRef, router:Router) { + constructor(elementRef:ElementRef, router:Router, location:Location) { this._domEl = elementRef.domElement; this._router = router; + this._location = location; this._params = StringMapWrapper.create(); DOM.on(this._domEl, 'click', (evt) => { evt.preventDefault(); @@ -64,10 +67,10 @@ export class RouterLink { onAllChangesDone() { if (isPresent(this._route) && isPresent(this._params)) { var newHref = this._router.generate(this._route, this._params); - this._href = newHref; + this._href = this._location.normalizeAbsolutely(newHref); // Keeping the link on the element to support contextual menu `copy link` // and other in-browser affordances. - DOM.setAttribute(this._domEl, 'href', newHref); + DOM.setAttribute(this._domEl, 'href', this._href); } } } diff --git a/modules/angular2/test/router/outlet_spec.js b/modules/angular2/test/router/outlet_spec.js index 8d21b65b11..4e56c7c87f 100644 --- a/modules/angular2/test/router/outlet_spec.js +++ b/modules/angular2/test/router/outlet_spec.js @@ -136,6 +136,19 @@ export function main() { })); + it('should generate absolute hrefs that include the base href', inject([AsyncTestCompleter], (async) => { + location.setBaseHref('/my/base'); + compile('') + .then((_) => rtr.config({'path': '/user', 'component': UserCmp, 'as': 'user'})) + .then((_) => rtr.navigate('/a/b')) + .then((_) => { + view.detectChanges(); + expect(DOM.getAttribute(view.rootNodes[0].childNodes[0], 'href')).toEqual('/my/base/user'); + async.done(); + }); + })); + + it('should generate link hrefs without params', inject([AsyncTestCompleter], (async) => { compile('') .then((_) => rtr.config({'path': '/user', 'component': UserCmp, 'as': 'user'}))