Skip to content

Commit e0cc13b

Browse files
committed
Revert "Use "react-router""
This reverts commit 15e01ea.
1 parent bb3281b commit e0cc13b

File tree

18 files changed

+325
-116
lines changed

18 files changed

+325
-116
lines changed

app/createPages.jsx

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import fs from 'fs';
22
import path from 'path';
33
import renderHtml from './lib/renderHtml';
44
import React from 'react';
5-
import Router from 'react-router';
65
import AppView from './views/AppView';
76
import dataStore from './stores/dataStore';
7+
import navigation from './actions/navigation';
8+
import locationStore from './stores/locationStore';
89
import collectData from './lib/collectData';
910

1011
export default collectData().then(/** @param {JscsModel} data */ function(data) {
@@ -18,34 +19,38 @@ export default collectData().then(/** @param {JscsModel} data */ function(data)
1819
dataStore.setData(data);
1920

2021
var pathsToRender = [
21-
'index',
22-
'overview',
23-
'contributing',
24-
'rules',
25-
'changelog'
22+
'index.html',
23+
'overview.html',
24+
'contributing.html',
25+
'rules.html',
26+
'changelog.html'
2627
].concat(data.getRules().map(/** @param {RuleModel} rule */ function(rule) {
27-
return 'rule/' + rule.getName();
28+
return 'rule/' + rule.getName() + '.html';
2829
}));
2930

3031
pathsToRender.forEach(function(filePath) {
31-
32-
Router.run(AppView, '/' + filePath, function (Handler, state) {
33-
var html = renderHtml({
34-
title: 'JSCS',
35-
content: React.renderToString(<Handler/>),
36-
dataPath: '/assets/data.js',
37-
scriptPath: '/assets/bundle.js',
38-
stylePath: '/assets/bundle.css'
39-
});
40-
41-
var filename = outputDir + '/' + filePath + '.html';
42-
var dirname = path.dirname(filename);
43-
if (!fs.existsSync(dirname)) {
44-
fs.mkdirSync(dirname);
45-
}
46-
47-
fs.writeFileSync(filename, html);
32+
navigation.navigateToPath(filePath);
33+
34+
var html = renderHtml({
35+
title: locationStore.getTitle(),
36+
content: React.renderToString(React.createElement(AppView)),
37+
dataPath: locationStore.renderPath('assets', 'data', '.js'),
38+
scriptPath: locationStore.renderPath('assets', 'bundle', '.js'),
39+
stylePath: locationStore.renderPath('assets', 'bundle', '.css'),
40+
locationState: JSON.stringify({
41+
page: locationStore.getPage(),
42+
data: locationStore.getData()
43+
})
4844
});
4945

46+
var filename = outputDir + '/' + filePath;
47+
var dirname = path.dirname(filename);
48+
if (!fs.existsSync(dirname)) {
49+
fs.mkdirSync(dirname);
50+
}
51+
52+
fs.writeFileSync(filename, html);
53+
54+
console.log(filePath);
5055
});
5156
});

app/index.jsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react';
2-
import Router from 'react-router';
32
import dataStore from './stores/dataStore';
43
import JscsModel from './models/JscsModel';
54

@@ -9,6 +8,4 @@ if (typeof window.__jscsData !== 'undefined') {
98

109
var AppView = require('./views/AppView');
1110

12-
Router.run(AppView, Router.HistoryLocation, function (Handler) {
13-
React.render(<Handler/>, document.getElementById('root'));
14-
});
11+
React.render(<AppView />, document.getElementById('root'));

app/lib/html.tpl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
</head>
88
<body>
9-
<div id="root">{%content%}</div>
9+
<div id="root">
10+
{%content%}
11+
</div>
12+
<script type="application/javascript">
13+
window.__locationState = {%locationState%};
14+
</script>
1015
<script type="application/javascript" src="{%dataPath%}"></script>
1116
<script type="application/javascript" src="{%scriptPath%}"></script>
1217
</body>

app/lib/renderHtml.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ function renderHtml({title, content, dataPath, scriptPath, stylePath, locationSt
88
.replace('{%dataPath%}', dataPath)
99
.replace('{%scriptPath%}', scriptPath)
1010
.replace('{%stylePath%}', stylePath)
11+
.replace('{%locationState%}', locationState)
1112
.replace('{%content%}', content);
1213
}
1314

app/mixins/PageTitle.jsx

Lines changed: 0 additions & 25 deletions
This file was deleted.

app/prepareData.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from 'fs';
22
import renderHtml from './lib/renderHtml';
33
import React from 'react';
44
import dataStore from './stores/dataStore';
5+
import locationStore from './stores/locationStore';
56
import collectData from './lib/collectData';
67

78
export default collectData().then(/** @param {JscsModel} data */ function(data) {

app/stores/locationStore.jsx

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
import {EventEmitter} from 'events';
2+
import appDispatcher from '../dispatchers/appDispatcher';
3+
import dataStore from './dataStore';
4+
5+
class LocationStore extends EventEmitter {
6+
constructor() {
7+
super();
8+
9+
this._state = {
10+
page: 'index',
11+
data: null
12+
};
13+
14+
if (typeof window !== 'undefined') {
15+
16+
this._state = parsePath(window.location.pathname);
17+
18+
if (window.__locationState) {
19+
this._state = processRewrites(window.__locationState, getCurrentWindowHash());
20+
}
21+
22+
var onUrlChanged = () => {
23+
let newState = processRewrites(parsePath(String(window.location.pathname)), getCurrentWindowHash());
24+
this._navigate(newState, false);
25+
};
26+
27+
if (typeof window.onpopstate !== 'undefined') {
28+
window.addEventListener('popstate', onUrlChanged);
29+
} else if (typeof window.onhashchange !== 'undefined') {
30+
window.addEventListener('hashchange', onUrlChanged);
31+
}
32+
}
33+
34+
appDispatcher.register(this._onDispatch.bind(this));
35+
}
36+
37+
_onDispatch(payload) {
38+
if (payload.action === 'NAVIGATE') {
39+
this._navigate(payload, true);
40+
}
41+
42+
if (payload.action === 'NAVIGATE_TO_PATH') {
43+
this._navigate(parsePath(payload.path), true);
44+
}
45+
}
46+
47+
_navigate(newState, pushToHistory) {
48+
if (this._state.page !== newState.page || this._state.data !== newState.data) {
49+
var newPath = this.renderPath(
50+
newState.page, newState.data
51+
);
52+
this._state = newState;
53+
if (typeof document !== 'undefined') {
54+
document.title = this.getTitle();
55+
}
56+
if (pushToHistory &&
57+
typeof window !== 'undefined' &&
58+
typeof window.history.pushState !== 'undefined'
59+
) {
60+
try {
61+
window.history.replaceState({scroll: [window.scrollX, window.scrollY]}, document.title, window.location.pathname);
62+
window.history.pushState({scroll: [0, 0]}, this.getTitle(), newPath);
63+
} catch (e) {} // Can fail on file:// origins
64+
}
65+
this.emit('change');
66+
}
67+
}
68+
69+
getPage() {
70+
return this._state.page;
71+
}
72+
73+
getData() {
74+
return this._state.data;
75+
}
76+
77+
renderPath(page, data, extension) {
78+
var pathToRoot = this._state.data ? '../' : './';
79+
if (page === 'index') {
80+
return pathToRoot;
81+
} else {
82+
return pathToRoot + page + (data ? '/' + data : '') + (extension || '.html');
83+
}
84+
}
85+
86+
getTitle() {
87+
var page = this._state.page;
88+
if (page === 'index') {
89+
return 'JSCS: JavaScript Code Style checker';
90+
} else {
91+
var title = '';
92+
if (page === 'rule') {
93+
title = this._state.data + ' rule';
94+
} else {
95+
title = page.substr(0, 1).toUpperCase() + page.substr(1);
96+
}
97+
return 'JSCS - ' + title;
98+
}
99+
}
100+
}
101+
102+
export default new LocationStore();
103+
104+
function parsePath(path) {
105+
var hashPos = path.indexOf('#');
106+
if (hashPos !== -1) {
107+
path = path.substr(0, hashPos);
108+
}
109+
var pathBits = path.replace(/^\/|\.html$/g, '').split('/');
110+
if (pathBits.length === 1 && pathBits[0] === '') {
111+
return {
112+
page: 'index',
113+
data: null
114+
};
115+
} else {
116+
return {
117+
page: pathBits.shift(),
118+
data: pathBits.shift() || null
119+
};
120+
}
121+
}
122+
123+
function getCurrentWindowHash() {
124+
if (typeof window !== 'undefined') {
125+
var fullHash = window.location.hash;
126+
if (fullHash && fullHash.charAt(0) === '#') {
127+
return fullHash.slice(1);
128+
}
129+
}
130+
return '';
131+
}
132+
133+
/**
134+
* Processing legacy urls.
135+
* @private
136+
*/
137+
function processRewrites(state, windowHash) {
138+
if (windowHash) {
139+
var ruleName = getRuleName(windowHash);
140+
if ((state.page === 'rule' || state.page === 'rules') && ruleName) {
141+
return {
142+
page: 'rule',
143+
data: ruleName
144+
};
145+
}
146+
}
147+
return state;
148+
}
149+
150+
let lowerRuleNameIndex;
151+
152+
function getRuleName(input) {
153+
if (!lowerRuleNameIndex) {
154+
lowerRuleNameIndex = dataStore.getData().getRules().reduce((obj, rule) => {
155+
obj[rule.getName().toLowerCase()] = rule.getName();
156+
return obj;
157+
}, {})
158+
}
159+
160+
return lowerRuleNameIndex[input.toLowerCase()];
161+
}

app/views/AppView/RouteView.jsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import locationStore from '../../stores/locationStore';
3+
4+
var RouteView = React.createClass({
5+
getInitialState: function() {
6+
return {
7+
page: locationStore.getPage()
8+
};
9+
},
10+
11+
componentDidMount: function() {
12+
this._pageChangeHandler = (function() {
13+
if (
14+
typeof window !== 'undefined' &&
15+
typeof window.history.state !== 'undefined'
16+
) {
17+
window.scrollTo.apply(window, window.history.state.scroll);
18+
}
19+
this.setState({
20+
page: locationStore.getPage()
21+
});
22+
}).bind(this);
23+
24+
locationStore.on('change', this._pageChangeHandler);
25+
},
26+
27+
componentWillUnmount: function() {
28+
locationStore.removeListener('change', this._pageChangeHandler);
29+
},
30+
31+
render: function() {
32+
var contents = '';
33+
34+
if (this.state.page === this.props.page) {
35+
contents = this.props.children;
36+
}
37+
38+
return (
39+
<div className="route-view">
40+
{contents}
41+
</div>
42+
);
43+
}
44+
});
45+
46+
module.exports = RouteView;

0 commit comments

Comments
 (0)