react-router
Version:
A complete routing library for React
122 lines (103 loc) • 3.78 kB
JavaScript
;
exports.__esModule = true;
exports.runEnterHooks = runEnterHooks;
exports.runChangeHooks = runChangeHooks;
exports.runLeaveHooks = runLeaveHooks;
var _AsyncUtils = require('./AsyncUtils');
var _routerWarning = require('./routerWarning');
var _routerWarning2 = _interopRequireDefault(_routerWarning);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function createTransitionHook(hook, route, asyncArity) {
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
hook.apply(route, args);
if (hook.length < asyncArity) {
var callback = args[args.length - 1];
// Assume hook executes synchronously and
// automatically call the callback.
callback();
}
};
}
function getEnterHooks(routes) {
return routes.reduce(function (hooks, route) {
if (route.onEnter) hooks.push(createTransitionHook(route.onEnter, route, 3));
return hooks;
}, []);
}
function getChangeHooks(routes) {
return routes.reduce(function (hooks, route) {
if (route.onChange) hooks.push(createTransitionHook(route.onChange, route, 4));
return hooks;
}, []);
}
function runTransitionHooks(length, iter, callback) {
if (!length) {
callback();
return;
}
var redirectInfo = void 0;
function replace(location, deprecatedPathname, deprecatedQuery) {
if (deprecatedPathname) {
process.env.NODE_ENV !== 'production' ? (0, _routerWarning2.default)(false, '`replaceState(state, pathname, query) is deprecated; use `replace(location)` with a location descriptor instead. http://tiny.cc/router-isActivedeprecated') : void 0;
redirectInfo = {
pathname: deprecatedPathname,
query: deprecatedQuery,
state: location
};
return;
}
redirectInfo = location;
}
(0, _AsyncUtils.loopAsync)(length, function (index, next, done) {
iter(index, replace, function (error) {
if (error || redirectInfo) {
done(error, redirectInfo); // No need to continue.
} else {
next();
}
});
}, callback);
}
/**
* Runs all onEnter hooks in the given array of routes in order
* with onEnter(nextState, replace, callback) and calls
* callback(error, redirectInfo) when finished. The first hook
* to use replace short-circuits the loop.
*
* If a hook needs to run asynchronously, it may use the callback
* function. However, doing so will cause the transition to pause,
* which could lead to a non-responsive UI if the hook is slow.
*/
function runEnterHooks(routes, nextState, callback) {
var hooks = getEnterHooks(routes);
return runTransitionHooks(hooks.length, function (index, replace, next) {
hooks[index](nextState, replace, next);
}, callback);
}
/**
* Runs all onChange hooks in the given array of routes in order
* with onChange(prevState, nextState, replace, callback) and calls
* callback(error, redirectInfo) when finished. The first hook
* to use replace short-circuits the loop.
*
* If a hook needs to run asynchronously, it may use the callback
* function. However, doing so will cause the transition to pause,
* which could lead to a non-responsive UI if the hook is slow.
*/
function runChangeHooks(routes, state, nextState, callback) {
var hooks = getChangeHooks(routes);
return runTransitionHooks(hooks.length, function (index, replace, next) {
hooks[index](state, nextState, replace, next);
}, callback);
}
/**
* Runs all onLeave hooks in the given array of routes in order.
*/
function runLeaveHooks(routes) {
for (var i = 0, len = routes.length; i < len; ++i) {
if (routes[i].onLeave) routes[i].onLeave.call(routes[i]);
}
}