92 lines
3.1 KiB
JavaScript
92 lines
3.1 KiB
JavaScript
import { useSidebarItems } from '@theme/useSidebarItems';
|
|
import { useThemeLocaleData } from '@theme/useThemeData';
|
|
import { computed } from 'vue';
|
|
import { resolveRoute, usePageFrontmatter, useRoute } from 'vuepress/client';
|
|
import { isPlainObject, isString } from 'vuepress/shared';
|
|
import { getAutoLink } from '../utils/index.js';
|
|
const resolveFromFrontmatterConfig = (config, currentPath) => {
|
|
if (config === false) {
|
|
return false;
|
|
}
|
|
if (isString(config)) {
|
|
return getAutoLink(config, currentPath);
|
|
}
|
|
if (isPlainObject(config)) {
|
|
return {
|
|
...config,
|
|
link: getAutoLink(config.link, currentPath).link,
|
|
};
|
|
}
|
|
return null;
|
|
};
|
|
/**
|
|
* Resolve `prev` or `next` config from sidebar items
|
|
*/
|
|
const resolveFromSidebarItems = (sidebarItems, currentPath, offset) => {
|
|
const linkIndex = sidebarItems.findIndex((item) => item.link === currentPath);
|
|
if (linkIndex !== -1) {
|
|
const targetItem = sidebarItems[linkIndex + offset];
|
|
if (!targetItem)
|
|
return null;
|
|
if (targetItem.link)
|
|
return targetItem;
|
|
if ('prefix' in targetItem && !resolveRoute(targetItem.prefix).notFound)
|
|
return {
|
|
...targetItem,
|
|
link: targetItem.prefix,
|
|
};
|
|
return null;
|
|
}
|
|
for (const item of sidebarItems) {
|
|
if ('children' in item) {
|
|
const childResult = resolveFromSidebarItems(item.children, currentPath, offset);
|
|
if (childResult) {
|
|
return childResult;
|
|
}
|
|
}
|
|
}
|
|
const prefixIndex = sidebarItems.findIndex((item) => 'prefix' in item && item.prefix === currentPath);
|
|
if (prefixIndex !== -1) {
|
|
const targetItem = sidebarItems[prefixIndex + offset];
|
|
if (!targetItem)
|
|
return null;
|
|
if (targetItem.link)
|
|
return targetItem;
|
|
if ('prefix' in targetItem && !resolveRoute(targetItem.prefix).notFound)
|
|
return {
|
|
...targetItem,
|
|
link: targetItem.prefix,
|
|
};
|
|
return null;
|
|
}
|
|
return null;
|
|
};
|
|
export const useRelatedLinks = () => {
|
|
const frontmatter = usePageFrontmatter();
|
|
const themeLocale = useThemeLocaleData();
|
|
const sidebarItems = useSidebarItems();
|
|
const route = useRoute();
|
|
const prevLink = computed(() => {
|
|
const prevConfig = resolveFromFrontmatterConfig(frontmatter.value.prev, route.path);
|
|
return prevConfig === false
|
|
? null
|
|
: (prevConfig ??
|
|
(themeLocale.value.prev === false
|
|
? null
|
|
: resolveFromSidebarItems(sidebarItems.value, route.path, -1)));
|
|
});
|
|
const nextLink = computed(() => {
|
|
const nextConfig = resolveFromFrontmatterConfig(frontmatter.value.next, route.path);
|
|
return nextConfig === false
|
|
? null
|
|
: (nextConfig ??
|
|
(themeLocale.value.next === false
|
|
? null
|
|
: resolveFromSidebarItems(sidebarItems.value, route.path, 1)));
|
|
});
|
|
return {
|
|
prevLink,
|
|
nextLink,
|
|
};
|
|
};
|