UNPKG

react-view-router

Version:
1,231 lines (1,222 loc) 67.1 kB
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