mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-06-18 03:58:15 +08:00
fix($browser): detect changes to the browser url that happened in sync
Closes #6976.
This commit is contained in:
@@ -234,6 +234,13 @@ function Browser(window, document, $log, $sniffer) {
|
||||
return callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks whether the url has changed outside of Angular.
|
||||
* Needs to be exported to be able to check for changes that have been done in sync,
|
||||
* as hashchange/popstate events fire in async.
|
||||
*/
|
||||
self.$$checkUrlChange = fireUrlChange;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Misc API
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -608,6 +608,8 @@ function $RootScopeProvider(){
|
||||
logIdx, logMsg, asyncTask;
|
||||
|
||||
beginPhase('$digest');
|
||||
// Check for changes to browser url that happened in sync before the call to $digest
|
||||
$browser.$$checkUrlChange();
|
||||
|
||||
lastDirtyWatch = null;
|
||||
|
||||
|
||||
2
src/ngMock/angular-mocks.js
vendored
2
src/ngMock/angular-mocks.js
vendored
@@ -56,6 +56,8 @@ angular.mock.$Browser = function() {
|
||||
return listener;
|
||||
};
|
||||
|
||||
self.$$checkUrlChange = angular.noop;
|
||||
|
||||
self.cookieHash = {};
|
||||
self.lastCookieHash = {};
|
||||
self.deferredFns = [];
|
||||
|
||||
@@ -36,7 +36,7 @@ function MockWindow() {
|
||||
};
|
||||
|
||||
this.location = {
|
||||
href: 'http://server',
|
||||
href: 'http://server/',
|
||||
replace: noop
|
||||
};
|
||||
|
||||
@@ -414,7 +414,7 @@ describe('browser', function() {
|
||||
|
||||
expect(replaceState).not.toHaveBeenCalled();
|
||||
expect(locationReplace).not.toHaveBeenCalled();
|
||||
expect(fakeWindow.location.href).toEqual('http://server');
|
||||
expect(fakeWindow.location.href).toEqual('http://server/');
|
||||
});
|
||||
|
||||
it('should use history.replaceState when available', function() {
|
||||
@@ -426,7 +426,7 @@ describe('browser', function() {
|
||||
|
||||
expect(pushState).not.toHaveBeenCalled();
|
||||
expect(locationReplace).not.toHaveBeenCalled();
|
||||
expect(fakeWindow.location.href).toEqual('http://server');
|
||||
expect(fakeWindow.location.href).toEqual('http://server/');
|
||||
});
|
||||
|
||||
it('should set location.href when pushState not available', function() {
|
||||
@@ -448,7 +448,7 @@ describe('browser', function() {
|
||||
|
||||
expect(pushState).not.toHaveBeenCalled();
|
||||
expect(replaceState).not.toHaveBeenCalled();
|
||||
expect(fakeWindow.location.href).toEqual('http://server');
|
||||
expect(fakeWindow.location.href).toEqual('http://server/');
|
||||
});
|
||||
|
||||
it('should return $browser to allow chaining', function() {
|
||||
@@ -615,4 +615,32 @@ describe('browser', function() {
|
||||
expect(browser.baseHref()).toEqual('/base/path/');
|
||||
});
|
||||
});
|
||||
|
||||
describe('integration tests with $location', function() {
|
||||
|
||||
beforeEach(module(function($provide, $locationProvider) {
|
||||
spyOn(fakeWindow.history, 'pushState').andCallFake(function(stateObj, title, newUrl) {
|
||||
fakeWindow.location.href = newUrl;
|
||||
});
|
||||
$provide.value('$browser', browser);
|
||||
browser.pollFns = [];
|
||||
|
||||
$locationProvider.html5Mode(true);
|
||||
}));
|
||||
|
||||
it('should update $location when it was changed outside of Angular in sync '+
|
||||
'before $digest was called', function() {
|
||||
inject(function($rootScope, $location) {
|
||||
fakeWindow.history.pushState(null, '', 'http://server/someTestHash');
|
||||
|
||||
// Verify that infinite digest reported in #6976 no longer occurs
|
||||
expect(function() {
|
||||
$rootScope.$digest();
|
||||
}).not.toThrow();
|
||||
|
||||
expect($location.path()).toBe('/someTestHash');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user