mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-29 21:37:00 +08:00
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:
@@ -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
|
* @private
|
||||||
* Note: this method is used only by scenario runner
|
* Note: this method is used only by scenario runner
|
||||||
@@ -190,8 +195,10 @@ function Browser(window, document, $log, $sniffer) {
|
|||||||
}
|
}
|
||||||
if (replace) {
|
if (replace) {
|
||||||
location.replace(url);
|
location.replace(url);
|
||||||
} else {
|
} else if (!sameBase) {
|
||||||
location.href = url;
|
location.href = url;
|
||||||
|
} else {
|
||||||
|
location.hash = getHash(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/* global getHash:true, stripHash:true */
|
||||||
|
|
||||||
var historyEntriesLength;
|
var historyEntriesLength;
|
||||||
var sniffer = {};
|
var sniffer = {};
|
||||||
|
|
||||||
@@ -51,6 +53,12 @@ function MockWindow(options) {
|
|||||||
mockWindow.history.state = null;
|
mockWindow.history.state = null;
|
||||||
historyEntriesLength++;
|
historyEntriesLength++;
|
||||||
},
|
},
|
||||||
|
get hash() {
|
||||||
|
return getHash(locationHref);
|
||||||
|
},
|
||||||
|
set hash(value) {
|
||||||
|
locationHref = stripHash(locationHref) + '#' + value;
|
||||||
|
},
|
||||||
replace: function(url) {
|
replace: function(url) {
|
||||||
locationHref = url;
|
locationHref = url;
|
||||||
mockWindow.history.state = null;
|
mockWindow.history.state = null;
|
||||||
@@ -550,6 +558,17 @@ describe('browser', function() {
|
|||||||
expect(locationReplace).not.toHaveBeenCalled();
|
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() {
|
it('should use location.replace when history.replaceState not available', function() {
|
||||||
sniffer.history = false;
|
sniffer.history = false;
|
||||||
browser.url('http://new.org', true);
|
browser.url('http://new.org', true);
|
||||||
@@ -561,6 +580,7 @@ describe('browser', function() {
|
|||||||
expect(fakeWindow.location.href).toEqual('http://server/');
|
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() {
|
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;
|
sniffer.history = true;
|
||||||
browser.url('http://server/#123', true);
|
browser.url('http://server/#123', true);
|
||||||
@@ -572,6 +592,7 @@ describe('browser', function() {
|
|||||||
expect(fakeWindow.location.href).toEqual('http://server/');
|
expect(fakeWindow.location.href).toEqual('http://server/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should return $browser to allow chaining', function() {
|
it('should return $browser to allow chaining', function() {
|
||||||
expect(browser.url('http://any.com')).toBe(browser);
|
expect(browser.url('http://any.com')).toBe(browser);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user