diff options
| -rw-r--r-- | src/service/location.js | 6 | ||||
| -rw-r--r-- | test/service/locationSpec.js | 37 |
2 files changed, 41 insertions, 2 deletions
diff --git a/src/service/location.js b/src/service/location.js index d0ae9de7..3e8ba0c3 100644 --- a/src/service/location.js +++ b/src/service/location.js @@ -530,8 +530,10 @@ function $LocationProvider(){ // update $location when $browser url changes $browser.onUrlChange(function(newUrl) { if (currentUrl.absUrl() != newUrl) { - currentUrl.$$parse(newUrl); - $rootScope.$apply(); + $rootScope.$evalAsync(function() { + currentUrl.$$parse(newUrl); + }); + if (!$rootScope.$$phase) $rootScope.$digest(); } }); diff --git a/test/service/locationSpec.js b/test/service/locationSpec.js index c7cc9c23..97f2ab63 100644 --- a/test/service/locationSpec.js +++ b/test/service/locationSpec.js @@ -364,6 +364,43 @@ describe('$location', function() { })); + // location.href = '...' fires hashchange event synchronously, so it might happen inside $apply + it('should not $apply when browser url changed inside $apply', inject( + function($rootScope, $browser, $location) { + var OLD_URL = $browser.url(), + NEW_URL = 'http://updated.com/url'; + + + $rootScope.$apply(function() { + $browser.url(NEW_URL); + $browser.poll(); // simulate firing event from browser + expect($location.absUrl()).toBe(OLD_URL); // should be async + }); + + expect($location.absUrl()).toBe(NEW_URL); + })); + + // location.href = '...' fires hashchange event synchronously, so it might happen inside $digest + it('should not $apply when browser url changed inside $digest', inject( + function($rootScope, $browser, $location) { + var OLD_URL = $browser.url(), + NEW_URL = 'http://updated.com/url', + notRunYet = true; + + $rootScope.$watch(function() { + if (notRunYet) { + notRunYet = false; + $browser.url(NEW_URL); + $browser.poll(); // simulate firing event from browser + expect($location.absUrl()).toBe(OLD_URL); // should be async + } + }); + + $rootScope.$digest(); + expect($location.absUrl()).toBe(NEW_URL); + })); + + it('should update browser when $location changes', inject(function($rootScope, $browser, $location) { var $browserUrl = spyOnlyCallsWithArgs($browser, 'url').andCallThrough(); $location.path('/new/path'); |
