diff --git a/.babelrc b/.babelrc index 7a81beaf06..435f8aceb2 100644 --- a/.babelrc +++ b/.babelrc @@ -3,5 +3,8 @@ "loose": "all", "plugins": [ "dev-expression" + ], + "blacklist": [ + "es7.classProperties" ] } diff --git a/modules/IndexRedirect.js b/modules/IndexRedirect.js index 90992e6368..13af7cde96 100644 --- a/modules/IndexRedirect.js +++ b/modules/IndexRedirect.js @@ -11,26 +11,6 @@ const { string, object } = React.PropTypes */ class IndexRedirect extends Component { - static createRouteFromReactElement(element, parentRoute) { - /* istanbul ignore else: sanity check */ - if (parentRoute) { - parentRoute.indexRoute = Redirect.createRouteFromReactElement(element) - } else { - warning( - false, - 'An <IndexRedirect> does not make sense at the root of your route config' - ) - } - } - - static propTypes = { - to: string.isRequired, - query: object, - state: object, - onEnter: falsy, - children: falsy - } - /* istanbul ignore next: sanity check */ render() { invariant( @@ -41,4 +21,24 @@ class IndexRedirect extends Component { } +IndexRedirect.propTypes = { + to: string.isRequired, + query: object, + state: object, + onEnter: falsy, + children: falsy +} + +IndexRedirect.createRouteFromReactElement = function (element, parentRoute) { + /* istanbul ignore else: sanity check */ + if (parentRoute) { + parentRoute.indexRoute = Redirect.createRouteFromReactElement(element) + } else { + warning( + false, + 'An <IndexRedirect> does not make sense at the root of your route config' + ) + } +} + export default IndexRedirect diff --git a/modules/IndexRoute.js b/modules/IndexRoute.js index 206d29d5b6..58ed2941d7 100644 --- a/modules/IndexRoute.js +++ b/modules/IndexRoute.js @@ -12,26 +12,6 @@ const { func } = React.PropTypes */ class IndexRoute extends Component { - static createRouteFromReactElement(element, parentRoute) { - /* istanbul ignore else: sanity check */ - if (parentRoute) { - parentRoute.indexRoute = createRouteFromReactElement(element) - } else { - warning( - false, - 'An <IndexRoute> does not make sense at the root of your route config' - ) - } - } - - static propTypes = { - path: falsy, - component, - components, - getComponent: func, - getComponents: func - } - /* istanbul ignore next: sanity check */ render() { invariant( @@ -39,7 +19,27 @@ class IndexRoute extends Component { '<IndexRoute> elements are for router configuration only and should not be rendered' ) } + +} +IndexRoute.propTypes = { + path: falsy, + component, + components, + getComponent: func, + getComponents: func +} + +IndexRoute.createRouteFromReactElement = function (element, parentRoute) { + /* istanbul ignore else: sanity check */ + if (parentRoute) { + parentRoute.indexRoute = createRouteFromReactElement(element) + } else { + warning( + false, + 'An <IndexRoute> does not make sense at the root of your route config' + ) + } } export default IndexRoute diff --git a/modules/Link.js b/modules/Link.js index 6803f964ad..5ef142f3e8 100644 --- a/modules/Link.js +++ b/modules/Link.js @@ -38,26 +38,6 @@ function isEmptyObject(object) { */ class Link extends Component { - static contextTypes = { - history: object - } - - static propTypes = { - to: string.isRequired, - query: object, - hash: string, - state: object, - activeStyle: object, - activeClassName: string, - onlyActiveOnIndex: bool.isRequired, - onClick: func - } - - static defaultProps = { - onlyActiveOnIndex: false, - className: '', - style: {} - } handleClick(event) { let allowTransition = true @@ -122,4 +102,25 @@ class Link extends Component { } +Link.contextTypes = { + history: object +} + +Link.propTypes = { + to: string.isRequired, + query: object, + hash: string, + state: object, + activeStyle: object, + activeClassName: string, + onlyActiveOnIndex: bool.isRequired, + onClick: func +} + +Link.defaultProps = { + onlyActiveOnIndex: false, + className: '', + style: {} +} + export default Link diff --git a/modules/Redirect.js b/modules/Redirect.js index 3ec78d2986..6e8f7c21f2 100644 --- a/modules/Redirect.js +++ b/modules/Redirect.js @@ -15,70 +15,70 @@ const { string, object } = React.PropTypes */ class Redirect extends Component { - static createRouteFromReactElement(element) { - const route = createRouteFromReactElement(element) - - if (route.from) - route.path = route.from - - route.onEnter = function (nextState, replaceState) { - const { location, params } = nextState - - 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, - pathname, - route.query || location.query - ) - } - - return route + /* istanbul ignore next: sanity check */ + render() { + invariant( + false, + '<Redirect> elements are for router configuration only and should not be rendered' + ) } - static 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 +Redirect.createRouteFromReactElement = function (element) { + const route = createRouteFromReactElement(element) + + if (route.from) + route.path = route.from + + route.onEnter = function (nextState, replaceState) { + const { location, params } = nextState + + 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) } - return '/' + parentPattern + replaceState( + route.state || location.state, + pathname, + route.query || location.query + ) } - static propTypes = { - path: string, - from: string, // Alias for path - to: string.isRequired, - query: object, - state: object, - onEnter: falsy, - children: falsy - } + return route +} - /* istanbul ignore next: sanity check */ - render() { - invariant( - false, - '<Redirect> elements are for router configuration only and should not be rendered' - ) +Redirect.getRoutePattern = function (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 +} + +Redirect.propTypes = { + path: string, + from: string, // Alias for path + to: string.isRequired, + query: object, + state: object, + onEnter: falsy, + children: falsy } export default Redirect diff --git a/modules/Route.js b/modules/Route.js index 171611b2f8..7edc2907d2 100644 --- a/modules/Route.js +++ b/modules/Route.js @@ -17,16 +17,6 @@ const { string, func } = React.PropTypes */ class Route extends Component { - static createRouteFromReactElement = createRouteFromReactElement - - static propTypes = { - path: string, - component, - components, - getComponent: func, - getComponents: func - } - /* istanbul ignore next: sanity check */ render() { invariant( @@ -37,4 +27,14 @@ class Route extends Component { } +Route.createRouteFromReactElement = createRouteFromReactElement + +Route.propTypes = { + path: string, + component, + components, + getComponent: func, + getComponents: func +} + export default Route diff --git a/modules/Router.js b/modules/Router.js index df196c43c7..363beb68cb 100644 --- a/modules/Router.js +++ b/modules/Router.js @@ -15,22 +15,6 @@ const { func, object } = React.PropTypes */ class Router extends Component { - static propTypes = { - history: object, - children: routes, - routes, // alias for children - RoutingContext: func.isRequired, - createElement: func, - onError: func, - onUpdate: func, - parseQueryString: func, - stringifyQuery: func - } - - static defaultProps = { - RoutingContext - } - constructor(props, context) { super(props, context) @@ -107,4 +91,20 @@ class Router extends Component { } +Router.propTypes = { + history: object, + children: routes, + routes, // alias for children + RoutingContext: func.isRequired, + createElement: func, + onError: func, + onUpdate: func, + parseQueryString: func, + stringifyQuery: func +} + +Router.defaultProps = { + RoutingContext +} + export default Router diff --git a/modules/RoutingContext.js b/modules/RoutingContext.js index 0362c48183..b2b0d8154b 100644 --- a/modules/RoutingContext.js +++ b/modules/RoutingContext.js @@ -11,24 +11,6 @@ const { array, func, object } = React.PropTypes */ class RoutingContext extends Component { - static propTypes = { - history: object.isRequired, - createElement: func.isRequired, - location: object.isRequired, - routes: array.isRequired, - params: object.isRequired, - components: array.isRequired - } - - static defaultProps = { - createElement: React.createElement - } - - static childContextTypes = { - history: object.isRequired, - location: object.isRequired - } - getChildContext() { const { history, location } = this.props return { history, location } @@ -90,4 +72,22 @@ class RoutingContext extends Component { } +RoutingContext.propTypes = { + history: object.isRequired, + createElement: func.isRequired, + location: object.isRequired, + routes: array.isRequired, + params: object.isRequired, + components: array.isRequired +} + +RoutingContext.defaultProps = { + createElement: React.createElement +} + +RoutingContext.childContextTypes = { + history: object.isRequired, + location: object.isRequired +} + export default RoutingContext diff --git a/modules/__tests__/RouteComponent-test.js b/modules/__tests__/RouteComponent-test.js index 6b217e492d..490ca13b0f 100644 --- a/modules/__tests__/RouteComponent-test.js +++ b/modules/__tests__/RouteComponent-test.js @@ -44,10 +44,7 @@ describe('a Route Component', function () { it('receives the right context', function (done) { class RouteComponent extends Component { - static contextTypes = { - history: object.isRequired, - location: object.isRequired - } + componentDidMount() { expect(this.context.history).toEqual(this.props.history) expect(this.context.location).toEqual(this.props.location) @@ -56,6 +53,11 @@ describe('a Route Component', function () { return null } } + + RouteComponent.contextTypes = { + history: object.isRequired, + location: object.isRequired + } const route = { path: '/', component: RouteComponent } diff --git a/modules/__tests__/Router-test.js b/modules/__tests__/Router-test.js index 58c74113bd..42a4eb075d 100644 --- a/modules/__tests__/Router-test.js +++ b/modules/__tests__/Router-test.js @@ -255,11 +255,11 @@ describe('Router', function () { const Child = () => <span>child</span> class LabelWrapper extends Component { - static defaultProps = { - createElement: React.createElement + constructor() { + this.createElement = this.createElement.bind(this) } - createElement = (component, props) => { + createElement(component, props) { const { label, createElement } = this.props return ( @@ -283,6 +283,10 @@ describe('Router', function () { } } + LabelWrapper.defaultProps = { + createElement: React.createElement + } + const CustomRoutingContext = props => ( <LabelWrapper label="m1"> <LabelWrapper label="m2">