fix($browser): prevent infinite digests when clearing the hash of a url

By using `location.hash` to update the current browser location when only
the hash has changed, we prevent the browser from attempting to reload.

Closes #9629
Closes #9635
Closes #10228
Closes #10308
This commit is contained in:
Peter Bacon Darwin
2014-11-11 17:10:29 +00:00
parent d21dff21ed
commit 10ac594809
2 changed files with 29 additions and 1 deletions

View File

@@ -61,6 +61,11 @@ function Browser(window, document, $log, $sniffer) {
}
}
function getHash(url) {
var index = url.indexOf('#');
return index === -1 ? '' : url.substr(index + 1);
}
/**
* @private
* Note: this method is used only by scenario runner
@@ -190,8 +195,10 @@ function Browser(window, document, $log, $sniffer) {
}
if (replace) {
location.replace(url);
} else {
} else if (!sameBase) {
location.href = url;
} else {
location.hash = getHash(url);
}
}
return self;

View File

@@ -1,5 +1,7 @@
'use strict';
/* global getHash:true, stripHash:true */
var historyEntriesLength;
var sniffer = {};
@@ -51,6 +53,12 @@ function MockWindow(options) {
mockWindow.history.state = null;
historyEntriesLength++;
},
get hash() {
return getHash(locationHref);
},
set hash(value) {
locationHref = stripHash(locationHref) + '#' + value;
},
replace: function(url) {
locationHref = url;
mockWindow.history.state = null;
@@ -550,6 +558,17 @@ describe('browser', function() {
expect(locationReplace).not.toHaveBeenCalled();
});
it("should retain the # character when the only change is clearing the hash fragment, to prevent page reload", function() {
sniffer.history = true;
browser.url('http://server/#123');
expect(fakeWindow.location.href).toEqual('http://server/#123');
browser.url('http://server/');
expect(fakeWindow.location.href).toEqual('http://server/#');
});
it('should use location.replace when history.replaceState not available', function() {
sniffer.history = false;
browser.url('http://new.org', true);
@@ -561,6 +580,7 @@ describe('browser', function() {
expect(fakeWindow.location.href).toEqual('http://server/');
});
it('should use location.replace and not use replaceState when the url only changed in the hash fragment to please IE10/11', function() {
sniffer.history = true;
browser.url('http://server/#123', true);
@@ -572,6 +592,7 @@ describe('browser', function() {
expect(fakeWindow.location.href).toEqual('http://server/');
});
it('should return $browser to allow chaining', function() {
expect(browser.url('http://any.com')).toBe(browser);
});