Skip to content

Commit d707114

Browse files
Angel Balcarcelbtford
Angel Balcarcel
authored andcommitted
fix($location): prevent infinite digest error in IE7
Refactored `replacedUrl` to store the new URL on both `location.replace` and setting `location.href` directly to handle delays in the actual location value change in IE. Closes angular#2802
1 parent 78a5889 commit d707114

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

src/ng/browser.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function Browser(window, document, $log, $sniffer) {
125125

126126
var lastBrowserUrl = location.href,
127127
baseElement = document.find('base'),
128-
replacedUrl = null;
128+
newLocation = null;
129129

130130
/**
131131
* @name ng.$browser#url
@@ -163,28 +163,28 @@ function Browser(window, document, $log, $sniffer) {
163163
baseElement.attr('href', baseElement.attr('href'));
164164
}
165165
} else {
166+
newLocation = url;
166167
if (replace) {
167168
location.replace(url);
168-
replacedUrl = url;
169169
} else {
170170
location.href = url;
171-
replacedUrl = null;
172171
}
173172
}
174173
return self;
175174
// getter
176175
} else {
177-
// - the replacedUrl is a workaround for an IE8-9 issue with location.replace method that doesn't update
178-
// location.href synchronously
176+
// - newLocation is a workaround for an IE7-9 issue with location.replace and location.href
177+
// methods not updating location.href synchronously.
179178
// - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
180-
return replacedUrl || location.href.replace(/%27/g,"'");
179+
return newLocation || location.href.replace(/%27/g,"'");
181180
}
182181
};
183182

184183
var urlChangeListeners = [],
185184
urlChangeInit = false;
186185

187186
function fireUrlChange() {
187+
newLocation = null;
188188
if (lastBrowserUrl == self.url()) return;
189189

190190
lastBrowserUrl = self.url();

test/ng/browserSpecs.js

+25-2
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ describe('browser', function() {
287287
it('should default path in cookie to "" (empty string)', function () {
288288
browser.cookies('cookie', 'bender');
289289
// This only fails in Safari and IE when cookiePath returns undefined
290-
// Where it now succeeds since baseHref return '' instead of undefined
290+
// Where it now succeeds since baseHref return '' instead of undefined
291291
expect(document.cookie).toEqual('cookie=bender');
292292
});
293293
});
@@ -535,9 +535,32 @@ describe('browser', function() {
535535
fakeWindow.setTimeout.flush();
536536
expect(callback).toHaveBeenCalledWith('http://server.new');
537537

538+
callback.reset();
539+
538540
fakeWindow.fire('popstate');
539541
fakeWindow.fire('hashchange');
540-
expect(callback).toHaveBeenCalledOnce();
542+
expect(callback).not.toHaveBeenCalled();
543+
});
544+
545+
describe('after an initial location change by browser.url method when neither history nor hashchange supported', function() {
546+
beforeEach(function() {
547+
sniffer.history = false;
548+
sniffer.hashchange = false;
549+
browser.url("http://server.current");
550+
});
551+
552+
it('should fire callback with the correct URL on location change outside of angular', function() {
553+
browser.onUrlChange(callback);
554+
555+
fakeWindow.location.href = 'http://server.new';
556+
fakeWindow.setTimeout.flush();
557+
expect(callback).toHaveBeenCalledWith('http://server.new');
558+
559+
fakeWindow.fire('popstate');
560+
fakeWindow.fire('hashchange');
561+
expect(callback).toHaveBeenCalledOnce();
562+
});
563+
541564
});
542565

543566
it('should not fire urlChange if changed by browser.url method (polling)', function() {

0 commit comments

Comments
 (0)