Skip to content

Commit

Permalink
Remove dependency on route-recognizer
Browse files Browse the repository at this point in the history
- Use regular expressions instead for more flexibility, better
  performance, and a smaller package
  • Loading branch information
jdlehman committed Sep 25, 2015
1 parent 23749e4 commit 76df023
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 38 deletions.
2 changes: 1 addition & 1 deletion dist/switcheroo.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions docs/components/Switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,4 @@ A "Switch" component is always used inside of the context of a `Switcher` compon

### path

The `path` prop is a string that if matches the path, the corresponding handler component will be rendered. If you define multiple `Switch`es with the same path, the last one will be used. switcheroo makes use of [`route-recognizer`](https://github.com/tildeio/route-recognizer) to match paths with the URL, meaning that dynamic segments and star segments will work.

```js
// dynamic segments
"/post/:id" matches "/post/1", "/post/100", and "/post/whatever", but not "/post"

// star segements
"/post/*everything" matches "/post/one", "post/one/two", and "/post/one/two/three", but not "/post"
```
The `path` prop is a string representing a regular expression. If the regular expression matches the path, the corresponding handler component will be rendered. If you define multiple `Switch`es with the same path, the first one will be used.
9 changes: 8 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,14 @@ module.exports = function(config) {
},
module: {
loaders: [
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
query: {
auxiliaryCommentBefore: 'istanbul ignore next'
}
}
],
postLoaders: [
{
Expand Down
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,5 @@
},
"peerDependencies": {
"react": ">=0.12.0 <0.14.0"
},
"dependencies": {
"route-recognizer": "^0.1.9"
}
}
28 changes: 9 additions & 19 deletions src/components/Switcher.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {Component} from 'react';
import Recognizer from 'route-recognizer';
import {ensureTrailingSlash} from 'helpers';
import window from 'window';

export default class Switcher extends Component {
Expand All @@ -18,7 +18,7 @@ export default class Switcher extends Component {
onChange: React.PropTypes.func,
wrapper: React.PropTypes.any,
location: React.PropTypes.string,
baseURL: React.PropTypes.string
basePath: React.PropTypes.string
};

static defaultProps = {
Expand All @@ -32,7 +32,6 @@ export default class Switcher extends Component {
constructor(props) {
super(props);
this.defaultSwitch = props.defaultHandler ? React.createElement(props.defaultHandler, props.defaultHandlerProps) : null;
this.initializeRecognizer(props);

var currentPath = this.getLocation();
var switchElement = this.getSwitch(currentPath);
Expand All @@ -54,8 +53,6 @@ export default class Switcher extends Component {
}

componentWillReceiveProps(nextProps) {
this.initializeRecognizer(nextProps);

var currentPath = this.getLocation();
var switchElement = this.getSwitch(currentPath);

Expand Down Expand Up @@ -86,22 +83,15 @@ export default class Switcher extends Component {
}

getSwitch = (path) => {
var handlers = this.recognizer.recognize(path);
return (handlers && handlers[0] && handlers[0].handler) || null;
var children = [].concat(this.props.children);
var consistentPath = ensureTrailingSlash(path);
return children.filter(child => {
var fullChildPath = ensureTrailingSlash(this.props.basePath + child.props.path);
var regex = new RegExp(`^${fullChildPath}$`);
return consistentPath.match(regex);
})[0] || null;
}

initializeRecognizer = (props) => {
this.recognizer = new Recognizer();
var children = [].concat(props.children);
children.forEach((child) => {
this.recognizer.add([{
path: `${props.basePath}${child.props.path}`,
handler: child.props.handler || child
}]);
});
}


handleRouteChange = (ev) => {
var currentPath = this.getLocation();
var switchElement = this.getSwitch(currentPath);
Expand Down
3 changes: 3 additions & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function ensureTrailingSlash(path) {
return path.slice(-1) !== '/' ? `${path}/` : path;
}
8 changes: 4 additions & 4 deletions test/components/Switcher_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ describe('Switcher', function() {
<Switcher>
<div path="/">Home</div>
<div path="/another">Another</div>
<div path="/wildCardPath/*anything">Wild</div>
<div path="/path/:dynamic/more">Dynamic</div>
<div path="/wildCardPath/.*">Wild</div>
<div path="/path/.+/more">Dynamic</div>
<div path="/duplicate">Dup 1</div>
<div path="/duplicate">Dup 2</div>
</Switcher>,
Expand All @@ -121,9 +121,9 @@ describe('Switcher', function() {
assert.isNull(swtch);
});

it('gets last match if duplicate paths', function() {
it('gets first match if duplicate paths', function() {
var swtch = this.switcher.getSwitch('/duplicate');
assert.equal(swtch.props.children, 'Dup 2');
assert.equal(swtch.props.children, 'Dup 1');
});

it('handles paths with wild cards', function() {
Expand Down
Loading

0 comments on commit 76df023

Please sign in to comment.