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