diff --git a/src/ng/location.js b/src/ng/location.js index 12f6c14cc0cb..0a47445f6f87 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -659,16 +659,17 @@ function $LocationProvider(){ // update $location when $browser url changes $browser.onUrlChange(function(newUrl) { if ($location.absUrl() != newUrl) { - if ($rootScope.$broadcast('$locationChangeStart', newUrl, - $location.absUrl()).defaultPrevented) { - $browser.url($location.absUrl()); - return; - } $rootScope.$evalAsync(function() { var oldUrl = $location.absUrl(); $location.$$parse(newUrl); - afterLocationChange(oldUrl); + if ($rootScope.$broadcast('$locationChangeStart', newUrl, + oldUrl).defaultPrevented) { + $location.$$parse(oldUrl); + $browser.url(oldUrl); + } else { + afterLocationChange(oldUrl); + } }); if (!$rootScope.$$phase) $rootScope.$digest(); } diff --git a/test/ng/locationSpec.js b/test/ng/locationSpec.js index f23965f80ee5..ff823d306efd 100644 --- a/test/ng/locationSpec.js +++ b/test/ng/locationSpec.js @@ -4,6 +4,8 @@ describe('$location', function() { var url; + beforeEach(module(provideLog)); + afterEach(function() { // link rewriting used in html5 mode on legacy browsers binds to document.onClick, so we need // to clean this up after each test. @@ -1401,6 +1403,32 @@ describe('$location', function() { dealoc($rootElement); }); }); + + it('should always return the new url value via path() when $locationChangeStart event occurs regardless of cause', + inject(function($location, $rootScope, $browser, log) { + var base = $browser.url(); + + $rootScope.$on('$locationChangeStart', function() { + log($location.path()); + }); + + // change through $location service + $rootScope.$apply(function() { + $location.path('/myNewPath'); + }); + + // reset location + $rootScope.$apply(function() { + $location.path(''); + }); + + // change through $browser + $browser.url(base + '#/myNewPath'); + $browser.poll(); + + expect(log).toEqual(['/myNewPath', '/', '/myNewPath']); + }) + ); }); describe('LocationHtml5Url', function() {