devstar插件

This commit is contained in:
2025-07-26 16:40:29 +08:00
commit 30033daafe
4387 changed files with 1041101 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
import { defineComponent, onMounted, ref } from 'vue';
export const ClientOnly = defineComponent({
setup(_, { slots }) {
const show = ref(false);
onMounted(() => {
show.value = true;
});
return () => (show.value && slots.default ? slots.default() : null);
}
});

View File

@@ -0,0 +1,24 @@
import { useData, useRoute } from 'vitepress';
import { defineComponent, h, watch } from 'vue';
import { contentUpdatedCallbacks } from '../utils';
const runCbs = () => contentUpdatedCallbacks.forEach((fn) => fn());
export const Content = defineComponent({
name: 'VitePressContent',
props: {
as: { type: [Object, String], default: 'div' }
},
setup(props) {
const route = useRoute();
const { frontmatter, site } = useData();
watch(frontmatter, runCbs, { deep: true, flush: 'post' });
return () => h(props.as, site.value.contentProps ?? { style: { position: 'relative' } }, [
route.component
? h(route.component, {
onVnodeMounted: runCbs,
onVnodeUpdated: runCbs,
onVnodeUnmounted: runCbs
})
: '404 Page Not Found'
]);
}
});

View File

@@ -0,0 +1,40 @@
import { inBrowser, onContentUpdated } from 'vitepress';
export function useCodeGroups() {
if (import.meta.env.DEV) {
onContentUpdated(() => {
document.querySelectorAll('.vp-code-group > .blocks').forEach((el) => {
Array.from(el.children).forEach((child) => {
child.classList.remove('active');
});
el.children[0].classList.add('active');
});
});
}
if (inBrowser) {
window.addEventListener('click', (e) => {
const el = e.target;
if (el.matches('.vp-code-group input')) {
// input <- .tabs <- .vp-code-group
const group = el.parentElement?.parentElement;
if (!group)
return;
const i = Array.from(group.querySelectorAll('input')).indexOf(el);
if (i < 0)
return;
const blocks = group.querySelector('.blocks');
if (!blocks)
return;
const current = Array.from(blocks.children).find((child) => child.classList.contains('active'));
if (!current)
return;
const next = blocks.children[i];
if (!next || current === next)
return;
current.classList.remove('active');
next.classList.add('active');
const label = group?.querySelector(`label[for="${el.id}"]`);
label?.scrollIntoView({ block: 'nearest' });
}
});
}
}

View File

@@ -0,0 +1,73 @@
import { inBrowser } from 'vitepress';
export function useCopyCode() {
if (inBrowser) {
const timeoutIdMap = new WeakMap();
window.addEventListener('click', (e) => {
const el = e.target;
if (el.matches('div[class*="language-"] > button.copy')) {
const parent = el.parentElement;
const sibling = el.nextElementSibling?.nextElementSibling;
if (!parent || !sibling) {
return;
}
const isShell = /language-(shellscript|shell|bash|sh|zsh)/.test(parent.className);
const ignoredNodes = ['.vp-copy-ignore', '.diff.remove'];
// Clone the node and remove the ignored nodes
const clone = sibling.cloneNode(true);
clone
.querySelectorAll(ignoredNodes.join(','))
.forEach((node) => node.remove());
let text = clone.textContent || '';
if (isShell) {
text = text.replace(/^ *(\$|>) /gm, '').trim();
}
copyToClipboard(text).then(() => {
el.classList.add('copied');
clearTimeout(timeoutIdMap.get(el));
const timeoutId = setTimeout(() => {
el.classList.remove('copied');
el.blur();
timeoutIdMap.delete(el);
}, 2000);
timeoutIdMap.set(el, timeoutId);
});
}
});
}
}
async function copyToClipboard(text) {
try {
return navigator.clipboard.writeText(text);
}
catch {
const element = document.createElement('textarea');
const previouslyFocusedElement = document.activeElement;
element.value = text;
// Prevent keyboard from showing on mobile
element.setAttribute('readonly', '');
element.style.contain = 'strict';
element.style.position = 'absolute';
element.style.left = '-9999px';
element.style.fontSize = '12pt'; // Prevent zooming on iOS
const selection = document.getSelection();
const originalRange = selection
? selection.rangeCount > 0 && selection.getRangeAt(0)
: null;
document.body.appendChild(element);
element.select();
// Explicit selection workaround for iOS
element.selectionStart = 0;
element.selectionEnd = text.length;
document.execCommand('copy');
document.body.removeChild(element);
if (originalRange) {
selection.removeAllRanges(); // originalRange can't be truthy when selection is falsy
selection.addRange(originalRange);
}
// Get the focus back on the previously focused element, if any
if (previouslyFocusedElement) {
;
previouslyFocusedElement.focus();
}
}
}

