pull/3440/merge
烽宁 1 year ago committed by GitHub
commit 4bc637d4ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,12 +0,0 @@
import { ensureStartingSlash } from 'client/theme-default/support/utils'
describe('client/theme-default/utils', () => {
describe('ensureStartingSlash', () => {
test('it adds slash to the beginning of the given path', () => {
expect(ensureStartingSlash('path')).toBe('/path')
expect(ensureStartingSlash('path/nested')).toBe('/path/nested')
expect(ensureStartingSlash('/path')).toBe('/path')
expect(ensureStartingSlash('/path/nested')).toBe('/path/nested')
})
})
})

@ -1,4 +1,5 @@
import { getSidebar, hasActiveLink } from 'client/theme-default/support/sidebar'
import { getSidebar, ensureStartingSlash } from 'shared/shared'
import { hasActiveLink } from 'client/theme-default/support/sidebar'
describe('client/theme-default/support/sidebar', () => {
describe('getSidebar', () => {
@ -143,3 +144,14 @@ describe('client/theme-default/support/sidebar', () => {
})
})
})
describe('client/theme-default/utils', () => {
describe('ensureStartingSlash', () => {
test('it adds slash to the beginning of the given path', () => {
expect(ensureStartingSlash('path')).toBe('/path')
expect(ensureStartingSlash('path/nested')).toBe('/path/nested')
expect(ensureStartingSlash('/path')).toBe('/path')
expect(ensureStartingSlash('/path/nested')).toBe('/path/nested')
})
})
})

