fix($location): $location.path() behaviour when $locationChangeStart is triggered by the browser

Fixed inconsistency in $location.path() behaviour on the $locationChangeStart event when using
back/forward buttons in the browser or manually changing the url in the address bar.
$location.path() now returns the target url in these cases.

Closes #4989
Closes #5089
Closes #5118
Closes #5580
This commit is contained in:
Sebastian K 2013-11-22 14:33:19 +01:00 committed by Igor Minar
parent 7dfedb732d
commit cf686285c2
2 changed files with 35 additions and 6 deletions

View file

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

View file

@ -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() {