View File

@@ -0,0 +1,81 @@
import { watchEffect } from 'vue';
import { createTitle, mergeHead } from '../../shared';
export function useUpdateHead(route, siteDataByRouteRef) {
let isFirstUpdate = true;
let managedHeadElements = [];
const updateHeadTags = (newTags) => {
if (import.meta.env.PROD && isFirstUpdate) {
// in production, the initial meta tags are already pre-rendered so we
// skip the first update.
isFirstUpdate = false;
newTags.forEach((tag) => {
const headEl = createHeadElement(tag);
for (const el of document.head.children) {
if (el.isEqualNode(headEl)) {
managedHeadElements.push(el);
return;
}
}
});
return;
}
const newElements = newTags.map(createHeadElement);
managedHeadElements.forEach((oldEl, oldIndex) => {
const matchedIndex = newElements.findIndex((newEl) => newEl?.isEqualNode(oldEl ?? null));
if (matchedIndex !== -1) {
delete newElements[matchedIndex];
}
else {
oldEl?.remove();
delete managedHeadElements[oldIndex];
}
});
newElements.forEach((el) => el && document.head.appendChild(el));
managedHeadElements = [...managedHeadElements, ...newElements].filter(Boolean);
};
watchEffect(() => {
const pageData = route.data;
const siteData = siteDataByRouteRef.value;
const pageDescription = pageData && pageData.description;
const frontmatterHead = (pageData && pageData.frontmatter.head) || [];
// update title and description
const title = createTitle(siteData, pageData);
if (title !== document.title) {
document.title = title;
}
const description = pageDescription || siteData.description;
let metaDescriptionElement = document.querySelector(`meta[name=description]`);
if (metaDescriptionElement) {
if (metaDescriptionElement.getAttribute('content') !== description) {
metaDescriptionElement.setAttribute('content', description);
}
}
else {
createHeadElement(['meta', { name: 'description', content: description }]);
}
updateHeadTags(mergeHead(siteData.head, filterOutHeadDescription(frontmatterHead)));
});
}
function createHeadElement([tag, attrs, innerHTML]) {
const el = document.createElement(tag);
for (const key in attrs) {
el.setAttribute(key, attrs[key]);
}
if (innerHTML) {
el.innerHTML = innerHTML;
}
if (tag === 'script' && attrs.async == null) {
// async is true by default for dynamically created scripts
;
el.async = false;
}
return el;
}
function isMetaDescription(headConfig) {
return (headConfig[0] === 'meta' &&
headConfig[1] &&
headConfig[1].name === 'description');
}
function filterOutHeadDescription(head) {
return head.filter((h) => !isMetaDescription(h));
}

View File

