Skip to content

Commit f1f07ee

Browse files
committed
Merge pull request STRML#69 from fgnass/nested-contexts
better support for nested contextual routers
2 parents 6f6c835 + f879fd8 commit f1f07ee

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

lib/RouterMixin.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ var RouterMixin = {
5050
var parentMatch = parent.getMatch();
5151

5252
invariant(
53-
props.path || isString(parentMatch.unmatchedPath),
53+
props.path ||
54+
isString(parentMatch.unmatchedPath) ||
55+
parentMatch.matchedPath == parentMatch.path,
5456
"contextual router has nothing to match on: %s", parentMatch.unmatchedPath
5557
);
5658

57-
path = props.path || parentMatch.unmatchedPath;
58-
prefix = parentMatch.matchedPath;
59+
path = props.path || parentMatch.unmatchedPath || '/';
60+
prefix = parent.state.prefix + parentMatch.matchedPath;
5961
} else {
6062

6163
path = props.path || this.getEnvironment().getPath();

tests/server.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,83 @@ describe('react-router-component (on server)', function() {
123123

124124
});
125125

126+
127+
describe('nested contextual routers', function() {
128+
129+
var Level2 = React.createClass({
130+
131+
render: function() {
132+
return Router.Locations({className: 'L2', contextual: true},
133+
Router.Location({
134+
path: '/',
135+
handler: function(props) {
136+
return Router.Link({href: '/hello'});
137+
}
138+
}),
139+
Router.Location({
140+
path: '/:slug',
141+
handler: function(props) {
142+
return Router.Link({global: true, href: '/hi'});
143+
}
144+
})
145+
)
146+
}
147+
});
148+
149+
var Level1 = React.createClass({
150+
151+
render: function() {
152+
return Router.Locations({className: 'L1', contextual: true},
153+
Router.Location({
154+
path: '/',
155+
handler: function(props) {
156+
return Router.Link({href: '/l2'});
157+
}
158+
}),
159+
Router.Location({
160+
path: '/:slug(/*)',
161+
handler: Level2
162+
})
163+
)
164+
}
165+
});
166+
167+
var App = React.createClass({
168+
169+
render: function() {
170+
return Router.Locations({className: 'App', path: this.props.path},
171+
Router.Location({
172+
path: '/l1/:slug(/*)',
173+
handler: Level1
174+
})
175+
);
176+
}
177+
});
178+
179+
it ('renders Link component with href scoped to its prefix', function() {
180+
var markup = React.renderComponentToString(App({path: '/l1/nice'}));
181+
assert(markup.match(/class="App"/));
182+
assert(markup.match(/class="L1"/));
183+
assert(markup.match(/href="/l1/nice/l2"/));
184+
});
185+
186+
it ('renders nested Link component with href scoped to its prefix', function() {
187+
var markup = React.renderComponentToString(App({path: '/l1/nice/l2'}));
188+
assert(markup.match(/class="App"/));
189+
assert(markup.match(/class="L1"/));
190+
assert(markup.match(/class="L2"/));
191+
assert(markup.match(/href="/l1/nice/l2/hello"/));
192+
});
193+
194+
it ('renders global Link component with correct href (not scoped to a router)', function() {
195+
var markup = React.renderComponentToString(App({path: '/l1/nice/l2/foo'}));
196+
assert(markup.match(/class="App"/));
197+
assert(markup.match(/class="L2"/));
198+
assert(markup.match(/href="/hi"/));
199+
});
200+
201+
});
202+
126203
describe('async router', function() {
127204
var App = React.createClass({
128205

0 commit comments

Comments
 (0)