From cbcc84887d6b6d35258adabb97c714cd9c1e272d Mon Sep 17 00:00:00 2001 From: Erik Simmler Date: Fri, 25 Oct 2013 13:50:32 -0400 Subject: [PATCH] fix($state): use $browser.baseHref() when generating urls with .href() If an angular app is placed in a subdirectory and a tag is used, ui-router should use the configured value when generating urls through $state.href(). Thanks to @mfield for the testing help! --- src/state.js | 14 ++++++++++++-- test/stateSpec.js | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/state.js b/src/state.js index 964780a17..22d3229a9 100644 --- a/src/state.js +++ b/src/state.js @@ -448,14 +448,15 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $ */ // $urlRouter is injected just to ensure it gets instantiated this.$get = $get; - $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$location', '$urlRouter']; - function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $location, $urlRouter) { + $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$location', '$urlRouter', '$browser']; + function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $location, $urlRouter, $browser) { var TransitionSuperseded = $q.reject(new Error('transition superseded')); var TransitionPrevented = $q.reject(new Error('transition prevented')); var TransitionAborted = $q.reject(new Error('transition aborted')); var TransitionFailed = $q.reject(new Error('transition failed')); var currentLocation = $location.url(); + var baseHref = $browser.baseHref(); function syncUrl() { if ($location.url() !== currentLocation) { @@ -830,6 +831,15 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $ if (!$locationProvider.html5Mode() && url) { url = "#" + $locationProvider.hashPrefix() + url; } + + if (baseHref !== '/') { + if ($locationProvider.html5Mode()) { + url = baseHref.slice(0, -1) + url; + } else if (options.absolute){ + url = baseHref.slice(1) + url; + } + } + if (options.absolute && url) { url = $location.protocol() + '://' + $location.host() + diff --git a/test/stateSpec.js b/test/stateSpec.js index d52a36fca..775261c3b 100644 --- a/test/stateSpec.js +++ b/test/stateSpec.js @@ -632,6 +632,28 @@ describe('state', function () { locationProvider.hashPrefix("!"); expect($state.href("home")).toEqual("#!/"); })); + + describe('when $browser.baseHref() exists', function() { + beforeEach(inject(function($browser) { + spyOn($browser, 'baseHref').andCallFake(function() { + return '/base/'; + }); + })); + + it('does not prepend relative urls', inject(function($state) { + expect($state.href("home")).toEqual("#/"); + })); + + it('prepends absolute urls', inject(function($state) { + expect($state.href("home", null, { absolute: true })).toEqual("http://server/base/#/"); + })); + + it('prepends relative and absolute urls in html5Mode', inject(function($state) { + locationProvider.html5Mode(true); + expect($state.href("home")).toEqual("/base/"); + expect($state.href("home", null, { absolute: true })).toEqual("http://server/base/"); + })); + }); }); describe('.get()', function () {