@@ -0,0 +1,99 @@
// Customized pre-fetch for page chunks based on
// https://github.com/GoogleChromeLabs/quicklink
import { onMounted, onUnmounted, watch } from 'vue';
import { useRoute } from '../router';
import { inBrowser, pathToFile } from '../utils';
const hasFetched = new Set();
const createLink = () => document.createElement('link');
const viaDOM = (url) => {
const link = createLink();
link.rel = `prefetch`;
link.href = url;
document.head.appendChild(link);
};
const viaXHR = (url) => {
const req = new XMLHttpRequest();
req.open('GET', url, (req.withCredentials = true));
req.send();
};
let link;
const doFetch = inBrowser &&
(link = createLink()) &&
link.relList &&
link.relList.supports &&
link.relList.supports('prefetch')
? viaDOM
: viaXHR;
export function usePrefetch() {
if (!inBrowser) {
return;
}
if (!window.IntersectionObserver) {
return;
}
let conn;
if ((conn = navigator.connection) &&
(conn.saveData || /2g/.test(conn.effectiveType))) {
// Don't prefetch if using 2G or if Save-Data is enabled.
return;
}
const rIC = window.requestIdleCallback || setTimeout;
let observer = null;
const observeLinks = () => {
if (observer) {
observer.disconnect();
}
observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const link = entry.target;
observer.unobserve(link);
const { pathname } = link;
if (!hasFetched.has(pathname)) {
hasFetched.add(pathname);
const pageChunkPath = pathToFile(pathname);
if (pageChunkPath)
doFetch(pageChunkPath);
}
}
});
});
rIC(() => {
document
.querySelectorAll('#app a')
.forEach((link) => {
const { hostname, pathname } = new URL(link.href instanceof SVGAnimatedString
? link.href.animVal
: link.href, link.baseURI);
const extMatch = pathname.match(/\.\w+$/);
if (extMatch && extMatch[0] !== '.html') {
return;
}
if (
// only prefetch same tab navigation, since a new tab will load
// the lean js chunk instead.
link.target !== '_blank' &&
// only prefetch inbound links
hostname === location.hostname) {
if (pathname !== location.pathname) {
observer.observe(link);
}
else {
// No need to prefetch chunk for the current page, but also mark
// it as already fetched. This is because the initial page uses its
// lean chunk, and if we don't mark it, navigation to another page
// with a link back to the first page will fetch its full chunk
// which isn't needed.
hasFetched.add(pathname);
}
}
});
});
};
onMounted(observeLinks);
const route = useRoute();
watch(() => route.path, observeLinks);
onUnmounted(() => {
observer && observer.disconnect();
});
}

61
node_modules/vitepress/dist/client/app/data.js generated vendored Normal file
View File

@@ -0,0 +1,61 @@
import siteData from '@siteData';
import { useDark, usePreferredDark } from '@vueuse/core';
import { computed, inject, readonly, ref, shallowRef, watch } from 'vue';
import { APPEARANCE_KEY, createTitle, inBrowser, resolveSiteDataByRoute } from '../shared';
export const dataSymbol = Symbol();
// site data is a singleton
export const siteDataRef = shallowRef((import.meta.env.PROD ? siteData : readonly(siteData)));
// hmr
if (import.meta.hot) {
import.meta.hot.accept('/@siteData', (m) => {
if (m) {
siteDataRef.value = m.default;
}
});
}
// per-app data
export function initData(route) {
const site = computed(() => resolveSiteDataByRoute(siteDataRef.value, route.data.relativePath));
const appearance = site.value.appearance; // fine with reactivity being lost here, config change triggers a restart
const isDark = appearance === 'force-dark'
? ref(true)
: appearance === 'force-auto'
? usePreferredDark()
: appearance
? useDark({
storageKey: APPEARANCE_KEY,
initialValue: () => (appearance === 'dark' ? 'dark' : 'auto'),
...(typeof appearance === 'object' ? appearance : {})
})
: ref(false);
const hashRef = ref(inBrowser ? location.hash : '');
if (inBrowser) {
window.addEventListener('hashchange', () => {
hashRef.value = location.hash;
});
}
watch(() => route.data, () => {
hashRef.value = inBrowser ? location.hash : '';
});
return {
site,
theme: computed(() => site.value.themeConfig),
page: computed(() => route.data),
frontmatter: computed(() => route.data.frontmatter),
params: computed(() => route.data.params),
lang: computed(() => site.value.lang),
dir: computed(() => route.data.frontmatter.dir || site.value.dir),
localeIndex: computed(() => site.value.localeIndex || 'root'),
title: computed(() => createTitle(site.value, route.data)),
description: computed(() => route.data.description || site.value.description),
isDark,
hash: computed(() => hashRef.value)
};
}
export function useData() {
const data = inject(dataSymbol);
if (!data) {
throw new Error('vitepress data not properly injected in app');
}
return data;
}

29
node_modules/vitepress/dist/client/app/devtools.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
import { setupDevToolsPlugin } from '@vue/devtools-api';
const COMPONENT_STATE_TYPE = 'VitePress';
export const setupDevtools = (app, router, data) => {
setupDevToolsPlugin({
// fix recursive reference
app: app,
id: 'org.vuejs.vitepress',
label: 'VitePress',
packageName: 'vitepress',
homepage: 'https://vitepress.dev',
componentStateTypes: [COMPONENT_STATE_TYPE]
}, (api) => {
// TODO: remove any
api.on.inspectComponent((payload) => {
payload.instanceData.state.push({
type: COMPONENT_STATE_TYPE,
key: 'route',
value: router.route,
editable: false
});
payload.instanceData.state.push({
type: COMPONENT_STATE_TYPE,
key: 'data',
value: data,
editable: false
});
});
});
};

