Skip to content

Commit 1e3c93c

Browse files
committed
Support for IE9 (with hash router)
1 parent c180904 commit 1e3c93c

File tree

5 files changed

+158
-58
lines changed

5 files changed

+158
-58
lines changed

.zuul.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ browsers:
33
- name: chrome
44
version: 27..latest
55
- name: ie
6-
version: 10..latest
6+
version: 9..latest
77
- name: safari
88
version: 6..latest
99
- name: firefox

README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@ also provides a method to navigate between locations which sets the correct
2929
React router component also provides advanced features like support for full
3030
page server side rendering and nested and contextual routers.
3131

32-
Its functionality is tested using [Saucelabs][] on all modern browsers (IE >=
33-
10, Chrome >= 27, Firefox >= 25, Safari >= 6 and Mobile Safari on iPhone and
34-
iPad >= 6). Basically, the browsers which support the HTML5 History API.
32+
Its functionality is tested using [Saucelabs][] on all modern browsers (IE >= 9,
33+
Chrome >= 27, Firefox >= 25, Safari >= 6 and Mobile Safari on iPhone and iPad >=
34+
6).
35+
36+
Note that browsers which do not support History API (IE 9 and below) should use
37+
"hash" router. Also the library may work in IE8 with [needed
38+
shims][React-Shims] included.
3539

3640
## Installation
3741

@@ -44,4 +48,5 @@ See [docs][] for the usage.
4448
[docs]: http://andreypopp.viewdocs.io/react-router-component
4549
[React]: http://facebook.github.io/react/
4650
[React-Refs]: http://facebook.github.io/react/docs/more-about-refs.html
51+
[React-Shims]: http://facebook.github.io/react/docs/working-with-the-browser.html#polyfills-needed-to-support-older-browsers
4752
[Saucelabs]: saucelabs.com

docs/index.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@ also provides a method to navigate between locations which sets the correct
2929
React router component also provides advanced features like support for full
3030
page server side rendering and nested and contextual routers.
3131

32-
Its functionality is tested using [Saucelabs][] on all modern browsers (IE >=
33-
10, Chrome >= 27, Firefox >= 25, Safari >= 6 and Mobile Safari on iPhone and
34-
iPad >= 6). Basically, the browsers which support the HTML5 History API.
32+
Its functionality is tested using [Saucelabs][] on all modern browsers (IE >= 9,
33+
Chrome >= 27, Firefox >= 25, Safari >= 6 and Mobile Safari on iPhone and iPad >=
34+
6).
35+
36+
Note that browsers which do not support History API (IE 9 and below) should use
37+
"hash" router. Also the library may work in IE8 with [needed
38+
shims][React-Shims] included.
3539

3640
## Installation
3741

@@ -110,4 +114,5 @@ and contextual routers.
110114

111115
[React]: http://facebook.github.io/react/
112116
[React-Refs]: http://facebook.github.io/react/docs/more-about-refs.html
117+
[React-Shims]: http://facebook.github.io/react/docs/working-with-the-browser.html#polyfills-needed-to-support-older-browsers
113118
[Saucelabs]: saucelabs.com