@ -12,6 +12,7 @@ export default defineConfig({
{ find: '@siteData', replacement: resolve(dir, './shims.ts') },
{ find: 'client', replacement: resolve(dir, '../../src/client') },
{ find: 'node', replacement: resolve(dir, '../../src/node') },
{ find: 'shared', replacement: resolve(dir, '../../src/shared') },
{
find: /^vitepress$/,
replacement: resolve(dir, '../../src/client/index.js')

@ -1,5 +1,5 @@
import { computed } from 'vue'
import { ensureStartingSlash } from '../support/utils'
import { ensureStartingSlash } from '../../shared'
import { useData } from './data'
export function useLangs({ correspondingLink = false } = {}) {

@ -1,7 +1,7 @@
import { computed } from 'vue'
import { useData } from './data'
import { isActive } from '../../shared'
import { getSidebar, getFlatSideBarLinks } from '../support/sidebar'
import { isActive, getSidebar } from '../../shared'
import { getFlatSideBarLinks } from '../support/sidebar'
export function usePrevNext() {
const { page, theme, frontmatter } = useData()

@ -11,10 +11,9 @@ import {
type ComputedRef,
type Ref
} from 'vue'
import { isActive } from '../../shared'
import { isActive, getSidebar } from '../../shared'
import {
hasActiveLink as containsActiveLink,
getSidebar,
getSidebarGroups
} from '../support/sidebar'
import { useData } from './data'

@ -1,6 +1,4 @@
import type { DefaultTheme } from 'vitepress/theme'
import { ensureStartingSlash } from './utils'
import { isActive } from '../../shared'
import { isActive, type SidebarItem } from '../../shared'
export interface SidebarLink {
text: string
@ -8,38 +6,6 @@ export interface SidebarLink {
docFooterText?: string
}
type SidebarItem = DefaultTheme.SidebarItem
/**
* Get the `Sidebar` from sidebar option. This method will ensure to get correct
* sidebar config from `MultiSideBarConfig` with various path combinations such
* as matching `guide/` and `/guide/`. If no matching config was found, it will
* return empty array.
*/
export function getSidebar(
_sidebar: DefaultTheme.Sidebar | undefined,
path: string
): SidebarItem[] {
if (Array.isArray(_sidebar)) return addBase(_sidebar)
if (_sidebar == null) return []
path = ensureStartingSlash(path)
const dir = Object.keys(_sidebar)
.sort((a, b) => {
return b.split('/').length - a.split('/').length
})
.find((dir) => {
// make sure the multi sidebar key starts with slash too
return path.startsWith(ensureStartingSlash(dir))
})
const sidebar = dir ? _sidebar[dir] : []
return Array.isArray(sidebar)
? addBase(sidebar)
: addBase(sidebar.items, sidebar.base)
}
/**
* Get or generate sidebar group from the given sidebar items.
*/
@ -107,13 +73,3 @@ export function hasActiveLink(
? hasActiveLink(path, items.items)
: false
}
function addBase(items: SidebarItem[], _base?: string): SidebarItem[] {
return [...items].map((_item) => {
const item = { ..._item }
const base = item.base || _base
if (base && item.link) item.link = base + item.link
if (item.items) item.items = addBase(item.items, base)
return item
})
}

@ -16,10 +16,6 @@ export function throttleAndDebounce(fn: () => void, delay: number): () => void {
}
}
export function ensureStartingSlash(path: string): string {
return /^\//.test(path) ? path : `/${path}`
}
export function normalizeLink(url: string): string {
const { pathname, search, hash, protocol } = new URL(url, 'http://a.com')

@ -9,8 +9,10 @@ import { createMarkdownRenderer } from '../markdown/markdown'
import {
getLocaleForPath,
slash,
getSidebar,
type DefaultTheme,
type MarkdownEnv
type MarkdownEnv,
type SidebarItem
} from '../shared'
import { processIncludes } from '../utils/processIncludes'
@ -116,12 +118,37 @@ export async function localSearchPlugin(
return id
}
function getParentTitles(sidebar: SidebarItem[], fileId: string) {
const titles: string[] = [],
path: string[] = []
const backtrack = (sidebar: SidebarItem[] | undefined) => {
if (!sidebar) return
for (let i = 0; i < sidebar?.length; i++) {
if (sidebar[i].link === fileId) {
titles.push(...path)
return
}
path.push(sidebar[i].text!)
backtrack(sidebar[i].items)
path.pop()
}
}
backtrack(sidebar)
return titles
}
async function indexFile(page: string) {
const file = path.join(siteConfig.srcDir, page)
// get file metadata
const fileId = getDocId(file)
const locale = getLocaleForPath(siteConfig.site, page)
const index = getIndexByLocale(locale)
const sidebar = getSidebar(
siteConfig.site?.locales[locale]?.themeConfig?.sidebar ??
siteConfig.site?.themeConfig.sidebar,
fileId
)
const parentTitles = getParentTitles(sidebar, fileId.replace(/\.html$/, ''))
// retrieve file and split into "sections"
const html = await render(file)
const sections =
@ -132,7 +159,8 @@ export async function localSearchPlugin(
// add sections to the locale index
for await (const section of sections) {
if (!section || !(section.text || section.titles)) break
const { anchor, text, titles } = section
let { anchor, text, titles } = section
titles = [...parentTitles, ...titles]
const id = anchor ? [fileId, anchor].join('#') : fileId
index.add({
id,

@ -1,4 +1,9 @@
import type { HeadConfig, PageData, SiteData } from '../../types/shared'
import type {
HeadConfig,
PageData,
SiteData,
DefaultTheme
} from '../../types/shared'
export type {
Awaitable,
@ -14,6 +19,8 @@ export type {
SiteData
} from '../../types/shared'
export type SidebarItem = DefaultTheme.SidebarItem
export const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i
export const APPEARANCE_KEY = 'vitepress-theme-appearance'
@ -219,3 +226,47 @@ export function treatAsHtml(filename: string): boolean {
export function escapeRegExp(str: string) {
return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
}
/**
* Get the `Sidebar` from sidebar option. This method will ensure to get correct
* sidebar config from `MultiSideBarConfig` with various path combinations such
* as matching `guide/` and `/guide/`. If no matching config was found, it will
* return empty array.
*/
export function getSidebar(
_sidebar: DefaultTheme.Sidebar | undefined,
path: string
): SidebarItem[] {
if (Array.isArray(_sidebar)) return addBase(_sidebar)
if (_sidebar == null) return []
path = ensureStartingSlash(path)
const dir = Object.keys(_sidebar)
.sort((a, b) => {
return b.split('/').length - a.split('/').length
})
.find((dir) => {
// make sure the multi sidebar key starts with slash too
return path.startsWith(ensureStartingSlash(dir))
})
const sidebar = dir ? _sidebar[dir] : []
return Array.isArray(sidebar)
? addBase(sidebar)
: addBase(sidebar.items, sidebar.base)
}
function addBase(items: SidebarItem[], _base?: string): SidebarItem[] {
return [...items].map((_item) => {
const item = { ..._item }
const base = item.base || _base
if (base && item.link) item.link = base + item.link
if (item.items) item.items = addBase(item.items, base)
return item
})
}
export function ensureStartingSlash(path: string): string {
return /^\//.test(path) ? path : `/${path}`
}

Loading…
Cancel
Save