UNPKG

react-router-4-compat

Version:

A wrapped version of react router 4 which compatible with react router 3

501 lines (439 loc) 17.2 kB
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _next(value) { step("next", value); } function _throw(err) { step("throw", err); } _next(); }); }; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _inheritsLoose(subClass, superClass) { subClass.prototype.__proto__ = superClass && superClass.prototype; subClass.__proto__ = superClass; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import React from 'react'; import PropTypes from 'prop-types'; import Switch from 'react-router/Switch'; import Route from 'react-router/Route'; import matchPath from 'react-router/matchPath'; import { AsyncComponent } from 'react-async-wrapper'; import { mapValues, assignWith, some } from './utils'; import withRouter4Compat from './withRouter'; var createState = function createState(match, location, history) { return _objectSpread({ match: match, location: location, history: history }, location); }; var createPromiseFromCallback = function createPromiseFromCallback(state, callbackFunc) { return new Promise(function (resolve, reject) { callbackFunc(state, function (err, result) { if (err) { reject(err); } else { resolve(result); } }); }); }; var createRoutePropertyPromise = function createRoutePropertyPromise(state, staticValue, dynamicValue) { if (staticValue) { return staticValue; } if (dynamicValue) { return createPromiseFromCallback(state, dynamicValue); } return null; }; var createRoutePromise = function createRoutePromise(state, route) { var component = route.component, getComponent = route.getComponent, indexRoute = route.indexRoute, getIndexRoute = route.getIndexRoute, childRoutes = route.childRoutes, getChildRoutes = route.getChildRoutes; return Promise.all([createRoutePropertyPromise(state, component, getComponent), createRoutePropertyPromise(state, indexRoute, getIndexRoute), createRoutePropertyPromise(state, childRoutes, getChildRoutes)]).then(function (_ref) { var comp = _ref[0], ir = _ref[1], cr = _ref[2]; return _objectSpread({}, route, { component: comp, indexRoute: ir, childRoutes: cr }); }); }; export var createRoutes = function createRoutes(routes, onError, routeStack) { if (routeStack === void 0) { routeStack = []; } return routes.map(function (_route) { var path = _route.path, component = _route.component, getComponent = _route.getComponent, indexRoute = _route.indexRoute, getIndexRoute = _route.getIndexRoute, childRoutes = _route.childRoutes, getChildRoutes = _route.getChildRoutes, onEnter = _route.onEnter, exact = _route.exact; if (!component && !getComponent && !onEnter) { return null; } return React.createElement(Route, { key: path || 0, path: path, exact: !!exact // eslint-disable-next-line react/no-children-prop , children: function children(props) { var match = props.match, location = props.location, history = props.history; var routeState = createState(match, location, history); if (component && (indexRoute || !getIndexRoute) && (childRoutes || !getChildRoutes) && !onEnter) { return React.createElement(Route4Compat, _extends({}, props, { state: routeState, route: _route, routeStack: routeStack, onError: onError })); } var asyncJobs = []; if (onEnter) { asyncJobs.push(function () { return new Promise(function (resolve, reject) { if (onEnter.length >= 3) { onEnter(routeState, history.replace, function (err) { if (err) { reject(err); } else { resolve(); } }); } else { onEnter(routeState, history.replace); resolve(); } }); }); } return React.createElement(AsyncComponent, { batch: true, onError: onError, asyncJobs: asyncJobs, asyncProps: { route: function route() { return createRoutePromise(routeState, _route); } }, loadingComponent: function loadingComponent() { return null; }, reloadOnUpdate: false }, React.createElement(Route4Compat, _extends({}, props, { routeStack: routeStack, state: routeState, onError: onError }))); } }); }).filter(function (v) { return v; }); }; export var makePath = function makePath(base, path) { if (!path) { return base || '/'; } if (path.startsWith('/')) { return path; } return (base === '/' ? '' : base) + "/" + path; }; var shallowEqual = function shallowEqual(obj1, obj2) { if (obj1 === obj2) { return true; } if (!obj1 || !obj2) { return false; } var keys1 = Object.keys(obj1); var keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) { return false; } for (var i = 0; i < keys1.length; ++i) { var key = keys1[i]; if (obj1[key] !== obj2[key]) { return false; } } return true; }; var Route4Compat = /*#__PURE__*/ function (_React$Component) { function Route4Compat() { return _React$Component.apply(this, arguments) || this; } var _proto = Route4Compat.prototype; _proto.componentWillMount = function componentWillMount() { this.context.routesCompat = this.props.routeStack.concat([this.props.route]); this.context.routesUpdater(this.context.routesCompat); }; _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps, ignored) { var _this$props = this.props, route = _this$props.route, state = _this$props.state, history = _this$props.history, onError = _this$props.onError; var onChange = route.onChange; if (onChange) { if (onChange.length >= 4) { new Promise(function (resolve, reject) { onChange(state, nextProps.state, history.replace, function (err) { if (err) { reject(err); } else { resolve(); } }); }).catch(onError); } else { try { onChange(state, nextProps.state, history.replace); } catch (e) { onError(e); } } } }; _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState, nextContext) { // noinspection JSUnusedLocalSymbols var nextMatch = nextProps.match, nextParams = nextProps.params, nState = nextProps.state, nextRoute = nextProps.route, nextRouteStack = nextProps.routeStack, nextRest = _objectWithoutProperties(nextProps, ["match", "params", "state", "route", "routeStack"]); // noinspection JSUnusedLocalSymbols var _this$props2 = this.props, thisMatch = _this$props2.match, thisParams = _this$props2.params, tState = _this$props2.state, thisRoute = _this$props2.route, thisRouteStack = _this$props2.routeStack, thisRest = _objectWithoutProperties(_this$props2, ["match", "params", "state", "route", "routeStack"]); var _ref2 = nextMatch || {}, nextMatchParams = _ref2.params, nextMatchRest = _objectWithoutProperties(_ref2, ["params"]); var _ref3 = thisMatch || {}, thisMatchParams = _ref3.params, thisMatchRest = _objectWithoutProperties(_ref3, ["params"]); return !shallowEqual(this.state, nextState) || !shallowEqual(this.context, nextContext) || !shallowEqual(thisMatchParams, nextMatchParams) || !shallowEqual(thisMatchRest, nextMatchRest) || !shallowEqual(thisRoute, nextRoute) || !shallowEqual(thisRouteStack, nextRouteStack) || !shallowEqual(thisRest, nextRest); }; _proto.componentWillUnmount = function componentWillUnmount() { var _this$props3 = this.props, route = _this$props3.route, state = _this$props3.state, onError = _this$props3.onError; var onLeave = route.onLeave; if (onLeave) { try { onLeave(state); } catch (e) { onError(e); } } }; _proto.render = function render() { var _this$props4 = this.props, _route2 = _this$props4.route, routeStack = _this$props4.routeStack, state = _this$props4.state, onError = _this$props4.onError, rest = _objectWithoutProperties(_this$props4, ["route", "routeStack", "state", "onError"]); var path = _route2.path, Comp = _route2.component, indexRoute = _route2.indexRoute; if (!Comp) { return null; } var childRoutes = _route2.childRoutes; if (some(childRoutes, function (childRoute) { return !childRoute.components && childRoute.getComponents; })) { // noinspection RequiredAttributes return React.createElement(AsyncComponent, { batch: true, onError: onError, loadingComponent: function loadingComponent() { return null; }, asyncProps: { route: function () { var _route3 = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee() { return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: return _context.abrupt("return", Promise.all((childRoutes || []).map(function (childRoute) { if (childRoute.components || !childRoute.getComponents) { return { childRoute: childRoute }; } else { return new Promise(function (resolve, reject) { return childRoute.getComponents(state, function (err, res) { if (err) { reject(err); } else { resolve({ childRoute: childRoute, components: res }); } }); }); } })).then(function (subComponents) { return _objectSpread({}, _route2, { childRoutes: subComponents.map(function (_ref4) { var childRoute = _ref4.childRoute, components = _ref4.components; return _objectSpread({}, childRoute, { components: components }); }) }); })); case 1: case "end": return _context.stop(); } } }, _callee, this); })); return function route() { return _route3.apply(this, arguments); }; }() }, reloadOnUpdate: false }, React.createElement(Route4Compat, _extends({ routeStack: routeStack, state: state, onError: onError }, rest))); } var components = {}; if (childRoutes) { childRoutes = childRoutes.map(function (childRoute) { var childPath = childRoute.path; if (!childPath.startsWith('/')) { return _objectSpread({}, childRoute, { path: makePath(path, childPath) }); } return childRoute; }); var _loop = function _loop(i) { var childRoute = childRoutes[i]; var childComponents = childRoute.components; if (childComponents) { assignWith(components, childComponents, function (objValue, srcValue) { if (!objValue) { return [{ path: childRoute.path, component: srcValue }]; } else { objValue.push({ path: childRoute.path, component: srcValue }); return objValue; } }); } }; for (var i = 0; i < childRoutes.length; ++i) { _loop(i); } } var routes; var routesCompat = this.context.routesCompat; if (indexRoute) { routes = [_objectSpread({}, indexRoute, { path: makePath(path, indexRoute.path), exact: true })].concat(childRoutes || []); } else { routes = (childRoutes || []).concat(); } var comps = mapValues(components, function (compRoutes) { return function (props) { if (compRoutes.length === 1) { return React.createElement(Route, _extends({}, props, { path: compRoutes[0].path, component: withRouter4Compat(compRoutes[0].component) })); } else { return React.createElement(Switch, null, compRoutes.map(function (compRoute) { return React.createElement(Route, _extends({}, props, { path: compRoute.path, component: withRouter4Compat(compRoute.component) })); })); } }; }); var validRoutes = routes.filter(function (r) { return !!matchPath(state.location.pathname, r, state.match); }); return validRoutes.length > 0 ? React.createElement(Comp, _extends({}, rest, { router: state.history, params: state.match.params, location: state.location, routes: routesCompat }, comps), createRoutes([validRoutes[0]], onError, routeStack.concat([_route2]))) : React.createElement(Comp, _extends({}, rest, { router: state.history, params: state.match.params, location: state.location, routes: routesCompat }, comps)); }; _inheritsLoose(Route4Compat, _React$Component); return Route4Compat; }(React.Component); Route4Compat.contextTypes = { router: PropTypes.object }; export var RoutePropType = PropTypes.shape({ path: PropTypes.string, component: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), getComponent: PropTypes.func, indexRoute: PropTypes.object, getIndexRoute: PropTypes.func, childRoutes: PropTypes.arrayOf(PropTypes.object), getChildRoutes: PropTypes.func, onLeave: PropTypes.func, onChange: PropTypes.func, exact: PropTypes.bool, strict: PropTypes.bool, sensitive: PropTypes.bool }); Route4Compat.propTypes = { route: RoutePropType, routeStack: PropTypes.arrayOf(RoutePropType), onError: PropTypes.func, state: PropTypes.object }; Route4Compat.defaultProps = { route: {}, routeStack: [], onError: function onError() { return null; }, state: {} }; Route4Compat.contextTypes = { routesCompat: PropTypes.arrayOf(RoutePropType), routesUpdater: PropTypes.func }; export default Route4Compat;