UNPKG

react-crossroads

Version:

Client side router for web applications built with React and utilizing the Flux architecture. The backing routing engine is CrossroadsJs.

152 lines (132 loc) 5.05 kB
var React, Redirect, RouteDefinition, Routes, TYPE, factory, merge, _, _childrenValid, _hasDefault, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __slice = [].slice; React = require('react'); RouteDefinition = require('./RouteDefinition'); Redirect = require('./Redirect'); merge = require('react/lib/merge'); _ = require('lodash'); TYPE = 'Routes'; _childrenValid = (function() { var VALID_TYPES, validate; VALID_TYPES = ['Route', 'Routes', 'DefaultRoute', 'NotFoundRoute', 'Redirect']; validate = function(props, propName, componentName) { var child, defaultCount, err, validChild, _i, _len, _ref; validChild = function(child) { var _ref; if (_ref = child.type, __indexOf.call(VALID_TYPES, _ref) < 0) { return new Error("All children must be a proper type [Proper types: " + (JSON.stringify(VALID_TYPES)) + "]"); } }; if (_.isArray(props[propName])) { if (props[propName].length === 0) { return new Error('Must provide at least one child'); } defaultCount = 0; _ref = props[propName]; for (_i = 0, _len = _ref.length; _i < _len; _i++) { child = _ref[_i]; if (child == null) { return new Error('All child elements must be defined'); } if (child.type === 'DefaultRoute') { defaultCount += 1; } err = validChild(child); if (err != null) { return err; } } if (defaultCount > 1) { return new Error('Only one <DefaultRoute /> is allowed per <Routes /> container'); } } else { err = validChild(props[propName]); if (err != null) { return err; } } }; return RouteDefinition.PropTypes.createChainableTypeChecker(validate); })(); _hasDefault = function(children) { return _.any(children, function(child) { return child.type === 'DefaultRoute'; }); }; Routes = (function(_super) { __extends(Routes, _super); Routes.prototype.type = TYPE; function Routes(props, children) { var defaultProps; this.children = children; defaultProps = { handlerProps: {}, exclude: false, children: this.children }; this.props = merge(defaultProps, props); this._hasDefault = _hasDefault(this.children); this._hasPath = (this.props.path != null) || (this.props.name != null); Routes.__super__.constructor.call(this); } Routes.prototype.propTypes = { handler: RouteDefinition.PropTypes.componentClass, path: React.PropTypes.string, name: React.PropTypes.string, handlerProps: React.PropTypes.object.isRequired, children: _childrenValid.isRequired, exclude: React.PropTypes.bool }; Routes.prototype.register = function(parents, routePrefix, routeStore) { var child, shouldRegister, _i, _len, _ref; this.path = this.buildPath(this.props, routePrefix); this.chain = __slice.call(parents).concat([this]); _ref = this.children; for (_i = 0, _len = _ref.length; _i < _len; _i++) { child = _ref[_i]; child.register(this.chain, this.path, routeStore); if (child.type === 'DefaultRoute') { this.defaultRoute = child; } } shouldRegister = !this._hasDefault; shouldRegister = shouldRegister && this._hasPath; shouldRegister = shouldRegister && (this.props.handler != null); shouldRegister = shouldRegister && !this.props.exclude; if (shouldRegister) { return routeStore.register(this); } else if (this._hasDefault && !routeStore.hasRoute(this.name)) { if (this.defaultRoute.path !== this.path) { this.redirect = new Redirect({ fromPath: this.path, to: this.defaultRoute.name }); this.redirect.name = this.name; this.redirect.register(parents, routePrefix, routeStore); return this.route = this.redirect.route; } else { return routeStore.registerAlias(this, this.defaultRoute); } } }; Routes.prototype.makePath = function(params) { if (this.route != null) { return this.route.interpolate(params); } else if (this.defaultRoute != null) { return this.defaultRoute.makePath(params); } else { throw new Error('This routes container was not registered, therefore there is no path to be made from it'); } }; return Routes; })(RouteDefinition); factory = function() { var children, props; props = arguments[0], children = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return new Routes(props, _.flatten(children)); }; factory.type = 'Routes'; module.exports = factory;