@react-navigation/core
Advanced tools
Comparing version 0.0.0-alpha.8 to 0.0.0-alpha.9
@@ -17,2 +17,6 @@ 'use strict'; | ||
var _getNavigationActionCreators = require('./getNavigationActionCreators'); | ||
var _getNavigationActionCreators2 = _interopRequireDefault(_getNavigationActionCreators); | ||
var _invariant = require('./invariant'); | ||
@@ -56,3 +60,4 @@ | ||
var actionCreators = _extends({}, navigation.actions, navigation.router.getActionCreators(childRoute, navigation.state.key), childRouter ? childRouter.getActionCreators(focusedGrandChildRoute, childRoute.key) : {}); | ||
var actionCreators = _extends({}, navigation.actions, navigation.router.getActionCreators(childRoute, navigation.state.key), childRouter ? childRouter.getActionCreators(focusedGrandChildRoute, childRoute.key) : {}, (0, _getNavigationActionCreators2.default)(childRoute)); | ||
var actionHelpers = {}; | ||
@@ -59,0 +64,0 @@ Object.keys(actionCreators).forEach(function (actionName) { |
@@ -7,4 +7,2 @@ 'use strict'; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
@@ -14,6 +12,2 @@ | ||
var _pathToRegexp = require('path-to-regexp'); | ||
var _pathToRegexp2 = _interopRequireDefault(_pathToRegexp); | ||
var _NavigationActions = require('./NavigationActions'); | ||
@@ -49,6 +43,4 @@ | ||
var _getNavigationActionCreators = require('./getNavigationActionCreators'); | ||
var _pathUtils = require('./pathUtils'); | ||
var _getNavigationActionCreators2 = _interopRequireDefault(_getNavigationActionCreators); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -58,10 +50,2 @@ | ||
function isEmpty(obj) { | ||
if (!obj) return true; | ||
for (var key in obj) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
function behavesLikePushAction(action) { | ||
@@ -107,4 +91,2 @@ return action.type === _NavigationActions2.default.NAVIGATE || action.type === _StackActions2.default.PUSH; | ||
var initialChildRouter = childRouters[initialRouteName]; | ||
var pathsByRouteNames = _extends({}, stackConfig.paths) || {}; | ||
var paths = []; | ||
@@ -157,39 +139,6 @@ function getInitialState(action) { | ||
// Build paths for each route | ||
routeNames.forEach(function (routeName) { | ||
var pathPattern = pathsByRouteNames[routeName] || routeConfigs[routeName].path; | ||
var matchExact = !!pathPattern && !childRouters[routeName]; | ||
if (pathPattern === undefined) { | ||
pathPattern = routeName; | ||
} | ||
var keys = []; | ||
var re = void 0, | ||
toPath = void 0, | ||
priority = void 0; | ||
if (typeof pathPattern === 'string') { | ||
// pathPattern may be either a string or a regexp object according to path-to-regexp docs. | ||
re = (0, _pathToRegexp2.default)(pathPattern, keys); | ||
toPath = _pathToRegexp2.default.compile(pathPattern); | ||
priority = 0; | ||
} else { | ||
// for wildcard match | ||
re = (0, _pathToRegexp2.default)('*', keys); | ||
toPath = function toPath() { | ||
return ''; | ||
}; | ||
matchExact = true; | ||
priority = -1; | ||
} | ||
if (!matchExact) { | ||
var wildcardRe = (0, _pathToRegexp2.default)(pathPattern + '/*', keys); | ||
re = new RegExp('(?:' + re.source + ')|(?:' + wildcardRe.source + ')'); | ||
} | ||
pathsByRouteNames[routeName] = { re: re, keys: keys, toPath: toPath, priority: priority }; | ||
}); | ||
var _createPathParser = (0, _pathUtils.createPathParser)(childRouters, routeConfigs, stackConfig.paths, initialRouteName, initialRouteParams), | ||
getPathAndParamsForRoute = _createPathParser.getPathAndParamsForRoute, | ||
_getActionForPathAndParams = _createPathParser.getActionForPathAndParams; | ||
paths = Object.entries(pathsByRouteNames); | ||
paths.sort(function (a, b) { | ||
return b[1].priority - a[1].priority; | ||
}); | ||
return { | ||
@@ -211,3 +160,3 @@ childRouters: childRouters, | ||
getActionCreators: function getActionCreators(route, navStateKey) { | ||
return _extends({}, (0, _getNavigationActionCreators2.default)(route), getCustomActionCreators(route, navStateKey), { | ||
return _extends({}, getCustomActionCreators(route, navStateKey), { | ||
pop: function pop(n, params) { | ||
@@ -411,3 +360,5 @@ return _StackActions2.default.pop(_extends({ | ||
}); | ||
return _StateUtils2.default.push(state, _route3); | ||
return _extends({}, _StateUtils2.default.push(state, _route3), { | ||
isTransitioning: action.immediate !== true | ||
}); | ||
} | ||
@@ -548,148 +499,6 @@ } | ||
var route = state.routes[state.index]; | ||
var routeName = route.routeName; | ||
var screen = (0, _getScreenForRouteName2.default)(routeConfigs, routeName); | ||
var subPath = pathsByRouteNames[routeName].toPath(route.params); | ||
var path = subPath; | ||
var params = route.params; | ||
if (screen && screen.router) { | ||
var stateRoute = route; | ||
// If it has a router it's a navigator. | ||
// If it doesn't have router it's an ordinary React component. | ||
var child = screen.router.getPathAndParamsForState(stateRoute); | ||
path = subPath ? subPath + '/' + child.path : child.path; | ||
params = child.params ? _extends({}, params, child.params) : params; | ||
} | ||
return { | ||
path: path, | ||
params: params | ||
}; | ||
return getPathAndParamsForRoute(route); | ||
}, | ||
getActionForPathAndParams: function getActionForPathAndParams(pathToResolve, inputParams) { | ||
// If the path is empty (null or empty string) | ||
// just return the initial route action | ||
if (!pathToResolve) { | ||
return _NavigationActions2.default.navigate({ | ||
routeName: initialRouteName, | ||
params: inputParams | ||
}); | ||
} | ||
var _pathToResolve$split = pathToResolve.split('?'), | ||
_pathToResolve$split2 = _slicedToArray(_pathToResolve$split, 2), | ||
pathNameToResolve = _pathToResolve$split2[0], | ||
queryString = _pathToResolve$split2[1]; | ||
// Attempt to match `pathNameToResolve` with a route in this router's | ||
// routeConfigs | ||
var matchedRouteName = void 0; | ||
var pathMatch = void 0; | ||
var pathMatchKeys = void 0; | ||
// eslint-disable-next-line no-restricted-syntax | ||
var _iteratorNormalCompletion2 = true; | ||
var _didIteratorError2 = false; | ||
var _iteratorError2 = undefined; | ||
try { | ||
for (var _iterator2 = paths[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var _ref = _step2.value; | ||
var _ref2 = _slicedToArray(_ref, 2); | ||
var routeName = _ref2[0]; | ||
var path = _ref2[1]; | ||
var re = path.re, | ||
keys = path.keys; | ||
pathMatch = re.exec(pathNameToResolve); | ||
if (pathMatch && pathMatch.length) { | ||
pathMatchKeys = keys; | ||
matchedRouteName = routeName; | ||
break; | ||
} | ||
} | ||
// We didn't match -- return null | ||
} catch (err) { | ||
_didIteratorError2 = true; | ||
_iteratorError2 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return) { | ||
_iterator2.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError2) { | ||
throw _iteratorError2; | ||
} | ||
} | ||
} | ||
if (!matchedRouteName) { | ||
// If the path is empty (null or empty string) | ||
// just return the initial route action | ||
if (!pathToResolve) { | ||
return _NavigationActions2.default.navigate({ | ||
routeName: initialRouteName | ||
}); | ||
} | ||
return null; | ||
} | ||
// Determine nested actions: | ||
// If our matched route for this router is a child router, | ||
// get the action for the path AFTER the matched path for this | ||
// router | ||
var nestedAction = void 0; | ||
var nestedQueryString = queryString ? '?' + queryString : ''; | ||
if (childRouters[matchedRouteName]) { | ||
nestedAction = childRouters[matchedRouteName].getActionForPathAndParams(pathMatch.slice(pathMatchKeys.length).join('/') + nestedQueryString); | ||
if (!nestedAction) { | ||
return null; | ||
} | ||
} | ||
// reduce the items of the query string. any query params may | ||
// be overridden by path params | ||
var queryParams = !isEmpty(inputParams) ? inputParams : (queryString || '').split('&').reduce(function (result, item) { | ||
if (item !== '') { | ||
var nextResult = result || {}; | ||
var _item$split = item.split('='), | ||
_item$split2 = _slicedToArray(_item$split, 2), | ||
key = _item$split2[0], | ||
value = _item$split2[1]; | ||
nextResult[key] = value; | ||
return nextResult; | ||
} | ||
return result; | ||
}, null); | ||
// reduce the matched pieces of the path into the params | ||
// of the route. `params` is null if there are no params. | ||
var params = pathMatch.slice(1).reduce(function (result, matchResult, i) { | ||
var key = pathMatchKeys[i]; | ||
if (key.asterisk || !key) { | ||
return result; | ||
} | ||
var nextResult = result || inputParams || {}; | ||
var paramName = key.name; | ||
var decodedMatchResult = void 0; | ||
try { | ||
decodedMatchResult = decodeURIComponent(matchResult); | ||
} catch (e) { | ||
// ignore `URIError: malformed URI` | ||
} | ||
nextResult[paramName] = decodedMatchResult || matchResult; | ||
return nextResult; | ||
}, queryParams); | ||
return _NavigationActions2.default.navigate(_extends({ | ||
routeName: matchedRouteName | ||
}, params ? { params: params } : {}, nestedAction ? { action: nestedAction } : {})); | ||
getActionForPathAndParams: function getActionForPathAndParams(path, params) { | ||
return _getActionForPathAndParams(path, params); | ||
}, | ||
@@ -696,0 +505,0 @@ |
@@ -33,6 +33,4 @@ 'use strict'; | ||
var _getNavigationActionCreators = require('./getNavigationActionCreators'); | ||
var _pathUtils = require('./pathUtils'); | ||
var _getNavigationActionCreators2 = _interopRequireDefault(_getNavigationActionCreators); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -59,3 +57,3 @@ | ||
var order = config.order || Object.keys(routeConfigs); | ||
var paths = config.paths || {}; | ||
var getCustomActionCreators = config.getCustomActionCreators || defaultActionCreators; | ||
@@ -72,5 +70,2 @@ | ||
var routeConfig = routeConfigs[routeName]; | ||
if (!paths[routeName]) { | ||
paths[routeName] = typeof routeConfig.path === 'string' ? routeConfig.path : routeName; | ||
} | ||
childRouters[routeName] = null; | ||
@@ -82,2 +77,7 @@ var screen = (0, _getScreenForRouteName2.default)(routeConfigs, routeName); | ||
}); | ||
var _createPathParser = (0, _pathUtils.createPathParser)(childRouters, routeConfigs, config.paths, initialRouteName, initialRouteParams), | ||
getPathAndParamsForRoute = _createPathParser.getPathAndParamsForRoute, | ||
_getActionForPathAndParams = _createPathParser.getActionForPathAndParams; | ||
if (initialRouteIndex === -1) { | ||
@@ -107,39 +107,41 @@ throw new Error('Invalid initialRouteName \'' + initialRouteName + '\'.' + ('Should be one of ' + order.map(function (n) { | ||
return { | ||
childRouters: childRouters, | ||
function getNextState(prevState, possibleNextState) { | ||
if (!prevState) { | ||
return possibleNextState; | ||
} | ||
getInitialState: function getInitialState() { | ||
var routes = order.map(resetChildRoute); | ||
return { | ||
routes: routes, | ||
index: initialRouteIndex, | ||
isTransitioning: false | ||
}; | ||
}, | ||
getNextState: function getNextState(prevState, possibleNextState) { | ||
if (!prevState) { | ||
return possibleNextState; | ||
} | ||
var nextState = void 0; | ||
if (prevState.index !== possibleNextState.index && resetOnBlur) { | ||
var prevRouteName = prevState.routes[prevState.index].routeName; | ||
var nextRoutes = [].concat(_toConsumableArray(possibleNextState.routes)); | ||
nextRoutes[prevState.index] = resetChildRoute(prevRouteName); | ||
var nextState = void 0; | ||
if (prevState.index !== possibleNextState.index && resetOnBlur) { | ||
var prevRouteName = prevState.routes[prevState.index].routeName; | ||
var nextRoutes = [].concat(_toConsumableArray(possibleNextState.routes)); | ||
nextRoutes[prevState.index] = resetChildRoute(prevRouteName); | ||
return _extends({}, possibleNextState, { | ||
routes: nextRoutes | ||
}); | ||
} else { | ||
nextState = possibleNextState; | ||
} | ||
return _extends({}, possibleNextState, { | ||
routes: nextRoutes | ||
}); | ||
} else { | ||
nextState = possibleNextState; | ||
} | ||
return nextState; | ||
} | ||
return nextState; | ||
}, | ||
function getInitialState() { | ||
var routes = order.map(resetChildRoute); | ||
return { | ||
routes: routes, | ||
index: initialRouteIndex, | ||
isTransitioning: false | ||
}; | ||
} | ||
return { | ||
childRouters: childRouters, | ||
getActionCreators: function getActionCreators(route, stateKey) { | ||
return _extends({}, (0, _getNavigationActionCreators2.default)(route), getCustomActionCreators(route, stateKey)); | ||
return getCustomActionCreators(route, stateKey); | ||
}, | ||
getStateForAction: function getStateForAction(action, inputState) { | ||
var prevState = inputState ? _extends({}, inputState) : inputState; | ||
var state = inputState || this.getInitialState(); | ||
var state = inputState || getInitialState(); | ||
var activeChildIndex = state.index; | ||
@@ -174,3 +176,3 @@ | ||
_routes[state.index] = activeChildState; | ||
return this.getNextState(prevState, _extends({}, state, { | ||
return getNextState(prevState, _extends({}, state, { | ||
routes: _routes | ||
@@ -217,3 +219,3 @@ })); | ||
_routes2[activeChildIndex] = newChildState; | ||
return this.getNextState(prevState, _extends({}, state, { | ||
return getNextState(prevState, _extends({}, state, { | ||
routes: _routes2, | ||
@@ -239,3 +241,3 @@ index: activeChildIndex | ||
}); | ||
return this.getNextState(prevState, _extends({}, state, { | ||
return getNextState(prevState, _extends({}, state, { | ||
routes: _routes3 | ||
@@ -247,3 +249,3 @@ })); | ||
if (activeChildIndex !== state.index) { | ||
return this.getNextState(prevState, _extends({}, state, { | ||
return getNextState(prevState, _extends({}, state, { | ||
index: activeChildIndex | ||
@@ -291,3 +293,3 @@ })); | ||
if (index !== state.index || routes !== state.routes) { | ||
return this.getNextState(prevState, _extends({}, state, { | ||
return getNextState(prevState, _extends({}, state, { | ||
index: index, | ||
@@ -313,61 +315,6 @@ routes: routes | ||
var route = state.routes[state.index]; | ||
var routeName = order[state.index]; | ||
var subPath = paths[routeName]; | ||
var screen = (0, _getScreenForRouteName2.default)(routeConfigs, routeName); | ||
var path = subPath; | ||
var params = route.params; | ||
if (screen && screen.router) { | ||
var stateRoute = route; | ||
// If it has a router it's a navigator. | ||
// If it doesn't have router it's an ordinary React component. | ||
var child = screen.router.getPathAndParamsForState(stateRoute); | ||
path = subPath ? subPath + '/' + child.path : child.path; | ||
params = child.params ? _extends({}, params, child.params) : params; | ||
} | ||
return { | ||
path: path, | ||
params: params | ||
}; | ||
return getPathAndParamsForRoute(route); | ||
}, | ||
/** | ||
* Gets an optional action, based on a relative path and query params. | ||
* | ||
* This will return null if there is no action matched | ||
*/ | ||
getActionForPathAndParams: function getActionForPathAndParams(path, params) { | ||
if (!path) { | ||
return _NavigationActions2.default.navigate({ | ||
routeName: initialRouteName, | ||
params: params | ||
}); | ||
} | ||
return order.map(function (childId) { | ||
var parts = path.split('/'); | ||
var pathToTest = paths[childId]; | ||
var partsInTestPath = pathToTest.split('/').length; | ||
var pathPartsToTest = parts.slice(0, partsInTestPath).join('/'); | ||
if (pathPartsToTest === pathToTest) { | ||
var childRouter = childRouters[childId]; | ||
var action = _NavigationActions2.default.navigate({ | ||
routeName: childId | ||
}); | ||
if (childRouter && childRouter.getActionForPathAndParams) { | ||
action.action = childRouter.getActionForPathAndParams(parts.slice(partsInTestPath).join('/'), params); | ||
} | ||
if (params) { | ||
action.params = params; | ||
} | ||
return action; | ||
} | ||
return null; | ||
}).find(function (action) { | ||
return !!action; | ||
}) || order.map(function (childId) { | ||
var childRouter = childRouters[childId]; | ||
return childRouter && childRouter.getActionForPathAndParams(path, params); | ||
}).find(function (action) { | ||
return !!action; | ||
}) || null; | ||
return _getActionForPathAndParams(path, params); | ||
}, | ||
@@ -374,0 +321,0 @@ |
@@ -26,3 +26,3 @@ 'use strict'; | ||
if (!screenComponent || typeof screenComponent !== 'function' && typeof screenComponent !== 'string' && !routeConfig.getScreen) { | ||
throw new Error('The component for route \'' + routeName + '\' must be a\nReact component. For example:\n\nimport MyScreen from \'./MyScreen\';\n...\n' + routeName + ': MyScreen,\n\nYou can also use a navigator:\n\nimport MyNavigator from \'./MyNavigator\';\n...\n' + routeName + ': MyNavigator,\n\n'); | ||
throw new Error('The component for route \'' + routeName + '\' must be a React component. For example:\n\nimport MyScreen from \'./MyScreen\';\n...\n' + routeName + ': MyScreen,\n}\n\nYou can also use a navigator:\n\nimport MyNavigator from \'./MyNavigator\';\n...\n' + routeName + ': MyNavigator,\n}'); | ||
} | ||
@@ -29,0 +29,0 @@ |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -8,3 +8,3 @@ Object.defineProperty(exports, "__esModule", { | ||
exports.default = function (obj, key, defaultValue) { | ||
if (obj.hasOwnProperty(key)) { | ||
if (obj.hasOwnProperty(key) && typeof obj[key] !== 'undefined') { | ||
return obj; | ||
@@ -11,0 +11,0 @@ } |
@@ -6,6 +6,7 @@ { | ||
"react-lifecycles-compat": "^3.0.2", | ||
"query-string": "^6.1.0", | ||
"prop-types": "^15.6.1", | ||
"hoist-non-react-statics": "^2.5.0" | ||
}, | ||
"version": "0.0.0-alpha.8", | ||
"version": "0.0.0-alpha.9", | ||
"main": "lib/index", | ||
@@ -12,0 +13,0 @@ "react-native": "src/index", |
import getChildEventSubscriber from './getChildEventSubscriber'; | ||
import getChildRouter from './getChildRouter'; | ||
import getNavigationActionCreators from './getNavigationActionCreators'; | ||
import invariant from './invariant'; | ||
@@ -36,4 +37,6 @@ | ||
...navigation.router.getActionCreators(childRoute, navigation.state.key), | ||
...(childRouter ? childRouter.getActionCreators(focusedGrandChildRoute, childRoute.key) : {}) | ||
...(childRouter ? childRouter.getActionCreators(focusedGrandChildRoute, childRoute.key) : {}), | ||
...getNavigationActionCreators(childRoute) | ||
}; | ||
const actionHelpers = {}; | ||
@@ -40,0 +43,0 @@ Object.keys(actionCreators).forEach(actionName => { |
@@ -1,3 +0,1 @@ | ||
import pathToRegexp from 'path-to-regexp'; | ||
import NavigationActions from './NavigationActions'; | ||
@@ -11,12 +9,4 @@ import StackActions from './StackActions'; | ||
import { generateKey } from './KeyGenerator'; | ||
import getNavigationActionCreators from './getNavigationActionCreators'; | ||
import { createPathParser } from './pathUtils'; | ||
function isEmpty(obj) { | ||
if (!obj) return true; | ||
for (let key in obj) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
function behavesLikePushAction(action) { | ||
@@ -57,4 +47,2 @@ return action.type === NavigationActions.NAVIGATE || action.type === StackActions.PUSH; | ||
const initialChildRouter = childRouters[initialRouteName]; | ||
const pathsByRouteNames = { ...stackConfig.paths } || {}; | ||
let paths = []; | ||
@@ -112,33 +100,7 @@ function getInitialState(action) { | ||
// Build paths for each route | ||
routeNames.forEach(routeName => { | ||
let pathPattern = pathsByRouteNames[routeName] || routeConfigs[routeName].path; | ||
let matchExact = !!pathPattern && !childRouters[routeName]; | ||
if (pathPattern === undefined) { | ||
pathPattern = routeName; | ||
} | ||
const keys = []; | ||
let re, toPath, priority; | ||
if (typeof pathPattern === 'string') { | ||
// pathPattern may be either a string or a regexp object according to path-to-regexp docs. | ||
re = pathToRegexp(pathPattern, keys); | ||
toPath = pathToRegexp.compile(pathPattern); | ||
priority = 0; | ||
} else { | ||
// for wildcard match | ||
re = pathToRegexp('*', keys); | ||
toPath = () => ''; | ||
matchExact = true; | ||
priority = -1; | ||
} | ||
if (!matchExact) { | ||
const wildcardRe = pathToRegexp(`${pathPattern}/*`, keys); | ||
re = new RegExp(`(?:${re.source})|(?:${wildcardRe.source})`); | ||
} | ||
pathsByRouteNames[routeName] = { re, keys, toPath, priority }; | ||
}); | ||
const { | ||
getPathAndParamsForRoute, | ||
getActionForPathAndParams | ||
} = createPathParser(childRouters, routeConfigs, stackConfig.paths, initialRouteName, initialRouteParams); | ||
paths = Object.entries(pathsByRouteNames); | ||
paths.sort((a, b) => b[1].priority - a[1].priority); | ||
return { | ||
@@ -162,3 +124,2 @@ childRouters, | ||
return { | ||
...getNavigationActionCreators(route), | ||
...getCustomActionCreators(route, navStateKey), | ||
@@ -343,3 +304,6 @@ pop: (n, params) => StackActions.pop({ | ||
}; | ||
return StateUtils.push(state, route); | ||
return { | ||
...StateUtils.push(state, route), | ||
isTransitioning: action.immediate !== true | ||
}; | ||
} | ||
@@ -482,113 +446,7 @@ } | ||
const route = state.routes[state.index]; | ||
const routeName = route.routeName; | ||
const screen = getScreenForRouteName(routeConfigs, routeName); | ||
const subPath = pathsByRouteNames[routeName].toPath(route.params); | ||
let path = subPath; | ||
let params = route.params; | ||
if (screen && screen.router) { | ||
const stateRoute = route; | ||
// If it has a router it's a navigator. | ||
// If it doesn't have router it's an ordinary React component. | ||
const child = screen.router.getPathAndParamsForState(stateRoute); | ||
path = subPath ? `${subPath}/${child.path}` : child.path; | ||
params = child.params ? { ...params, ...child.params } : params; | ||
} | ||
return { | ||
path, | ||
params | ||
}; | ||
return getPathAndParamsForRoute(route); | ||
}, | ||
getActionForPathAndParams(pathToResolve, inputParams) { | ||
// If the path is empty (null or empty string) | ||
// just return the initial route action | ||
if (!pathToResolve) { | ||
return NavigationActions.navigate({ | ||
routeName: initialRouteName, | ||
params: inputParams | ||
}); | ||
} | ||
const [pathNameToResolve, queryString] = pathToResolve.split('?'); | ||
// Attempt to match `pathNameToResolve` with a route in this router's | ||
// routeConfigs | ||
let matchedRouteName; | ||
let pathMatch; | ||
let pathMatchKeys; | ||
// eslint-disable-next-line no-restricted-syntax | ||
for (const [routeName, path] of paths) { | ||
const { re, keys } = path; | ||
pathMatch = re.exec(pathNameToResolve); | ||
if (pathMatch && pathMatch.length) { | ||
pathMatchKeys = keys; | ||
matchedRouteName = routeName; | ||
break; | ||
} | ||
} | ||
// We didn't match -- return null | ||
if (!matchedRouteName) { | ||
// If the path is empty (null or empty string) | ||
// just return the initial route action | ||
if (!pathToResolve) { | ||
return NavigationActions.navigate({ | ||
routeName: initialRouteName | ||
}); | ||
} | ||
return null; | ||
} | ||
// Determine nested actions: | ||
// If our matched route for this router is a child router, | ||
// get the action for the path AFTER the matched path for this | ||
// router | ||
let nestedAction; | ||
let nestedQueryString = queryString ? '?' + queryString : ''; | ||
if (childRouters[matchedRouteName]) { | ||
nestedAction = childRouters[matchedRouteName].getActionForPathAndParams(pathMatch.slice(pathMatchKeys.length).join('/') + nestedQueryString); | ||
if (!nestedAction) { | ||
return null; | ||
} | ||
} | ||
// reduce the items of the query string. any query params may | ||
// be overridden by path params | ||
const queryParams = !isEmpty(inputParams) ? inputParams : (queryString || '').split('&').reduce((result, item) => { | ||
if (item !== '') { | ||
const nextResult = result || {}; | ||
const [key, value] = item.split('='); | ||
nextResult[key] = value; | ||
return nextResult; | ||
} | ||
return result; | ||
}, null); | ||
// reduce the matched pieces of the path into the params | ||
// of the route. `params` is null if there are no params. | ||
const params = pathMatch.slice(1).reduce((result, matchResult, i) => { | ||
const key = pathMatchKeys[i]; | ||
if (key.asterisk || !key) { | ||
return result; | ||
} | ||
const nextResult = result || inputParams || {}; | ||
const paramName = key.name; | ||
let decodedMatchResult; | ||
try { | ||
decodedMatchResult = decodeURIComponent(matchResult); | ||
} catch (e) { | ||
// ignore `URIError: malformed URI` | ||
} | ||
nextResult[paramName] = decodedMatchResult || matchResult; | ||
return nextResult; | ||
}, queryParams); | ||
return NavigationActions.navigate({ | ||
routeName: matchedRouteName, | ||
...(params ? { params } : {}), | ||
...(nestedAction ? { action: nestedAction } : {}) | ||
}); | ||
getActionForPathAndParams(path, params) { | ||
return getActionForPathAndParams(path, params); | ||
}, | ||
@@ -595,0 +453,0 @@ |
@@ -8,3 +8,3 @@ import invariant from './invariant'; | ||
import validateRouteConfigMap from './validateRouteConfigMap'; | ||
import getNavigationActionCreators from './getNavigationActionCreators'; | ||
import { createPathParser } from './pathUtils'; | ||
@@ -24,3 +24,3 @@ const defaultActionCreators = (route, navStateKey) => ({}); | ||
const order = config.order || Object.keys(routeConfigs); | ||
const paths = config.paths || {}; | ||
const getCustomActionCreators = config.getCustomActionCreators || defaultActionCreators; | ||
@@ -37,5 +37,2 @@ | ||
const routeConfig = routeConfigs[routeName]; | ||
if (!paths[routeName]) { | ||
paths[routeName] = typeof routeConfig.path === 'string' ? routeConfig.path : routeName; | ||
} | ||
childRouters[routeName] = null; | ||
@@ -47,2 +44,8 @@ const screen = getScreenForRouteName(routeConfigs, routeName); | ||
}); | ||
const { | ||
getPathAndParamsForRoute, | ||
getActionForPathAndParams | ||
} = createPathParser(childRouters, routeConfigs, config.paths, initialRouteName, initialRouteParams); | ||
if (initialRouteIndex === -1) { | ||
@@ -71,41 +74,38 @@ throw new Error(`Invalid initialRouteName '${initialRouteName}'.` + `Should be one of ${order.map(n => `"${n}"`).join(', ')}`); | ||
return { | ||
childRouters, | ||
function getNextState(prevState, possibleNextState) { | ||
if (!prevState) { | ||
return possibleNextState; | ||
} | ||
getInitialState() { | ||
const routes = order.map(resetChildRoute); | ||
let nextState; | ||
if (prevState.index !== possibleNextState.index && resetOnBlur) { | ||
const prevRouteName = prevState.routes[prevState.index].routeName; | ||
const nextRoutes = [...possibleNextState.routes]; | ||
nextRoutes[prevState.index] = resetChildRoute(prevRouteName); | ||
return { | ||
routes, | ||
index: initialRouteIndex, | ||
isTransitioning: false | ||
...possibleNextState, | ||
routes: nextRoutes | ||
}; | ||
}, | ||
} else { | ||
nextState = possibleNextState; | ||
} | ||
getNextState(prevState, possibleNextState) { | ||
if (!prevState) { | ||
return possibleNextState; | ||
} | ||
return nextState; | ||
} | ||
let nextState; | ||
if (prevState.index !== possibleNextState.index && resetOnBlur) { | ||
const prevRouteName = prevState.routes[prevState.index].routeName; | ||
const nextRoutes = [...possibleNextState.routes]; | ||
nextRoutes[prevState.index] = resetChildRoute(prevRouteName); | ||
function getInitialState() { | ||
const routes = order.map(resetChildRoute); | ||
return { | ||
routes, | ||
index: initialRouteIndex, | ||
isTransitioning: false | ||
}; | ||
} | ||
return { | ||
...possibleNextState, | ||
routes: nextRoutes | ||
}; | ||
} else { | ||
nextState = possibleNextState; | ||
} | ||
return { | ||
childRouters, | ||
return nextState; | ||
}, | ||
getActionCreators(route, stateKey) { | ||
return { | ||
...getNavigationActionCreators(route), | ||
...getCustomActionCreators(route, stateKey) | ||
}; | ||
return getCustomActionCreators(route, stateKey); | ||
}, | ||
@@ -115,3 +115,3 @@ | ||
let prevState = inputState ? { ...inputState } : inputState; | ||
let state = inputState || this.getInitialState(); | ||
let state = inputState || getInitialState(); | ||
let activeChildIndex = state.index; | ||
@@ -148,3 +148,3 @@ | ||
routes[state.index] = activeChildState; | ||
return this.getNextState(prevState, { | ||
return getNextState(prevState, { | ||
...state, | ||
@@ -196,3 +196,3 @@ routes | ||
routes[activeChildIndex] = newChildState; | ||
return this.getNextState(prevState, { | ||
return getNextState(prevState, { | ||
...state, | ||
@@ -221,3 +221,3 @@ routes, | ||
}; | ||
return this.getNextState(prevState, { | ||
return getNextState(prevState, { | ||
...state, | ||
@@ -230,3 +230,3 @@ routes | ||
if (activeChildIndex !== state.index) { | ||
return this.getNextState(prevState, { | ||
return getNextState(prevState, { | ||
...state, | ||
@@ -275,3 +275,3 @@ index: activeChildIndex | ||
if (index !== state.index || routes !== state.routes) { | ||
return this.getNextState(prevState, { | ||
return getNextState(prevState, { | ||
...state, | ||
@@ -302,56 +302,7 @@ index, | ||
const route = state.routes[state.index]; | ||
const routeName = order[state.index]; | ||
const subPath = paths[routeName]; | ||
const screen = getScreenForRouteName(routeConfigs, routeName); | ||
let path = subPath; | ||
let params = route.params; | ||
if (screen && screen.router) { | ||
const stateRoute = route; | ||
// If it has a router it's a navigator. | ||
// If it doesn't have router it's an ordinary React component. | ||
const child = screen.router.getPathAndParamsForState(stateRoute); | ||
path = subPath ? `${subPath}/${child.path}` : child.path; | ||
params = child.params ? { ...params, ...child.params } : params; | ||
} | ||
return { | ||
path, | ||
params | ||
}; | ||
return getPathAndParamsForRoute(route); | ||
}, | ||
/** | ||
* Gets an optional action, based on a relative path and query params. | ||
* | ||
* This will return null if there is no action matched | ||
*/ | ||
getActionForPathAndParams(path, params) { | ||
if (!path) { | ||
return NavigationActions.navigate({ | ||
routeName: initialRouteName, | ||
params | ||
}); | ||
} | ||
return order.map(childId => { | ||
const parts = path.split('/'); | ||
const pathToTest = paths[childId]; | ||
const partsInTestPath = pathToTest.split('/').length; | ||
const pathPartsToTest = parts.slice(0, partsInTestPath).join('/'); | ||
if (pathPartsToTest === pathToTest) { | ||
const childRouter = childRouters[childId]; | ||
const action = NavigationActions.navigate({ | ||
routeName: childId | ||
}); | ||
if (childRouter && childRouter.getActionForPathAndParams) { | ||
action.action = childRouter.getActionForPathAndParams(parts.slice(partsInTestPath).join('/'), params); | ||
} | ||
if (params) { | ||
action.params = params; | ||
} | ||
return action; | ||
} | ||
return null; | ||
}).find(action => !!action) || order.map(childId => { | ||
const childRouter = childRouters[childId]; | ||
return childRouter && childRouter.getActionForPathAndParams(path, params); | ||
}).find(action => !!action) || null; | ||
return getActionForPathAndParams(path, params); | ||
}, | ||
@@ -358,0 +309,0 @@ |
@@ -16,4 +16,3 @@ import invariant from './invariant'; | ||
if (!screenComponent || typeof screenComponent !== 'function' && typeof screenComponent !== 'string' && !routeConfig.getScreen) { | ||
throw new Error(`The component for route '${routeName}' must be a | ||
React component. For example: | ||
throw new Error(`The component for route '${routeName}' must be a React component. For example: | ||
@@ -23,2 +22,3 @@ import MyScreen from './MyScreen'; | ||
${routeName}: MyScreen, | ||
} | ||
@@ -30,4 +30,3 @@ You can also use a navigator: | ||
${routeName}: MyNavigator, | ||
`); | ||
}`); | ||
} | ||
@@ -34,0 +33,0 @@ |
export default ((obj, key, defaultValue) => { | ||
if (obj.hasOwnProperty(key)) { | ||
if (obj.hasOwnProperty(key) && typeof obj[key] !== 'undefined') { | ||
return obj; | ||
@@ -4,0 +4,0 @@ } |
57
155353
5
3642
+ Addedquery-string@^6.1.0
+ Addeddecode-uri-component@0.2.2(transitive)
+ Addedfilter-obj@1.1.0(transitive)
+ Addedquery-string@6.14.1(transitive)
+ Addedsplit-on-first@1.1.0(transitive)
+ Addedstrict-uri-encode@2.0.0(transitive)