Skip to content

Commit

Permalink
[added] Support <Redirect to="relative/path">
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisirhc committed Oct 6, 2015
1 parent 0f5b493 commit 428da54
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 7 deletions.
37 changes: 30 additions & 7 deletions modules/Redirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,22 @@ const Redirect = React.createClass({
if (route.from)
route.path = route.from

// TODO: Handle relative pathnames, see #1658
invariant(
route.to.charAt(0) === '/',
'<Redirect to> must be an absolute path. This should be fixed in the future'
)

route.onEnter = function (nextState, replaceState) {
const { location, params } = nextState
const pathname = route.to ? formatPattern(route.to, params) : location.pathname

let pathname
if (route.to.charAt(0) === '/') {
pathname = formatPattern(route.to, params)
}
else if (!route.to) {
pathname = location.pathname
}
else {
let routeIndex = nextState.routes.indexOf(route)
let parentPattern = Redirect.getRoutePattern(nextState.routes, routeIndex - 1)
let pattern = parentPattern.replace(/\/*$/, '/') + route.to
pathname = formatPattern(pattern, params)
}

replaceState(
route.state || location.state,
Expand All @@ -41,6 +48,22 @@ const Redirect = React.createClass({
}

return route
},

getRoutePattern(routes, routeIndex) {
let parentPattern = ''

for (let i = routeIndex; i >= 0; i--) {
let route = routes[i]
let pattern = route.path || ''
parentPattern = pattern.replace(/\/*$/, '/') + parentPattern

if (pattern.indexOf('/') === 0) {
break
}
}

return '/' + parentPattern
}

},
Expand Down
28 changes: 28 additions & 0 deletions modules/__tests__/Redirect-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,32 @@ describe('A <Redirect>', function () {
})
})

it('works with relative paths', function (done) {
React.render((
<Router history={createHistory('/nested/route1')}>
<Route path="nested">
<Route path="route2" />
<Redirect from="route1" to="route2" />
</Route>
</Router>
), node, function () {
expect(this.state.location.pathname).toEqual('/nested/route2')
done()
})
})

it('works with relative paths with param', function (done) {
React.render((
<Router history={createHistory('/nested/1/route1')}>
<Route path="nested/:id">
<Route path="route2" />
<Redirect from="route1" to="route2" />
</Route>
</Router>
), node, function () {
expect(this.state.location.pathname).toEqual('/nested/1/route2')
done()
})
})

})

0 comments on commit 428da54

Please sign in to comment.