Socket
Socket
Sign inDemoInstall

react-router

Package Overview
Dependencies
4
Maintainers
1
Versions
429
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.0 to 0.0.1

Readme.md

238

index.js
var Backbone = require('backbone')
, _ = require('lodash')
, $ = window.jQuery
var _ = require('lodash')
, d = React.DOM
, Route = require('./route')
DEFAULTS = {
_index: React.createClass({
render: function () {
return d.span({className: 'react-router_index'})
}
}),
_error: React.createClass({
displayName: 'DefaultError',
render: function () {
return d.div({className: 'react-router_error'},
d.strong({}, 'Error Loading Model:'),
this.props.error)
},
}),
_loading: React.createClass({
render: function () {
return d.span({className: 'react-router_loading'})
}
})
}
Backbone.$ = $
module.exports = {
module.exports = {
getDefaultProps: function () {
return {
_baseroute: '',
_on: function (fn) {
window.addEventListener('hashchange', fn)
},
_off: function (fn) {
window.removeEventListener('hashchange', fn)
},
_path: function (path) {
if (arguments.length === 1) {
window.location.hash = '#' + path
} else {
return window.location.hash.slice(1)
}
},
goTo: function () {throw 'override'}
}
},
getInitialState: function () {
this.createRoutes()
return {
_route: this.defaultRoute(),
_navigations: 0
_route: ''
}
},
createRoutes: function () {
var routes = this.routes
, _routes = this._routes = {}
if ('function' === typeof routes) {
routes = routes()
componentWillMount: function () {
if (this.props.goTo) {
// I'm not the top router
var cancel = this.enter && this.enter()
if (cancel) return
}
Object.keys(routes).forEach(function (route) {
_routes[route] = new Route(route, routes[route])
})
this.props._on(this.pathchange)
this.setRouteFromPath()
},
defaultRoute: function () {
var found = null
for (var route in this._routes) {
var obj = route.match('')
if (!obj) continue;
found = {
name: route.name,
params: obj,
raw: ''
}
break;
componentWillUnmount: function () {
this.props._off(this.pathchange)
},
showTitle: function () {
var title = this.title
if ('function' === typeof title) title = title()
this.setTitle(title)
},
componentDidMount: function () {
// if there are no child routes
if (!this.refs._outlet && this.title) {
this.showTitle()
}
return found
},
/**
* Returns the route object, which looks like
* {
* name: the name of the route,
* raw: the raw /matched/url/stuff
* params: {} obj of the parsed params
* }
*/
getRoute: function () {
return this.state._route
componentDidUpdate: function () {
// if there are no child routes
if (!this.refs._outlet && this.title) {
this.showTitle()
}
},
setRoute: function (name, params) {
params = params || {}
if (!this._routes[name]) {
console.warn('Route not defined', name)
setTitle: function (text) {
document.title = text
},
/** Do we need this for something?
componentDidUpdate: function (oprops, ostate) {
if (ostate._route === this.state._route) return
},
**/
pathchange: function () {
this.setRouteFromPath()
},
setRouteFromPath: function () {
// check the current url, if there's information for me there then load
// that into the _route state
var path = this.props._path()
if (path.indexOf(this.props._baseroute) === -1) {
// left this path. we will soon be destructed.
return
}
var fragment = this._routes[name].toFragment(params)
if (fragment === false) {
console.warn('Invalid params given for route', name, params)
throw new Error('Invalid params for route ' + name)
var hash = path.slice(this.props._baseroute.length)
if (hash.length && hash[0] === '/') hash = hash.slice(1)
var part = hash.split('/', 1)[0]
this.setState({_route: part})
},
goTo: function (route, global, force) {
var full, part
if (global) {
if (route.indexOf(this.props._baseroute) !== 0) {
return this.props.goTo(route, global, force)
}
full = route
part = route.slice(this.props._baseroute.length).split('/', 1)[0]
} else {
if (route.slice(0, 3) === '../' || route === '..') {
return this.props.goTo(route.slice(3), global, force)
}
full = this.props._baseroute
if (full.length && full[full.length-1] !== '/' && route.length && route[0] !== '/') {
full += '/'
}
full += route
part = route.split('/', 1)[0]
}
Backbone.history.navigate(fragment, {trigger: false})
this.onRoute(name, params, fragment)
var switching = part !== this.state._route
if (switching && !force) {
/** Not sure how this should work exactly. It should probably be async....
if (this.refs._outlet.leave && !this.refs._outlet.leave()) {
console.log('Routing cancelled by current outlet', this.state._route, route)
return
}
**/
}
this.props._path(full)
},
onRoute: function (name, params, fragment) {
this.setState({
_route: {
name: name,
raw: fragment,
params: params
},
_navigations: this.state._navigations + 1
})
},
setupRoutes: function () {
var that = this
for (var name in this._routes) {
this._routes[name].register(that.onRoute.bind(that, name))
outlet: function () {
var route = this.routes[this.state._route]
, rname = this.state._route
if (!route && this.routes['*'] && rname) route = this.routes['*']
if (!route && (rname || !this.model)) {
console.log('Invalid router state envountered; no good route here...' + this.state._route)
this.goTo('')
return false
}
if ('string' === typeof route) {
this.goTo(route)
return false
}
var args = {}
// model routes
if (!rname && this.model) {
if (this.state.modelLoading) {
rname = '_loading'
} else if (this.state.modelError) {
rname = '_error'
args.error = this.state.modelError
} else {
rname = '_index'
args.model = this.state.model
}
route = this.routes[rname] || DEFAULTS[rname]
}
if (Array.isArray(route)) {
args = _.extend(args, route[1].call(this))
cls = route[0]
} else {
cls = route
}
var context = this.props.ctx ? _.extend({}, this.props.ctx) : {}
if (this.getContext) {
_.extend(context, this.getContext())
}
args.ctx = context
args.goTo = this.goTo
args._baseroute = (this.props._baseroute ? this.props._baseroute + '/' : '') + rname
args.ref = '_outlet'
args.param = rname
return cls(args)
},
componentDidMount: function () {
this.setupRoutes()
Backbone.history.start()
}
}
{
"name": "react-router",
"version": "0.0.0",
"version": "0.0.1",
"description": "An integrated router mixin for react components",

@@ -11,5 +11,10 @@ "main": "index.js",

"backbone": "~1.1.0",
"expect.js": "~0.2.0"
"expect.js": "~0.2.0",
"lodash": "~2.4.1"
},
"devDependencies": {},
"devDependencies": {
"mocha": "~1.17.1",
"envify": "~0.2.0",
"react": "~0.8.0"
},
"scripts": {

@@ -20,3 +25,3 @@ "test": "make test"

"type": "git",
"url": "git://github.com/jaredly/reactor.git"
"url": "git://github.com/jaredly/react-router.git"
},

@@ -30,5 +35,5 @@ "keywords": [

"bugs": {
"url": "https://github.com/jaredly/reactor/issues"
"url": "https://github.com/jaredly/react-router/issues"
},
"homepage": "https://github.com/jaredly/reactor"
"homepage": "https://github.com/jaredly/react-router"
}
var expect = require('expect.js')
, Route = require('../route')
, mixin = require('../')
var months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun']
function merge(a, b) {
if (!b) return a
for (var c in b) {
a[c] = b[c]
}
return a
}
var DateParser = {
compare: function (a, b) {
return a.getTime() === b.getTime()
},
stringify: function (date) {
return date.getTime()
},
parse: function (num) {
return new Date(+num)
function Awesome(props, state) {
props._on = props._on || function () { }
props._off = props._off || function () { }
props._path = props._path || function () { }
this.props = merge(this.getDefaultProps(), props)
this.state = merge(this.getInitialState(), state)
this.refs = {
_outlet: { }
}
}
var MonthParser = {
months: months,
match: months.join('|'),
stringify: function (num) {
return months[num]
},
parse: function (month) {
return months.indexOf(month.toLowerCase())
Awesome.prototype = mixin
Awesome.prototype.setState = function (state) {
for (var name in state) {
this.state[name] = state[name]
}

@@ -31,103 +32,104 @@ }

describe('Router', function () {
describe('most basic', function () {
var r
describe('simply setup', function () {
var awe, path
beforeEach(function () {
r = new Route('test', '')
awe = new Awesome({
_path: function (val) {
if (arguments.length) path = val
return path
}
})
})
it('should match the empty route', function () {
var m = r.match('')
expect(m).to.be.ok()
expect(m).to.eql({})
describe('#setRouteFromPath', function () {
it('should load up the index', function () {
path = ''
awe.setRouteFromPath()
expect(awe.state._route).to.equal('')
})
it('should load up a simple path', function () {
path = 'some'
awe.setRouteFromPath()
expect(awe.state._route).to.equal('some')
})
it('should load up the first part of a complex path', function () {
path = 'great/thing'
awe.setRouteFromPath()
expect(awe.state._route).to.equal('great')
})
})
it('should not match other things', function () {
var m = r.match('something')
expect(m).to.not.be.ok()
})
it('should not match other complex things', function () {
var m = r.match('something/else')
expect(m).to.not.be.ok()
})
})
describe('with two routes', function () {
var r
beforeEach(function () {
r = new Route('test', ['some/thing', 'other/:num'])
describe('#goTo', function () {
it('should set the path', function () {
path = ''
awe.goTo('parties')
expect(path).to.equal('parties')
})
})
it('should match the first', function () {
var m = r.match('some/thing')
expect(m).to.eql({})
})
it('should match the second', function () {
var m = r.match('other/23m')
expect(m).to.eql({num: '23m'})
})
it('should not match another', function () {
expect(r.match('other')).to.not.be.ok()
})
})
describe('with complex parsing', function () {
var r
describe('somewhat nested', function () {
var awe, path
beforeEach(function () {
r = new Route('test', {
match: 'one/:two/:three',
args: {
two: Number,
three: MonthParser
awe = new Awesome({
_baseroute: 'some/thing',
_path: function (val) {
if (arguments.length) path = val
return path
}
})
})
it('should parse', function () {
var m = r.match('one/34/jan')
expect(m).to.eql({
two: 34,
three: 0
describe('#setRouteFromPath', function () {
it('should load up to the index', function () {
path = 'some/thing'
awe.setRouteFromPath()
expect(awe.state._route).to.equal('')
})
})
it('should serialize', function () {
var frag = r.toFragment({
two: 36,
three: 1
it('should strip the trailing slash', function () {
path = 'some/thing/'
awe.setRouteFromPath()
expect(awe.state._route).to.equal('')
})
expect(frag).to.equal('one/36/feb')
})
it('should not parse something that does not match the type', function () {
expect(r.match('one/34/foo')).to.not.be.ok()
})
})
it('should load up a simple path', function () {
path = 'some/thing/else'
awe.setRouteFromPath()
expect(awe.state._route).to.equal('else')
})
describe('with defaults', function () {
var r
beforeEach(function () {
r = new Route('test', {
match: ['', 'one/:two/:three'],
args: {
two: {
default: 5,
type: Number
},
three: {
default: new Date(10000),
type: DateParser
}
}
it('should load up a complex path', function () {
path = 'some/thing/here/is/great'
awe.setRouteFromPath()
expect(awe.state._route).to.equal('here')
})
})
it('should fill in the default', function () {
expect(r.match('')).to.eql({two: 5, three: new Date(10000)})
})
it('should override the default', function () {
expect(r.match('one/12/10')).to.eql({two: 12, three: new Date(10)})
})
it('should serialize normally', function () {
expect(r.toFragment({two: 7, three: new Date(20)})).to.equal('one/7/20')
describe('#goTo', function () {
it('should set the index', function () {
path = 'some/thing/else'
awe.goTo('')
expect(path).to.equal('some/thing')
})
it('should set a path', function () {
path = 'some/thing/else'
awe.goTo('here')
expect(path).to.equal('some/thing/here')
})
it('should set a complex path', function () {
path = 'some/thing/else'
awe.goTo('here/is/great')
expect(path).to.equal('some/thing/here/is/great')
})
})
it('should serialize default', function () {
expect(r.toFragment({two: 5, three: new Date(10000)})).to.equal('')
})
})
// TODO: test outlet and things
// TODO: test global goTo, pass up higher paths
// TODO: test pathchange, ignore hashes not sharing a base path
// TODO: refuse bequest, refuse leave... should that be async?
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc