Skip to content

Commit 37d9bac

Browse files
committed
[fixed] isActive on <Link onlyActiveOnIndex>
Fixes #2066 Closes #2069
1 parent 029646f commit 37d9bac

File tree

2 files changed

+59
-41
lines changed

2 files changed

+59
-41
lines changed

modules/__tests__/IndexLink-test.js

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,56 @@ import Router from '../Router'
88
import Route from '../Route'
99
import IndexLink from '../IndexLink'
1010

11-
describe('an <IndexLink/>', function () {
11+
describe('An <IndexLink>', function () {
1212

13-
var node
14-
beforeEach(function () {
15-
node = document.createElement('div')
16-
})
17-
18-
afterEach(function () {
19-
React.unmountComponentAtNode(node)
20-
})
21-
22-
var App = React.createClass({
23-
render () {
13+
const App = React.createClass({
14+
render() {
2415
return (
2516
<div>
2617
<ul>
27-
<li><IndexLink id="appLink" to="/" activeClassName="active">app </IndexLink></li>
28-
<li><IndexLink id="deepLink" to="/deep" activeClassName="active">deep </IndexLink></li>
18+
<li><IndexLink id="appLink" to="/" activeClassName="active">app</IndexLink></li>
19+
<li><IndexLink id="deepLink" to="/deep" activeClassName="active">deep</IndexLink></li>
2920
</ul>
3021
{this.props.children}
3122
</div>
3223
)
3324
}
3425
})
3526

36-
var Parent = React.createClass({
37-
render () {
27+
const Parent = React.createClass({
28+
render() {
3829
return <div>parent {this.props.children}</div>
3930
}
4031
})
4132

42-
var Child = React.createClass({
43-
render () {
33+
const Child = React.createClass({
34+
render() {
4435
return <div>child </div>
4536
}
4637
})
4738

48-
var routes = (
39+
const routes = (
4940
<Route path="/" component={App}>
50-
<IndexRoute component={Child}/>
41+
<IndexRoute component={Child} />
5142
<Route path="/deep" component={Parent}>
52-
<IndexRoute component={Child}/>
43+
<IndexRoute component={Child} />
5344
</Route>
5445
</Route>
5546
)
5647

48+
let node
49+
beforeEach(function () {
50+
node = document.createElement('div')
51+
})
52+
53+
afterEach(function () {
54+
React.unmountComponentAtNode(node)
55+
})
56+
5757
describe('when linking to the root', function () {
58-
it('is active when the parents route is active', function (done) {
58+
it("is active when the parent's route is active", function (done) {
5959
React.render((
60-
<Router history={createHistory('/')} routes={routes}/>
60+
<Router history={createHistory('/')} routes={routes} />
6161
), node, function () {
6262
expect(node.querySelector('#appLink').className).toEqual('active')
6363
expect(node.querySelector('#deepLink').className).toEqual('')
@@ -67,9 +67,9 @@ describe('an <IndexLink/>', function () {
6767
})
6868

6969
describe('when linking deep into the route hierarchy', function () {
70-
it('is active when the parents route is active', function (done) {
70+
it("is active when the parent's route is active", function (done) {
7171
React.render((
72-
<Router history={createHistory('/deep')} routes={routes}/>
72+
<Router history={createHistory('/deep')} routes={routes} />
7373
), node, function () {
7474
expect(node.querySelector('#appLink').className).toEqual('')
7575
expect(node.querySelector('#deepLink').className).toEqual('active')

modules/isActive.js

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
import { matchPattern } from './PatternUtils'
22

33
/**
4-
* Returns true if a route and params that match the given
5-
* pathname are currently active.
4+
* Returns true if the given pathname matches the active pathname.
65
*/
7-
function pathnameIsActive(pathname, activePathname, activeRoutes, activeParams) {
8-
if (pathname === activePathname || activePathname.indexOf(pathname + '/') === 0)
9-
return true
6+
function pathnameIsActive(pathname, activePathname) {
7+
return pathname === activePathname || activePathname.indexOf(pathname + '/') === 0
8+
}
9+
10+
function paramsAreActive(paramNames, paramValues, activeParams) {
11+
return paramNames.every(function (paramName, index) {
12+
return String(paramValues[index]) === String(activeParams[paramName])
13+
})
14+
}
1015

16+
function getMatchingRoute(pathname, activeRoutes, activeParams) {
1117
let route, pattern, basename = ''
1218
for (let i = 0, len = activeRoutes.length; i < len; ++i) {
1319
route = activeRoutes[i]
1420

15-
if (!route.path)
16-
return false
21+
//if (!route.path)
22+
// return false
1723

1824
pattern = route.path || ''
1925

@@ -22,16 +28,29 @@ function pathnameIsActive(pathname, activePathname, activeRoutes, activeParams)
2228

2329
let { remainingPathname, paramNames, paramValues } = matchPattern(pattern, pathname)
2430

25-
if (remainingPathname === '') {
26-
return paramNames.every(function (paramName, index) {
27-
return String(paramValues[index]) === String(activeParams[paramName])
28-
})
29-
}
31+
if (remainingPathname === '' && paramsAreActive(paramNames, paramValues, activeParams))
32+
return route
3033

3134
basename = pattern
3235
}
3336

34-
return false
37+
return null
38+
}
39+
40+
/**
41+
* Returns true if the given pathname matches the active routes
42+
* and params.
43+
*/
44+
function routeIsActive(pathname, activeRoutes, activeParams, indexOnly) {
45+
let route = getMatchingRoute(pathname, activeRoutes, activeParams)
46+
47+
if (route == null)
48+
return false
49+
50+
if (indexOnly)
51+
return activeRoutes.length > 1 && activeRoutes[activeRoutes.length - 2].indexRoute === route
52+
53+
return true
3554
}
3655

3756
/**
@@ -60,11 +79,10 @@ function isActive(pathname, query, indexOnly, location, routes, params) {
6079
if (location == null)
6180
return false
6281

63-
if (indexOnly && (routes.length < 2 || routes[routes.length - 2].indexRoute !== routes[routes.length - 1]))
82+
if (!pathnameIsActive(pathname, location.pathname) && !routeIsActive(pathname, routes, params, indexOnly))
6483
return false
6584

66-
return pathnameIsActive(pathname, location.pathname, routes, params) &&
67-
queryIsActive(query, location.query)
85+
return queryIsActive(query, location.query)
6886
}
6987

7088
export default isActive

0 commit comments

Comments
 (0)