144
node_modules/vitepress/dist/client/app/index.js generated vendored Normal file
View File

@@ -0,0 +1,144 @@
import RawTheme from '@theme/index';
import { createApp as createClientApp, createSSRApp, defineComponent, h, onMounted, watchEffect } from 'vue';
import { ClientOnly } from './components/ClientOnly';
import { Content } from './components/Content';
import { useCodeGroups } from './composables/codeGroups';
import { useCopyCode } from './composables/copyCode';
import { useUpdateHead } from './composables/head';
import { usePrefetch } from './composables/preFetch';
import { dataSymbol, initData, siteDataRef, useData } from './data';
import { RouterSymbol, createRouter, scrollTo } from './router';
import { inBrowser, pathToFile } from './utils';
function resolveThemeExtends(theme) {
if (theme.extends) {
const base = resolveThemeExtends(theme.extends);
return {
...base,
...theme,
async enhanceApp(ctx) {
if (base.enhanceApp)
await base.enhanceApp(ctx);
if (theme.enhanceApp)
await theme.enhanceApp(ctx);
}
};
}
return theme;
}
const Theme = resolveThemeExtends(RawTheme);
const VitePressApp = defineComponent({
name: 'VitePressApp',
setup() {
const { site, lang, dir } = useData();
// change the language on the HTML element based on the current lang
onMounted(() => {
watchEffect(() => {
document.documentElement.lang = lang.value;
document.documentElement.dir = dir.value;
});
});
if (import.meta.env.PROD && site.value.router.prefetchLinks) {
// in prod mode, enable intersectionObserver based pre-fetch
usePrefetch();
}
// setup global copy code handler
useCopyCode();
// setup global code groups handler
useCodeGroups();
if (Theme.setup)
Theme.setup();
return () => h(Theme.Layout);
}
});
export async function createApp() {
;
globalThis.__VITEPRESS__ = true;
const router = newRouter();
const app = newApp();
app.provide(RouterSymbol, router);
const data = initData(router.route);
app.provide(dataSymbol, data);
// install global components
app.component('Content', Content);
app.component('ClientOnly', ClientOnly);
// expose $frontmatter & $params
Object.defineProperties(app.config.globalProperties, {
$frontmatter: {
get() {
return data.frontmatter.value;
}
},
$params: {
get() {
return data.page.value.params;
}
}
});
if (Theme.enhanceApp) {
await Theme.enhanceApp({
app,
router,
siteData: siteDataRef
});
}
// setup devtools in dev mode
if (import.meta.env.DEV || __VUE_PROD_DEVTOOLS__) {
import('./devtools.js').then(({ setupDevtools }) => setupDevtools(app, router, data));
}
return { app, router, data };
}
function newApp() {
return import.meta.env.PROD
? createSSRApp(VitePressApp)
: createClientApp(VitePressApp);
}
function newRouter() {
let isInitialPageLoad = inBrowser;
return createRouter((path) => {
let pageFilePath = pathToFile(path);
let pageModule = null;
if (pageFilePath) {
// use lean build if this is the initial page load
if (isInitialPageLoad) {
pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js');
}
if (import.meta.env.DEV) {
pageModule = import(/*@vite-ignore*/ pageFilePath).catch(() => {
// try with/without trailing slash
// in prod this is handled in src/client/app/utils.ts#pathToFile
const url = new URL(pageFilePath, 'http://a.com');
const path = (url.pathname.endsWith('/index.md')
? url.pathname.slice(0, -9) + '.md'
: url.pathname.slice(0, -3) + '/index.md') +
url.search +
url.hash;
return import(/*@vite-ignore*/ path);
});
}
else {
pageModule = import(/*@vite-ignore*/ pageFilePath);
}
}
if (inBrowser) {
isInitialPageLoad = false;
}
return pageModule;
}, Theme.NotFound);
}
if (inBrowser) {
createApp().then(({ app, router, data }) => {
// wait until page component is fetched before mounting
router.go().then(() => {
// dynamically update head tags
useUpdateHead(router.route, data.site);
app.mount('#app');
// scroll to hash on new tab during dev
if (import.meta.env.DEV && location.hash) {
const target = document.getElementById(decodeURIComponent(location.hash).slice(1));
if (target) {
scrollTo(target, location.hash);
}
}
});
});
}

