Skip to content

Commit

Permalink
[fixed] Make <Route name>s global, again
Browse files Browse the repository at this point in the history
  • Loading branch information
mjackson committed Feb 24, 2015
1 parent ab802c0 commit 196390f
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 87 deletions.
6 changes: 3 additions & 3 deletions examples/dynamic-segments/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ var User = React.createClass({
<div className="User">
<h1>User id: {userId}</h1>
<ul>
<li><Link to="user.task" params={{userId: userId, taskId: "foo"}}>foo task</Link></li>
<li><Link to="user.task" params={{userId: userId, taskId: "bar"}}>bar task</Link></li>
<li><Link to="task" params={{userId: userId, taskId: "foo"}}>foo task</Link></li>
<li><Link to="task" params={{userId: userId, taskId: "bar"}}>bar task</Link></li>
</ul>
<RouteHandler/>
</div>
Expand All @@ -53,7 +53,7 @@ var routes = (
<Route path="/" handler={App}>
<Route name="user" path="/user/:userId" handler={User}>
<Route name="task" path="tasks/:taskId" handler={Task}/>
<Redirect from="todos/:taskId" to="user.task"/>
<Redirect from="todos/:taskId" to="task"/>
</Route>
</Route>
);
Expand Down
2 changes: 1 addition & 1 deletion examples/partial-app-loading/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var Dashboard = React.createClass({
<div>
<h1>Dashboard!</h1>
<ul>
<li><Link to="dashboard.inbox">Inbox</Link></li>
<li><Link to="inbox">Inbox</Link></li>
</ul>
<RouteHandler/>
</div>
Expand Down
90 changes: 9 additions & 81 deletions modules/Route.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,102 +15,30 @@ function Route(name, path, ignoreScrollBehavior, isDefault, isNotFound, onEnter,
this.handler = handler;
}

Route.prototype.toString = function () {
var string = '<Route';

if (this.name)
string += ` name="${this.name}"`;

string += ` path="${this.path}">`;

return string;
};

/**
* Appends the given route to this route's child routes.
*/
Route.prototype.appendChildRoute = function (route) {
Route.prototype.appendChild = function (route) {
invariant(
route instanceof Route,
'route.appendChildRoute must use a valid Route'
'route.appendChild must use a valid Route'
);

if (!this.childRoutes)
this.childRoutes = [];

if (route.name) {
invariant(
this.childRoutes.every(function (childRoute) {
return childRoute.name !== route.name;
}),
'Route %s may not have more than one child route named "%s"',
this, route.name
);
}

this.childRoutes.push(route);
};

/**
* Allows looking up a child route using a "." delimited string, e.g.:
*
* route.appendChildRoute(
* Router.createRoute({ name: 'user' }, function () {
* Router.createRoute({ name: 'new' });
* })
* );
*
* var NewUserRoute = route.lookupChildRoute('user.new');
*
* See also Route.findRouteByName.
*/
Route.prototype.lookupChildRoute = function (names) {
if (!this.childRoutes)
return null;

return Route.findRouteByName(this.childRoutes, names);
};

/**
* Searches the given array of routes and returns the route that matches
* the given name. The name should be a . delimited string like "user.new"
* that specifies the names of nested routes. Routes in the hierarchy that
* do not have a name do not need to be specified in the search string.
*
* var routes = [
* Router.createRoute({ name: 'user' }, function () {
* Router.createRoute({ name: 'new' });
* })
* ];
*
* var NewUserRoute = Route.findRouteByName(routes, 'user.new');
*/
Route.findRouteByName = function (routes, names) {
if (typeof names === 'string')
names = names.split('.');

var route, foundRoute;
for (var i = 0, len = routes.length; i < len; ++i) {
route = routes[i];

if (route.name === names[0]) {
if (names.length === 1)
return route;

if (!route.childRoutes)
return null;
Route.prototype.toString = function () {
var string = '<Route';

return Route.findRouteByName(route.childRoutes, names.slice(1));
} else if (route.name == null) {
// Transparently skip over unnamed routes in the tree.
foundRoute = route.lookupChildRoute(names);
if (this.name)
string += ` name="${this.name}"`;

if (foundRoute != null)
return foundRoute;
}
}
string += ` path="${this.path}">`;

return null;
return string;
};

var _currentRoute;
Expand Down Expand Up @@ -223,7 +151,7 @@ Route.createRoute = function (options, callback) {
parentRoute.notFoundRoute = route;
}

parentRoute.appendChildRoute(route);
parentRoute.appendChild(route);
}

// Any routes created in the callback
Expand Down
2 changes: 1 addition & 1 deletion modules/__tests__/Router-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ describe('Router.makePath', function () {

describe('when there is a route with the given name', function () {
it('returns the correct path', function () {
expect(router.makePath('home.users.user', { id: 6 })).toEqual('/home/users/6');
expect(router.makePath('user', { id: 6 })).toEqual('/home/users/6');
});
});

Expand Down
25 changes: 24 additions & 1 deletion modules/createRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ function hasMatch(routes, route, prevParams, nextParams, prevQuery, nextQuery) {
});
}

function addRoutesToNamedRoutes(routes, namedRoutes) {
var route;
for (var i = 0, len = routes.length; i < len; ++i) {
route = routes[i];

if (route.name) {
invariant(
namedRoutes[route.name] == null,
'You may not have more than one route named "%s"',
route.name
);

namedRoutes[route.name] = route;
}

if (route.childRoutes)
addRoutesToNamedRoutes(route.childRoutes, namedRoutes);
}
}

/**
* Creates and returns a new router using the given options. A router
* is a ReactComponent class that knows how to react to changes in the
Expand Down Expand Up @@ -134,6 +154,7 @@ function createRouter(options) {

clearAllRoutes: function () {
this.cancelPendingTransition();
this.namedRoutes = {};
this.routes = [];
},

Expand All @@ -144,6 +165,8 @@ function createRouter(options) {
if (isReactChildren(routes))
routes = createRoutesFromReactChildren(routes);

addRoutesToNamedRoutes(routes, this.namedRoutes);

this.routes.push.apply(this.routes, routes);
},

Expand Down Expand Up @@ -174,7 +197,7 @@ function createRouter(options) {
if (Path.isAbsolute(to)) {
path = to;
} else {
var route = (to instanceof Route) ? to : Route.findRouteByName(this.routes, to);
var route = (to instanceof Route) ? to : this.namedRoutes[to];

invariant(
route instanceof Route,
Expand Down

0 comments on commit 196390f

Please sign in to comment.