Initial rearrangment of vuetom site source

This commit is contained in:
2024-10-09 08:23:08 +00:00
parent dbd456a517
commit e9d08bd263
233 changed files with 22841 additions and 1 deletions

View File

@@ -0,0 +1,2 @@
export const defaultLang = 'zh-CN'
export const PREFERRED_LANG_KEY = 'vuetom_lang'

View File

@@ -0,0 +1,23 @@
import { computed } from 'vue'
import { useRoute } from 'vitepress'
import { defaultLang } from './constant.js'
export const useLang = () => {
const route = useRoute()
return computed(() => {
// the first part of the first slash
const path = route.data?.relativePath
let lang
if (path?.includes('/')) {
lang = path.split('/').shift()
} else {
lang = defaultLang
}
return lang
})
}
export default {}

View File

@@ -0,0 +1,137 @@
import {
reactive, ref, markRaw, shallowRef
} from 'vue'
import { inBrowser, withBase, useData } from 'vitepress'
// @ts-ignore
import siteData from '@siteData'
export const siteDataRef = shallowRef(siteData)
const routes: any = ref([])
const NotFound = () => '404 Not Found'
const notFoundPageData = {
relativePath: '',
title: '404',
description: 'Not Found',
headers: [],
frontmatter: {},
lastUpdated: 0
}
const getDefaultRoute = () => ({
path: '/',
component: null,
data: notFoundPageData
})
const createRouterRoutes = (
loadPageModule: Function,
fallbackComponent: any
) => {
// const router = useRouter()
const { theme } = useData()
const { pages } = theme.value
let latestPendingPath = ''
async function loadPage(
href = '/index',
scrollPosition = 0,
isRetry = false
) {
const route = reactive(getDefaultRoute())
const pendingPath = `/posts${href}`
try {
let page = loadPageModule(pendingPath)
if ('then' in page && typeof page.then === 'function') {
page = await page
}
const { default: comp, __pageData } = page
if (!comp) {
throw new Error(`Invalid route component: ${comp}`)
}
route.path = inBrowser ? pendingPath : pendingPath
route.component = markRaw(comp)
route.data = markRaw(__pageData)
} catch (err) {
// @ts-ignore
if (!/fetch/.test(err.message) && !/^\/404(\.html|\/)?$/.test(href)) {
console.error(err)
}
if (!isRetry) {
try {
const res = await fetch(`${siteDataRef.value.base}hashmap.json`)
// eslint-disable-next-line no-underscore-dangle
window.__VP_HASH_MAP__ = await res.json()
await loadPage(href, scrollPosition, true)
return
} catch (e) {}
}
if (latestPendingPath === pendingPath) {
latestPendingPath = ''
route.path = inBrowser ? pendingPath : withBase(pendingPath)
route.component = fallbackComponent ? markRaw(fallbackComponent) : null
route.data = notFoundPageData
}
}
return route
}
pages.forEach(async (p: { link: string }) => {
const r = await loadPage(p.link)
routes.value.push(r)
})
return {
routes: routes.value
}
}
const getRoutes = () => {
let isInitialPageLoad = inBrowser
let initialPath = ''
return createRouterRoutes((path: string) => {
let pageFilePath = pathToFile(path)
if (isInitialPageLoad) {
initialPath = pageFilePath
}
if (isInitialPageLoad || initialPath === pageFilePath) {
pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js')
}
if (inBrowser) {
isInitialPageLoad = false
}
return import(/* @vite-ignore */ pageFilePath)
}, NotFound)
}
function pathToFile(path: string) {
let pagePath = path.replace(/\.html$/, '')
pagePath = decodeURIComponent(pagePath)
if (pagePath.endsWith('/')) {
pagePath += 'index'
}
// @ts-ignore
if (import.meta.env.DEV) {
pagePath += `.md?t=${Date.now()}`
} else {
// /foo/bar.html -> ./foo_bar.md
if (inBrowser) {
// @ts-ignore
const base = import.meta.env.BASE_URL
pagePath = `${
pagePath.slice(base.length - 1).replace(/\//g, '_') || 'index'
}.md`
const pageHash = __VP_HASH_MAP__[`posts_${pagePath.toLowerCase()}`]
pagePath = `${base}assets/posts_${pagePath}.${pageHash}.js`
} else {
// ssr
pagePath = `./${pagePath.slice(1).replace(/\//g, '_')}.md.js`
}
}
return pagePath
}
export { getRoutes }
export default {}

View File

@@ -0,0 +1,68 @@
export const hashRE = /#.*$/
export const extRE = /(index)?\.(md|html)$/
export const endingSlashRE = /\/$/
export const outboundRE = /^[a-z]+:/i
export function isNullish(value: any) {
return value === null || value === undefined
}
export function isArray(value: any) {
return Array.isArray(value)
}
export function isExternal(path: string) {
return outboundRE.test(path)
}
export function isActive(route: any, path: string) {
if (path === undefined) {
return false
}
const routePath = normalize(`/${route.data.relativePath}`)
const pagePath = normalize(path)
return routePath === pagePath
}
export function normalize(path: string) {
return decodeURI(path).replace(hashRE, '').replace(extRE, '')
}
export function joinUrl(base: string, path: string) {
const baseEndsWithSlash = base.endsWith('/')
const pathStartsWithSlash = path.startsWith('/')
if (baseEndsWithSlash && pathStartsWithSlash) {
return base.slice(0, -1) + path
}
if (!baseEndsWithSlash && !pathStartsWithSlash) {
return `${base}/${path}`
}
return base + path
}
/**
* get the path without filename (the last segment). for example, if the given
* path is `/guide/getting-started.html`, this method will return `/guide/`.
* Always with a trailing slash.
*/
export function getPathDirName(path: string) {
const segments = path.split('/')
if (segments[segments.length - 1]) {
segments.pop()
}
return ensureEndingSlash(segments.join('/'))
}
export function ensureSlash(path: string) {
return ensureEndingSlash(ensureStartingSlash(path))
}
export function ensureStartingSlash(path: string) {
return /^\//.test(path) ? path : `/${path}`
}
export function ensureEndingSlash(path: string) {
return /(\.html|\/)$/.test(path) ? path : `${path}/`
}
/**
* Remove `.md` or `.html` extention from the given path. It also converts
* `index` to slush.
*/
export function removeExtention(path: string) {
return path.replace(/(index)?(\.(md|html))?$/, '') || '/'
}