mirror of
				https://github.com/em-squared/5e-drs.git
				synced 2025-10-31 05:24:20 +00:00 
			
		
		
		
	
		
			
	
	
		
			241 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			241 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|   | export const hashRE = /#.*$/ | ||
|  | export const extRE = /\.(md|html)$/ | ||
|  | export const endingSlashRE = /\/$/ | ||
|  | export const outboundRE = /^[a-z]+:/i | ||
|  | 
 | ||
|  | export function normalize (path) { | ||
|  |   return decodeURI(path) | ||
|  |     .replace(hashRE, '') | ||
|  |     .replace(extRE, '') | ||
|  | } | ||
|  | 
 | ||
|  | export function getHash (path) { | ||
|  |   const match = path.match(hashRE) | ||
|  |   if (match) { | ||
|  |     return match[0] | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | export function isExternal (path) { | ||
|  |   return outboundRE.test(path) | ||
|  | } | ||
|  | 
 | ||
|  | export function isMailto (path) { | ||
|  |   return /^mailto:/.test(path) | ||
|  | } | ||
|  | 
 | ||
|  | export function isTel (path) { | ||
|  |   return /^tel:/.test(path) | ||
|  | } | ||
|  | 
 | ||
|  | export function ensureExt (path) { | ||
|  |   if (isExternal(path)) { | ||
|  |     return path | ||
|  |   } | ||
|  |   const hashMatch = path.match(hashRE) | ||
|  |   const hash = hashMatch ? hashMatch[0] : '' | ||
|  |   const normalized = normalize(path) | ||
|  | 
 | ||
|  |   if (endingSlashRE.test(normalized)) { | ||
|  |     return path | ||
|  |   } | ||
|  |   return normalized + '.html' + hash | ||
|  | } | ||
|  | 
 | ||
|  | export function isActive (route, path) { | ||
|  |   const routeHash = decodeURIComponent(route.hash) | ||
|  |   const linkHash = getHash(path) | ||
|  |   if (linkHash && routeHash !== linkHash) { | ||
|  |     return false | ||
|  |   } | ||
|  |   const routePath = normalize(route.path) | ||
|  |   const pagePath = normalize(path) | ||
|  |   return routePath === pagePath | ||
|  | } | ||
|  | 
 | ||
|  | export function resolvePage (pages, rawPath, base) { | ||
|  |   if (isExternal(rawPath)) { | ||
|  |     return { | ||
|  |       type: 'external', | ||
|  |       path: rawPath | ||
|  |     } | ||
|  |   } | ||
|  |   if (base) { | ||
|  |     rawPath = resolvePath(rawPath, base) | ||
|  |   } | ||
|  |   const path = normalize(rawPath) | ||
|  |   for (let i = 0; i < pages.length; i++) { | ||
|  |     if (normalize(pages[i].regularPath) === path) { | ||
|  |       return Object.assign({}, pages[i], { | ||
|  |         type: 'page', | ||
|  |         path: ensureExt(pages[i].path) | ||
|  |       }) | ||
|  |     } | ||
|  |   } | ||
|  |   console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`) | ||
|  |   return {} | ||
|  | } | ||
|  | 
 | ||
|  | function resolvePath (relative, base, append) { | ||
|  |   const firstChar = relative.charAt(0) | ||
|  |   if (firstChar === '/') { | ||
|  |     return relative | ||
|  |   } | ||
|  | 
 | ||
|  |   if (firstChar === '?' || firstChar === '#') { | ||
|  |     return base + relative | ||
|  |   } | ||
|  | 
 | ||
|  |   const stack = base.split('/') | ||
|  | 
 | ||
|  |   // remove trailing segment if:
 | ||
|  |   // - not appending
 | ||
|  |   // - appending to trailing slash (last segment is empty)
 | ||
|  |   if (!append || !stack[stack.length - 1]) { | ||
|  |     stack.pop() | ||
|  |   } | ||
|  | 
 | ||
|  |   // resolve relative path
 | ||
|  |   const segments = relative.replace(/^\//, '').split('/') | ||
|  |   for (let i = 0; i < segments.length; i++) { | ||
|  |     const segment = segments[i] | ||
|  |     if (segment === '..') { | ||
|  |       stack.pop() | ||
|  |     } else if (segment !== '.') { | ||
|  |       stack.push(segment) | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   // ensure leading slash
 | ||
|  |   if (stack[0] !== '') { | ||
|  |     stack.unshift('') | ||
|  |   } | ||
|  | 
 | ||
|  |   return stack.join('/') | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * @param { Page } page | ||
|  |  * @param { string } regularPath | ||
|  |  * @param { SiteData } site | ||
|  |  * @param { string } localePath | ||
|  |  * @returns { SidebarGroup } | ||
|  |  */ | ||
|  | export function resolveSidebarItems (page, regularPath, site, localePath) { | ||
|  |   const { pages, themeConfig } = site | ||
|  | 
 | ||
|  |   const localeConfig = localePath && themeConfig.locales | ||
|  |     ? themeConfig.locales[localePath] || themeConfig | ||
|  |     : themeConfig | ||
|  | 
 | ||
|  |   const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar | ||
|  |   if (pageSidebarConfig === 'auto') { | ||
|  |     return resolveHeaders(page) | ||
|  |   } | ||
|  | 
 | ||
|  |   const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar | ||
|  |   if (!sidebarConfig) { | ||
|  |     return [] | ||
|  |   } else { | ||
|  |     const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig) | ||
|  |     return config | ||
|  |       ? config.map(item => resolveItem(item, pages, base)) | ||
|  |       : [] | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * @param { Page } page | ||
|  |  * @returns { SidebarGroup } | ||
|  |  */ | ||
|  | function resolveHeaders (page) { | ||
|  |   const headers = groupHeaders(page.headers || []) | ||
|  |   return [{ | ||
|  |     type: 'group', | ||
|  |     collapsable: false, | ||
|  |     title: page.title, | ||
|  |     path: null, | ||
|  |     children: headers.map(h => ({ | ||
|  |       type: 'auto', | ||
|  |       title: h.title, | ||
|  |       basePath: page.path, | ||
|  |       path: page.path + '#' + h.slug, | ||
|  |       children: h.children || [] | ||
|  |     })) | ||
|  |   }] | ||
|  | } | ||
|  | 
 | ||
|  | export function groupHeaders (headers) { | ||
|  |   // group h3s under h2
 | ||
|  |   headers = headers.map(h => Object.assign({}, h)) | ||
|  |   let lastH2 | ||
|  |   headers.forEach(h => { | ||
|  |     if (h.level === 2) { | ||
|  |       lastH2 = h | ||
|  |     } else if (lastH2) { | ||
|  |       (lastH2.children || (lastH2.children = [])).push(h) | ||
|  |     } | ||
|  |   }) | ||
|  |   return headers.filter(h => h.level === 2) | ||
|  | } | ||
|  | 
 | ||
|  | export function resolveNavLinkItem (linkItem) { | ||
|  |   return Object.assign(linkItem, { | ||
|  |     type: linkItem.items && linkItem.items.length ? 'links' : 'link' | ||
|  |   }) | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * @param { Route } route | ||
|  |  * @param { Array<string|string[]> | Array<SidebarGroup> | [link: string]: SidebarConfig } config | ||
|  |  * @returns { base: string, config: SidebarConfig } | ||
|  |  */ | ||
|  | export function resolveMatchingConfig (regularPath, config) { | ||
|  |   if (Array.isArray(config)) { | ||
|  |     return { | ||
|  |       base: '/', | ||
|  |       config: config | ||
|  |     } | ||
|  |   } | ||
|  |   for (const base in config) { | ||
|  |     if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) { | ||
|  |       return { | ||
|  |         base, | ||
|  |         config: config[base] | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  |   return {} | ||
|  | } | ||
|  | 
 | ||
|  | function ensureEndingSlash (path) { | ||
|  |   return /(\.html|\/)$/.test(path) | ||
|  |     ? path | ||
|  |     : path + '/' | ||
|  | } | ||
|  | 
 | ||
|  | function resolveItem (item, pages, base, groupDepth = 1) { | ||
|  |   if (typeof item === 'string') { | ||
|  |     return resolvePage(pages, item, base) | ||
|  |   } else if (Array.isArray(item)) { | ||
|  |     return Object.assign(resolvePage(pages, item[0], base), { | ||
|  |       title: item[1] | ||
|  |     }) | ||
|  |   } else { | ||
|  |     const children = item.children || [] | ||
|  |     if (children.length === 0 && item.path) { | ||
|  |       return Object.assign(resolvePage(pages, item.path, base), { | ||
|  |         title: item.title | ||
|  |       }) | ||
|  |     } | ||
|  |     return { | ||
|  |       type: 'group', | ||
|  |       path: item.path, | ||
|  |       title: item.title, | ||
|  |       sidebarDepth: item.sidebarDepth, | ||
|  |       children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)), | ||
|  |       collapsable: item.collapsable !== false | ||
|  |     } | ||
|  |   } | ||
|  | } |