247
node_modules/vitepress/dist/client/app/router.js generated vendored Normal file
View File

@@ -0,0 +1,247 @@
import { inject, markRaw, nextTick, reactive, readonly } from 'vue';
import { notFoundPageData, treatAsHtml } from '../shared';
import { siteDataRef } from './data';
import { getScrollOffset, inBrowser, withBase } from './utils';
export const RouterSymbol = Symbol();
// we are just using URL to parse the pathname and hash - the base doesn't
// matter and is only passed to support same-host hrefs.
const fakeHost = 'http://a.com';
const getDefaultRoute = () => ({
path: '/',
component: null,
data: notFoundPageData
});
export function createRouter(loadPageModule, fallbackComponent) {
const route = reactive(getDefaultRoute());
const router = {
route,
go
};
async function go(href = inBrowser ? location.href : '/') {
href = normalizeHref(href);
if ((await router.onBeforeRouteChange?.(href)) === false)
return;
if (inBrowser && href !== normalizeHref(location.href)) {
// save scroll position before changing url
history.replaceState({ scrollPosition: window.scrollY }, '');
history.pushState({}, '', href);
}
await loadPage(href);
await (router.onAfterRouteChange ?? router.onAfterRouteChanged)?.(href);
}
let latestPendingPath = null;
async function loadPage(href, scrollPosition = 0, isRetry = false) {
if ((await router.onBeforePageLoad?.(href)) === false)
return;
const targetLoc = new URL(href, fakeHost);
const pendingPath = (latestPendingPath = targetLoc.pathname);
try {
let page = await loadPageModule(pendingPath);
if (!page) {
throw new Error(`Page not found: ${pendingPath}`);
}
if (latestPendingPath === pendingPath) {
latestPendingPath = null;
const { default: comp, __pageData } = page;
if (!comp) {
throw new Error(`Invalid route component: ${comp}`);
}
await router.onAfterPageLoad?.(href);
route.path = inBrowser ? pendingPath : withBase(pendingPath);
route.component = markRaw(comp);
route.data = import.meta.env.PROD
? markRaw(__pageData)
: readonly(__pageData);
if (inBrowser) {
nextTick(() => {
let actualPathname = siteDataRef.value.base +
__pageData.relativePath.replace(/(?:(^|\/)index)?\.md$/, '$1');
if (!siteDataRef.value.cleanUrls && !actualPathname.endsWith('/')) {
actualPathname += '.html';
}
if (actualPathname !== targetLoc.pathname) {
targetLoc.pathname = actualPathname;
href = actualPathname + targetLoc.search + targetLoc.hash;
history.replaceState({}, '', href);
}
if (targetLoc.hash && !scrollPosition) {
let target = null;
try {
target = document.getElementById(decodeURIComponent(targetLoc.hash).slice(1));
}
catch (e) {
console.warn(e);
}
if (target) {
scrollTo(target, targetLoc.hash);
return;
}
}
window.scrollTo(0, scrollPosition);
});
}
}
}
catch (err) {
if (!/fetch|Page not found/.test(err.message) &&
!/^\/404(\.html|\/)?$/.test(href)) {
console.error(err);
}
// retry on fetch fail: the page to hash map may have been invalidated
// because a new deploy happened while the page is open. Try to fetch
// the updated pageToHash map and fetch again.
if (!isRetry) {
try {
const res = await fetch(siteDataRef.value.base + 'hashmap.json');
window.__VP_HASH_MAP__ = await res.json();
await loadPage(href, scrollPosition, true);
return;
}
catch (e) { }
}
if (latestPendingPath === pendingPath) {
latestPendingPath = null;
route.path = inBrowser ? pendingPath : withBase(pendingPath);
route.component = fallbackComponent ? markRaw(fallbackComponent) : null;
const relativePath = inBrowser
? pendingPath
.replace(/(^|\/)$/, '$1index')
.replace(/(\.html)?$/, '.md')
.replace(/^\//, '')
: '404.md';
route.data = { ...notFoundPageData, relativePath };
}
}
}
if (inBrowser) {
if (history.state === null) {
history.replaceState({}, '');
}
window.addEventListener('click', (e) => {
if (e.defaultPrevented ||
!(e.target instanceof Element) ||
e.target.closest('button') || // temporary fix for docsearch action buttons
e.button !== 0 ||
e.ctrlKey ||
e.shiftKey ||
e.altKey ||
e.metaKey)
return;
const link = e.target.closest('a');
if (!link ||
link.closest('.vp-raw') ||
link.hasAttribute('download') ||
link.hasAttribute('target'))
return;
const linkHref = link.getAttribute('href') ??
(link instanceof SVGAElement ? link.getAttribute('xlink:href') : null);
if (linkHref == null)
return;
const { href, origin, pathname, hash, search } = new URL(linkHref, link.baseURI);
const currentUrl = new URL(location.href); // copy to keep old data
// only intercept inbound html links
if (origin === currentUrl.origin && treatAsHtml(pathname)) {
e.preventDefault();
if (pathname === currentUrl.pathname &&
search === currentUrl.search) {
// scroll between hash anchors in the same page
// avoid duplicate history entries when the hash is same
if (hash !== currentUrl.hash) {
history.pushState({}, '', href);
// still emit the event so we can listen to it in themes
window.dispatchEvent(new HashChangeEvent('hashchange', {
oldURL: currentUrl.href,
newURL: href
}));
}
if (hash) {
// use smooth scroll when clicking on header anchor links
scrollTo(link, hash, link.classList.contains('header-anchor'));
}
else {
window.scrollTo(0, 0);
}
}
else {
go(href);
}
}
}, { capture: true });
window.addEventListener('popstate', async (e) => {
if (e.state === null)
return;
const href = normalizeHref(location.href);
await loadPage(href, (e.state && e.state.scrollPosition) || 0);
await (router.onAfterRouteChange ?? router.onAfterRouteChanged)?.(href);
});
window.addEventListener('hashchange', (e) => {
e.preventDefault();
});
}
handleHMR(route);
return router;
}
export function useRouter() {
const router = inject(RouterSymbol);
if (!router) {
throw new Error('useRouter() is called without provider.');
}
return router;
}
export function useRoute() {
return useRouter().route;
}
export function scrollTo(el, hash, smooth = false) {
let target = null;
try {
target = el.classList.contains('header-anchor')
? el
: document.getElementById(decodeURIComponent(hash).slice(1));
}
catch (e) {
console.warn(e);
}
if (target) {
const targetPadding = parseInt(window.getComputedStyle(target).paddingTop, 10);
const targetTop = window.scrollY +
target.getBoundingClientRect().top -
getScrollOffset() +
targetPadding;
function scrollToTarget() {
// only smooth scroll if distance is smaller than screen height.
if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight)
window.scrollTo(0, targetTop);
else
window.scrollTo({ left: 0, top: targetTop, behavior: 'smooth' });
}
requestAnimationFrame(scrollToTarget);
}
}
function handleHMR(route) {
// update route.data on HMR updates of active page
if (import.meta.hot) {
// hot reload pageData
import.meta.hot.on('vitepress:pageData', (payload) => {
if (shouldHotReload(payload)) {
route.data = payload.pageData;
}
});
}
}
function shouldHotReload(payload) {
const payloadPath = payload.path.replace(/(?:(^|\/)index)?\.md$/, '$1');
const locationPath = location.pathname
.replace(/(?:(^|\/)index)?\.html$/, '')
.slice(siteDataRef.value.base.length - 1);
return payloadPath === locationPath;
}
function normalizeHref(href) {
const url = new URL(href, fakeHost);
url.pathname = url.pathname.replace(/(^|\/)index(\.html)?$/, '$1');
// ensure correct deep link so page refresh lands on correct files.
if (siteDataRef.value.cleanUrls)
url.pathname = url.pathname.replace(/\.html$/, '');
else if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html'))
url.pathname += '.html';
return url.pathname + url.search + url.hash;
}