index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ function createRouter(component, environment) {
9999

100100
return {
101101
path: path,
102-
pattern: page.pattern,
102+
pattern: page ? page.pattern : null,
103103
route: page ? page : notFound ? notFound : null,
104104
match: match,
105105
getChildren: getChildren
@@ -155,7 +155,7 @@ var HistoryAPIRouterEnvironment = {
155155
var HashChangeRouterEnvironment = {
156156

157157
getPath: function() {
158-
return window.location.hash;
158+
return window.location.hash.slice(1);
159159
},
160160

161161
updatePath: function(path) {
@@ -171,7 +171,7 @@ var HashChangeRouterEnvironment = {
171171
},
172172

173173
onHashChange: function() {
174-
var path = window.location.hash;
174+
var path = window.location.hash.slice(1);
175175

176176
if (this.state.match.path !== path) {
177177
this.setState({match: this.matchPath(path)});

tests.js

+138-48
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,64 @@ var assert = require('assert');
22
var React = require('react');
33
var Router = require('./index');
44

5-
var NestedRouter = React.createClass({
6-
render: function() {
7-
return React.DOM.div(null,
8-
Router.Locations(null,
9-
Router.Location({path: '/__zuul/nested/'}, function(props) {
10-
return 'nested/root';
11-
}),
12-
Router.Location({path: '/__zuul/nested/page'}, function(props) {
13-
return 'nested/page';
14-
})
15-
));
16-
}
17-
});
18-
19-
var ContextualRouter = React.createClass({
20-
render: function() {
21-
return React.DOM.div(null,
22-
Router.Locations({contextual: true},
23-
Router.Location({path: '/'}, function(props) {
24-
return 'contextual/root';
25-
}),
26-
Router.Location({path: '/page'}, function(props) {
27-
return 'contextual/page';
28-
})
29-
));
30-
}
31-
});
32-
33-
var App = React.createClass({
34-
35-
render: function() {
36-
return Router.Locations({ref: 'router', className: 'App'},
37-
Router.Location({path: '/__zuul'}, function(props) {
38-
return Router.Link({ref: 'link', href: '/__zuul/hello'}, 'mainpage')
39-
}),
40-
Router.Location({path: '/__zuul/nested/*'}, function(props) {
41-
return NestedRouter();
42-
}),
43-
Router.Location({path: '/__zuul/contextual/*'}, function(props) {
44-
return ContextualRouter();
45-
}),
46-
Router.Location({path: '/__zuul/:slug'}, function(props) {
47-
return props.slug
48-
})
49-
);
50-
}
51-
});
5+
var historyAPI = window.history !== undefined && window.history.pushState !== undefined;
526

537
function getText(node) {
548
return node.textContent || node.innerText;
559
}
5610

5711
describe('react-router-component', function() {
5812

13+
if (!historyAPI) return;
14+
15+
var NestedRouter = React.createClass({
16+
render: function() {
17+
return React.DOM.div(null,
18+
Router.Locations(null,
19+
Router.Location({path: '/__zuul/nested/'}, function(props) {
20+
return 'nested/root';
21+
}),
22+
Router.Location({path: '/__zuul/nested/page'}, function(props) {
23+
return 'nested/page';
24+
})
25+
));
26+
}
27+
});
28+
29+
var ContextualRouter = React.createClass({
30+
render: function() {
31+
return React.DOM.div(null,
32+
Router.Locations({contextual: true},
33+
Router.Location({path: '/'}, function(props) {
34+
return 'contextual/root';
35+
}),
36+
Router.Location({path: '/page'}, function(props) {
37+
return 'contextual/page';
38+
})
39+
));
40+
}
41+
});
42+
43+
var App = React.createClass({
44+
45+
render: function() {
46+
return Router.Locations({ref: 'router', className: 'App'},
47+
Router.Location({path: '/__zuul'}, function(props) {
48+
return Router.Link({ref: 'link', href: '/__zuul/hello'}, 'mainpage')
49+
}),
50+
Router.Location({path: '/__zuul/nested/*'}, function(props) {
51+
return NestedRouter();
52+
}),
53+
Router.Location({path: '/__zuul/contextual/*'}, function(props) {
54+
return ContextualRouter();
55+
}),
56+
Router.Location({path: '/__zuul/:slug'}, function(props) {
57+
return props.slug
58+
})
59+
);
60+
}
61+
});
62+
5963
var host, app, router;
6064

6165
beforeEach(function() {
@@ -77,7 +81,9 @@ describe('react-router-component', function() {
7781

7882
it('renders', function() {
7983
assert.equal(getText(host), 'mainpage');
80-
assert.ok(app.getDOMNode().classList.contains('App'));
84+
var dom = app.getDOMNode();
85+
if (dom.classList)
86+
assert.ok(dom.classList.contains('App'));
8187
});
8288

8389
it('navigates to a different route', function(done) {
@@ -151,6 +157,89 @@ describe('react-router-component', function() {
151157
});
152158
});
153159

160+
it('navigates via onClick event', function(done) {
161+
assert.equal(getText(host), 'mainpage');
162+
router.refs.link.onClick();
163+
setTimeout(function() {
164+
assert.equal(getText(host), 'hello');
165+
done();
166+
}, 200);
167+
});
168+
});
169+
});
170+
171+
describe('react-router-component (hash routing)', function() {
172+
173+
var App = React.createClass({
174+
175+
render: function() {
176+
return Router.HashChange.Locations({ref: 'router', className: 'App'},
177+
Router.HashChange.Location({path: '/'}, function(props) {
178+
return Router.HashChange.Link({ref: 'link', href: '/hello'}, 'mainpage')
179+
}),
180+
Router.HashChange.Location({path: '/:slug'}, function(props) {
181+
return props.slug
182+
})
183+
);
184+
}
185+
});
186+
187+
var host, app, router;
188+
189+
beforeEach(function() {
190+
host = document.createElement('div');
191+
document.body.appendChild(host);
192+
app = React.renderComponent(App(), host);
193+
router = app.refs.router;
194+
});
195+
196+
afterEach(function(done) {
197+
React.unmountComponentAtNode(host);
198+
document.body.removeChild(host);
199+
host = null;
200+
app = null;
201+
router = null
202+
window.location.hash = '';
203+
setTimeout(done, 200);
204+
});
205+
206+
it('renders', function() {
207+
assert.equal(getText(host), 'mainpage');
208+
var dom = app.getDOMNode();
209+
if (dom.classList)
210+
assert.ok(dom.classList.contains('App'));
211+
});
212+
213+
it('navigates to a different route', function(done) {
214+
assert.equal(getText(host), 'mainpage');
215+
router.navigate('/hello', function() {
216+
assert.equal(getText(host), 'hello');
217+
done();
218+
});
219+
});
220+
221+
it('handles "haschange" event', function(done) {
222+
assert.equal(getText(host), 'mainpage');
223+
router.navigate('/hello', function() {
224+
assert.equal(getText(host), 'hello');
225+
window.location.hash = '/';
226+
setTimeout(function() {
227+
assert.equal(getText(host), 'mainpage');
228+
done();
229+
}, 200);
230+
});
231+
});
232+
233+
describe('Link component', function() {
234+
235+
it('navigates via .navigate(path) call', function(done) {
236+
assert.equal(getText(host), 'mainpage');
237+
router.refs.link.navigate('/hello', function() {
238+
assert.equal(getText(host), 'hello');
239+
done();
240+
});
241+
});
242+
154243
it('navigates via onClick event', function(done) {
155244
assert.equal(getText(host), 'mainpage');
156245
router.refs.link.onClick();
@@ -162,3 +251,4 @@ describe('react-router-component', function() {
162251
});
163252

164253
});
254+

0 commit comments

Comments
 (0)