Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Fix hashchange event on IE7 #361

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions regression/issue-353.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html xmlns:ng="http://angularjs.org">
<script type="text/javascript" src="../build/angular.js" ng:autobind></script>
<script type="text/javascript">
function Cntl($route) {
$route.when('/item1', {});
$route.when('/item2', {});
$route.onChange(function() {
alert('change');
});
}
Cntl.$inject = ['$route'];
</script>
<body ng:controller="Cntl">
<a href="#/item1">test</a>
<a href="#/item2">test</a>
</body>
</html>
6 changes: 0 additions & 6 deletions src/AngularPublic.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ angularService('$browser', function($log){
if (!browserSingleton) {
browserSingleton = new Browser(window, jqLite(window.document), jqLite(window.document.body),
XHR, $log);
var addPollFn = browserSingleton.addPollFn;
browserSingleton.addPollFn = function(){
browserSingleton.addPollFn = addPollFn;
browserSingleton.startPoller(100, function(delay, fn){setTimeout(delay,fn);});
return addPollFn.apply(browserSingleton, arguments);
};
browserSingleton.bind();
}
return browserSingleton;
Expand Down
13 changes: 9 additions & 4 deletions src/Browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ function Browser(window, document, body, XHR, $log) {
//////////////////////////////////////////////////////////////
// Poll Watcher API
//////////////////////////////////////////////////////////////
var pollFns = [];
var pollFns = [],
pollTimeout;

/**
* @workInProgress
Expand All @@ -160,11 +161,13 @@ function Browser(window, document, body, XHR, $log) {
* @param {function()} fn Poll function to add
*
* @description
* Adds a function to the list of functions that poller periodically executes
* Adds a function to the list of functions that poller periodically executes,
* and starts polling if not started yet.
*
* @returns {function()} the added function
*/
self.addPollFn = function(fn) {
if (!pollTimeout) self.startPoller(100, setTimeout);
pollFns.push(fn);
return fn;
};
Expand All @@ -185,7 +188,7 @@ function Browser(window, document, body, XHR, $log) {
self.startPoller = function(interval, setTimeout) {
(function check(){
self.poll();
setTimeout(check, interval);
pollTimeout = setTimeout(check, interval);
})();
};

Expand Down Expand Up @@ -247,7 +250,9 @@ function Browser(window, document, body, XHR, $log) {
* @return {function()} Returns the registered listener fn - handy if the fn is anonymous.
*/
self.onHashChange = function(listener) {
if ('onhashchange' in window) {
// IE8 comp mode returns true, but doesn't support hashchange event
var dm = window.document.documentMode;
if ('onhashchange' in window && (!isDefined(dm) || dm >= 8)) {
jqLite(window).bind('hashchange', listener);
} else {
var lastBrowserUrl = self.getUrl();
Expand Down
50 changes: 48 additions & 2 deletions test/BrowserSpecs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ describe('browser', function(){

function fakeSetTimeout(fn) {
setTimeoutQueue.push(fn);
return Math.random();
}

fakeSetTimeout.flush = function() {
Expand Down Expand Up @@ -371,6 +372,10 @@ describe('browser', function(){
});

describe('poller', function(){
beforeEach(function() {
spyOn(browser, 'startPoller');
});

it('should call all fns on poll', function(){
var log = '';
browser.addPollFn(function(){log+='a';});
Expand All @@ -386,6 +391,7 @@ describe('browser', function(){
var log = '';
var setTimeoutSpy = jasmine.createSpy('setTimeout');
browser.addPollFn(function(){log+='.';});
browser.startPoller.andCallThrough();
browser.startPoller(50, setTimeoutSpy);
expect(log).toEqual('.');
expect(setTimeoutSpy.mostRecentCall.args[1]).toEqual(50);
Expand All @@ -398,16 +404,36 @@ describe('browser', function(){
var returnedFn = browser.addPollFn(fn);
expect(returnedFn).toBe(fn);
});

it('should auto start poller when first fn registered', function() {
browser.addPollFn(function() {});

expect(browser.startPoller).toHaveBeenCalled();
expect(browser.startPoller.callCount).toBe(1);
});

it('should auto start poller only when first fn registered', function() {
browser.startPoller.andCallThrough();
browser.addPollFn(function() {});
browser.addPollFn(function() {});
browser.addPollFn(function() {});

expect(browser.startPoller.callCount).toBe(1);
});
});


describe('url api', function() {
it('should use $browser poller to detect url changes when onhashchange event is unsupported',
function() {

fakeWindow = {location: {href:"http://server"}};
fakeWindow = {
location: {href:"http://server"},
document: {}
};

browser = new Browser(fakeWindow, {}, {});
browser.startPoller = function() {};

var events = [];

Expand Down Expand Up @@ -442,7 +468,8 @@ describe('browser', function(){
onHashChngListener = listener;
},
removeEventListener: angular.noop,
detachEvent: angular.noop
detachEvent: angular.noop,
document: {}
};
fakeWindow.onhashchange = true;

Expand All @@ -466,5 +493,24 @@ describe('browser', function(){
jqLite(fakeWindow).dealoc();
}
});

// asynchronous test
it('should fire onHashChange when location.hash change', function() {
var callback = jasmine.createSpy('onHashChange');
browser = new Browser(window, {}, {});
browser.onHashChange(callback);

window.location.hash = 'new-hash';
browser.startPoller(100, setTimeout);

waitsFor(function() {
return callback.callCount;
}, 'onHashChange callback to be called', 1000);

runs(function() {
if (!jQuery) jqLite(window).dealoc();
window.location.hash = '';
});
});
});
});