1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 1× 66× 66× 66× 66× 66× 66× 44× 44× 44× 66× 66× 66× 42× 42× 42× 42× 66× 62× 62× 62× 62× 66× 66× 10× 10× 10× 10× 66× 66× 66× | import transitionPath, { nameToIDs } from 'router5.transition-path'; import asyncProcess from './async'; import constants from './constants'; export default transition; function transition(router, toState, fromState, callback) { let cancelled = false; const additionalArgs = router.getAdditionalArgs(); const isCancelled = () => cancelled; const cancel = () => cancelled = true; const done = (err, state) => { if (!err && !isCancelled() && router.options.autoCleanUp) { const activeSegments = nameToIDs(toState.name); Object.keys(router._canDeact).forEach(name => { if (activeSegments.indexOf(name) === -1) router._canDeact[name] = undefined; }); } callback(isCancelled() ? { code: constants.TRANSITION_CANCELLED } : err, state || toState); }; const {toDeactivate, toActivate} = transitionPath(toState, fromState); const asyncBase = { isCancelled, toState, fromState, additionalArgs: [] }; const canDeactivate = (toState, fromState, cb) => { let canDeactivateFunctionMap = toDeactivate .filter(name => router._canDeact[name]) .reduce((fnMap, name) => ({ ...fnMap, [name]: router._canDeact[name] }), {}); asyncProcess( canDeactivateFunctionMap, { ...asyncBase, additionalArgs }, err => { const errObj = err ? (err instanceof Error ? { error: err } : { segment: err }) : null; cb(err ? { code: constants.CANNOT_DEACTIVATE, ...errObj } : null); } ); }; const canActivate = (toState, fromState, cb) => { const canActivateFunctionMap = toActivate .filter(name => router._canAct[name]) .reduce((fnMap, name) => ({ ...fnMap, [name]: router._canAct[name] }), {}); asyncProcess( canActivateFunctionMap, { ...asyncBase, additionalArgs }, err => { const errObj = err ? (err instanceof Error ? { error: err } : { segment: err }) : null; cb(err ? { code: constants.CANNOT_ACTIVATE, ...errObj } : null); } ); }; const middlewareFn = router.mware; const middleware = (toState, fromState, cb) => { let mwareFunction = Array.isArray(router.mware) ? router.mware : [router.mware]; asyncProcess( mwareFunction, { ...asyncBase, additionalArgs }, (err, state) => { const errObj = err ? (typeof err === 'object' ? err : { error: err }) : null; cb(err ? { code: constants.TRANSITION_ERR, ...errObj } : null, state || toState); } ); }; let pipeline = (fromState ? [canDeactivate] : []) .concat(canActivate) .concat(middlewareFn ? middleware : []); asyncProcess(pipeline, asyncBase, done); return cancel; } |