mirror of https://github.com/vuejs/vitepress
When there's extention in the sidebar item links, such as `.md` or `.html`, the "next and prev link" is failing. This commit fixes that issue.pull/141/head
parent
af8a162cd3
commit
6dcf6b3796
@ -0,0 +1,123 @@
|
||||
import {
|
||||
getSideBarConfig,
|
||||
getFlatSideBarLinks
|
||||
} from 'client/theme-default/support/sideBar'
|
||||
|
||||
describe('client/theme-default/support/sideBar', () => {
|
||||
it('gets the correct sidebar items', () => {
|
||||
expect(getSideBarConfig(false, '')).toEqual(false)
|
||||
expect(getSideBarConfig('auto', '')).toEqual('auto')
|
||||
|
||||
const sidebar = [{ text: 'Title 01', link: 'title-01' }]
|
||||
const expected = [{ text: 'Title 01', link: 'title-01' }]
|
||||
|
||||
expect(getSideBarConfig(sidebar, '')).toEqual(expected)
|
||||
})
|
||||
|
||||
it('gets the correct sidebar items from the given path', () => {
|
||||
const sidebar = {
|
||||
'/': [{ text: 'R', link: 'r' }],
|
||||
'/guide/': [{ text: 'G', link: 'g' }]
|
||||
}
|
||||
|
||||
expect(getSideBarConfig(sidebar, '/')).toEqual(sidebar['/'])
|
||||
expect(getSideBarConfig(sidebar, '/guide/')).toEqual(sidebar['/guide/'])
|
||||
})
|
||||
|
||||
it('gets the correct sidebar items with various combination', () => {
|
||||
const s = {
|
||||
'/guide/': [{ text: 'G', link: 'g' }],
|
||||
api: [{ text: 'A', link: 'a' }]
|
||||
}
|
||||
|
||||
expect(getSideBarConfig(s, '/guide/')).toEqual(s['/guide/'])
|
||||
expect(getSideBarConfig(s, '/guide')).toEqual(s['/guide/'])
|
||||
expect(getSideBarConfig(s, 'guide/')).toEqual(s['/guide/'])
|
||||
expect(getSideBarConfig(s, 'guide/nested')).toEqual(s['/guide/'])
|
||||
expect(getSideBarConfig(s, '/guide/nested')).toEqual(s['/guide/'])
|
||||
expect(getSideBarConfig(s, 'guide/nested/')).toEqual(s['/guide/'])
|
||||
expect(getSideBarConfig(s, '/api/')).toEqual(s['api'])
|
||||
expect(getSideBarConfig(s, '/api')).toEqual(s['api'])
|
||||
expect(getSideBarConfig(s, 'api/')).toEqual(s['api'])
|
||||
expect(getSideBarConfig(s, 'api/nested')).toEqual(s['api'])
|
||||
expect(getSideBarConfig(s, '/api/nested')).toEqual(s['api'])
|
||||
expect(getSideBarConfig(s, 'api/nested/')).toEqual(s['api'])
|
||||
expect(getSideBarConfig(s, '/')).toEqual('auto')
|
||||
})
|
||||
|
||||
it('creates flat sidebar links', () => {
|
||||
const sidebar = [
|
||||
{ text: 'Title 01', link: '/title-01' },
|
||||
{ text: 'Title 02', link: '/title-02' },
|
||||
{ text: 'Title 03', link: '/title-03' }
|
||||
]
|
||||
|
||||
const expected = [
|
||||
{ text: 'Title 01', link: '/title-01' },
|
||||
{ text: 'Title 02', link: '/title-02' },
|
||||
{ text: 'Title 03', link: '/title-03' }
|
||||
]
|
||||
|
||||
expect(getFlatSideBarLinks(sidebar)).toEqual(expected)
|
||||
})
|
||||
|
||||
it('creates flat sidebar links with mixed sidebar group', () => {
|
||||
const sidebar = [
|
||||
{
|
||||
text: 'Title 01',
|
||||
link: '/title-01',
|
||||
children: [
|
||||
{ text: 'Children 01', link: '/children-01' },
|
||||
{ text: 'Children 02', link: '/children-02' }
|
||||
]
|
||||
},
|
||||
{ text: 'Title 02', link: '/title-02' },
|
||||
{ text: 'Title 03', link: '/title-03' }
|
||||
]
|
||||
|
||||
const expected = [
|
||||
{ text: 'Title 01', link: '/title-01' },
|
||||
{ text: 'Children 01', link: '/children-01' },
|
||||
{ text: 'Children 02', link: '/children-02' },
|
||||
{ text: 'Title 02', link: '/title-02' },
|
||||
{ text: 'Title 03', link: '/title-03' }
|
||||
]
|
||||
|
||||
expect(getFlatSideBarLinks(sidebar)).toEqual(expected)
|
||||
})
|
||||
|
||||
it('ignores any items with no `link` property', () => {
|
||||
const sidebar = [
|
||||
{
|
||||
text: 'Title 01',
|
||||
children: [
|
||||
{ text: 'Children 01', link: '/children-01' },
|
||||
{ text: 'Children 02', link: '/children-02' }
|
||||
]
|
||||
},
|
||||
{ text: 'Title 02', link: '/title-02' }
|
||||
]
|
||||
|
||||
const expected = [
|
||||
{ text: 'Children 01', link: '/children-01' },
|
||||
{ text: 'Children 02', link: '/children-02' },
|
||||
{ text: 'Title 02', link: '/title-02' }
|
||||
]
|
||||
|
||||
expect(getFlatSideBarLinks(sidebar)).toEqual(expected)
|
||||
})
|
||||
|
||||
it('removes `.md` or `.html` extention', () => {
|
||||
const sidebar = [
|
||||
{ text: 'Title 01', link: '/title-01.md' },
|
||||
{ text: 'Title 02', link: '/title-02.html' }
|
||||
]
|
||||
|
||||
const expected = [
|
||||
{ text: 'Title 01', link: '/title-01' },
|
||||
{ text: 'Title 02', link: '/title-02' }
|
||||
]
|
||||
|
||||
expect(getFlatSideBarLinks(sidebar)).toEqual(expected)
|
||||
})
|
||||
})
|
@ -0,0 +1,70 @@
|
||||
import { DefaultTheme } from '../config'
|
||||
import {
|
||||
isArray,
|
||||
ensureSlash,
|
||||
ensureStartingSlash,
|
||||
removeExtention
|
||||
} from '../utils'
|
||||
|
||||
export function isSideBarConfig(
|
||||
sidebar: DefaultTheme.SideBarConfig | DefaultTheme.MultiSideBarConfig
|
||||
): sidebar is DefaultTheme.SideBarConfig {
|
||||
return sidebar === false || sidebar === 'auto' || isArray(sidebar)
|
||||
}
|
||||
|
||||
export function isSideBarGroup(
|
||||
item: DefaultTheme.SideBarItem
|
||||
): item is DefaultTheme.SideBarGroup {
|
||||
return (item as DefaultTheme.SideBarGroup).children !== undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `SideBarConfig` 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 `auto` as a fallback.
|
||||
*/
|
||||
export function getSideBarConfig(
|
||||
sidebar: DefaultTheme.SideBarConfig | DefaultTheme.MultiSideBarConfig,
|
||||
path: string
|
||||
): DefaultTheme.SideBarConfig {
|
||||
if (isSideBarConfig(sidebar)) {
|
||||
return sidebar
|
||||
}
|
||||
|
||||
// get the very first segment of the path to compare with nulti sidebar keys
|
||||
// and make sure it's surrounded by slash
|
||||
path = ensureStartingSlash(path).split('/')[1] || '/'
|
||||
path = ensureSlash(path)
|
||||
|
||||
for (const dir in sidebar) {
|
||||
// make sure the multi sidebar key is surrounded by slash too
|
||||
if (path === ensureSlash(dir)) {
|
||||
return sidebar[dir]
|
||||
}
|
||||
}
|
||||
|
||||
return 'auto'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get flat sidebar links from the sidebar items. This method is useful for
|
||||
* creating the "next and prev link" feature. It will ignore any items that
|
||||
* don't have `link` property and removes `.md` or `.html` extension if a
|
||||
* link contains it.
|
||||
*/
|
||||
export function getFlatSideBarLinks(
|
||||
sidebar: DefaultTheme.SideBarItem[]
|
||||
): DefaultTheme.SideBarLink[] {
|
||||
return sidebar.reduce<DefaultTheme.SideBarLink[]>((links, item) => {
|
||||
if (item.link) {
|
||||
links.push({ text: item.text, link: removeExtention(item.link) })
|
||||
}
|
||||
|
||||
if (isSideBarGroup(item)) {
|
||||
links = [...links, ...getFlatSideBarLinks(item.children)]
|
||||
}
|
||||
|
||||
return links
|
||||
}, [])
|
||||
}
|
Loading…
Reference in new issue