10
node_modules/vitepress/dist/client/app/ssr.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
// entry for SSR
import { renderToString } from 'vue/server-renderer';
import { createApp } from './index';
export async function render(path) {
const { app, router } = await createApp();
await router.go(path);
const ctx = { content: '', vpSocialIcons: new Set() };
ctx.content = await renderToString(app, ctx);
return ctx;
}

1
node_modules/vitepress/dist/client/app/theme.js generated vendored Normal file
View File

@@ -0,0 +1 @@
export {};

119
node_modules/vitepress/dist/client/app/utils.js generated vendored Normal file
View File

@@ -0,0 +1,119 @@
import { h, onMounted, onUnmounted, shallowRef } from 'vue';
import { EXTERNAL_URL_RE, inBrowser, sanitizeFileName } from '../shared';
import { siteDataRef } from './data';
export { escapeHtml as _escapeHtml, inBrowser } from '../shared';
/**
* Join two paths by resolving the slash collision.
*/
export function joinPath(base, path) {
return `${base}${path}`.replace(/\/+/g, '/');
}
/**
* Append base to internal (non-relative) urls
*/
export function withBase(path) {
return EXTERNAL_URL_RE.test(path) || !path.startsWith('/')
? path
: joinPath(siteDataRef.value.base, path);
}
/**
* Converts a url path to the corresponding js chunk filename.
*/
export function pathToFile(path) {
let pagePath = path.replace(/\.html$/, '');
pagePath = decodeURIComponent(pagePath);
pagePath = pagePath.replace(/\/$/, '/index'); // /foo/ -> /foo/index
if (import.meta.env.DEV) {
// always force re-fetch content in dev
pagePath += `.md?t=${Date.now()}`;
}
else {
// in production, each .md file is built into a .md.js file following
// the path conversion scheme.
// /foo/bar.html -> ./foo_bar.md
if (inBrowser) {
const base = import.meta.env.BASE_URL;
pagePath =
sanitizeFileName(pagePath.slice(base.length).replace(/\//g, '_') || 'index') + '.md';
// client production build needs to account for page hash, which is
// injected directly in the page's html
let pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()];
if (!pageHash) {
pagePath = pagePath.endsWith('_index.md')
? pagePath.slice(0, -9) + '.md'
: pagePath.slice(0, -3) + '_index.md';
pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()];
}
if (!pageHash)
return null;
pagePath = `${base}${__ASSETS_DIR__}/${pagePath}.${pageHash}.js`;
}
else {
// ssr build uses much simpler name mapping
pagePath = `./${sanitizeFileName(pagePath.slice(1).replace(/\//g, '_'))}.md.js`;
}
}
return pagePath;
}
export let contentUpdatedCallbacks = [];
/**
* Register callback that is called every time the markdown content is updated
* in the DOM.
*/
export function onContentUpdated(fn) {
contentUpdatedCallbacks.push(fn);
onUnmounted(() => {
contentUpdatedCallbacks = contentUpdatedCallbacks.filter((f) => f !== fn);
});
}
export function defineClientComponent(loader, args, cb) {
return {
setup() {
const comp = shallowRef();
onMounted(async () => {
let res = await loader();
// interop module default
if (res && (res.__esModule || res[Symbol.toStringTag] === 'Module')) {
res = res.default;
}
comp.value = res;
await cb?.();
});
return () => (comp.value ? h(comp.value, ...(args ?? [])) : null);
}
};
}
export function getScrollOffset() {
let scrollOffset = siteDataRef.value.scrollOffset;
let offset = 0;
let padding = 24;
if (typeof scrollOffset === 'object' && 'padding' in scrollOffset) {
padding = scrollOffset.padding;
scrollOffset = scrollOffset.selector;
}
if (typeof scrollOffset === 'number') {
offset = scrollOffset;
}
else if (typeof scrollOffset === 'string') {
offset = tryOffsetSelector(scrollOffset, padding);
}
else if (Array.isArray(scrollOffset)) {
for (const selector of scrollOffset) {
const res = tryOffsetSelector(selector, padding);
if (res) {
offset = res;
break;
}
}
}
return offset;
}
function tryOffsetSelector(selector, padding) {
const el = document.querySelector(selector);
if (!el)
return 0;
const bot = el.getBoundingClientRect().bottom;
if (bot < 0)
return 0;
return bot + padding;
}