react-view-router
Version:
react-view-router
1,231 lines (1,222 loc) • 67.1 kB
JavaScript
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
var _excluded = ["name", "mode", "basename"],
_excluded2 = ["routes", "inheritProps", "rememberInitialRoute", "install", "queryProps"];
import _regeneratorRuntime from "@babel/runtime/regenerator";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import "core-js/modules/es6.regexp.replace.js";
import "core-js/modules/es7.array.includes.js";
import "core-js/modules/es6.regexp.search.js";
import "core-js/modules/es6.array.filter.js";
import "core-js/modules/es6.array.map.js";
import "core-js/modules/es6.object.to-string.js";
import "core-js/modules/es6.promise.js";
import "core-js/modules/es6.regexp.match.js";
import "core-js/modules/es7.object.values.js";
import "core-js/modules/es6.array.slice.js";
import "core-js/modules/es6.symbol.js";
import "core-js/modules/es7.object.get-own-property-descriptors.js";
import { createHashHistory, createBrowserHistory, createMemoryHistory, getPossibleHistory } from './history-fix';
import config from './config';
import { flatten, isAbsoluteUrl, innumerable, isPlainObject, getRouterViewPath, getCompleteRoute, normalizeRoutes, normalizeLocation, resolveRedirect, resolveAbort, copyOwnProperties, matchRoutes, isFunction, isLocation, nextTick, once, isRouteGuardInfoHooks, isReadonly, afterInterceptors, getRouteChildren, readRouteMeta, readonly, getLoactionAction, getHostRouterView, camelize, reverseArray, isMatchedRoutePropsChanged, isRoute, walkRoutes, warn, createEmptyRouteState, DEFAULT_STATE_NAME, hasOwnProp, isString, isNumber, isEmptyRouteState } from './util';
import { RouteLazy, hasRouteLazy, hasMatchedRouteLazy } from './route-lazy';
import { getGuardsComponent } from './route-guard';
import { createHashHref, HistoryType } from './history';
var HISTORY_METHS = ['push', 'replace', 'redirect', 'go', 'back', 'forward', 'block'];
var idSeed = 1;
// eslint-disable-next-line no-undef
var version = typeof "2.2.3" === 'undefined' ? undefined : "2.2.3";
class ReactViewRouter {
constructor(options = {}) {
_defineProperty(this, "version", version);
_defineProperty(this, "isReactViewRouterInstance", true);
_defineProperty(this, "parent", null);
_defineProperty(this, "children", []);
_defineProperty(this, "options", {});
_defineProperty(this, "mode", HistoryType.hash);
_defineProperty(this, "basename", '');
_defineProperty(this, "basenameNoSlash", '');
_defineProperty(this, "name", '');
_defineProperty(this, "routeNameMap", {});
_defineProperty(this, "routes", normalizeRoutes([]));
_defineProperty(this, "stacks", []);
_defineProperty(this, "plugins", []);
_defineProperty(this, "beforeEachGuards", []);
_defineProperty(this, "afterUpdateGuards", []);
_defineProperty(this, "beforeResolveGuards", []);
_defineProperty(this, "afterEachGuards", []);
_defineProperty(this, "resolveNameFns", []);
_defineProperty(this, "prevRoute", null);
_defineProperty(this, "currentRoute", null);
_defineProperty(this, "pendingRoute", null);
_defineProperty(this, "initialRoute", {});
_defineProperty(this, "queryProps", {});
_defineProperty(this, "viewRoot", null);
_defineProperty(this, "errorCallbacks", []);
_defineProperty(this, "apps", []);
_defineProperty(this, "Apps", []);
_defineProperty(this, "isRunning", false);
_defineProperty(this, "isHistoryCreater", false);
_defineProperty(this, "rememberInitialRoute", false);
// scrollBehavior: ReactViewRouterScrollBehavior|null = null;
_defineProperty(this, "_history", null);
_defineProperty(this, "_nexting", null);
_defineProperty(this, "_interceptorCounter", 0);
this.id = idSeed++;
this._initRouter(options);
this.getHostRouterView = getHostRouterView;
this.nextTick = nextTick.bind(this);
this._handleRouteInterceptor = this._handleRouteInterceptor.bind(this);
this.use(this.options);
if (!options.manual) this.start(undefined, true);
}
_initRouter(options) {
var name = options.name,
mode = options.mode,
basename = options.basename,
moreOptions = _objectWithoutProperties(options, _excluded);
if (name != null) this.name = name;
if (mode != null) {
if (typeof mode !== 'string') {
moreOptions.history = mode;
mode = mode.type;
}
if (this.mode !== mode) this.mode = mode;
}
if (basename !== undefined) {
if (basename && !/\/$/.test(basename)) basename += '/';
this.basename = this.mode === HistoryType.memory && (!moreOptions.history || moreOptions.history.type !== HistoryType.memory) ? '' : basename.replace(/\/{2,}/g, '/');
this.basenameNoSlash = this.basename ? this.basename.endsWith('/') ? this.basename.substr(0, basename.length - 1) : this.basename : this.basename;
}
Object.assign(this.options, moreOptions);
if (this.options.keepAlive && !this.options.renderUtils) {
throw new Error('endable keepAlive need "renderUtils", but it cannot be found from router\'s options!');
}
}
_updateParent(parent) {
if (parent === this) parent = null;
if (this.parent === parent) return;
if (parent) {
if (parent.children && !parent.children.includes(this)) parent.children.push(this);
} else if (this.parent && this.parent.children) {
var idx = this.parent.children.indexOf(this);
if (~idx) this.parent.children.splice(idx, 1);
}
this.parent = parent;
}
get history() {
if (this._history) return this._history;
switch (this.mode) {
case HistoryType.browser:
this._history = createBrowserHistory(this.options, this);
break;
case HistoryType.memory:
this._history = createMemoryHistory(this.options, this);
break;
default:
this._history = createHashHistory(this.options, this);
}
HISTORY_METHS.forEach(key => {
if (!this[key] || !this[key].bindThis) return;
this[key] = this[key].bind(this);
innumerable(this[key], 'bindThis', true);
});
this._history.refresh && this._history.refresh();
this._history && (this._history.destroy = () => this._history = null);
return this._history;
}
get pluginName() {
return this.name;
}
get top() {
return this.parent ? this.parent.top : this;
}
get isBrowserMode() {
return this.mode === HistoryType.browser;
}
get isHashMode() {
return this.mode === HistoryType.hash;
}
get isMemoryMode() {
return this.mode === HistoryType.memory;
}
get isPrepared() {
return this.isRunning && Boolean(this.currentRoute && this.viewRoot && this.viewRoot.state.inited && this.viewRoot._isMounted);
}
_startHistory() {
if (this._history && this._history.destroy) this._history.destroy();
this._unlisten = this.history.listen(({
location
}, interceptors) => {
var to = location;
if (interceptors && Array.isArray(interceptors)) {
var interceptorItem = interceptors.find(v => v.router === this);
if (interceptorItem && interceptorItem.payload) to = interceptorItem.payload;
}
this.updateRoute(to);
});
this._uninterceptor = this.history.interceptorTransitionTo(this._handleRouteInterceptor, this);
this._refreshInitialRoute();
}
start(routerOptions = {}, isInit = false) {
this.stop({
isInit
});
this._callEvent('onStart', this, routerOptions, isInit);
this._initRouter(routerOptions);
this._startHistory();
this.isRunning = true;
}
stop(options = {}) {
this._callEvent('onStop', this, options);
if (this._unlisten) {
this._unlisten();
this._unlisten = undefined;
}
if (this._uninterceptor) {
this._uninterceptor();
this._uninterceptor = undefined;
}
if (this._history && this._history.destroy) {
this._history.destroy();
}
this._history = null;
this._interceptorCounter = 0;
this.isRunning = false;
this.isHistoryCreater = false;
if (!options.ignoreClearRoute) {
this.initialRoute = {
location: {}
};
this.prevRoute = null;
this.currentRoute = null;
this.pendingRoute = null;
}
}
use(_ref) {
var routes = _ref.routes,
inheritProps = _ref.inheritProps,
rememberInitialRoute = _ref.rememberInitialRoute,
install = _ref.install,
queryProps = _ref.queryProps,
restOptions = _objectWithoutProperties(_ref, _excluded2);
if (rememberInitialRoute !== undefined) this.rememberInitialRoute = rememberInitialRoute;
// if (scrollBehavior !== undefined) this.scrollBehavior = scrollBehavior;
if (queryProps) this.queryProps = queryProps;
if (routes) {
var originRoutes = this.routes;
this.routes = routes ? normalizeRoutes(routes) : normalizeRoutes([]);
this._callEvent('onRoutesChange', this.routes, originRoutes);
this._walkRoutes(this.routes);
if (this._history && this.initialRoute) this._refreshInitialRoute();
}
if (inheritProps !== undefined) config.inheritProps = inheritProps;
Object.assign(config, restOptions);
if (install) this.install = install.bind(this);
}
plugin(plugin) {
if (isFunction(plugin)) {
plugin = this.plugins.find(p => p.onRouteChange === plugin) || {
onRouteChange: plugin
};
} else if (~this.plugins.indexOf(plugin)) return;
var idx = this.plugins.findIndex(p => {
if (plugin.name) return p.name === plugin.name;
return p === plugin;
});
if (~idx) {
var _this$plugins$splice = this.plugins.splice(idx, 1, plugin),
_this$plugins$splice2 = _slicedToArray(_this$plugins$splice, 1),
old = _this$plugins$splice2[0];
if (old && old.uninstall) old.uninstall(this);
} else this.plugins.push(plugin);
if (plugin.install) plugin.install(this);
return () => {
var idx = this.plugins.indexOf(plugin);
if (~idx) {
this.plugins.splice(idx, 1);
if (plugin.uninstall) plugin.uninstall(this);
}
};
}
_walkRoutes(routes, parent) {
walkRoutes(routes, (route, routeIndex, rs) => {
this._callEvent('onWalkRoute', route, routeIndex, rs);
if (route.name) {
var name = camelize(route.name);
if (this.routeNameMap[name]) {
warn(`[react-view-router] route name '${route.name}'(path is [${route.path}]) is duplicate with [${this.routeNameMap[name]}]`);
}
this.routeNameMap[name] = route.path;
}
}, parent);
}
_refreshInitialRoute() {
var historyLocation = _objectSpread({}, this.history.realtimeLocation);
this.updateRoute(historyLocation);
if (this.rememberInitialRoute) {
var stack;
if (this.basename) {
var stacks = reverseArray(this.history.stacks.concat(historyLocation));
var basename = this.basenameNoSlash;
for (var i = 0; i < stacks.length; i++) {
var currentStack = stacks[i];
if (!currentStack.pathname.startsWith(basename)) break;
if (i === stacks.length - 1 || !stacks[i + 1].pathname.startsWith(basename)) {
stack = currentStack;
break;
}
}
} else if (this.history.stacks.length) {
stack = this.history.stacks[0];
}
if (stack) {
var _globalThis$location;
historyLocation = this._normalizeLocation({
pathname: stack.pathname,
search: stack.search
});
if (!this.isMemoryMode && globalThis !== null && globalThis !== void 0 && (_globalThis$location = globalThis.location) !== null && _globalThis$location !== void 0 && _globalThis$location.search) {
var query = this.parseQuery(globalThis.location.search, this.queryProps);
if (this.isHashMode) {
Object.assign(historyLocation.query, query);
} else if (this.isBrowserMode) {
Object.keys(historyLocation.query).forEach(key => {
if (query[key] !== undefined) historyLocation.query[key] = query[key];
});
}
}
}
}
this.initialRoute = this.createRoute(this._transformLocation(historyLocation));
// innumerable(this.initialRoute, 'location', location);
}
_callEvent(event, ...args) {
var plugin = null;
try {
var ret;
this.plugins.forEach(p => {
plugin = p;
var newRet = p[event] && p[event].call(p, ...args, ret);
if (newRet !== undefined) ret = newRet;
});
return ret;
} catch (ex) {
if (plugin && plugin.name && ex && ex.message) {
ex.message = `[${plugin.name}:${event}]${ex.message}`;
}
throw ex;
}
}
_isVuelikeComponent(comp) {
return comp && this.vuelike && (
// eslint-disable-next-line no-proto
comp.__proto__ && comp.isVuelikeComponentInstance || comp.__vuelike || comp.__vuelikeComponentClass);
}
_getComponentGurads(mr, guardName, onBindInstance, onGetLazyResovle) {
var _this = this;
var ret = [];
var componentInstances = mr.componentInstances;
var getGuard = (obj, guardName) => {
var guard = obj && obj[guardName];
if (guard) innumerable(guard, 'instance', obj);
return guard;
};
// route config
var routeGuardName = guardName.replace('Route', '');
var r = mr.config;
var guards = r[routeGuardName];
if (guards) ret.push(guards);
var toResovle = (c, componentKey) => {
var ret = [];
if (c) {
var cc = c.__component ? getGuardsComponent(c, true) : c;
var cg = getGuard(c.__guards, guardName);
if (cg) ret.push(cg);
var ccg = cc && getGuard(cc.prototype, guardName);
if (ccg) {
if (this.vuelike && !ccg.isMobxFlow && cc.__flows && ~cc.__flows.indexOf(guardName)) ccg = this.vuelike.flow(ccg);
ret.push(ccg);
}
if (this._isVuelikeComponent(cc) && Array.isArray(cc.mixins)) {
cc.mixins.forEach(m => {
var ccg = m && (getGuard(m, guardName) || getGuard(m.prototype, guardName));
if (!ccg) return;
if (this.vuelike && !ccg.isMobxFlow && m.__flows && ~m.__flows.indexOf(guardName)) ccg = this.vuelike.flow(ccg);
ret.push(ccg);
});
}
}
var ci = componentInstances[componentKey];
if (isRouteGuardInfoHooks(ci)) {
var cig = getGuard(ci, guardName);
if (cig) ret.push(cig);
}
if (onBindInstance) ret = ret.map(v => onBindInstance(v, componentKey, ci, mr)).filter(Boolean);else if (ci) {
ret = ret.map(v => {
var ret = v.bind(ci);
ret.instance = v.instance;
return ret;
});
}
ret = flatten(ret);
ret.forEach(v => v.route = mr);
return ret;
};
var replaceInterceptors = (newInterceptors, interceptors, index) => {
interceptors.splice(index, 1, ...newInterceptors);
return interceptors[index];
};
// route component
r.components && Object.keys(r.components).forEach(key => {
var c = r.components[key];
if (!c) return;
var isResolved = this._callEvent('onGetRouteComponentGurads', ret, r, c, key, guardName, {
router: this,
onBindInstance,
onGetLazyResovle,
toResovle,
getGuard,
replaceInterceptors: replaceInterceptors
});
if (isResolved === true) return ret;
if (c instanceof RouteLazy) {
var lazyResovleCb;
var lazyResovle = /*#__PURE__*/function () {
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(interceptors, index) {
var nc, ret;
return _regeneratorRuntime.wrap(function (_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
lazyResovleCb && lazyResovleCb();
_context.next = 1;
return c.toResolve(_this, r, key);
case 1:
nc = _context.sent;
nc = _this._callEvent('onLazyResolveComponent', nc, r) || nc;
ret = toResovle(nc, key);
return _context.abrupt("return", replaceInterceptors(ret, interceptors, index));
case 2:
case "end":
return _context.stop();
}
}, _callee);
}));
return function lazyResovle(_x, _x2) {
return _ref2.apply(this, arguments);
};
}();
lazyResovle.lazy = true;
lazyResovle.route = mr;
onGetLazyResovle && onGetLazyResovle(lazyResovle, cb => lazyResovleCb = cb);
ret.push(lazyResovle);
return;
}
ret.push(...toResovle(c, key));
});
return ret;
}
_getSameMatched(route, compare) {
var ret = [];
if (!compare) return [];
route && route.matched.some((tr, i) => {
var fr = compare.matched[i];
if (tr.path !== fr.path) return true;
ret.push(tr);
});
return ret.filter(r => !r.redirect);
}
_getChangeMatched(route, route2, options = {}) {
var ret = [];
if (!route2) return [...route.matched];
var start = false;
route && route.matched.some((tr, i) => {
var fr = route2.matched[i];
if (!start) {
start = options.containLazy && hasRouteLazy(tr) || !fr || fr.path !== tr.path || Boolean(options.compare && options.compare(tr, fr));
if (!start) return;
}
ret.push(tr);
var count = options.count;
if (isFunction(count)) count = count(ret, tr, fr);
return isNumber(count) && ret.length === count;
});
return ret.filter(r => !r.redirect);
}
_getBeforeEachGuards(to, from, current = null) {
var ret = [...this.beforeEachGuards];
if (this.viewRoot && this.viewRoot.props.beforeEach) {
ret.push(this.viewRoot.props.beforeEach);
}
// to.matched.forEach(mr => {
// Object.keys(mr.viewInstances).forEach(key => {
// let view = mr.viewInstances[key];
// if (!view || view === this.viewRoot) return;
// const beforeEach = view.props.beforeEach;
// if (beforeEach) ret.push(beforeEach);
// });
// });
if (from) {
var fm = this._getChangeMatched(from, to).filter(r => Object.keys(r.viewInstances).some(key => r.viewInstances[key]));
reverseArray(fm).forEach(mr => {
reverseArray(mr.guards.beforeLeave).forEach(g => {
if (g.called) return;
if (g.instance) {
var beforeEnterGuard = mr.guards.beforeEnter.find(g2 => g2.instance === g.instance);
if (beforeEnterGuard && !beforeEnterGuard.called) return;
}
ret.push(g.guard);
});
});
}
if (to) {
var tm = this._getChangeMatched(to, from, {
containLazy: true,
compare: (tr, fr) => fr.guards.beforeEnter.some(g => !g.called)
});
tm.forEach(mr => mr.guards.beforeEnter.forEach(g => {
if (!g.lazy && g.called) return;
ret.push(g.guard);
}));
}
return flatten(ret);
}
_getBeforeResolveGuards(to, from) {
var ret = [...this.beforeResolveGuards];
if (to) {
var tm = this._getChangeMatched(to, from, {
compare: (tr, fr) => fr.guards.beforeResolve.some(g => !g.called)
});
tm.forEach(mr => {
mr.guards.beforeResolve.forEach(g => {
if (g.called) return;
ret.push(g.guard);
});
});
}
return flatten(ret);
}
_getRouteUpdateGuards(to, from) {
var ret = [...this.afterUpdateGuards, ...this.afterEachGuards.filter(g => g.update)];
var fm = [];
to && to.matched.some((tr, i) => {
var fr = from && from.matched[i];
if (!fr || fr.path !== tr.path) return true;
fm.push(fr);
});
reverseArray(fm.filter(r => !r.redirect)).forEach(mr => reverseArray(mr.guards.update).forEach(g => {
if (g.called) return;
ret.push(g.guard);
}));
return ret;
}
_getAfterEachGuards(to, from) {
var ret = [];
if (from) {
var fm = this._getChangeMatched(from, to).filter(r => Object.keys(r.viewInstances).some(key => r.viewInstances[key]));
reverseArray(fm.filter(r => !r.redirect)).forEach(mr => reverseArray(mr.guards.afterLeave).forEach(g => {
if (g.called) return;
ret.push(g.guard);
}));
}
if (this.viewRoot && this.viewRoot.props.afterEach) {
ret.push(this.viewRoot.props.afterEach);
}
ret.push(...this.afterEachGuards);
return flatten(ret);
}
_isMatchBasename(location) {
if (!this.basename) return true;
if (location.basename && !location.absolute) return location.basename === this.basename;
var pathname = location.path || location.pathname;
return pathname.startsWith(this.basenameNoSlash);
}
_transformLocation(location) {
if (!location || isRoute(location)) return location;
if (this.basename) {
var pathname = location.pathname;
if (!location.absolute && location.basename != null) pathname = location.basename + pathname;else if (pathname.length < this.basename.length) {
var parent = this.parent;
while (parent) {
if (pathname.length >= parent.basename.length) {
var parentMatched = parent.getMatched(pathname);
if (parentMatched.length) {
pathname = parentMatched[parentMatched.length - 1].path + parentMatched.unmatchedPath;
break;
}
}
parent = parent.parent;
}
}
if (!/\/$/.test(pathname)) pathname += '/';
location = _objectSpread(_objectSpread({}, location), {}, {
absolute: false
});
var isCurrentBasename = pathname.startsWith(this.basenameNoSlash);
if (isCurrentBasename) {
location.pathname = location.pathname.substr(this.basename.length - 1) || '/';
location.fullPath = location.pathname + location.search;
location.basename = this.basename;
} else {
location.pathname = '';
location.fullPath = '';
}
if (location.path != null) location.path = location.pathname;
}
return location;
}
_getInterceptor(interceptors, index) {
var _this2 = this;
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
var interceptor, newInterceptor;
return _regeneratorRuntime.wrap(function (_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
interceptor = interceptors[index];
case 1:
if (!(interceptor && interceptor.lazy)) {
_context2.next = 3;
break;
}
_context2.next = 2;
return interceptor(interceptors, index);
case 2:
interceptor = _context2.sent;
_context2.next = 1;
break;
case 3:
newInterceptor = _this2._callEvent('onGetRouteInterceptor', interceptor, interceptors, index);
if (newInterceptor && (isFunction(newInterceptor) || newInterceptor.then)) interceptor = newInterceptor;
return _context2.abrupt("return", interceptor);
case 4:
case "end":
return _context2.stop();
}
}, _callee2);
}))();
}
_routetInterceptors(interceptors, to, from, next) {
var _this3 = this;
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
var throwError, isBlock, beforeInterceptor, _beforeInterceptor, _t2, _t3, _t4, _t5, _t6, _t7;
return _regeneratorRuntime.wrap(function (_context5) {
while (1) switch (_context5.prev = _context5.next) {
case 0:
_beforeInterceptor = function _beforeInterceptor3() {
_beforeInterceptor = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(interceptor, index, to, from, next) {
var _this4 = this;
var nextWrapper;
return _regeneratorRuntime.wrap(function (_context4) {
while (1) switch (_context4.prev = _context4.next) {
case 0:
if (interceptor) {
_context4.next = 1;
break;
}
return _context4.abrupt("return", next());
case 1:
nextWrapper = this._nexting = once(/*#__PURE__*/function () {
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(f1) {
var nextInterceptor, _t;
return _regeneratorRuntime.wrap(function (_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
if (!isBlock.call(_this4, f1, interceptor, v => {
f1 = v;
})) {
_context3.next = 1;
break;
}
return _context3.abrupt("return", next(f1));
case 1:
if (f1 === true) f1 = undefined;
_context3.prev = 2;
_context3.next = 3;
return _this4._getInterceptor(interceptors, ++index);
case 3:
nextInterceptor = _context3.sent;
if (nextInterceptor) {
_context3.next = 4;
break;
}
return _context3.abrupt("return", next(res => isFunction(f1) && f1(res)));
case 4:
_context3.next = 5;
return beforeInterceptor.call(_this4, nextInterceptor, index, to, from, res => {
var ret = next(res);
if (interceptor.global) isFunction(f1) && f1(res);
return ret;
});
case 5:
return _context3.abrupt("return", _context3.sent);
case 6:
_context3.prev = 6;
_t = _context3["catch"](2);
throwError = true;
console.error(_t);
next(isString(_t) ? new Error(_t) : _t);
case 7:
case "end":
return _context3.stop();
}
}, _callee3, null, [[2, 6]]);
}));
return function (_x8) {
return _ref3.apply(this, arguments);
};
}());
_context4.next = 2;
return interceptor(to, from, nextWrapper, {
route: interceptor.route,
router: this
});
case 2:
return _context4.abrupt("return", _context4.sent);
case 3:
case "end":
return _context4.stop();
}
}, _callee4, this);
}));
return _beforeInterceptor.apply(this, arguments);
};
beforeInterceptor = function _beforeInterceptor2(_x3, _x4, _x5, _x6, _x7) {
return _beforeInterceptor.apply(this, arguments);
};
throwError = false;
isBlock = (v, interceptor, update) => {
if (throwError) return true;
var _isLocation = isString(v) || isLocation(v);
if (_isLocation && interceptor) {
var _to = isRoute(v) ? v : _this3._normalizeLocation(v, {
route: interceptor.route
});
v = _to && _this3.createRoute(_to, {
action: getLoactionAction(to),
from: to,
matchedProvider: getCompleteRoute(to) || getCompleteRoute(from),
isRedirect: true
});
if (v && v.fullPath === to.fullPath) {
v = undefined;
_isLocation = false;
} else if (v) update(v);
}
return !_this3._history || v === false || _isLocation || v instanceof Error;
};
if (!next) {
_context5.next = 3;
break;
}
_t2 = beforeInterceptor;
_t3 = _this3;
_context5.next = 1;
return _this3._getInterceptor(interceptors, 0);
case 1:
_t4 = _context5.sent;
_t5 = to;
_t6 = from;
_t7 = next;
_context5.next = 2;
return _t2.call.call(_t2, _t3, _t4, 0, _t5, _t6, _t7);
case 2:
_context5.next = 4;
break;
case 3:
afterInterceptors.call(_this3, interceptors, to, from);
case 4:
case "end":
return _context5.stop();
}
}, _callee5);
}))();
}
_handleRouteInterceptor(_x9, _x0) {
var _this5 = this;
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6(location, callback, isInit = false) {
var pathname, url, nexts, error, isContinue, _t8, _t9;
return _regeneratorRuntime.wrap(function (_context6) {
while (1) switch (_context6.prev = _context6.next) {
case 0:
if (_this5.isRunning) {
_context6.next = 1;
break;
}
return _context6.abrupt("return", callback(true));
case 1:
if (!location) {
_context6.next = 4;
break;
}
pathname = location.path || location.pathname;
if (isInit && _this5.basename && !location.basename && _this5.history.location.pathname === pathname) {
if (_this5.parent && _this5.parent.currentRoute) {
url = _this5.parent.currentRoute.url;
if (url && _this5.parent.basename) url = _this5.parent.basename.substr(0, _this5.parent.basename.length - 1) + url;
if (!pathname.startsWith(url)) {
if (location.pathname != null) location.pathname = url;
if (location.path != null) location.path = url;
if (location.query) location.query = _this5.parent.currentRoute.query;
if (!isReadonly(location, 'search')) location.search = _this5.parent.currentRoute.search;
}
}
}
if (!(_this5.pendingRoute && _this5.pendingRoute.fullPath === location.fullPath)) {
_context6.next = 2;
break;
}
return _context6.abrupt("return", callback(!_this5._nexting));
case 2:
if (!(_this5.basename && location.absolute && !pathname.startsWith(_this5.basename))) {
_context6.next = 3;
break;
}
return _context6.abrupt("return", callback(true));
case 3:
location = _this5._transformLocation(location);
case 4:
if (_this5._isMatchBasename(location)) {
_context6.next = 5;
break;
}
return _context6.abrupt("return", callback(true));
case 5:
if (!(!location || !location.pathname && _this5.currentRoute && !_this5.currentRoute.path)) {
_context6.next = 6;
break;
}
return _context6.abrupt("return", callback(true));
case 6:
if (!(!isInit && !location.onInit && (!_this5.viewRoot || !_this5.viewRoot.state.inited))) {
_context6.next = 7;
break;
}
return _context6.abrupt("return", callback(true));
case 7:
nexts = [];
isContinue = true;
_this5._callEvent('onRouteing', ok => {
if (ok === false) isContinue = false;else if (isLocation(ok)) location = ok;else if (isFunction(ok)) nexts.push(ok);
});
_context6.prev = 8;
_t8 = isContinue;
if (!_t8) {
_context6.next = 10;
break;
}
_context6.next = 9;
return _this5._internalHandleRouteInterceptor(location, callback, isInit);
case 9:
_t8 = _context6.sent;
case 10:
return _context6.abrupt("return", _t8);
case 11:
_context6.prev = 11;
_t9 = _context6["catch"](8);
error = _t9;
case 12:
_context6.prev = 12;
nexts.forEach(next => next(Boolean(!isContinue || error), error, {
location,
isInit
}));
return _context6.finish(12);
case 13:
case "end":
return _context6.stop();
}
}, _callee6, null, [[8, 11, 12, 13]]);
})).apply(this, arguments);
}
_normalizeLocation(to, options = {}) {
return normalizeLocation(to, _objectSpread({
basename: this.basename,
mode: this.mode,
queryProps: this.queryProps
}, options));
}
_internalHandleRouteInterceptor(location, callback, isInit = false) {
var isContinue = false;
var interceptorCounter = ++this._interceptorCounter;
try {
var to = this.createRoute(location, {
matchedProvider: hasOwnProp(location, 'basename') && location.basename !== this.basename ? this.currentRoute : null
});
var from = isInit ? null : to.redirectedFrom && to.redirectedFrom.basename === this.basename ? to.redirectedFrom : this.currentRoute;
var current = this.currentRoute;
var checkIsContinue = () => !to.path || this.isRunning && interceptorCounter === this._interceptorCounter && Boolean(this.viewRoot && this.viewRoot._isMounted);
var afterCallback = (isContinue, to, isRouteAbort = true, ok = undefined) => {
if (isContinue) to.onInit && to.onInit(isContinue, to);else if (isRouteAbort) {
this._callEvent('onRouteAbort', to, ok);
to.onAbort && to.onAbort(isContinue, to, ok);
}
this.nextTick(() => {
if (!checkIsContinue()) return;
if (!isInit && (!current || current.fullPath !== to.fullPath)) {
this._routetInterceptors(this._getRouteUpdateGuards(to, current), to, current);
}
});
};
if (!to) return;
var realtimeLocation = this.history.realtimeLocation;
if (from && from.isComplete && (!realtimeLocation || realtimeLocation.pathname === this.history.location.pathname) && to.matchedPath === from.matchedPath) {
isContinue = checkIsContinue();
if (isContinue) {
callback(newIsContinue => {
afterCallback(newIsContinue, to);
}, to);
} else callback(isContinue, to);
return;
}
var fallbackViews = [];
if (hasMatchedRouteLazy(to.matched)) {
this.viewRoot && fallbackViews.push(this.viewRoot);
reverseArray(this._getSameMatched(isInit ? null : this.currentRoute, to)).some(m => {
var keys = Object.keys(m.viewInstances).filter(key => m.viewInstances[key] && m.viewInstances[key].props.fallback);
if (!keys.length) return;
return fallbackViews = keys.map(key => m.viewInstances[key]);
});
}
fallbackViews.forEach(fallbackView => fallbackView._updateResolving(true, to));
this._routetInterceptors(this._getBeforeEachGuards(to, from, current), to, from, ok => {
this._nexting = null;
fallbackViews.length && setTimeout(() => fallbackViews.forEach(fallbackView => fallbackView._updateResolving(false)), 0);
var resolveOptions = {
from: to,
isInit: Boolean(isInit || to.onInit)
};
if (resolveOptions.isInit && this.pendingRoute && to.fullPath !== this.pendingRoute.fullPath) {
ok = this.pendingRoute;
this.pendingRoute = null;
}
// if (isString(ok)) ok = { path: ok };
isContinue = checkIsContinue() && Boolean(ok === undefined || ok && !(ok instanceof Error) && !isLocation(ok));
if (isContinue) {
var toLast = to.matched[to.matched.length - 1];
if (toLast && toLast.config.exact && toLast.redirect) {
ok = resolveRedirect(toLast.redirect, toLast, resolveOptions);
if (ok) isContinue = false;
}
}
if (isContinue && !isLocation(ok)) {
to.matched.filter(mr => mr.abort).some(r => {
var abort = resolveAbort(r.abort, r, resolveOptions);
if (abort) {
ok = isString(abort) ? new Error(abort) : abort === true ? undefined : abort;
isContinue = false;
}
return abort;
});
}
var onNext = newOk => {
isContinue = newOk;
if (isContinue) this._routetInterceptors(this._getBeforeResolveGuards(to, current), to, current);
// callback(isContinue, to);
var okIsLocation = isLocation(ok);
var isRouteAbort = !isContinue && !okIsLocation;
afterCallback(isContinue, to, isRouteAbort, ok);
if (!isContinue) {
if (okIsLocation) {
return this.redirect(ok, isRouteAbort ? undefined : to.onComplete, isRouteAbort ? undefined : to.onAbort, to.onInit || (isInit ? callback : null), to);
}
if (ok instanceof Error) this.errorCallbacks.forEach(cb => cb(ok));
return;
}
this.nextTick(() => {
if (isFunction(ok)) ok = ok(to);
if (to && isFunction(to.onComplete)) to.onComplete(Boolean(ok), to);
this._routetInterceptors(this._getAfterEachGuards(to, current), to, current);
});
};
if (!isContinue) {
try {
onNext(isContinue);
} finally {
callback(isContinue, to);
}
return;
}
return callback(onNext, to);
});
} catch (ex) {
console.error(ex);
if (!isContinue) callback(isContinue, null);
}
}
_go(to, onComplete, onAbort, onInit, replace) {
return new Promise((resolve, reject) => {
function doComplete(res, _to) {
onComplete && onComplete(res, _to);
resolve(res);
}
function doAbort(res, _to) {
onAbort && onAbort(res, _to);
reject(res === false && _to === null ? new Error('to path cannot be empty!') : res);
}
if (!this.isRunning) {
doAbort(new Error('router is not running!'), null);
return;
}
var _to;
try {
_to = this._normalizeLocation(to, {
route: to && to.route || this.currentRoute,
resolvePathCb: (path, to) => {
var newPath = path.replace(/\[([A-z0-9.\-_#@$%^&*():|?<>=+]+)\]/g, (m, name) => {
var ret = this.nameToPath(name, to, {
onComplete: onInit || onComplete,
onAbort
});
if (ret == null) throw new Error(`route name [${name}]not be found!`);
if (ret === true) throw 'cancel';
return ret;
});
return newPath;
}
});
} catch (ex) {
if (ex === 'cancel') return;
throw ex;
}
if (!_to) {
doAbort(false, null);
return;
}
if (isFunction(onComplete)) _to.onComplete = once(doComplete);
if (isFunction(onAbort)) _to.onAbort = once(doAbort);
if (onInit) _to.onInit = onInit;
var holdInitialQueryProps = this.options.holdInitialQueryProps;
if (holdInitialQueryProps) {
var query = this.initialRoute.query;
if (Array.isArray(holdInitialQueryProps)) {
query = holdInitialQueryProps.reduce((p, key) => {
var value = query[key];
if (value === undefined) return p;
p[key] = value;
return p;
}, {});
} else if (isFunction(holdInitialQueryProps)) {
query = holdInitialQueryProps(this.initialRoute.query);
}
copyOwnProperties(_to.query, query);
}
_to.isReplace = Boolean(replace);
if (this._nexting && (!to.pendingIfNotPrepared || this.isPrepared)) {
this._nexting(_to);
return;
}
if (_to.fullPath && isAbsoluteUrl(_to.fullPath) && globalThis !== null && globalThis !== void 0 && globalThis.location) {
if (replace) globalThis.location.replace(_to.fullPath);else globalThis.location.href = _to.fullPath;
return;
}
if (!this.isPrepared && !onInit) {
this.pendingRoute = _to;
var location = this.history.realtimeLocation;
if (_to.fullPath === `${location.pathname}${location.search}`) return;
} else {
this.pendingRoute = null;
}
var isContinue = onInit || this._callEvent('onRouteGo', to, doComplete, doAbort, Boolean(replace));
if (isContinue === false) return;
var history = this.history;
if (_to.absolute && globalThis.location) {
var url = '';
if (this.basename) {
if (this.top && !this.top.basename) {
history = this.top.history;
} else if (!this.isMemoryMode) {
url = history.createHref(_to);
}
} else if (this.isMemoryMode) {
var mode = isString(_to.absolute) ? _to.absolute : '';
if (!mode || mode === HistoryType.memory) {
var guessHistory = getPossibleHistory(this.options);
if (guessHistory) {
if (guessHistory.type === HistoryType.memory) history = guessHistory;else {
mode = guessHistory.type;
url = guessHistory.createHref(_to);
}
} else {
mode = HistoryType.hash;
url = createHashHref(_to, this.options.hashType);
}
warn(`[react-view-router] warning: parent router mode is ${mode || 'unknown'}, it could be '${mode}' mode that to go!`);
} else url = history.createHref(_to);
// if (mode === HistoryType.hash) url = getBaseHref() + (url.startsWith('#') ? '' : '#') + url;
}
if (url) {
if (replace) globalThis.location.replace(url);else globalThis.location.href = url;
return;
}
}
if (_to.backIfVisited && _to.basename === this.basename) {
var historyIndex = this.history.index;
var isMatch = _to.backIfVisited === 'full-matcth' ? (to, s) => to.search === s.search : (to, s) => Object.keys(to.query).every(key => to.query[key] == s.query[key]);
var stack = reverseArray(this.stacks).find(s => {
var stackPath = this.getMatchedPath(s.pathname);
var toPath = _to.path || '';
if (this.basename) toPath = toPath.substr(this.basenameNoSlash.length, toPath.length);
return stackPath === this.getMatchedPath(toPath) && isMatch(to, s) && s.index <= historyIndex;
});
if (stack) {
this.go(stack);
return;
}
}
if (replace) history.replace(_to);else history.push(_to);
});
}
_replace(to, onComplete, onAbort, onInit) {
return this._go(to, onComplete, onAbort, onInit, true);
}
_push(to, onComplete, onAbort, onInit) {
return this._go(to, onComplete, onAbort, onInit);
}
resolveRouteName(fn) {
var _off = () => {
var idx = this.resolveNameFns.indexOf(fn);
if (~idx) this.resolveNameFns.splice(idx, 1);
};
_off();
this.resolveNameFns.push(fn);
return _off;
}
nameToPath(name, options = {}, events = {}) {
name = camelize(name);
var path = this.routeNameMap[name];
if (path == null) {
this.resolveNameFns.some(fn => {
var newPath = fn(name, options, this, events);
if (typeof newPath !== 'string' && newPath !== true) return;
path = newPath;
return true;
});
} else if (options.absolute) {
if (this.basename) path = `${this.basename}${path}`;
}
if (path == null && options.absolute && this.parent) {
path = this.parent.nameToPath(name, options, events);
if (path != null && this.parent.basename) {
path = `${this.parent.basename}${path}`;
}
}
return path;
}
updateRouteMeta(route, newValue, options = {}) {
if (!route || !route.meta) return;
var changed = false;
var oldValue = {};
Object.keys(newValue).forEach(key => {
if (route.meta[key] === newValue[key]) return;
oldValue[key] = route.meta[key];
changed = true;
});
if (!changed) return;
Object.assign(route.meta, newValue);
route.metaComputed = null;
// if (route.config && !options.ignoreConfigRoute) Object.assign(route.config.meta, newValue);
this._callEvent('onRouteMetaChange', newValue, oldValue, route, this);
return changed;
}
createMatchedRoute(route, match) {
var _ref4 = match || {},
url = _ref4.url,
_ref4$path = _ref4.path,
path = _ref4$path === void 0 ? route.path : _ref4$path,
regx = _ref4.regx,
params = _ref4.params;
var subpath = route.subpath,
_route$meta = route.meta,
meta = _route$meta === void 0 ? {} : _route$meta,
redirect = route.redirect,
depth = route.depth;
function guardToGuardInfo(originGuard, instance) {
var guardInfo = {
guard: function matchedRouteGuardWrapper() {
guardInfo.called = true;
return originGuard.apply(this, arguments);
},
instance: instance || originGuard.instance,
called: false
};
copyOwnProperties(guardInfo.guard, originGuard);
return guardInfo;
}
function guardsToMatchedRouteGuards(guards) {
return guards.filter(v => !v.lazy).map(v => guardToGuardInfo(v));
}
var beforeEnter;
var beforeResolve;
var update;
var beforeLeave;
var afterLeave;
var that = this;
var ret = {
url,
path,
subpath,
depth,
regx,
redirect,
params,
componentInstances: {},
viewInstances: {},
guards: {
get beforeEnter() {
if (beforeEnter) return beforeEnter;
beforeEnter = [];
that._getComponentGurads(ret, 'beforeRouteEnter', (fn, name, ci, r) => {
var ret = function beforeRouteEnterWraper(to, from, next) {
return fn(to, from, (cb, ...args) => {
if (isFunction(cb)) {
var _cb = cb;
r.config._pending && (r.config._pending.completeCallbacks[name] = ci => {
var res = _cb(ci);
that._callEvent('onRouteEnterNext', r, ci, res);
return res;
});
cb = undefined;
}
return next(cb, ...args);
}, {
route: r,
router: that
});
};
var guardInfo = guardToGuardInfo(ret, fn.instance);
beforeEnter.push(guardInfo);
return guardInfo.guard;
}, (lazyResovleFn, hook) => {
var guardInfo = {
lazy: true,
guard: lazyResovleFn
};
hook(() => {
var idx = beforeEnter.indexOf(guardInfo);
if (~idx) beforeEnter.splice(idx, 1);
});
return beforeEnter.push(guardInfo);
});
return beforeEnter;
},
get beforeResolve() {
if (beforeResolve) return beforeResolve;
beforeResolve = guardsToMatchedRouteGuards(that._getComponentGurads(ret, 'beforeRouteResolve'));
return beforeResolve;
},
get update() {
if (update) return update;
update = guardsToMatchedRouteGuards(that._getComponentGurads(ret, 'beforeRouteUpdate'));
return update;
},
get beforeLeave() {
if (beforeLeave) return beforeLeave;
beforeLeave = [];
that._getComponentGurads(ret, 'beforeRouteLeave', (fn, name, ci, r) => {
var ret = function beforeRouteLeaveWraper(to, from, next) {
return fn.call(ci, to, from, (cb, ...args) => {
if (isFunction(cb)) {
var _c