mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-14 08:45:20 +08:00
chore(vue-router): add eslint and prettier (#26636)
This commit is contained in:
@ -17,7 +17,7 @@ runs:
|
||||
path: ./packages/vue
|
||||
filename: VueBuild.zip
|
||||
- name: Install Vue Router Dependencies
|
||||
run: npm install
|
||||
run: npm ci
|
||||
shell: bash
|
||||
working-directory: ./packages/vue-router
|
||||
- name: Sync
|
||||
|
26
packages/vue-router/.eslintrc.js
Normal file
26
packages/vue-router/.eslintrc.js
Normal file
@ -0,0 +1,26 @@
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"@ionic/eslint-config/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": "tsconfig.json",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/prefer-optional-chain": "off",
|
||||
"@typescript-eslint/ban-types": "off"
|
||||
}
|
||||
};
|
4078
packages/vue-router/package-lock.json
generated
4078
packages/vue-router/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,10 @@
|
||||
"description": "Vue Router integration for @ionic/vue",
|
||||
"scripts": {
|
||||
"test.spec": "jest",
|
||||
"lint": "echo add linter",
|
||||
"eslint": "eslint src",
|
||||
"prettier": "prettier \"./src/**/*.{html,ts,tsx,js,jsx}\"",
|
||||
"lint": "npm run eslint && npm run prettier -- --write --cache",
|
||||
"lint.fix": "npm run eslint -- --fix && npm run prettier -- --write --cache",
|
||||
"bundle": "rollup --config rollup.config.js",
|
||||
"build": "npm run clean && npm run compile && npm run bundle",
|
||||
"clean": "rimraf dist",
|
||||
@ -46,10 +49,16 @@
|
||||
"@ionic/vue": "^6.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
"@ionic/prettier-config": "^2.0.0",
|
||||
"@types/jest": "^28.1.1",
|
||||
"@types/node": "^14.10.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||
"@typescript-eslint/parser": "^5.48.2",
|
||||
"eslint": "^7.32.0",
|
||||
"jest": "^28.1.1",
|
||||
"jest-environment-jsdom": "^28.1.1",
|
||||
"prettier": "^2.8.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.32.1",
|
||||
"ts-jest": "^28.0.5",
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { App } from 'vue';
|
||||
import type { App } from "vue";
|
||||
import {
|
||||
createRouter as createVueRouter,
|
||||
createWebHistory as createVueWebHistory,
|
||||
createWebHashHistory as createVueWebHashHistory,
|
||||
createMemoryHistory as createVueMemoryHistory
|
||||
} from 'vue-router';
|
||||
import { createIonRouter } from './router';
|
||||
import { createViewStacks } from './viewStacks';
|
||||
import { IonicVueRouterOptions } from './types';
|
||||
createMemoryHistory as createVueMemoryHistory,
|
||||
} from "vue-router";
|
||||
|
||||
import { createIonRouter } from "./router";
|
||||
import type { IonicVueRouterOptions } from "./types";
|
||||
import { createViewStacks } from "./viewStacks";
|
||||
|
||||
export const createRouter = (opts: IonicVueRouterOptions) => {
|
||||
const routerOptions = { ...opts };
|
||||
@ -19,8 +20,8 @@ export const createRouter = (opts: IonicVueRouterOptions) => {
|
||||
|
||||
const oldInstall = router.install.bind(router);
|
||||
router.install = (app: App) => {
|
||||
app.provide('navManager', ionRouter);
|
||||
app.provide('viewStacks', viewStacks);
|
||||
app.provide("navManager", ionRouter);
|
||||
app.provide("viewStacks", viewStacks);
|
||||
|
||||
oldInstall(app);
|
||||
};
|
||||
@ -29,8 +30,10 @@ export const createRouter = (opts: IonicVueRouterOptions) => {
|
||||
router.isReady = () => oldIsReady();
|
||||
|
||||
return router;
|
||||
}
|
||||
};
|
||||
|
||||
export const createWebHistory = (base?: string) => createVueWebHistory(base);
|
||||
export const createWebHashHistory = (base?: string) => createVueWebHashHistory(base);
|
||||
export const createMemoryHistory = (base?: string) => createVueMemoryHistory(base);
|
||||
export const createWebHashHistory = (base?: string) =>
|
||||
createVueWebHashHistory(base);
|
||||
export const createMemoryHistory = (base?: string) =>
|
||||
createVueMemoryHistory(base);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { RouteInfo } from './types';
|
||||
import type { RouteInfo } from "./types";
|
||||
|
||||
export const createLocationHistory = () => {
|
||||
const locationHistory: RouteInfo[] = [];
|
||||
@ -14,20 +14,22 @@ export const createLocationHistory = () => {
|
||||
break;
|
||||
}
|
||||
|
||||
if (routeInfo.routerDirection === 'root') {
|
||||
if (routeInfo.routerDirection === "root") {
|
||||
clearHistory();
|
||||
addRoute(routeInfo);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const update = (routeInfo: RouteInfo) => {
|
||||
const locationIndex = locationHistory.findIndex(x => x.id === routeInfo.id);
|
||||
const locationIndex = locationHistory.findIndex(
|
||||
(x) => x.id === routeInfo.id
|
||||
);
|
||||
if (locationIndex > -1) {
|
||||
locationHistory.splice(locationIndex, 1, routeInfo);
|
||||
}
|
||||
const tabArray = tabsHistory[routeInfo.tab || ''];
|
||||
const tabArray = tabsHistory[routeInfo.tab || ""];
|
||||
if (tabArray) {
|
||||
const tabIndex = tabArray.findIndex(x => x.id === routeInfo.id);
|
||||
const tabIndex = tabArray.findIndex((x) => x.id === routeInfo.id);
|
||||
if (tabIndex > -1) {
|
||||
tabArray.splice(tabIndex, 1, routeInfo);
|
||||
} else {
|
||||
@ -36,7 +38,7 @@ export const createLocationHistory = () => {
|
||||
} else if (routeInfo.tab) {
|
||||
tabsHistory[routeInfo.tab] = [routeInfo];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const pop = (routeInfo: RouteInfo) => {
|
||||
const tabHistory = getTabsHistory(routeInfo.tab);
|
||||
@ -61,19 +63,22 @@ export const createLocationHistory = () => {
|
||||
// Replace with updated route
|
||||
locationHistory.pop();
|
||||
locationHistory.push(routeInfo);
|
||||
}
|
||||
};
|
||||
|
||||
const addRoute = (routeInfo: RouteInfo) => {
|
||||
const tabHistory = getTabsHistory(routeInfo.tab);
|
||||
if (tabHistory) {
|
||||
// If the latest routeInfo is the same (going back and forth between tabs), replace it
|
||||
if (tabHistory[tabHistory.length - 1] && tabHistory[tabHistory.length - 1].id === routeInfo.id) {
|
||||
if (
|
||||
tabHistory[tabHistory.length - 1] &&
|
||||
tabHistory[tabHistory.length - 1].id === routeInfo.id
|
||||
) {
|
||||
tabHistory.pop();
|
||||
}
|
||||
tabHistory.push(routeInfo);
|
||||
}
|
||||
locationHistory.push(routeInfo);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Wipes the location history arrays.
|
||||
@ -90,17 +95,21 @@ export const createLocationHistory = () => {
|
||||
* then there will not be any route index in
|
||||
* tabs either.
|
||||
*/
|
||||
const existingRouteIndex = locationHistory.findIndex(r => r.position === position);
|
||||
const existingRouteIndex = locationHistory.findIndex(
|
||||
(r) => r.position === position
|
||||
);
|
||||
if (existingRouteIndex === -1) return;
|
||||
|
||||
locationHistory.splice(existingRouteIndex);
|
||||
|
||||
const clearTabHistory = (tab: string) => {
|
||||
const existingTabRouteIndex = tabsHistory[tab].findIndex(r => r.position === position);
|
||||
const existingTabRouteIndex = tabsHistory[tab].findIndex(
|
||||
(r) => r.position === position
|
||||
);
|
||||
if (existingTabRouteIndex === -1) return;
|
||||
|
||||
tabsHistory[tab].splice(existingTabRouteIndex);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* We also need to search the current tab
|
||||
@ -112,19 +121,19 @@ export const createLocationHistory = () => {
|
||||
const tabHistory = tabsHistory[tab];
|
||||
if (tab && tabHistory) {
|
||||
clearTabHistory(tab);
|
||||
/**
|
||||
* If we are not clearing items after
|
||||
* a tabs page, it is still possible
|
||||
* that there are future tabs pages to clear.
|
||||
* As a result, we need to search through
|
||||
* all the tab stacks and remove views that appear
|
||||
* after the given routeInfo.
|
||||
*
|
||||
* Example: /non-tabs-page --> /tabs/tab1 --> /non-tabs-page
|
||||
* (via router.go(-1)) --> /tabs/tab2. The /tabs/tab1 history
|
||||
* has been overwritten with /tabs/tab2. As a result,
|
||||
* the /tabs/tab1 route info in the Tab 1 stack should be removed.
|
||||
*/
|
||||
/**
|
||||
* If we are not clearing items after
|
||||
* a tabs page, it is still possible
|
||||
* that there are future tabs pages to clear.
|
||||
* As a result, we need to search through
|
||||
* all the tab stacks and remove views that appear
|
||||
* after the given routeInfo.
|
||||
*
|
||||
* Example: /non-tabs-page --> /tabs/tab1 --> /non-tabs-page
|
||||
* (via router.go(-1)) --> /tabs/tab2. The /tabs/tab1 history
|
||||
* has been overwritten with /tabs/tab2. As a result,
|
||||
* the /tabs/tab1 route info in the Tab 1 stack should be removed.
|
||||
*/
|
||||
} else {
|
||||
for (const tab in tabsHistory) {
|
||||
clearTabHistory(tab);
|
||||
@ -137,7 +146,7 @@ export const createLocationHistory = () => {
|
||||
|
||||
locationHistory.length = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
const getTabsHistory = (tab: string): RouteInfo[] => {
|
||||
let history;
|
||||
if (tab) {
|
||||
@ -148,7 +157,7 @@ export const createLocationHistory = () => {
|
||||
}
|
||||
|
||||
return history;
|
||||
}
|
||||
};
|
||||
|
||||
const size = () => locationHistory.length;
|
||||
|
||||
@ -166,7 +175,7 @@ export const createLocationHistory = () => {
|
||||
*/
|
||||
const index = currentHistory - initialHistory;
|
||||
return locationHistory[index] || last();
|
||||
}
|
||||
};
|
||||
const last = () => locationHistory[locationHistory.length - 1];
|
||||
|
||||
/**
|
||||
@ -177,9 +186,13 @@ export const createLocationHistory = () => {
|
||||
* the length of locationHistory, but that only worked since we were pruning
|
||||
* the array.
|
||||
*/
|
||||
const canGoBack = (deep: number = 1, initialHistory: number, currentHistory: number) => {
|
||||
const canGoBack = (
|
||||
deep = 1,
|
||||
initialHistory: number,
|
||||
currentHistory: number
|
||||
) => {
|
||||
return currentHistory - deep >= initialHistory;
|
||||
}
|
||||
};
|
||||
|
||||
const getFirstRouteInfoForTab = (tab: string): RouteInfo | undefined => {
|
||||
const tabHistory = getTabsHistory(tab);
|
||||
@ -187,7 +200,7 @@ export const createLocationHistory = () => {
|
||||
return tabHistory[0];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const getCurrentRouteInfoForTab = (tab: string): RouteInfo | undefined => {
|
||||
const tabHistory = getTabsHistory(tab);
|
||||
@ -195,7 +208,7 @@ export const createLocationHistory = () => {
|
||||
return tabHistory[tabHistory.length - 1];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds and returns the previous view based upon
|
||||
@ -207,7 +220,10 @@ export const createLocationHistory = () => {
|
||||
* do not modify the locationHistory stack so we would
|
||||
* not update pushedByRoute anyways.
|
||||
*/
|
||||
const findLastLocation = (routeInfo: RouteInfo, delta: number = -1): RouteInfo | undefined => {
|
||||
const findLastLocation = (
|
||||
routeInfo: RouteInfo,
|
||||
delta = -1
|
||||
): RouteInfo | undefined => {
|
||||
const routeInfos = getTabsHistory(routeInfo.tab);
|
||||
if (routeInfos) {
|
||||
if (delta < -1) {
|
||||
@ -236,7 +252,7 @@ export const createLocationHistory = () => {
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
current,
|
||||
@ -248,6 +264,6 @@ export const createLocationHistory = () => {
|
||||
getFirstRouteInfoForTab,
|
||||
getCurrentRouteInfoForTab,
|
||||
findLastLocation,
|
||||
clearHistory
|
||||
}
|
||||
}
|
||||
clearHistory,
|
||||
};
|
||||
};
|
||||
|
@ -1,27 +1,35 @@
|
||||
import {
|
||||
parseQuery,
|
||||
import type { AnimationBuilder } from "@ionic/vue";
|
||||
import type {
|
||||
Router,
|
||||
RouteLocationNormalized,
|
||||
NavigationFailure,
|
||||
RouteLocationRaw
|
||||
} from 'vue-router';
|
||||
import { createLocationHistory } from './locationHistory';
|
||||
import { generateId } from './utils';
|
||||
import {
|
||||
RouteLocationRaw,
|
||||
} from "vue-router";
|
||||
import { parseQuery } from "vue-router";
|
||||
|
||||
import { createLocationHistory } from "./locationHistory";
|
||||
import type {
|
||||
ExternalNavigationOptions,
|
||||
RouteInfo,
|
||||
RouteParams,
|
||||
RouteAction,
|
||||
RouteDirection,
|
||||
IonicVueRouterOptions,
|
||||
NavigationInformation
|
||||
} from './types';
|
||||
import { AnimationBuilder } from '@ionic/vue';
|
||||
NavigationInformation,
|
||||
} from "./types";
|
||||
import { generateId } from "./utils";
|
||||
|
||||
// TODO(FW-2969): types
|
||||
|
||||
export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) => {
|
||||
let currentNavigationInfo: NavigationInformation = { direction: undefined, action: undefined, delta: undefined };
|
||||
export const createIonRouter = (
|
||||
opts: IonicVueRouterOptions,
|
||||
router: Router
|
||||
) => {
|
||||
let currentNavigationInfo: NavigationInformation = {
|
||||
direction: undefined,
|
||||
action: undefined,
|
||||
delta: undefined,
|
||||
};
|
||||
|
||||
/**
|
||||
* Ionic Vue should only react to navigation
|
||||
@ -32,27 +40,37 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* which is fired once navigation is confirmed
|
||||
* and any user guards have run.
|
||||
*/
|
||||
router.afterEach((to: RouteLocationNormalized, _: RouteLocationNormalized, failure?: NavigationFailure) => {
|
||||
if (failure) return;
|
||||
router.afterEach(
|
||||
(
|
||||
to: RouteLocationNormalized,
|
||||
_: RouteLocationNormalized,
|
||||
failure?: NavigationFailure
|
||||
) => {
|
||||
if (failure) return;
|
||||
|
||||
const { direction, action, delta } = currentNavigationInfo;
|
||||
const { direction, action, delta } = currentNavigationInfo;
|
||||
|
||||
/**
|
||||
* When calling router.replace, we are not informed
|
||||
* about the replace action in opts.history.listen
|
||||
* but we can check to see if the latest routing action
|
||||
* was a replace action by looking at the history state.
|
||||
* We need to use opts.history rather than window.history
|
||||
* because window.history will be undefined when using SSR.
|
||||
*/
|
||||
/**
|
||||
* When calling router.replace, we are not informed
|
||||
* about the replace action in opts.history.listen
|
||||
* but we can check to see if the latest routing action
|
||||
* was a replace action by looking at the history state.
|
||||
* We need to use opts.history rather than window.history
|
||||
* because window.history will be undefined when using SSR.
|
||||
*/
|
||||
|
||||
currentHistoryPosition = opts.history.state.position as number;
|
||||
currentHistoryPosition = opts.history.state.position as number;
|
||||
|
||||
const replaceAction = opts.history.state.replaced ? 'replace' : undefined;
|
||||
handleHistoryChange(to, action || replaceAction, direction, delta);
|
||||
const replaceAction = opts.history.state.replaced ? "replace" : undefined;
|
||||
handleHistoryChange(to, action || replaceAction, direction, delta);
|
||||
|
||||
currentNavigationInfo = { direction: undefined, action: undefined, delta: undefined };
|
||||
});
|
||||
currentNavigationInfo = {
|
||||
direction: undefined,
|
||||
action: undefined,
|
||||
delta: undefined,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
const locationHistory = createLocationHistory();
|
||||
|
||||
@ -68,15 +86,15 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
let currentRouteInfo: RouteInfo;
|
||||
let incomingRouteParams: RouteParams;
|
||||
|
||||
let historyChangeListeners: any[] = [];
|
||||
const historyChangeListeners: any[] = [];
|
||||
|
||||
if (typeof (document as any) !== 'undefined') {
|
||||
document.addEventListener('ionBackButton', (ev: Event) => {
|
||||
if (typeof (document as any) !== "undefined") {
|
||||
document.addEventListener("ionBackButton", (ev: Event) => {
|
||||
(ev as any).detail.register(0, (processNextHandler: () => void) => {
|
||||
opts.history.go(-1);
|
||||
processNextHandler();
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
opts.history.listen((_: any, _x: any, info: any) => {
|
||||
@ -99,38 +117,46 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* are considered "pop" actions, but when going forward
|
||||
* we want to make sure the forward animation is used.
|
||||
*/
|
||||
action: (info.type === 'pop' && info.delta >= 1) ? 'push' : info.type,
|
||||
direction: info.direction === '' ? 'forward' : info.direction
|
||||
action: info.type === "pop" && info.delta >= 1 ? "push" : info.type,
|
||||
direction: info.direction === "" ? "forward" : info.direction,
|
||||
};
|
||||
});
|
||||
|
||||
const handleNavigateBack = (defaultHref?: string, routerAnimation?: AnimationBuilder) => {
|
||||
const routeInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition);
|
||||
const handleNavigateBack = (
|
||||
defaultHref?: string,
|
||||
routerAnimation?: AnimationBuilder
|
||||
) => {
|
||||
const routeInfo = locationHistory.current(
|
||||
initialHistoryPosition,
|
||||
currentHistoryPosition
|
||||
);
|
||||
if (routeInfo && routeInfo.pushedByRoute) {
|
||||
const prevInfo = locationHistory.findLastLocation(routeInfo);
|
||||
if (prevInfo) {
|
||||
incomingRouteParams = { ...prevInfo, routerAction: 'pop', routerDirection: 'back', routerAnimation: routerAnimation || routeInfo.routerAnimation };
|
||||
incomingRouteParams = {
|
||||
...prevInfo,
|
||||
routerAction: "pop",
|
||||
routerDirection: "back",
|
||||
routerAnimation: routerAnimation || routeInfo.routerAnimation,
|
||||
};
|
||||
if (
|
||||
routeInfo.lastPathname === routeInfo.pushedByRoute ||
|
||||
(
|
||||
/**
|
||||
* We need to exclude tab switches/tab
|
||||
* context changes here because tabbed
|
||||
* navigation is not linear, but router.back()
|
||||
* will go back in a linear fashion.
|
||||
*/
|
||||
prevInfo.pathname === routeInfo.pushedByRoute &&
|
||||
|
||||
/**
|
||||
* We need to exclude tab switches/tab
|
||||
* context changes here because tabbed
|
||||
* navigation is not linear, but router.back()
|
||||
* will go back in a linear fashion.
|
||||
*/
|
||||
(prevInfo.pathname === routeInfo.pushedByRoute &&
|
||||
/**
|
||||
* Tab info can be undefined or '' (empty string)
|
||||
* both are false-y values, so we can just use !.
|
||||
*/
|
||||
!routeInfo.tab && !prevInfo.tab
|
||||
)
|
||||
!routeInfo.tab &&
|
||||
!prevInfo.tab)
|
||||
) {
|
||||
router.back();
|
||||
} else {
|
||||
|
||||
/**
|
||||
* When going back to a child page of a tab
|
||||
* after being on another tab, we need to use
|
||||
@ -160,22 +186,28 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
router.go(prevInfo.position - routeInfo.position);
|
||||
}
|
||||
} else {
|
||||
handleNavigate(defaultHref, 'pop', 'back');
|
||||
handleNavigate(defaultHref, "pop", "back");
|
||||
}
|
||||
} else {
|
||||
handleNavigate(defaultHref, 'pop', 'back');
|
||||
handleNavigate(defaultHref, "pop", "back");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleNavigate = (path: RouteLocationRaw, routerAction?: RouteAction, routerDirection?: RouteDirection, routerAnimation?: AnimationBuilder, tab?: string) => {
|
||||
const handleNavigate = (
|
||||
path: RouteLocationRaw,
|
||||
routerAction?: RouteAction,
|
||||
routerDirection?: RouteDirection,
|
||||
routerAnimation?: AnimationBuilder,
|
||||
tab?: string
|
||||
) => {
|
||||
setIncomingRouteParams(routerAction, routerDirection, routerAnimation, tab);
|
||||
|
||||
if (routerAction === 'push') {
|
||||
if (routerAction === "push") {
|
||||
router.push(path);
|
||||
} else {
|
||||
router.replace(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO RouteLocationNormalized
|
||||
const handleHistoryChange = (
|
||||
@ -186,17 +218,22 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
) => {
|
||||
let leavingLocationInfo: RouteInfo;
|
||||
if (incomingRouteParams) {
|
||||
|
||||
/**
|
||||
* If we are replacing the state of a route
|
||||
* with another route, the "leaving" route
|
||||
* is at the same position in location history
|
||||
* as where the replaced route will exist.
|
||||
*/
|
||||
if (incomingRouteParams.routerAction === 'replace') {
|
||||
leavingLocationInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition);
|
||||
} else if (incomingRouteParams.routerAction === 'pop') {
|
||||
leavingLocationInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition + 1);
|
||||
if (incomingRouteParams.routerAction === "replace") {
|
||||
leavingLocationInfo = locationHistory.current(
|
||||
initialHistoryPosition,
|
||||
currentHistoryPosition
|
||||
);
|
||||
} else if (incomingRouteParams.routerAction === "pop") {
|
||||
leavingLocationInfo = locationHistory.current(
|
||||
initialHistoryPosition,
|
||||
currentHistoryPosition + 1
|
||||
);
|
||||
|
||||
/**
|
||||
* If the Ionic Router action was "pop"
|
||||
@ -233,7 +270,7 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* the past history and you can no longer go
|
||||
* forward to /page2 or /page3.
|
||||
*/
|
||||
if (action === 'replace') {
|
||||
if (action === "replace") {
|
||||
locationHistory.clearHistory();
|
||||
}
|
||||
} else {
|
||||
@ -249,8 +286,14 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* so we can grab the previous item in history relative
|
||||
* to where the history state currently is.
|
||||
*/
|
||||
const position = (incomingRouteParams.routerDirection === 'root') ? currentHistoryPosition : currentHistoryPosition - 1;
|
||||
leavingLocationInfo = locationHistory.current(initialHistoryPosition, position);
|
||||
const position =
|
||||
incomingRouteParams.routerDirection === "root"
|
||||
? currentHistoryPosition
|
||||
: currentHistoryPosition - 1;
|
||||
leavingLocationInfo = locationHistory.current(
|
||||
initialHistoryPosition,
|
||||
position
|
||||
);
|
||||
}
|
||||
} else {
|
||||
leavingLocationInfo = currentRouteInfo;
|
||||
@ -258,42 +301,49 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
|
||||
if (!leavingLocationInfo) {
|
||||
leavingLocationInfo = {
|
||||
pathname: '',
|
||||
search: ''
|
||||
}
|
||||
pathname: "",
|
||||
search: "",
|
||||
};
|
||||
}
|
||||
|
||||
const leavingUrl = leavingLocationInfo.pathname + leavingLocationInfo.search;
|
||||
const leavingUrl =
|
||||
leavingLocationInfo.pathname + leavingLocationInfo.search;
|
||||
if (leavingUrl !== location.fullPath) {
|
||||
if (!incomingRouteParams) {
|
||||
if (action === 'replace') {
|
||||
if (action === "replace") {
|
||||
incomingRouteParams = {
|
||||
routerAction: 'replace',
|
||||
routerDirection: 'none'
|
||||
}
|
||||
} else if (action === 'pop') {
|
||||
const routeInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition - delta);
|
||||
routerAction: "replace",
|
||||
routerDirection: "none",
|
||||
};
|
||||
} else if (action === "pop") {
|
||||
const routeInfo = locationHistory.current(
|
||||
initialHistoryPosition,
|
||||
currentHistoryPosition - delta
|
||||
);
|
||||
|
||||
if (routeInfo && routeInfo.pushedByRoute) {
|
||||
const prevRouteInfo = locationHistory.findLastLocation(routeInfo, delta);
|
||||
const prevRouteInfo = locationHistory.findLastLocation(
|
||||
routeInfo,
|
||||
delta
|
||||
);
|
||||
incomingRouteParams = {
|
||||
...prevRouteInfo,
|
||||
routerAction: 'pop',
|
||||
routerDirection: 'back'
|
||||
routerAction: "pop",
|
||||
routerDirection: "back",
|
||||
};
|
||||
} else {
|
||||
incomingRouteParams = {
|
||||
routerAction: 'pop',
|
||||
routerDirection: 'none'
|
||||
}
|
||||
routerAction: "pop",
|
||||
routerDirection: "none",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!incomingRouteParams) {
|
||||
incomingRouteParams = {
|
||||
routerAction: 'push',
|
||||
routerDirection: direction || 'forward'
|
||||
}
|
||||
routerAction: "push",
|
||||
routerDirection: direction || "forward",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,31 +351,39 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
if (incomingRouteParams?.id) {
|
||||
routeInfo = {
|
||||
...incomingRouteParams,
|
||||
lastPathname: leavingLocationInfo.pathname
|
||||
}
|
||||
|
||||
lastPathname: leavingLocationInfo.pathname,
|
||||
};
|
||||
} else {
|
||||
const isPushed = incomingRouteParams.routerAction === 'push' && incomingRouteParams.routerDirection === 'forward';
|
||||
const isPushed =
|
||||
incomingRouteParams.routerAction === "push" &&
|
||||
incomingRouteParams.routerDirection === "forward";
|
||||
routeInfo = {
|
||||
id: generateId('routeInfo'),
|
||||
id: generateId("routeInfo"),
|
||||
...incomingRouteParams,
|
||||
lastPathname: leavingLocationInfo.pathname,
|
||||
pathname: location.path,
|
||||
search: location.fullPath && location.fullPath.split('?')[1] || '',
|
||||
search: (location.fullPath && location.fullPath.split("?")[1]) || "",
|
||||
params: location.params && location.params,
|
||||
prevRouteLastPathname: leavingLocationInfo.lastPathname
|
||||
}
|
||||
prevRouteLastPathname: leavingLocationInfo.lastPathname,
|
||||
};
|
||||
|
||||
if (isPushed) {
|
||||
routeInfo.pushedByRoute = (leavingLocationInfo.pathname !== '') ? leavingLocationInfo.pathname : undefined;
|
||||
} else if (routeInfo.routerAction === 'pop') {
|
||||
routeInfo.pushedByRoute =
|
||||
leavingLocationInfo.pathname !== ""
|
||||
? leavingLocationInfo.pathname
|
||||
: undefined;
|
||||
} else if (routeInfo.routerAction === "pop") {
|
||||
const route = locationHistory.findLastLocation(routeInfo);
|
||||
routeInfo.pushedByRoute = route?.pushedByRoute;
|
||||
} else if (routeInfo.routerAction === 'push' && routeInfo.tab !== leavingLocationInfo.tab) {
|
||||
const lastRoute = locationHistory.getCurrentRouteInfoForTab(routeInfo.tab);
|
||||
} else if (
|
||||
routeInfo.routerAction === "push" &&
|
||||
routeInfo.tab !== leavingLocationInfo.tab
|
||||
) {
|
||||
const lastRoute = locationHistory.getCurrentRouteInfoForTab(
|
||||
routeInfo.tab
|
||||
);
|
||||
routeInfo.pushedByRoute = lastRoute?.pushedByRoute;
|
||||
} else if (routeInfo.routerAction === 'replace') {
|
||||
|
||||
} else if (routeInfo.routerAction === "replace") {
|
||||
/**
|
||||
* When replacing a route, we want to make sure we select the current route
|
||||
* that we are on, not the last route in the stack. The last route in the stack
|
||||
@ -337,7 +395,10 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* be replaced with /page3 even though /page2 is the last
|
||||
* item in the stack/
|
||||
*/
|
||||
const currentRouteInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition);
|
||||
const currentRouteInfo = locationHistory.current(
|
||||
initialHistoryPosition,
|
||||
currentHistoryPosition
|
||||
);
|
||||
|
||||
/**
|
||||
* If going from /home to /child, then replacing from
|
||||
@ -345,15 +406,21 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* say that /home was pushed by /home which is not correct.
|
||||
*/
|
||||
const currentPushedBy = currentRouteInfo?.pushedByRoute;
|
||||
const pushedByRoute = (currentPushedBy !== undefined && currentPushedBy !== routeInfo.pathname) ? currentPushedBy : routeInfo.pushedByRoute;
|
||||
const pushedByRoute =
|
||||
currentPushedBy !== undefined &&
|
||||
currentPushedBy !== routeInfo.pathname
|
||||
? currentPushedBy
|
||||
: routeInfo.pushedByRoute;
|
||||
|
||||
routeInfo.lastPathname = currentRouteInfo?.pathname || routeInfo.lastPathname;
|
||||
routeInfo.lastPathname =
|
||||
currentRouteInfo?.pathname || routeInfo.lastPathname;
|
||||
routeInfo.pushedByRoute = pushedByRoute;
|
||||
routeInfo.routerDirection = currentRouteInfo?.routerDirection || routeInfo.routerDirection;
|
||||
routeInfo.routerAnimation = currentRouteInfo?.routerAnimation || routeInfo.routerAnimation;
|
||||
routeInfo.routerDirection =
|
||||
currentRouteInfo?.routerDirection || routeInfo.routerDirection;
|
||||
routeInfo.routerAnimation =
|
||||
currentRouteInfo?.routerAnimation || routeInfo.routerAnimation;
|
||||
routeInfo.prevRouteLastPathname = currentRouteInfo?.lastPathname;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
routeInfo.position = currentHistoryPosition;
|
||||
@ -379,7 +446,8 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* we want to make sure we exclude that
|
||||
* action by ensuring historySize > 0.
|
||||
*/
|
||||
const isReplacing = historySize === historyDiff && historySize > 0 && action === 'replace';
|
||||
const isReplacing =
|
||||
historySize === historyDiff && historySize > 0 && action === "replace";
|
||||
if (historySize > historyDiff || isReplacing) {
|
||||
/**
|
||||
* When navigating back through the history,
|
||||
@ -400,7 +468,8 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
*/
|
||||
|
||||
if (
|
||||
(routeInfo.routerAction === 'push' || routeInfo.routerAction === 'replace') &&
|
||||
(routeInfo.routerAction === "push" ||
|
||||
routeInfo.routerAction === "replace") &&
|
||||
delta === undefined
|
||||
) {
|
||||
locationHistory.clearHistory(routeInfo);
|
||||
@ -422,20 +491,25 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
currentRouteInfo = routeInfo;
|
||||
}
|
||||
incomingRouteParams = undefined;
|
||||
historyChangeListeners.forEach(cb => cb(currentRouteInfo));
|
||||
}
|
||||
historyChangeListeners.forEach((cb) => cb(currentRouteInfo));
|
||||
};
|
||||
|
||||
const getCurrentRouteInfo = () => currentRouteInfo;
|
||||
|
||||
const canGoBack = (deep: number = 1) => locationHistory.canGoBack(deep, initialHistoryPosition, currentHistoryPosition);
|
||||
const canGoBack = (deep = 1) =>
|
||||
locationHistory.canGoBack(
|
||||
deep,
|
||||
initialHistoryPosition,
|
||||
currentHistoryPosition
|
||||
);
|
||||
|
||||
const navigate = (navigationOptions: ExternalNavigationOptions) => {
|
||||
const { routerAnimation, routerDirection, routerLink } = navigationOptions;
|
||||
|
||||
setIncomingRouteParams('push', routerDirection, routerAnimation);
|
||||
setIncomingRouteParams("push", routerDirection, routerAnimation);
|
||||
|
||||
router.push(routerLink);
|
||||
}
|
||||
};
|
||||
|
||||
const resetTab = (tab: string) => {
|
||||
/**
|
||||
@ -454,21 +528,21 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
if (routeInfo) {
|
||||
router.go(routeInfo.position - currentHistoryPosition);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const changeTab = (tab: string, path?: string) => {
|
||||
if (!path) return;
|
||||
|
||||
const routeInfo = locationHistory.getCurrentRouteInfoForTab(tab);
|
||||
const [pathname] = path.split('?');
|
||||
const [pathname] = path.split("?");
|
||||
|
||||
if (routeInfo) {
|
||||
incomingRouteParams = {
|
||||
...incomingRouteParams,
|
||||
routerAction: 'push',
|
||||
routerDirection: 'none',
|
||||
tab
|
||||
}
|
||||
routerAction: "push",
|
||||
routerDirection: "none",
|
||||
tab,
|
||||
};
|
||||
|
||||
/**
|
||||
* When going back to a tab
|
||||
@ -478,15 +552,17 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* tab you are on.
|
||||
*/
|
||||
if (routeInfo.pathname === pathname) {
|
||||
router.push({ path: routeInfo.pathname, query: parseQuery(routeInfo.search) });
|
||||
router.push({
|
||||
path: routeInfo.pathname,
|
||||
query: parseQuery(routeInfo.search),
|
||||
});
|
||||
} else {
|
||||
router.push({ path: pathname, query: parseQuery(routeInfo.search) });
|
||||
}
|
||||
} else {
|
||||
handleNavigate(pathname, "push", "none", undefined, tab);
|
||||
}
|
||||
else {
|
||||
handleNavigate(pathname, 'push', 'none', undefined, tab);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This method is invoked by the IonTabs component
|
||||
@ -506,7 +582,12 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* in the locationHistory stack. As a result,
|
||||
* we cannot use locationHistory.last() here.
|
||||
*/
|
||||
const ri = { ...locationHistory.current(initialHistoryPosition, currentHistoryPosition) };
|
||||
const ri = {
|
||||
...locationHistory.current(
|
||||
initialHistoryPosition,
|
||||
currentHistoryPosition
|
||||
),
|
||||
};
|
||||
|
||||
/**
|
||||
* handleHistoryChange is tabs-agnostic by design.
|
||||
@ -559,34 +640,42 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
ri.pushedByRoute = undefined;
|
||||
locationHistory.update(ri);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const registerHistoryChangeListener = (cb: any) => {
|
||||
historyChangeListeners.push(cb);
|
||||
}
|
||||
};
|
||||
|
||||
const setIncomingRouteParams = (routerAction: RouteAction = 'push', routerDirection: RouteDirection = 'forward', routerAnimation?: AnimationBuilder, tab?: string) => {
|
||||
const setIncomingRouteParams = (
|
||||
routerAction: RouteAction = "push",
|
||||
routerDirection: RouteDirection = "forward",
|
||||
routerAnimation?: AnimationBuilder,
|
||||
tab?: string
|
||||
) => {
|
||||
incomingRouteParams = {
|
||||
routerAction,
|
||||
routerDirection,
|
||||
routerAnimation,
|
||||
tab
|
||||
tab,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const goBack = (routerAnimation?: AnimationBuilder) => {
|
||||
setIncomingRouteParams('pop', 'back', routerAnimation);
|
||||
router.back()
|
||||
setIncomingRouteParams("pop", "back", routerAnimation);
|
||||
router.back();
|
||||
};
|
||||
|
||||
const goForward = (routerAnimation?: AnimationBuilder) => {
|
||||
setIncomingRouteParams('push', 'forward', routerAnimation);
|
||||
setIncomingRouteParams("push", "forward", routerAnimation);
|
||||
router.forward();
|
||||
}
|
||||
};
|
||||
|
||||
const getLeavingRouteInfo = () => {
|
||||
return locationHistory.current(initialHistoryPosition, currentHistoryPosition);
|
||||
}
|
||||
return locationHistory.current(
|
||||
initialHistoryPosition,
|
||||
currentHistoryPosition
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
handleNavigate,
|
||||
@ -600,6 +689,6 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
changeTab,
|
||||
registerHistoryChangeListener,
|
||||
goBack,
|
||||
goForward
|
||||
}
|
||||
}
|
||||
goForward,
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { AnimationBuilder } from '@ionic/vue';
|
||||
import { RouteLocationMatched, RouterOptions } from 'vue-router';
|
||||
import { Ref } from 'vue';
|
||||
import type { AnimationBuilder } from "@ionic/vue";
|
||||
import type { Ref } from "vue";
|
||||
import type { RouteLocationMatched, RouterOptions } from "vue-router";
|
||||
|
||||
// TODO(FW-2969): types
|
||||
|
||||
@ -56,8 +56,8 @@ export interface RouteParams {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export type RouteAction = 'push' | 'pop' | 'replace';
|
||||
export type RouteDirection = 'forward' | 'back' | 'root' | 'none';
|
||||
export type RouteAction = "push" | "pop" | "replace";
|
||||
export type RouteDirection = "forward" | "back" | "root" | "none";
|
||||
|
||||
export interface ViewItem {
|
||||
id: string;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const ids: { [k: string]: number } = { main: 0 };
|
||||
|
||||
export const generateId = (type = 'main') => {
|
||||
export const generateId = (type = "main") => {
|
||||
const id = (ids[type] ?? 0) + 1;
|
||||
ids[type] = id;
|
||||
return (id).toString();
|
||||
return id.toString();
|
||||
};
|
||||
|
@ -1,13 +1,11 @@
|
||||
import { generateId } from './utils';
|
||||
import { RouteInfo,
|
||||
ViewItem,
|
||||
ViewStacks,
|
||||
} from './types';
|
||||
import { RouteLocationMatched, Router } from 'vue-router';
|
||||
import { shallowRef } from 'vue';
|
||||
import { shallowRef } from "vue";
|
||||
import type { RouteLocationMatched, Router } from "vue-router";
|
||||
|
||||
import type { RouteInfo, ViewItem, ViewStacks } from "./types";
|
||||
import { generateId } from "./utils";
|
||||
|
||||
export const createViewStacks = (router: Router) => {
|
||||
let viewStacks: ViewStacks = {};
|
||||
const viewStacks: ViewStacks = {};
|
||||
|
||||
/**
|
||||
* Returns the number of active stacks.
|
||||
@ -20,11 +18,11 @@ export const createViewStacks = (router: Router) => {
|
||||
|
||||
const clear = (outletId: number) => {
|
||||
delete viewStacks[outletId];
|
||||
}
|
||||
};
|
||||
|
||||
const getViewStack = (outletId: number) => {
|
||||
return viewStacks[outletId];
|
||||
}
|
||||
};
|
||||
|
||||
const registerIonPage = (viewItem: ViewItem, ionPage: HTMLElement) => {
|
||||
viewItem.ionPageElement = ionPage;
|
||||
@ -36,45 +34,57 @@ export const createViewStacks = (router: Router) => {
|
||||
* and will not run route guards that
|
||||
* are written in the component.
|
||||
*/
|
||||
viewItem.matchedRoute.instances = { default: viewItem.vueComponentRef.value };
|
||||
}
|
||||
viewItem.matchedRoute.instances = {
|
||||
default: viewItem.vueComponentRef.value,
|
||||
};
|
||||
};
|
||||
|
||||
const findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number) => {
|
||||
return findViewItemByPath(routeInfo.pathname, outletId, false);
|
||||
}
|
||||
};
|
||||
|
||||
const findLeavingViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, mustBeIonRoute: boolean = true) => {
|
||||
const findLeavingViewItemByRouteInfo = (
|
||||
routeInfo: RouteInfo,
|
||||
outletId?: number,
|
||||
mustBeIonRoute = true
|
||||
) => {
|
||||
return findViewItemByPath(routeInfo.lastPathname, outletId, mustBeIonRoute);
|
||||
}
|
||||
};
|
||||
|
||||
const findViewItemByPathname = (pathname: string, outletId?: number) => {
|
||||
return findViewItemByPath(pathname, outletId, false);
|
||||
}
|
||||
};
|
||||
|
||||
const findViewItemInStack = (path: string, stack: ViewItem[]): ViewItem | undefined => {
|
||||
const findViewItemInStack = (
|
||||
path: string,
|
||||
stack: ViewItem[]
|
||||
): ViewItem | undefined => {
|
||||
return stack.find((viewItem: ViewItem) => {
|
||||
if (viewItem.pathname === path) {
|
||||
return viewItem;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const findViewItemByPath = (path: string, outletId?: number, mustBeIonRoute: boolean = false): ViewItem | undefined => {
|
||||
const findViewItemByPath = (
|
||||
path: string,
|
||||
outletId?: number,
|
||||
mustBeIonRoute = false
|
||||
): ViewItem | undefined => {
|
||||
const matchView = (viewItem: ViewItem) => {
|
||||
if (
|
||||
(mustBeIonRoute && !viewItem.ionRoute) ||
|
||||
path === ''
|
||||
) {
|
||||
if ((mustBeIonRoute && !viewItem.ionRoute) || path === "") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const resolvedPath = router.resolve(path);
|
||||
const findMatchedRoute = resolvedPath.matched.find((matchedRoute: RouteLocationMatched) => matchedRoute === viewItem.matchedRoute);
|
||||
const findMatchedRoute = resolvedPath.matched.find(
|
||||
(matchedRoute: RouteLocationMatched) =>
|
||||
matchedRoute === viewItem.matchedRoute
|
||||
);
|
||||
|
||||
if (findMatchedRoute) {
|
||||
|
||||
/**
|
||||
* /page/1 and /page/2 should not match
|
||||
* to the same view item otherwise there will
|
||||
@ -83,7 +93,7 @@ export const createViewStacks = (router: Router) => {
|
||||
* so the page 2 params are properly passed
|
||||
* to the developer's app.
|
||||
*/
|
||||
const hasParameter = findMatchedRoute.path.includes(':');
|
||||
const hasParameter = findMatchedRoute.path.includes(":");
|
||||
if (hasParameter && path !== viewItem.pathname) {
|
||||
return false;
|
||||
}
|
||||
@ -92,31 +102,39 @@ export const createViewStacks = (router: Router) => {
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
if (outletId) {
|
||||
const stack = viewStacks[outletId];
|
||||
if (!stack) return undefined;
|
||||
|
||||
const match = (router) ? stack.find(matchView) : findViewItemInStack(path, stack)
|
||||
const match = router
|
||||
? stack.find(matchView)
|
||||
: findViewItemInStack(path, stack);
|
||||
if (match) return match;
|
||||
} else {
|
||||
for (let outletId in viewStacks) {
|
||||
for (const outletId in viewStacks) {
|
||||
const stack = viewStacks[outletId];
|
||||
const viewItem = findViewItemInStack(path, stack);
|
||||
if (viewItem) {
|
||||
return viewItem;
|
||||
return viewItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(FW-2969): type
|
||||
const createViewItem = (outletId: number, vueComponent: any, matchedRoute: RouteLocationMatched, routeInfo: RouteInfo, ionPage?: HTMLElement): ViewItem => {
|
||||
const createViewItem = (
|
||||
outletId: number,
|
||||
vueComponent: any,
|
||||
matchedRoute: RouteLocationMatched,
|
||||
routeInfo: RouteInfo,
|
||||
ionPage?: HTMLElement
|
||||
): ViewItem => {
|
||||
return {
|
||||
id: generateId('viewItem'),
|
||||
id: generateId("viewItem"),
|
||||
pathname: routeInfo.pathname,
|
||||
outletId,
|
||||
matchedRoute,
|
||||
@ -127,9 +145,9 @@ export const createViewStacks = (router: Router) => {
|
||||
mount: false,
|
||||
exact: routeInfo.pathname === matchedRoute.path,
|
||||
params: routeInfo.params,
|
||||
vueComponentData: {}
|
||||
vueComponentData: {},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const add = (viewItem: ViewItem): void => {
|
||||
const { outletId } = viewItem;
|
||||
@ -138,25 +156,29 @@ export const createViewStacks = (router: Router) => {
|
||||
} else {
|
||||
viewStacks[outletId].push(viewItem);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const remove = (viewItem: ViewItem, outletId?: number): void => {
|
||||
if (!outletId) { throw Error('outletId required') }
|
||||
if (!outletId) {
|
||||
throw Error("outletId required");
|
||||
}
|
||||
|
||||
const viewStack = viewStacks[outletId];
|
||||
if (viewStack) {
|
||||
viewStacks[outletId] = viewStack.filter(item => item.id !== viewItem.id);
|
||||
viewStacks[outletId] = viewStack.filter(
|
||||
(item) => item.id !== viewItem.id
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getChildrenToRender = (outletId: number): ViewItem[] => {
|
||||
const viewStack = viewStacks[outletId];
|
||||
if (viewStack) {
|
||||
const components = viewStacks[outletId].filter(v => v.mount);
|
||||
const components = viewStacks[outletId].filter((v) => v.mount);
|
||||
return components;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* When navigating backwards, we need to clean up and
|
||||
@ -165,11 +187,15 @@ export const createViewStacks = (router: Router) => {
|
||||
* important when using router.go and stepping back
|
||||
* multiple pages at a time.
|
||||
*/
|
||||
const unmountLeavingViews = (outletId: number, viewItem: ViewItem, delta: number = 1) => {
|
||||
const unmountLeavingViews = (
|
||||
outletId: number,
|
||||
viewItem: ViewItem,
|
||||
delta = 1
|
||||
) => {
|
||||
const viewStack = viewStacks[outletId];
|
||||
if (!viewStack) return;
|
||||
|
||||
const startIndex = viewStack.findIndex(v => v === viewItem);
|
||||
const startIndex = viewStack.findIndex((v) => v === viewItem);
|
||||
|
||||
for (let i = startIndex + 1; i < startIndex - delta; i++) {
|
||||
const viewItem = viewStack[i];
|
||||
@ -178,7 +204,7 @@ export const createViewStacks = (router: Router) => {
|
||||
viewItem.ionRoute = false;
|
||||
viewItem.matchedRoute.instances = {};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* When navigating forward it is possible for
|
||||
@ -198,16 +224,20 @@ export const createViewStacks = (router: Router) => {
|
||||
* to go back to /page2 and /home, so we need both pages mounted
|
||||
* in the DOM.
|
||||
*/
|
||||
const mountIntermediaryViews = (outletId: number, viewItem: ViewItem, delta: number = 1) => {
|
||||
const mountIntermediaryViews = (
|
||||
outletId: number,
|
||||
viewItem: ViewItem,
|
||||
delta = 1
|
||||
) => {
|
||||
const viewStack = viewStacks[outletId];
|
||||
if (!viewStack) return;
|
||||
|
||||
const startIndex = viewStack.findIndex(v => v === viewItem);
|
||||
const startIndex = viewStack.findIndex((v) => v === viewItem);
|
||||
|
||||
for (let i = startIndex + 1; i < startIndex + delta; i++) {
|
||||
viewStack[i].mount = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
unmountLeavingViews,
|
||||
@ -222,6 +252,6 @@ export const createViewStacks = (router: Router) => {
|
||||
remove,
|
||||
registerIonPage,
|
||||
getViewStack,
|
||||
size
|
||||
}
|
||||
}
|
||||
size,
|
||||
};
|
||||
};
|
||||
|
Reference in New Issue
Block a user