From adce1015a1819c88968b127d0404843a909cd1be Mon Sep 17 00:00:00 2001 From: Angel Balcarcel Date: Fri, 9 Aug 2013 10:29:22 -0400 Subject: [PATCH] fix($location): prevent infinite digest error in IE7 Refactored the replacedUrl variable to store the new URL on both location.replace and setting location.href directly to handle delays in actual location value change in IE. Closes #2802 --- src/ng/browser.js | 12 ++++++------ test/ng/browserSpecs.js | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/ng/browser.js b/src/ng/browser.js index bfece6466cef..15207f0ba140 100644 --- a/src/ng/browser.js +++ b/src/ng/browser.js @@ -125,7 +125,7 @@ function Browser(window, document, $log, $sniffer) { var lastBrowserUrl = location.href, baseElement = document.find('base'), - replacedUrl = null; + newLocation = null; /** * @name ng.$browser#url @@ -160,21 +160,20 @@ function Browser(window, document, $log, $sniffer) { baseElement.attr('href', baseElement.attr('href')); } } else { + newLocation = url; if (replace) { location.replace(url); - replacedUrl = url; } else { location.href = url; - replacedUrl = null; } } return self; // getter } else { - // - the replacedUrl is a workaround for an IE8-9 issue with location.replace method that doesn't update - // location.href synchronously + // - newLocation is a workaround for an IE7-9 issue with location.replace and location.href + // methods not updating location.href synchronously. // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172 - return replacedUrl || location.href.replace(/%27/g,"'"); + return newLocation || location.href.replace(/%27/g,"'"); } }; @@ -182,6 +181,7 @@ function Browser(window, document, $log, $sniffer) { urlChangeInit = false; function fireUrlChange() { + newLocation = null; if (lastBrowserUrl == self.url()) return; lastBrowserUrl = self.url(); diff --git a/test/ng/browserSpecs.js b/test/ng/browserSpecs.js index 3ec78e615341..dace4587f30a 100755 --- a/test/ng/browserSpecs.js +++ b/test/ng/browserSpecs.js @@ -540,6 +540,27 @@ describe('browser', function() { expect(callback).toHaveBeenCalledOnce(); }); + describe('after an initial location change by browser.url method when neither history nor hashchange supported', function() { + beforeEach(function() { + sniffer.history = false; + sniffer.hashchange = false; + browser.url("http://server.current"); + }); + + it('should fire callback with the correct URL on location change outside of angular', function() { + browser.onUrlChange(callback); + + fakeWindow.location.href = 'http://server.new'; + fakeWindow.setTimeout.flush(); + expect(callback).toHaveBeenCalledWith('http://server.new'); + + fakeWindow.fire('popstate'); + fakeWindow.fire('hashchange'); + expect(callback).toHaveBeenCalledOnce(); + }); + + }); + it('should not fire urlChange if changed by browser.url method (polling)', function() { sniffer.history = false; sniffer.hashchange = false;