1
+
/** @jsx React.DOM */
2
+
3
+
function pushUrl(path) {
4
+
location.hash = path;
5
+
}
6
+
7
+
function toArray(maybeArray) {
8
+
return Array.isArray(maybeArray) ? maybeArray : [maybeArray];
9
+
}
10
+
11
+
function childrenArray(component) {
12
+
return component.props.children ? toArray(component.props.children) : [];
13
+
}
14
+
15
+
function matchedChildRoute(path, component) {
16
+
var children = childrenArray(component);
17
+
for (var i = 0, l = children.length; i < l; i ++) {
18
+
if (children[i].props.path === path) {
19
+
return children[i];
20
+
}
21
+
}
22
+
return false;
23
+
}
24
+
25
+
var Link = React.createClass({
26
+
handleClick: function(event) {
27
+
event.preventDefault();
28
+
var path = this.props.to;
29
+
pushUrl(path);
30
+
},
31
+
32
+
render: function() {
33
+
return (
34
+
<a href={this.props.to} onClick={this.handleClick}>{this.props.children}</a>
35
+
);
36
+
}
37
+
});
38
+
39
+
var Routed = {
40
+
41
+
getInitialState: function() {
42
+
return {activeChild: null};
43
+
},
44
+
45
+
componentWillMount: function(path) {
46
+
window.addEventListener('hashchange', this.handleRouteChange, false);
47
+
this.handleRouteChange();
48
+
},
49
+
50
+
componentWillUnmount: function() {
51
+
window.removeEventListener('hashchange', this.handleRouteChange);
52
+
},
53
+
54
+
handleRouteChange: function() {
55
+
var path = location.hash.substr(1);
56
+
var matched = matchedChildRoute(path, this)
57
+
this.setState({activeChild: matched});
58
+
},
59
+
60
+
outlet: function() {
61
+
var children = this.props.children;
62
+
if (!children) throw new Error("you don't have any children, why are you calling outlet()?");
63
+
return this.state.activeChild;
64
+
}
65
+
66
+
};
67
+
68
+
var App = React.createClass({
69
+
mixins: [Routed],
70
+
71
+
render: function() {
72
+
return (
73
+
<Root path="/">
74
+
<About path="/about"/>
75
+
<Users path="/users"/>
76
+
</Root>
77
+
);
78
+
}
79
+
});
80
+
81
+
var Root = React.createClass({
82
+
mixins: [Routed],
83
+
84
+
render: function() {
85
+
return (
86
+
<div className="Root">
87
+
<ul>
88
+
<li><Link to="/">Home</Link></li>
89
+
<li><Link to="/about">About</Link></li>
90
+
<li><Link to="/users">Users</Link></li>
91
+
</ul>
92
+
{this.outlet()}
93
+
</div>
94
+
);
95
+
}
96
+
});
97
+
98
+
var About = React.createClass({
99
+
mixins: [Routed],
100
+
101
+
render: function() {
102
+
return <div className="About"><h1>About</h1></div>;
103
+
}
104
+
});
105
+
106
+
var Users = React.createClass({
107
+
mixins: [Routed],
108
+
109
+
statics: {
110
+
cache: null
111
+
},
112
+
113
+
getInitialState: function() {
114
+
return {users: Users.cache || []};
115
+
},
116
+
117
+
componentDidMount: function() {
118
+
var url = 'http://addressbook-api.herokuapp.com/contacts';
119
+
if (!Users.cache) {
120
+
$.getJSON(url).then(function(res) {
121
+
Users.cache = res.contacts;
122
+
this.setState({users: res.contacts});
123
+
}.bind(this));
124
+
}
125
+
},
126
+
127
+
render: function() {
128
+
var users = this.state.users.map(function(user) {
129
+
return <div>{user.first} {user.last}</div>;
130
+
});
131
+
var content = !users.length ? 'Loading users...' : users;
132
+
return <div className="Users">{content}</div>;
133
+
}
134
+
});
135
+
136
+
var User = React.createClass({
137
+
mixins: [Routed],
138
+
139
+
componentDidMount: function() {
140
+
if (this.props.user) {
141
+
this.setState({user: user});
142
+
} else {
143
+
$.getJSON('/users/'+this.params.id).then(function(user) {
144
+
this.setState({user: user});
145
+
}.bind(this));
146
+
}
147
+
},
148
+
149
+
render: function() {
150
+
var use = this.state.user;
151
+
return (
152
+
<div className="User">
153
+
<h1>{user.name}</h1>
154
+
<nav>
155
+
<Link to="UserIndex">User</Link>
156
+
<Link to="UserAbout" user={user}>About</Link>
157
+
</nav>
158
+
{this.props.children}
159
+
</div>
160
+
);
161
+
}
162
+
});
163
+
164
+
var UserIndex = React.createClass({
165
+
mixins: [Routed],
166
+
167
+
render: function() {
168
+
return <div className="UserIndex"><h2>User Index</h2></div>
169
+
}
170
+
});
171
+
172
+
var UserAbout = React.createClass({
173
+
mixins: [Routed],
174
+
175
+
render: function() {
176
+
var user = this.props.user;
177
+
return (
178
+
<div className="UserIndex">
179
+
<h2>About {user.name}</h2>
180
+
<div>{user.description}</div>
181
+
</div>
182
+
);
183
+
}
184
+
});
185
+
186
+
React.renderComponent(<App/>, document.body);
187
+
188
+
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4