mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 10:01:59 +08:00
159 lines
4.2 KiB
TypeScript
159 lines
4.2 KiB
TypeScript
import { RouteInfo } from './types';
|
|
|
|
export const createLocationHistory = () => {
|
|
const locationHistory: RouteInfo[] = [];
|
|
const tabsHistory: { [k: string]: RouteInfo[] } = {};
|
|
|
|
const add = (routeInfo: RouteInfo) => {
|
|
switch (routeInfo.routerAction) {
|
|
case "replace":
|
|
replaceRoute(routeInfo);
|
|
break;
|
|
case "pop":
|
|
pop(routeInfo);
|
|
break;
|
|
default:
|
|
addRoute(routeInfo);
|
|
break;
|
|
}
|
|
|
|
if (routeInfo.routerDirection === 'root') {
|
|
clearHistory();
|
|
addRoute(routeInfo);
|
|
}
|
|
}
|
|
|
|
const update = (routeInfo: RouteInfo) => {
|
|
const locationIndex = locationHistory.findIndex(x => x.id === routeInfo.id);
|
|
if (locationIndex > -1) {
|
|
locationHistory.splice(locationIndex, 1, routeInfo);
|
|
}
|
|
const tabArray = tabsHistory[routeInfo.tab || ''];
|
|
if (tabArray) {
|
|
const tabIndex = tabArray.findIndex(x => x.id === routeInfo.id);
|
|
if (tabIndex > -1) {
|
|
tabArray.splice(tabIndex, 1, routeInfo);
|
|
} else {
|
|
tabArray.push(routeInfo);
|
|
}
|
|
} else if (routeInfo.tab) {
|
|
tabsHistory[routeInfo.tab] = [routeInfo];
|
|
}
|
|
}
|
|
|
|
const replaceRoute = (routeInfo: RouteInfo) => {
|
|
const routeInfos = getTabsHistory(routeInfo.tab);
|
|
routeInfos && routeInfos.pop();
|
|
locationHistory.pop();
|
|
addRoute(routeInfo);
|
|
}
|
|
|
|
const pop = (routeInfo: RouteInfo) => {
|
|
const tabHistory = getTabsHistory(routeInfo.tab);
|
|
let ri;
|
|
if (tabHistory) {
|
|
// Pop all routes until we are back
|
|
ri = tabHistory[tabHistory.length - 1];
|
|
while (ri && ri.id !== routeInfo.id) {
|
|
tabHistory.pop();
|
|
ri = tabHistory[tabHistory.length - 1];
|
|
}
|
|
// Replace with updated route
|
|
tabHistory.pop();
|
|
tabHistory.push(routeInfo);
|
|
}
|
|
|
|
ri = locationHistory[locationHistory.length - 1];
|
|
while (ri && ri.id !== routeInfo.id) {
|
|
locationHistory.pop();
|
|
ri = locationHistory[locationHistory.length - 1];
|
|
}
|
|
// 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) {
|
|
tabHistory.pop();
|
|
}
|
|
tabHistory.push(routeInfo);
|
|
}
|
|
locationHistory.push(routeInfo);
|
|
}
|
|
|
|
const clearHistory = () => {
|
|
locationHistory.length = 0;
|
|
Object.keys(tabsHistory).forEach(key => {
|
|
tabsHistory[key] = [];
|
|
});
|
|
}
|
|
const getTabsHistory = (tab: string): RouteInfo[] => {
|
|
let history;
|
|
if (tab) {
|
|
history = tabsHistory[tab];
|
|
if (!history) {
|
|
history = tabsHistory[tab] = [];
|
|
}
|
|
}
|
|
|
|
return history;
|
|
}
|
|
const previous = () => locationHistory[locationHistory.length - 2] || current();
|
|
const current = () => locationHistory[locationHistory.length - 1];
|
|
const canGoBack = (deep: number = 1) => locationHistory.length > deep;
|
|
|
|
const getFirstRouteInfoForTab = (tab: string): RouteInfo | undefined => {
|
|
const tabHistory = getTabsHistory(tab);
|
|
if (tabHistory) {
|
|
return tabHistory[0];
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
const getCurrentRouteInfoForTab = (tab: string): RouteInfo | undefined => {
|
|
const tabHistory = getTabsHistory(tab);
|
|
if (tabHistory) {
|
|
return tabHistory[tabHistory.length - 1];
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
const findLastLocation = (routeInfo: RouteInfo): RouteInfo | undefined => {
|
|
const routeInfos = getTabsHistory(routeInfo.tab);
|
|
if (routeInfos) {
|
|
for (let i = routeInfos.length - 2; i >= 0; i--) {
|
|
const ri = routeInfos[i];
|
|
if (ri) {
|
|
if (ri.pathname === routeInfo.pushedByRoute) {
|
|
return ri;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (let i = locationHistory.length - 2; i >= 0; i--) {
|
|
const ri = locationHistory[i];
|
|
if (ri) {
|
|
if (ri.pathname === routeInfo.pushedByRoute) {
|
|
return ri;
|
|
}
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
current,
|
|
previous,
|
|
add,
|
|
canGoBack,
|
|
update,
|
|
getFirstRouteInfoForTab,
|
|
getCurrentRouteInfoForTab,
|
|
findLastLocation
|
|
}
|
|
}
|