docs:更新文档

This commit is contained in:
张益铭
2021-03-01 15:06:11 +08:00
parent 1542135ab0
commit 9064b372e8
5835 changed files with 904126 additions and 161722 deletions

View File

@@ -0,0 +1,5 @@
export declare const Content: {
setup(): () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}> | null;
};

View File

@@ -0,0 +1,13 @@
import { h } from 'vue';
import { useRoute } from '../router';
import { usePrefetch } from '../composables/preFetch';
export const Content = {
setup() {
const route = useRoute();
if (process.env.NODE_ENV === 'production') {
// in prod mode, enable intersectionObserver based pre-fetch.
usePrefetch();
}
return () => (route.component ? h(route.component) : null);
}
};

View File

@@ -0,0 +1,55 @@
<template>
<div class="debug" :class="{ open }" @click="open = !open">
<pre>debug</pre>
<pre>$page {{ $page }}</pre>
<pre>$siteByRoute {{ $siteByRoute }}</pre>
<pre>$site {{ $site }}</pre>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const open = ref(false)
return {
open
}
}
}
</script>
<style>
.debug {
box-sizing: border-box;
position: fixed;
z-index: 999;
cursor: pointer;
bottom: 0;
right: 0;
width: 80px;
height: 30px;
padding: 5px;
overflow: hidden;
color: #eeeeee;
transition: all .15s ease;
background-color: rgba(0,0,0,0.85);
}
.debug.open {
width: 500px;
height: 100%;
margin-top: 0;
padding: 0 0;
overflow: scroll;
}
.debug pre {
font-family: Hack, monospace;
font-size: 13px;
margin: 0;
padding: 5px 10px;
border-bottom: 1px solid #eee;
}
</style>

View File

@@ -0,0 +1,4 @@
import { Ref } from 'vue';
import { SiteData } from '../../../../types/shared';
import { Route } from '../router';
export declare function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>): void;

View File

@@ -0,0 +1,57 @@
import { watchEffect } from 'vue';
export function useUpdateHead(route, siteDataByRouteRef) {
const metaTags = Array.from(document.querySelectorAll('meta'));
let isFirstUpdate = true;
const updateHeadTags = (newTags) => {
if (process.env.NODE_ENV === 'production' && isFirstUpdate) {
// in production, the initial meta tags are already pre-rendered so we
// skip the first update.
isFirstUpdate = false;
return;
}
metaTags.forEach((el) => document.head.removeChild(el));
metaTags.length = 0;
if (newTags && newTags.length) {
newTags.forEach((headConfig) => {
const el = createHeadElement(headConfig);
document.head.appendChild(el);
metaTags.push(el);
});
}
};
watchEffect(() => {
const pageData = route.data;
const siteData = siteDataByRouteRef.value;
const pageTitle = pageData && pageData.title;
document.title = (pageTitle ? pageTitle + ` | ` : ``) + siteData.title;
updateHeadTags([
['meta', { charset: 'utf-8' }],
[
'meta',
{
name: 'viewport',
content: 'width=device-width,initial-scale=1'
}
],
[
'meta',
{
name: 'description',
content: siteData.description
}
],
...siteData.head,
...((pageData && pageData.frontmatter.head) || [])
]);
});
}
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;
}
return el;
}

View File

@@ -0,0 +1 @@
export declare function usePrefetch(): void;

View File

@@ -0,0 +1,88 @@
// Customized pre-fetch for page chunks based on
// https://github.com/GoogleChromeLabs/quicklink
import { onMounted, onUnmounted, onUpdated } from 'vue';
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);
doFetch(pageChunkPath);
}
}
});
});
rIC(() => {
document.querySelectorAll('.vitepress-content a').forEach((link) => {
const { target, hostname, pathname } = link;
if (
// only prefetch same page navigation, since a new page will load
// the lean js chunk instead.
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);
onUpdated(observeLinks);
onUnmounted(() => {
observer && observer.disconnect();
});
}

View File

@@ -0,0 +1,5 @@
import { Ref } from 'vue';
import { SiteData } from '../../../../types/shared';
export declare type SiteDataRef<T = any> = Ref<SiteData<T>>;
export declare const siteDataRef: Ref<SiteData>;
export declare function useSiteData<T = any>(): Ref<SiteData<T>>;

View File

@@ -0,0 +1,13 @@
import serialized from '@siteData';
import { ref, readonly } from 'vue';
const parse = (data) => readonly(JSON.parse(data));
export const siteDataRef = ref(parse(serialized));
export function useSiteData() {
return siteDataRef;
}
// hmr
if (import.meta.hot) {
import.meta.hot.acceptDeps('/@siteData', (m) => {
siteDataRef.value = parse(m.default);
});
}

View File

@@ -0,0 +1,9 @@
export declare function useSiteDataByRoute(route?: import("../router").Route): import("vue").ComputedRef<{
themeConfig: any;
locales: {};
lang: string;
title: string;
description: string;
base: string;
head: import("../../../../types/shared").HeadConfig[];
}>;

View File

@@ -0,0 +1,9 @@
import { computed } from 'vue';
import { resolveSiteDataByRoute } from '/@shared/config';
import { siteDataRef } from './siteData';
import { useRoute } from '../router';
export function useSiteDataByRoute(route = useRoute()) {
return computed(() => {
return resolveSiteDataByRoute(siteDataRef.value, route.path);
});
}

8
node_modules/vitepress/dist/client/app/exports.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
export * from './theme';
export { useSiteData } from './composables/siteData';
export { useSiteDataByRoute } from './composables/siteDataByRoute';
export { useRouter, useRoute, Router, Route } from './router';
export { Content } from './components/Content';
import { ComponentOptions } from 'vue';
declare const Debug: ComponentOptions<{}, any, any, any, any, any, any, any>;
export { Debug };

13
node_modules/vitepress/dist/client/app/exports.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
// exports in this file are exposed to themes and md files via 'vitepress'
// so the user can do `import { useRoute, useSiteData } from 'vitepress'`
// theme types
export * from './theme';
// composables
export { useSiteData } from './composables/siteData';
export { useSiteDataByRoute } from './composables/siteDataByRoute';
export { useRouter, useRoute } from './router';
// components
export { Content } from './components/Content';
import _Debug from './components/Debug.vue';
const Debug = _Debug;
export { Debug };

4
node_modules/vitepress/dist/client/app/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export declare function createApp(): {
app: import("vue").App<Element>;
router: import("./router").Router;
};

2
node_modules/vitepress/dist/client/app/index.html generated vendored Normal file
View File

@@ -0,0 +1,2 @@
<div id="app"></div>
<script type="module" src="/@app/index.js"></script>

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

@@ -0,0 +1,93 @@
import { createApp as createClientApp, createSSRApp } from 'vue';
import { createRouter, RouterSymbol } from './router';
import { useUpdateHead } from './composables/head';
import { Content } from './components/Content';
import Debug from './components/Debug.vue';
import Theme from '/@theme/index';
import { inBrowser, pathToFile } from './utils';
import { useSiteDataByRoute } from './composables/siteDataByRoute';
import { siteDataRef } from './composables/siteData';
const NotFound = Theme.NotFound || (() => '404 Not Found');
export function createApp() {
let isInitialPageLoad = inBrowser;
let initialPath;
const router = createRouter((path) => {
let pageFilePath = pathToFile(path);
if (isInitialPageLoad) {
initialPath = pageFilePath;
}
// use lean build if this is the initial page load or navigating back
// to the initial loaded path (the static vnodes already adopted the
// static content on that load so no need to re-fetch the page)
if (isInitialPageLoad || initialPath === pageFilePath) {
pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js');
}
if (inBrowser) {
isInitialPageLoad = false;
// in browser: native dynamic import
return import(/*@vite-ignore*/ pageFilePath);
}
else {
// SSR, sync require
return require(pageFilePath);
}
}, NotFound);
// update route.data on HMR updates of active page
if (import.meta.hot) {
// hot reload pageData
import.meta.hot.on('vitepress:pageData', (payload) => {
if (payload.path.replace(/(\bindex)?\.md$/, '') ===
location.pathname.replace(/(\bindex)?\.html$/, '')) {
router.route.data = payload.pageData;
}
});
}
const app = process.env.NODE_ENV === 'production'
? createSSRApp(Theme.Layout)
: createClientApp(Theme.Layout);
app.provide(RouterSymbol, router);
app.component('Content', Content);
app.component('Debug', process.env.NODE_ENV === 'production' ? () => null : Debug);
const siteDataByRouteRef = useSiteDataByRoute(router.route);
if (inBrowser) {
// dynamically update head tags
useUpdateHead(router.route, siteDataByRouteRef);
}
Object.defineProperties(app.config.globalProperties, {
$site: {
get() {
return siteDataRef.value;
}
},
$siteByRoute: {
get() {
return siteDataByRouteRef.value;
}
},
$page: {
get() {
return router.route.data;
}
},
$theme: {
get() {
return siteDataByRouteRef.value.themeConfig;
}
}
});
if (Theme.enhanceApp) {
Theme.enhanceApp({
app,
router,
siteData: siteDataByRouteRef
});
}
return { app, router };
}
if (inBrowser) {
const { app, router } = createApp();
// wait unitl page component is fetched before mounting
router.go().then(() => {
app.mount('#app');
});
}

20
node_modules/vitepress/dist/client/app/router.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import type { Component, InjectionKey } from 'vue';
import { PageData } from '../../../types/shared';
export interface Route {
path: string;
data: PageData;
component: Component | null;
}
export interface Router {
route: Route;
go: (href?: string) => Promise<void>;
}
export declare const RouterSymbol: InjectionKey<Router>;
interface PageModule {
__pageData: string;
default: Component;
}
export declare function createRouter(loadPageModule: (path: string) => PageModule | Promise<PageModule>, fallbackComponent?: Component): Router;
export declare function useRouter(): Router;
export declare function useRoute(): Route;
export {};

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

@@ -0,0 +1,148 @@
import { reactive, inject, markRaw, nextTick, readonly } from 'vue';
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,
// this will be set upon initial page load, which is before
// the app is mounted, so it's guaranteed to be avaiable in
// components
data: null
});
export function createRouter(loadPageModule, fallbackComponent) {
const route = reactive(getDefaultRoute());
const inBrowser = typeof window !== 'undefined';
function go(href = inBrowser ? location.href : '/') {
// ensure correct deep link so page refresh lands on correct files.
const url = new URL(href, fakeHost);
if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html')) {
url.pathname += '.html';
href = url.pathname + url.search + url.hash;
}
if (inBrowser) {
// save scroll position before changing url
history.replaceState({ scrollPosition: window.scrollY }, document.title);
history.pushState(null, '', href);
}
return loadPage(href);
}
let latestPendingPath = null;
async function loadPage(href, scrollPosition = 0) {
const targetLoc = new URL(href, fakeHost);
const pendingPath = (latestPendingPath = targetLoc.pathname);
try {
let page = loadPageModule(pendingPath);
// only await if it returns a Promise - this allows sync resolution
// on initial render in SSR.
if ('then' in page && typeof page.then === 'function') {
page = await page;
}
if (latestPendingPath === pendingPath) {
latestPendingPath = null;
const { default: comp, __pageData } = page;
if (!comp) {
throw new Error(`Invalid route component: ${comp}`);
}
route.path = pendingPath;
route.component = markRaw(comp);
route.data = readonly(JSON.parse(__pageData));
if (inBrowser) {
nextTick(() => {
if (targetLoc.hash && !scrollPosition) {
const target = document.querySelector(decodeURIComponent(targetLoc.hash));
if (target) {
scrollTo(target, targetLoc.hash);
return;
}
}
window.scrollTo(0, scrollPosition);
});
}
}
}
catch (err) {
if (!err.message.match(/fetch/)) {
console.error(err);
}
if (latestPendingPath === pendingPath) {
latestPendingPath = null;
route.path = pendingPath;
route.component = fallbackComponent ? markRaw(fallbackComponent) : null;
}
}
}
if (inBrowser) {
window.addEventListener('click', (e) => {
const link = e.target.closest('a');
if (link) {
const { href, protocol, hostname, pathname, hash, target } = link;
const currentUrl = window.location;
// only intercept inbound links
if (!e.ctrlKey &&
!e.shiftKey &&
!e.altKey &&
!e.metaKey &&
target !== `_blank` &&
protocol === currentUrl.protocol &&
hostname === currentUrl.hostname) {
e.preventDefault();
if (pathname === currentUrl.pathname) {
// scroll between hash anchors in the same page
if (hash && hash !== currentUrl.hash) {
history.pushState(null, '', hash);
// use smooth scroll when clicking on header anchor links
scrollTo(link, hash, link.classList.contains('header-anchor'));
}
}
else {
go(href);
}
}
}
}, { capture: true });
window.addEventListener('popstate', (e) => {
loadPage(location.href, (e.state && e.state.scrollPosition) || 0);
});
window.addEventListener('hashchange', (e) => {
e.preventDefault();
});
}
return {
route,
go
};
}
export function useRouter() {
const router = inject(RouterSymbol);
if (!router) {
throw new Error('useRouter() is called without provider.');
}
// @ts-ignore
return router;
}
export function useRoute() {
return useRouter().route;
}
function scrollTo(el, hash, smooth = false) {
const pageOffset = document.querySelector('.navbar')
.offsetHeight;
const target = el.classList.contains('.header-anchor')
? el
: document.querySelector(decodeURIComponent(hash));
if (target) {
const targetTop = target.offsetTop - pageOffset - 15;
// 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'
});
}
}
}

13
node_modules/vitepress/dist/client/app/theme.d.ts generated vendored Normal file
View File

@@ -0,0 +1,13 @@
import { App, Ref, ComponentOptions } from 'vue';
import { Router } from './router';
import { SiteData } from '../../../types/shared';
export interface EnhanceAppContext {
app: App;
router: Router;
siteData: Ref<SiteData>;
}
export interface Theme {
Layout: ComponentOptions;
NotFound?: ComponentOptions;
enhanceApp?: (ctx: EnhanceAppContext) => void;
}

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

5
node_modules/vitepress/dist/client/app/utils.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
export declare const inBrowser: boolean;
/**
* Converts a url path to the corresponding js chunk filename.
*/
export declare function pathToFile(path: string): string;

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

@@ -0,0 +1,32 @@
export const inBrowser = typeof window !== 'undefined';
/**
* Converts a url path to the corresponding js chunk filename.
*/
export function pathToFile(path) {
let pagePath = path.replace(/\.html$/, '');
if (pagePath.endsWith('/')) {
pagePath += 'index';
}
if (import.meta.env.DEV) {
// awlays 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 = pagePath.slice(base.length).replace(/\//g, '_') + '.md';
// client production build needs to account for page hash, which is
// injected directly in the page's html
const pageHash = __VP_HASH_MAP__[pagePath];
pagePath = `${base}_assets/${pagePath}.${pageHash}.js`;
}
else {
// ssr build uses much simpler name mapping
pagePath = `./${pagePath.slice(1).replace(/\//g, '_')}.md.js`;
}
}
return pagePath;
}

10
node_modules/vitepress/dist/client/shared/config.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
import { SiteData } from '/@types/shared';
export declare function resolveSiteDataByRoute(siteData: SiteData, route: string): {
themeConfig: any;
locales: {};
lang: string;
title: string;
description: string;
base: string;
head: import("../../../types/shared").HeadConfig[];
};

50
node_modules/vitepress/dist/client/shared/config.js generated vendored Normal file
View File

@@ -0,0 +1,50 @@
const inBrowser = typeof window !== 'undefined';
function findMatchRoot(route, roots) {
// first match to the routes with the most deep level.
roots.sort((a, b) => {
const levelDelta = b.split('/').length - a.split('/').length;
if (levelDelta !== 0) {
return levelDelta;
}
else {
return b.length - a.length;
}
});
for (const r of roots) {
if (route.startsWith(r))
return r;
}
return undefined;
}
function resolveLocales(locales, route) {
const localeRoot = findMatchRoot(route, Object.keys(locales));
return localeRoot ? locales[localeRoot] : undefined;
}
// this merges the locales data to the main data by the route
export function resolveSiteDataByRoute(siteData, route) {
route = cleanRoute(siteData, route);
const localeData = resolveLocales(siteData.locales || {}, route) || {};
const localeThemeConfig = resolveLocales((siteData.themeConfig && siteData.themeConfig.locales) || {}, route) || {};
return {
...siteData,
...localeData,
themeConfig: {
...siteData.themeConfig,
...localeThemeConfig,
// clean the locales to reduce the bundle size
locales: {}
},
locales: {}
};
}
/**
* Clean up the route by removing the `base` path if it's set in config.
*/
function cleanRoute(siteData, route) {
if (!inBrowser) {
return route;
}
const base = siteData.base;
const baseWithoutSuffix = base.endsWith('/') ? base.slice(0, -1) : base;
return route.slice(baseWithoutSuffix.length);
}

View File

@@ -0,0 +1,131 @@
<template>
<div class="theme" :class="pageClasses">
<header class="navbar" v-if="showNavbar">
<NavBar>
<template #search>
<slot name="navbar-search" />
</template>
</NavBar>
<ToggleSideBarButton @toggle="toggleSidebar" />
</header>
<aside :class="{ open: openSideBar }">
<SideBar>
<template #top>
<slot name="sidebar-top" />
</template>
<template #bottom>
<slot name="sidebar-bottom" />
</template>
</SideBar>
</aside>
<!-- TODO: make this button accessible -->
<div class="sidebar-mask" @click="toggleSidebar(false)" />
<main class="home" aria-labelledby="main-title" v-if="enableHome">
<Home>
<template #hero>
<slot name="home-hero" />
</template>
<template #features>
<slot name="home-features" />
</template>
<template #footer>
<slot name="home-footer" />
</template>
</Home>
</main>
<main v-else>
<Page>
<template #top>
<slot name="page-top" />
</template>
<template #bottom>
<slot name="page-bottom" />
</template>
</Page>
</main>
</div>
<Debug />
</template>
<script>
import { ref, computed, watch } from 'vue'
import NavBar from './components/NavBar.vue'
import Home from './components/Home.vue'
import ToggleSideBarButton from './components/ToggleSideBarButton.vue'
import SideBar from './components/SideBar.vue'
import Page from './components/Page.vue'
import { useRoute, useSiteData, useSiteDataByRoute } from 'vitepress'
export default {
components: {
Home,
NavBar,
ToggleSideBarButton,
SideBar,
Page
},
setup() {
const route = useRoute()
const siteData = useSiteData()
const siteRouteData = useSiteDataByRoute()
const openSideBar = ref(false)
const enableHome = computed(() => !!route.data.frontmatter.home)
const showNavbar = computed(() => {
const { themeConfig } = siteRouteData.value
const { frontmatter } = route.data
if (
frontmatter.navbar === false
|| themeConfig.navbar === false) {
return false
}
return (
siteData.value.title
|| themeConfig.logo
|| themeConfig.repo
|| themeConfig.nav
)
})
const showSidebar = computed(() => {
const { frontmatter } = route.data
const { themeConfig } = siteRouteData.value
return (
!frontmatter.home
&& frontmatter.sidebar !== false
&& ((typeof themeConfig.sidebar === 'object') && (Object.keys(themeConfig.sidebar).length != 0)
|| (Array.isArray(themeConfig.sidebar) && themeConfig.sidebar.length != 0))
)
})
const pageClasses = computed(() => {
return [{
'no-navbar': !showNavbar.value,
'sidebar-open': openSideBar.value,
'no-sidebar': !showSidebar.value
}]
})
const toggleSidebar = (to) => {
openSideBar.value = typeof to === 'boolean' ? to : !openSideBar.value
}
const hideSidebar = toggleSidebar.bind(null, false)
// close the sidebar when navigating to a different location
watch(route, hideSidebar)
// TODO: route only changes when the pathname changes
// listening to hashchange does nothing because it's prevented in router
return {
showNavbar,
showSidebar,
openSideBar,
pageClasses,
enableHome,
toggleSidebar
}
}
}
</script>

View File

@@ -0,0 +1,26 @@
<template>
<div class="theme">
<h1>404</h1>
<blockquote>{{ getMsg() }}</blockquote>
<a :href="$site.base" aria-label="go to home">
Take me home.
</a>
</div>
</template>
<script>
const msgs = [
`There's nothing here.`,
`How did we get here?`,
`That's a Four-Oh-Four.`,
`Looks like we've got some broken links.`
]
export default {
setup: () => ({
getMsg() {
return msgs[Math.floor(Math.random() * msgs.length)]
}
})
}
</script>

View File

@@ -0,0 +1,219 @@
<template>
<header class="hero">
<img
v-if="data.heroImage"
:src="heroImageSrc"
:alt="data.heroAlt || 'hero'"
>
<h1
v-if="data.heroText !== null"
id="main-title"
>
{{ data.heroText || siteTitle || 'Hello' }}
</h1>
<p
v-if="data.tagline !== null"
class="description"
>
{{ data.tagline || siteDescription || 'Welcome to your VitePress site' }}
</p>
<p
v-if="data.actionText && data.actionLink"
class="action"
>
<NavBarLink :item="actionLink" />
</p>
<slot name="hero" />
</header>
<div
v-if="data.features && data.features.length"
class="features"
>
<div
v-for="(feature, index) in data.features"
:key="index"
class="feature"
>
<h2>{{ feature.title }}</h2>
<p>{{ feature.details }}</p>
</div>
<slot name="features" />
</div>
<div
v-if="data.footer"
class="footer"
>
{{ data.footer }}
<slot name="footer" />
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue'
import NavBarLink from './NavBarLink.vue'
import { withBase } from '../utils'
import { useRoute, useSiteData } from 'vitepress'
export default defineComponent({
components: {
NavBarLink
},
setup() {
const route = useRoute()
const siteData = useSiteData()
const data = computed(() => route.data.frontmatter)
const actionLink = computed(() => ({
link: data.value.actionLink,
text: data.value.actionText
}))
const heroImageSrc = computed(() => withBase(data.value.heroImage))
const siteTitle = computed(() => siteData.value.title)
const siteDescription = computed(() => siteData.value.description)
return {
data,
actionLink,
heroImageSrc,
siteTitle,
siteDescription
}
}
})
</script>
<style scoped>
.hero {
text-align: center;
}
.hero img {
max-width: 100%;
max-height: 280px;
display: block;
margin: 3rem auto 1.5rem;
}
.hero h1 {
font-size: 3rem;
}
.hero h1,
.hero .description,
.hero .action {
margin: 1.8rem auto;
}
.hero .description {
max-width: 35rem;
font-size: 1.6rem;
line-height: 1.3;
/* TODO: calculating lighten 40% color with using style :vars from `--text-color` */
color: #6a8bad;
}
::v-deep(.nav-link) {
display: inline-block;
font-size: 1.2rem;
color: #fff;
background-color: var(--accent-color);
margin-left: 0;
padding: 0.8rem 1.6rem;
border-radius: 4px;
transition: background-color .1s ease;
box-sizing: border-box;
/* TODO: calculating darken 10% color with using style vars from `--accent-color` */
border-bottom: 1px solid #389d70;
}
::v-deep(.nav-link:hover) {
/* TODO: calculating lighten 10% color with using style vars from `--accent-color` */
background-color: #4abf8a;
}
.features {
border-top: 1px solid var(--border-color);
padding: 1.2rem 0;
margin-top: 2.5rem;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
align-content: stretch;
justify-content: space-between;
}
.feature {
flex-grow: 1;
flex-basis: 30%;
max-width: 30%;
}
.feature h2 {
font-size: 1.4rem;
font-weight: 500;
border-bottom: none;
padding-bottom: 0;
/* TODO: calculating lighten 10% color with using style :vars from `--text-color` */
color: #3a5169;
}
.feature p {
/* TODO: calculating lighten 25% color with using style :vars from `--text-color` */
color: #4e6e8e;
}
.footer {
padding: 2.5rem;
border-top: 1px solid var(--border-color);
text-align: center;
/* TODO: calculating lighten 25% color with using style :vars from `--text-color` */
color: #4e6e8e;
}
@media screen and (max-width: 719px) {
.features {
flex-direction: column;
}
.feature {
max-width: 100%;
padding: 0 2.5rem;
}
}
@media screen and (max-width: 429px) {
.hero img {
max-height: 210px;
margin: 2rem auto 1.2rem;
}
.hero h1 {
font-size: 2rem;
}
.hero h1,
.hero .description,
.hero .action {
margin: 1.2rem auto;
}
.hero .description {
font-size: 1.2rem;
}
.hero .action-button {
font-size: 1rem;
padding: 0.6rem 1.2rem;
}
.feature h2 {
font-size: 1.25rem;
}
}
</style>

View File

@@ -0,0 +1,10 @@
import { withBase } from '../utils';
declare const _default: {
components: {
NavBarLinks: import("vue").ComponentOptions<{}, any, any, any, any, any, any, any>;
};
setup(): {
withBase: typeof withBase;
};
};
export default _default;

View File

@@ -0,0 +1,10 @@
import { withBase } from '../utils';
import NavBarLinks from './NavBarLinks.vue';
export default {
components: {
NavBarLinks
},
setup() {
return { withBase };
}
};

View File

@@ -0,0 +1,44 @@
<template>
<a
class="title"
:aria-label="$site.title + ', back to home'"
:href="$site.base"
>
<img
class="logo"
v-if="$theme.logo"
:src="withBase($theme.logo)"
alt="logo"
/>
<span>{{ $site.title }}</span>
</a>
<div class="flex-grow"></div>
<NavBarLinks class="hide-mobile" />
<slot name="search" />
</template>
<script src="./NavBar"></script>
<style>
.title {
font-size: 1.3rem;
font-weight: 600;
color: var(--text-color);
}
.flex-grow {
flex-grow: 1;
}
.logo {
margin-right: 0.75rem;
height: 1.3rem;
vertical-align: bottom;
}
@media screen and (max-width: 719px) {
.hide-mobile {
display: none;
}
}
</style>

View File

@@ -0,0 +1,21 @@
import { PropType } from 'vue';
import { DefaultTheme } from '../config';
declare const _default: import("vue").DefineComponent<{
item: {
type: PropType<DefaultTheme.NavItemWithLink>;
required: true;
};
}, {
classes: import("vue").ComputedRef<{
active: boolean;
external: boolean;
}>;
isActiveLink: import("vue").ComputedRef<boolean>;
isExternalLink: import("vue").ComputedRef<boolean>;
href: import("vue").ComputedRef<string>;
target: import("vue").ComputedRef<string>;
rel: import("vue").ComputedRef<string>;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
item: DefaultTheme.NavItemWithLink;
} & {}>, {}>;
export default _default;

View File

@@ -0,0 +1,62 @@
import { defineComponent, computed } from 'vue';
import { useRoute } from 'vitepress';
import { withBase, isExternal } from '../utils';
import OutboundLink from './icons/OutboundLink.vue';
const normalizePath = (path) => {
path = path
.replace(/#.*$/, '')
.replace(/\?.*$/, '')
.replace(/\.html$/, '');
if (path.endsWith('/')) {
path += 'index';
}
return path;
};
export default defineComponent({
components: {
OutboundLink
},
props: {
item: {
type: Object,
required: true
}
},
setup(props) {
const item = props.item;
const route = useRoute();
const classes = computed(() => ({
active: isActiveLink.value,
external: isExternalLink.value
}));
const isActiveLink = computed(() => {
return normalizePath(withBase(item.link)) === normalizePath(route.path);
});
const isExternalLink = computed(() => {
return isExternal(item.link);
});
const href = computed(() => {
return isExternalLink.value ? item.link : withBase(item.link);
});
const target = computed(() => {
if (item.target) {
return item.target;
}
return isExternalLink.value ? '_blank' : '';
});
const rel = computed(() => {
if (item.rel) {
return item.rel;
}
return isExternalLink.value ? 'noopener noreferrer' : '';
});
return {
classes,
isActiveLink,
isExternalLink,
href,
target,
rel
};
}
});

View File

@@ -0,0 +1,69 @@
<template>
<div class="nav-item">
<a
class="nav-link"
:class="classes"
:href="href"
:target="target"
:rel="rel"
:aria-label="item.ariaLabel"
>
{{ item.text }}
<OutboundLink v-if="isExternalLink" />
</a>
</div>
</template>
<script src="./NavBarLink"></script>
<style>
.nav-item {
position: relative;
display: inline-block;
margin-left: 1.5rem;
line-height: 2rem;
}
@media screen and (max-width: 719px) {
.nav-item {
display: block;
margin-left: 0;
padding: 0.3rem 1.5rem;
}
}
.nav-link {
display: block;
margin-bottom: -2px;
border-bottom: 2px solid transparent;
font-size: 0.9rem;
font-weight: 500;
line-height: 1.4rem;
color: var(--text-color);
white-space: nowrap;
}
.nav-link:hover,
.nav-link.active {
border-bottom-color: var(--accent-color);
}
.nav-link.external:hover {
border-bottom-color: transparent;
}
@media screen and (max-width: 719px) {
.nav-link {
line-height: 1.7;
font-size: 1em;
font-weight: 600;
border-bottom: none;
margin-bottom: 0;
}
.nav-link:hover,
.nav-link.active {
color: var(--accent-color);
}
}
</style>

View File

@@ -0,0 +1,21 @@
declare const _default: {
components: {
NavBarLink: import("vue").ComponentOptions<{}, any, any, any, any, any, any, any>;
NavDropdownLink: import("vue").ComponentOptions<{}, any, any, any, any, any, any, any>;
};
setup(): {
navData: import("vue").ComputedRef<any>;
repoInfo: import("vue").ComputedRef<{
link: string;
text: string;
} | null>;
localeCandidates: import("vue").ComputedRef<{
text: any;
items: {
text: any;
link: string;
}[];
} | null>;
};
};
export default _default;

View File

@@ -0,0 +1,85 @@
import { computed } from 'vue';
import { useSiteData, useSiteDataByRoute, useRoute } from 'vitepress';
import { inBrowser } from '/@app/utils';
import NavBarLink from './NavBarLink.vue';
import NavDropdownLink from './NavDropdownLink.vue';
const platforms = ['GitHub', 'GitLab', 'Bitbucket'].map((platform) => [platform, new RegExp(platform, 'i')]);
export default {
components: {
NavBarLink,
NavDropdownLink
},
setup() {
const siteDataByRoute = useSiteDataByRoute();
const siteData = useSiteData();
const route = useRoute();
const repoInfo = computed(() => {
const theme = siteData.value.themeConfig;
const repo = theme.docsRepo || theme.repo;
let text = theme.repoLabel;
if (repo) {
const link = /^https?:/.test(repo) ? repo : `https://github.com/${repo}`;
if (!text) {
// if no label is provided, deduce it from the repo url
const repoHosts = link.match(/^https?:\/\/[^/]+/);
if (repoHosts) {
const repoHost = repoHosts[0];
const foundPlatform = platforms.find(([_platform, re]) => re.test(repoHost));
text = foundPlatform && foundPlatform[0];
}
}
return { link, text: text || 'Source' };
}
return null;
});
const localeCandidates = computed(() => {
const locales = siteData.value.themeConfig.locales;
if (!locales) {
return null;
}
const localeKeys = Object.keys(locales);
if (localeKeys.length <= 1) {
return null;
}
// handle site base
const siteBase = inBrowser ? siteData.value.base : '/';
const siteBaseWithoutSuffix = siteBase.endsWith('/')
? siteBase.slice(0, -1)
: siteBase;
// remove site base in browser env
const routerPath = route.path.slice(siteBaseWithoutSuffix.length);
const currentLangBase = localeKeys.find((v) => {
if (v === '/') {
return false;
}
return routerPath.startsWith(v);
});
const currentContentPath = currentLangBase
? routerPath.substring(currentLangBase.length - 1)
: routerPath;
const candidates = localeKeys.map((v) => {
const localePath = v.endsWith('/') ? v.slice(0, -1) : v;
return {
text: locales[v].label || locales[v].lang,
link: `${localePath}${currentContentPath}`
};
});
const currentLangKey = currentLangBase ? currentLangBase : '/';
const selectText = locales[currentLangKey].selectText
? locales[currentLangKey].selectText
: 'Languages';
return {
text: selectText,
items: candidates
};
});
const navData = computed(() => {
return siteDataByRoute.value.themeConfig.nav;
});
return {
navData,
repoInfo,
localeCandidates
};
}
};

View File

@@ -0,0 +1,33 @@
<template>
<nav class="nav-links" v-if="navData || repoInfo">
<template v-if="navData">
<template v-for="item of navData">
<NavDropdownLink v-if="item.items" :item="item" />
<NavBarLink v-else :item="item" />
</template>
</template>
<NavDropdownLink v-if="localeCandidates" :item="localeCandidates" />
<NavBarLink v-if="repoInfo" :item="repoInfo" />
</nav>
</template>
<script src="./NavBarLinks"></script>
<style>
.nav-links {
display: flex;
align-items: center;
height: 35px;
list-style-type: none;
transform: translateY(1px);
}
@media screen and (max-width: 719px) {
.nav-links {
display: block;
height: auto;
padding: 0.5rem 0 1rem;
border-bottom: 1px solid var(--border-color);
}
}
</style>

View File

@@ -0,0 +1,15 @@
import { PropType } from 'vue';
import { DefaultTheme } from '../config';
declare const _default: import("vue").DefineComponent<{
item: {
type: PropType<DefaultTheme.NavItemWithChildren>;
required: true;
};
}, {
open: import("vue").Ref<boolean>;
setOpen: (value: boolean) => void;
isLastItemOfArray: <T>(item: T, array: T[]) => boolean | 0;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
item: DefaultTheme.NavItemWithChildren;
} & {}>, {}>;
export default _default;

View File

@@ -0,0 +1,33 @@
import NavBarLink from './NavBarLink.vue';
import { defineComponent, ref, watch } from 'vue';
import { useRoute } from 'vitepress';
export default defineComponent({
name: 'DropdownLink',
components: {
NavBarLink
},
props: {
item: {
type: Object,
required: true
}
},
setup(props) {
const open = ref(false);
const route = useRoute();
watch(() => route.path, () => {
open.value = false;
});
const setOpen = (value) => {
open.value = value;
};
const isLastItemOfArray = (item, array) => {
return array.length && array.indexOf(item) === array.length - 1;
};
return {
open,
setOpen,
isLastItemOfArray
};
}
});

View File

@@ -0,0 +1,218 @@
<template>
<div class="dropdown-wrapper" :class="{ open }">
<button
class="dropdown-title"
type="button"
:aria-label="item.ariaLabel"
@click="setOpen(!open)"
>
<span>{{ item.text }}</span>
<span class="arrow" :class="open ? 'down' : 'right'" />
</button>
<ul class="nav-dropdown">
<li v-for="(subItem, index) in item.items" :key="subItem.link || index" class="dropdown-item">
<h4 v-if="subItem.items">{{ subItem.text }}</h4>
<ul v-if="subItem.items" class="dropdown-subitem-wrapper">
<li
v-for="childSubItem in subItem.items"
:key="childSubItem.link"
class="dropdown-subitem"
>
<NavBarLink
:item="childSubItem"
@focusout="
isLastItemOfArray(childSubItem, subItem.items) &&
isLastItemOfArray(subItem, item.items) &&
setOpen(false)
"
/>
</li>
</ul>
<NavBarLink
v-else
:item="subItem"
@focusout="isLastItemOfArray(subItem, item.items) && setOpen(false)"
/>
</li>
</ul>
</div>
</template>
<script src="./NavDropdownLink"></script>
<style>
.dropdown-wrapper {
position: relative;
cursor: pointer;
display: block;
margin-left: 1.5rem;
}
.dropdown-wrapper .dropdown-title {
font: inherit;
color: var(--text-color);
font-size: 0.9rem;
font-weight: 500;
display: inline-block;
height: 1.75rem;
line-height: 1.75rem;
padding: inherit;
background: transparent;
border: none;
}
.dropdown-wrapper .dropdown-title:hover {
border-color: transparent;
}
.dropdown-wrapper .dropdown-title .arrow {
display: inline-block;
vertical-align: middle;
margin-top: -1px;
margin-left: 0.4rem;
}
.dropdown-wrapper .nav-dropdown .dropdown-item {
color: inherit;
line-height: 1.7rem;
}
.dropdown-wrapper .nav-dropdown .dropdown-item h4 {
margin: 0.45rem 0 0;
border-top: 1px solid #eee;
padding: 0.45rem 1.5rem 0 1.25rem;
}
.dropdown-wrapper .nav-dropdown .dropdown-item .nav-item {
margin-left: 0.5rem;
}
.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper {
padding: 0;
list-style: none;
}
.dropdown-wrapper
.nav-dropdown
.dropdown-item
.dropdown-subitem-wrapper
.dropdown-subitem {
font-size: 0.9em;
}
.dropdown-wrapper .nav-dropdown .dropdown-item a {
display: block;
line-height: 1.7rem;
position: relative;
border-bottom: none;
font-weight: 400;
margin-bottom: 0;
margin-left: 0;
padding: 0 1.5rem 0 1.25rem;
}
.dropdown-wrapper .nav-dropdown .dropdown-item a:hover {
color: var(--accent-color);
}
.dropdown-wrapper .nav-dropdown .dropdown-item a.active {
color: var(--accent-color);
}
.dropdown-wrapper .nav-dropdown .dropdown-item a.active::after {
content: '';
width: 0;
height: 0;
border-left: 5px solid var(--accent-color);
border-top: 3px solid transparent;
border-bottom: 3px solid transparent;
position: absolute;
top: calc(50% - 1.5px);
left: 8px;
}
.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4 {
margin-top: 0;
padding-top: 0;
border-top: 0;
}
.dropdown-wrapper {
height: 1.8rem;
}
.dropdown-wrapper:hover .nav-dropdown,
.dropdown-wrapper.open .nav-dropdown {
display: block;
}
.dropdown-wrapper.open:blur {
display: none;
}
.dropdown-wrapper .dropdown-title .arrow {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 6px solid #aaa;
border-bottom: 0;
}
.dropdown-wrapper .nav-dropdown {
display: none;
height: auto !important;
box-sizing: border-box;
max-height: calc(100vh - 2.7rem);
overflow-y: auto;
position: absolute;
top: 100%;
right: 0;
background-color: #fff;
padding: 0.6rem 0;
border: 1px solid #ddd;
border-bottom-color: #ccc;
text-align: left;
border-radius: 0.25rem;
white-space: nowrap;
margin: 0;
}
@media screen and (max-width: 719px) {
.dropdown-wrapper {
height: auto;
margin-left: 1.5rem;
}
.dropdown-wrapper .dropdown-title {
font-size: 1rem;
font-weight: 600;
}
.dropdown-wrapper .nav-dropdown {
position: relative;
top: none;
right: none;
border: none;
padding: 4px 0;
background-color: transparent;
}
.dropdown-wrapper:hover .nav-dropdown {
display: none;
}
.dropdown-wrapper.open .nav-dropdown {
display: block;
}
.dropdown-wrapper .nav-dropdown .dropdown-item .nav-item {
margin: 0;
padding: 0;
}
.dropdown-wrapper .nav-dropdown .dropdown-item .nav-link {
font-size: 0.9rem;
}
}
</style>

View File

@@ -0,0 +1,14 @@
declare const _default: {
setup(): {
next: import("vue").ComputedRef<{
text: string;
link: string;
} | undefined>;
prev: import("vue").ComputedRef<{
text: string;
link: string;
} | undefined>;
hasLinks: import("vue").ComputedRef<boolean>;
};
};
export default _default;

View File

@@ -0,0 +1,52 @@
import { computed } from 'vue';
import { useRoute, useSiteData } from 'vitepress';
export default {
setup() {
const route = useRoute();
// TODO: could this be useSiteData<DefaultTheme.Config> or is the siteData
// resolved and has a different structure?
const siteData = useSiteData();
const resolveLink = (targetLink) => {
let target;
Object.keys(siteData.value.themeConfig.sidebar).some((k) => {
return siteData.value.themeConfig.sidebar[k].some((v) => {
if (Array.isArray(v.children)) {
target = v.children.find((value) => {
return value.link === targetLink;
});
}
return !!target;
});
});
return target;
};
const next = computed(() => {
const pageData = route.data;
if (pageData.frontmatter.next === false) {
return undefined;
}
if (typeof pageData.frontmatter.next === 'string') {
return resolveLink(pageData.frontmatter.next);
}
return pageData.next;
});
const prev = computed(() => {
const pageData = route.data;
if (pageData.frontmatter.prev === false) {
return undefined;
}
if (typeof pageData.frontmatter.prev === 'string') {
return resolveLink(pageData.frontmatter.prev);
}
return pageData.prev;
});
const hasLinks = computed(() => {
return !!next || !!prev;
});
return {
next,
prev,
hasLinks
};
}
};

View File

@@ -0,0 +1,35 @@
<template>
<div v-if="hasLinks" class="links-wrapper">
<div class="prev-link">
<div v-if="prev">
<a :href="prev.link">{{ prev.text }}</a>
</div>
</div>
<div class="next-link">
<div v-if="next">
<a :href="next.link">{{ next.text }}</a>
</div>
</div>
</div>
</template>
<script src="./NextAndPrevLinks"></script>
<style>
.links-wrapper {
display: flex;
justify-content: space-between;
margin-top: 4rem;
border-top: 1px solid var(--border-color);
padding-top: 1rem;
padding-bottom: 2rem;
}
.links-wrapper a {
font-weight: 500;
}
.links-wrapper a:hover {
text-decoration: none !important;
}
</style>

View File

@@ -0,0 +1,42 @@
<template>
<div class="content">
<slot name="top" />
<Content />
<NextAndPrevLinks />
<PageEdit />
<slot name="bottom" />
</div>
</template>
<script>
import NextAndPrevLinks from './NextAndPrevLinks.vue'
import PageEdit from './PageEdit.vue'
export default {
components: { NextAndPrevLinks, PageEdit }
}
</script>
<style>
.content {
margin: 0 auto;
padding: 0.025rem 2.5rem 2rem;
/* if this is moved to a variable, add it to BuySellAds.vue */
max-width: 50rem;
}
.content a {
color: var(--accent-color);
}
.content a:hover {
text-decoration: underline;
}
.content img {
max-width: 100%;
}
/*
.content div > h1:first-child, .content div > h2:first-child {
margin-top: 0;
} */
</style>

View File

@@ -0,0 +1,10 @@
declare const _default: {
components: {
OutboundLink: import("vue").ComponentOptions<{}, any, any, any, any, any, any, any>;
};
setup(): {
editLink: import("vue").ComputedRef<string | null>;
editLinkText: import("vue").ComputedRef<string>;
};
};
export default _default;

View File

@@ -0,0 +1,50 @@
import { computed } from 'vue';
import OutboundLink from './icons/OutboundLink.vue';
import { endingSlashRE, isExternal } from '../utils';
import { useRoute, useSiteData } from 'vitepress';
function createEditLink(repo, docsRepo, docsDir, docsBranch, path) {
const bitbucket = /bitbucket.org/;
if (bitbucket.test(repo)) {
const base = isExternal(docsRepo) ? docsRepo : repo;
return (base.replace(endingSlashRE, '') +
`/src` +
`/${docsBranch}/` +
(docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '') +
path +
`?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`);
}
const base = isExternal(docsRepo)
? docsRepo
: `https://github.com/${docsRepo}`;
return (base.replace(endingSlashRE, '') +
`/edit` +
`/${docsBranch}/` +
(docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '') +
path);
}
export default {
components: {
OutboundLink
},
setup() {
const route = useRoute();
const siteData = useSiteData();
const editLink = computed(() => {
const pageData = route.data;
const showEditLink = pageData.frontmatter.editLink == null
? siteData.value.themeConfig.editLinks
: pageData.frontmatter.editLink;
const { repo, docsDir = '', docsBranch = 'master', docsRepo = repo } = siteData.value.themeConfig;
const { relativePath } = pageData;
if (showEditLink && relativePath && repo) {
return createEditLink(repo, docsRepo || repo, docsDir, docsBranch, relativePath);
}
return null;
});
const editLinkText = computed(() => siteData.value.themeConfig.editLinkText || 'Edit this page');
return {
editLink,
editLinkText
};
}
};

View File

@@ -0,0 +1,28 @@
<template>
<footer class="page-edit">
<a
v-if="editLink"
:href="editLink"
target="_blank"
rel="noopener noreferrer"
>
{{ editLinkText }}
<OutboundLink />
</a>
</footer>
</template>
<script src="./PageEdit"></script>
<style>
.page-edit {
padding-top: 1rem;
padding-bottom: 1rem;
overflow: auto;
}
.page-edit a {
color: var(--text-color);
margin-right: 0.25rem;
}
</style>

View File

@@ -0,0 +1,288 @@
<template>
<div class="search-box">
<input
ref="input"
aria-label="Search"
:value="query"
:class="{ 'focused': focused }"
:placeholder="placeholder"
autocomplete="off"
spellcheck="false"
@input="query = $event.target.value"
@focus="focused = true"
@blur="focused = false"
@keyup.enter="go(focusIndex)"
@keyup.up="onUp"
@keyup.down="onDown"
>
<ul
v-if="showSuggestions"
class="suggestions"
:class="{ 'align-right': alignRight }"
@mouseleave="unfocus"
>
<li
v-for="(s, i) in suggestions"
:key="i"
class="suggestion"
:class="{ focused: i === focusIndex }"
@mousedown="go(i)"
@mouseenter="focus(i)"
>
<a
:href="s.path"
@click.prevent
>
<span class="page-title">{{ s.title || s.path }}</span>
<span
v-if="s.header"
class="header"
>&gt; {{ s.header.title }}</span>
</a>
</li>
</ul>
</div>
</template>
<script>
import matchQuery from './match-query'
/* global SEARCH_MAX_SUGGESTIONS, SEARCH_PATHS, SEARCH_HOTKEYS */
export default {
name: 'SearchBox',
data () {
return {
query: '',
focused: false,
focusIndex: 0,
placeholder: undefined
}
},
computed: {
showSuggestions () {
return (
this.focused
&& this.suggestions
&& this.suggestions.length
)
},
suggestions () {
const query = this.query.trim().toLowerCase()
if (!query) {
return
}
const { pages } = this.$site
const max = this.$site.themeConfig.searchMaxSuggestions || SEARCH_MAX_SUGGESTIONS
const localePath = this.$localePath
const res = []
for (let i = 0; i < pages.length; i++) {
if (res.length >= max) break
const p = pages[i]
// filter out results that do not match current locale
if (this.getPageLocalePath(p) !== localePath) {
continue
}
// filter out results that do not match searchable paths
if (!this.isSearchable(p)) {
continue
}
if (matchQuery(query, p)) {
res.push(p)
} else if (p.headers) {
for (let j = 0; j < p.headers.length; j++) {
if (res.length >= max) break
const h = p.headers[j]
if (h.title && matchQuery(query, p, h.title)) {
res.push(Object.assign({}, p, {
path: p.path + '#' + h.slug,
header: h
}))
}
}
}
}
return res
},
// make suggestions align right when there are not enough items
alignRight () {
const navCount = (this.$site.themeConfig.nav || []).length
const repo = this.$site.repo ? 1 : 0
return navCount + repo <= 2
}
},
mounted () {
this.placeholder = this.$site.themeConfig.searchPlaceholder || ''
document.addEventListener('keydown', this.onHotkey)
},
beforeDestroy () {
document.removeEventListener('keydown', this.onHotkey)
},
methods: {
getPageLocalePath (page) {
for (const localePath in this.$site.locales || {}) {
if (localePath !== '/' && page.path.indexOf(localePath) === 0) {
return localePath
}
}
return '/'
},
isSearchable (page) {
let searchPaths = SEARCH_PATHS
// all paths searchables
if (searchPaths === null) { return true }
searchPaths = Array.isArray(searchPaths) ? searchPaths : new Array(searchPaths)
return searchPaths.filter(path => {
return page.path.match(path)
}).length > 0
},
onHotkey (event) {
if (event.srcElement === document.body && SEARCH_HOTKEYS.includes(event.key)) {
this.$refs.input.focus()
event.preventDefault()
}
},
onUp () {
if (this.showSuggestions) {
if (this.focusIndex > 0) {
this.focusIndex--
} else {
this.focusIndex = this.suggestions.length - 1
}
}
},
onDown () {
if (this.showSuggestions) {
if (this.focusIndex < this.suggestions.length - 1) {
this.focusIndex++
} else {
this.focusIndex = 0
}
}
},
go (i) {
if (!this.showSuggestions) {
return
}
this.$router.push(this.suggestions[i].path)
this.query = ''
this.focusIndex = 0
},
focus (i) {
this.focusIndex = i
},
unfocus () {
this.focusIndex = -1
}
}
}
</script>
<style lang="stylus">
.search-box
display inline-block
position relative
margin-right 1rem
input
cursor text
width 10rem
height: 2rem
color lighten($textColor, 25%)
display inline-block
border 1px solid darken($borderColor, 10%)
border-radius 2rem
font-size 0.9rem
line-height 2rem
padding 0 0.5rem 0 2rem
outline none
transition all .2s ease
background #fff url(search.svg) 0.6rem 0.5rem no-repeat
background-size 1rem
&:focus
cursor auto
border-color $accentColor
.suggestions
background #fff
width 20rem
position absolute
top 2 rem
border 1px solid darken($borderColor, 10%)
border-radius 6px
padding 0.4rem
list-style-type none
&.align-right
right 0
.suggestion
line-height 1.4
padding 0.4rem 0.6rem
border-radius 4px
cursor pointer
a
white-space normal
color lighten($textColor, 35%)
.page-title
font-weight 600
.header
font-size 0.9em
margin-left 0.25em
&.focused
background-color #f3f4f5
a
color $accentColor
@media (max-width: $MQNarrow)
.search-box
input
cursor pointer
width 0
border-color transparent
position relative
&:focus
cursor text
left 0
width 10rem
// Match IE11
@media all and (-ms-high-contrast: none)
.search-box input
height 2rem
@media (max-width: $MQNarrow) and (min-width: $MQMobile)
.search-box
.suggestions
left 0
@media (max-width: $MQMobile)
.search-box
margin-right 0
input
left 1rem
.suggestions
right 0
@media (max-width: $MQMobileNarrow)
.search-box
.suggestions
width calc(100vw - 4rem)
input:focus
width 8rem
</style>

View File

@@ -0,0 +1,19 @@
export interface ResolvedSidebarItem {
text: string;
link?: string;
isGroup?: boolean;
children?: ResolvedSidebarItem[];
}
declare type ResolvedSidebar = ResolvedSidebarItem[];
declare const _default: {
components: {
NavBarLinks: import("vue").ComponentOptions<{}, any, any, any, any, any, any, any>;
SideBarItem: import("vue").FunctionalComponent<{
item: ResolvedSidebarItem;
}, {}>;
};
setup(): {
items: import("vue").ComputedRef<ResolvedSidebar | undefined>;
};
};
export default _default;

View File

@@ -0,0 +1,89 @@
import { useRoute, useSiteDataByRoute } from 'vitepress';
import { computed } from 'vue';
import { getPathDirName } from '../utils';
import { useActiveSidebarLinks } from '../composables/activeSidebarLink';
import NavBarLinks from './NavBarLinks.vue';
import { SideBarItem } from './SideBarItem';
export default {
components: {
NavBarLinks,
SideBarItem
},
setup() {
const route = useRoute();
const siteData = useSiteDataByRoute();
useActiveSidebarLinks();
return {
items: computed(() => {
const { headers, frontmatter: { sidebar, sidebarDepth = 2 } } = route.data;
if (sidebar === 'auto') {
// auto, render headers of current page
return resolveAutoSidebar(headers, sidebarDepth);
}
else if (Array.isArray(sidebar)) {
// in-page array config
return resolveArraySidebar(sidebar, sidebarDepth);
}
else if (sidebar === false) {
return [];
}
else {
// no explicit page sidebar config
// check global theme config
const { sidebar: themeSidebar } = siteData.value.themeConfig;
if (themeSidebar === 'auto') {
return resolveAutoSidebar(headers, sidebarDepth);
}
else if (Array.isArray(themeSidebar)) {
return resolveArraySidebar(themeSidebar, sidebarDepth);
}
else if (themeSidebar === false) {
return [];
}
else if (typeof themeSidebar === 'object') {
return resolveMultiSidebar(themeSidebar, route.path, headers, sidebarDepth);
}
}
})
};
}
};
function resolveAutoSidebar(headers, depth) {
const ret = [];
if (headers === undefined) {
return [];
}
let lastH2 = undefined;
headers.forEach(({ level, title, slug }) => {
if (level - 1 > depth) {
return;
}
const item = {
text: title,
link: `#${slug}`
};
if (level === 2) {
lastH2 = item;
ret.push(item);
}
else if (lastH2) {
;
(lastH2.children || (lastH2.children = [])).push(item);
}
});
return ret;
}
function resolveArraySidebar(config, depth) {
return config;
}
function resolveMultiSidebar(config, path, headers, depth) {
const paths = [path, Object.keys(config)[0]];
const item = paths.map((x) => config[getPathDirName(x)]).find(Boolean);
if (Array.isArray(item)) {
return resolveArraySidebar(item, depth);
}
if (item === 'auto') {
return resolveAutoSidebar(headers, depth);
}
return [];
}

View File

@@ -0,0 +1,99 @@
<template>
<NavBarLinks class="show-mobile" />
<slot name="top" />
<ul class="sidebar">
<SideBarItem v-for="item of items" :item="item" />
</ul>
<slot name="bottom" />
</template>
<script src="./SideBar"></script>
<style>
.show-mobile {
display: none;
}
@media screen and (max-width: 719px) {
.show-mobile {
display: block;
}
}
.sidebar,
.sidebar-items {
list-style-type: none;
line-height: 2;
padding: 0;
margin: 0;
}
.sidebar {
padding: 1.5rem 0;
}
.sidebar-data {
padding: 1.5rem 0;
}
@media screen and (max-width: 719px) {
.sidebar-data {
padding: 1rem;
}
}
.sidebar-items .sidebar-items {
padding-left: 1rem;
}
.sidebar-items .sidebar-items .sidebar-link {
border-left: 0;
}
.sidebar-items .sidebar-items .sidebar-link.active {
font-weight: 500;
}
.sidebar-items .sidebar-link {
padding: 0.35rem 1rem 0.35rem 2rem;
line-height: 1.4;
font-size: 0.95em;
font-weight: 400;
}
.sidebar-item + .sidebar-item {
padding-top: 0.75rem;
}
.sidebar-items > .sidebar-item + .sidebar-item {
padding-top: 0;
}
.sidebar-link {
display: block;
margin: 0;
border-left: 0.25rem solid transparent;
padding: 0.35rem 1.5rem 0.35rem 1.25rem;
line-height: 1.7;
font-size: 1.05em;
font-weight: 700;
color: var(--text-color);
}
a.sidebar-link {
transition: color 0.15s ease;
}
a.sidebar-link:hover {
color: var(--accent-color);
}
a.sidebar-link.active {
border-left-color: var(--accent-color);
font-weight: 600;
color: var(--accent-color);
}
</style>

View File

@@ -0,0 +1,5 @@
import { FunctionalComponent } from 'vue';
import { ResolvedSidebarItem } from './SideBar';
export declare const SideBarItem: FunctionalComponent<{
item: ResolvedSidebarItem;
}>;

View File

@@ -0,0 +1,61 @@
import { useRoute, useSiteData } from 'vitepress';
import { h } from 'vue';
import { joinUrl, isActive } from '../utils';
export const SideBarItem = (props) => {
const { item: { link: relLink, text, children } } = props;
const route = useRoute();
const siteData = useSiteData();
const link = resolveLink(siteData.value.base, relLink || '');
const active = isActive(route, link);
const headers = route.data.headers;
const childItems = createChildren(active, children, headers);
return h('li', { class: 'sidebar-item' }, [
h(link ? 'a' : 'p', {
class: { 'sidebar-link': true, active },
href: link
}, text),
childItems
]);
};
function resolveLink(base, path) {
return path
? // keep relative hash to the same page
path.startsWith('#')
? path
: joinUrl(base, path)
: undefined;
}
function createChildren(active, children, headers) {
if (children && children.length > 0) {
return h('ul', { class: 'sidebar-items' }, children.map((c) => {
return h(SideBarItem, { item: c });
}));
}
return active && headers
? createChildren(false, resolveHeaders(headers))
: null;
}
function resolveHeaders(headers) {
return mapHeaders(groupHeaders(headers));
}
function groupHeaders(headers) {
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);
}
function mapHeaders(headers) {
return headers.map((header) => ({
text: header.title,
link: `#${header.slug}`,
children: header.children ? mapHeaders(header.children) : undefined
}));
}

View File

@@ -0,0 +1,46 @@
<template>
<div class="sidebar-button" @click="$emit('toggle')">
<svg
class="icon"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
role="img"
viewBox="0 0 448 512"
>
<path
fill="currentColor"
d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"
class
/>
</svg>
</div>
</template>
<script>
export default {
emits: ['toggle']
}
</script>
<style>
.sidebar-button {
position: absolute;
top: 0.6rem;
left: 1rem;
display: none;
padding: 0.6rem;
cursor: pointer;
}
.sidebar-button .icon {
display: block;
width: 1.25rem;
height: 1.25rem;
}
@media screen and (max-width: 719px) {
.sidebar-button {
display: block;
}
}
</style>

View File

@@ -0,0 +1,31 @@
<template functional>
<svg
class="icon outbound"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
x="0px"
y="0px"
viewBox="0 0 100 100"
width="15"
height="15"
>
<path
fill="currentColor"
d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"
/>
<polygon
fill="currentColor"
points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"
/>
</svg>
</template>
<style>
.icon.outbound {
color: #aaa;
display: inline-block;
vertical-align: middle;
position: relative;
top: -1px;
}
</style>

View File

@@ -0,0 +1,50 @@
import get from 'lodash.get'
export default (query, page, additionalStr = null) => {
let domain = get(page, 'title', '')
if (get(page, 'frontmatter.tags')) {
domain += ` ${page.frontmatter.tags.join(' ')}`
}
if (additionalStr) {
domain += ` ${additionalStr}`
}
return matchTest(query, domain)
}
const matchTest = (query, domain) => {
const escapeRegExp = (str) => str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
// eslint-disable-next-line no-control-regex
const nonASCIIRegExp = new RegExp('[^\x00-\x7F]')
const words = query
.split(/\s+/g)
.map((str) => str.trim())
.filter((str) => !!str)
if (!nonASCIIRegExp.test(query)) {
// if the query only has ASCII chars, treat as English
const hasTrailingSpace = query.endsWith(' ')
const searchRegex = new RegExp(
words
.map((word, index) => {
if (words.length === index + 1 && !hasTrailingSpace) {
// The last word - ok with the word being "startswith"-like
return `(?=.*\\b${escapeRegExp(word)})`
} else {
// Not the last word - expect the whole word exactly
return `(?=.*\\b${escapeRegExp(word)}\\b)`
}
})
.join('') + '.+',
'gi'
)
return searchRegex.test(domain)
} else {
// if the query has non-ASCII chars, treat as other languages
return words.some((word) => domain.toLowerCase().indexOf(word) > -1)
}
}

View File

@@ -0,0 +1 @@
export declare function useActiveSidebarLinks(): void;

View File

@@ -0,0 +1,78 @@
import { onMounted, onUnmounted, onUpdated } from 'vue';
export function useActiveSidebarLinks() {
let rootActiveLink = null;
let activeLink = null;
const decode = decodeURIComponent;
const deactiveLink = (link) => link && link.classList.remove('active');
const activateLink = (hash) => {
deactiveLink(activeLink);
deactiveLink(rootActiveLink);
activeLink = document.querySelector(`.sidebar a[href="${hash}"]`);
if (activeLink) {
activeLink.classList.add('active');
// also add active class to parent h2 anchors
const rootLi = activeLink.closest('.sidebar > ul > li');
if (rootLi && rootLi !== activeLink.parentElement) {
rootActiveLink = rootLi.querySelector('a');
rootActiveLink && rootActiveLink.classList.add('active');
}
else {
rootActiveLink = null;
}
}
};
const setActiveLink = () => {
const sidebarLinks = [].slice.call(document.querySelectorAll('.sidebar a'));
const anchors = [].slice
.call(document.querySelectorAll('.header-anchor'))
.filter((anchor) => sidebarLinks.some((sidebarLink) => sidebarLink.hash === anchor.hash));
const pageOffset = document.querySelector('.navbar')
.offsetHeight;
const scrollTop = window.scrollY;
const getAnchorTop = (anchor) => anchor.parentElement.offsetTop - pageOffset - 15;
for (let i = 0; i < anchors.length; i++) {
const anchor = anchors[i];
const nextAnchor = anchors[i + 1];
const isActive = (i === 0 && scrollTop === 0) ||
(scrollTop >= getAnchorTop(anchor) &&
(!nextAnchor || scrollTop < getAnchorTop(nextAnchor)));
// TODO: fix case when at page bottom
if (isActive) {
const targetHash = decode(anchor.hash);
history.replaceState(null, document.title, targetHash);
activateLink(targetHash);
return;
}
}
};
const onScroll = throttleAndDebounce(setActiveLink, 300);
onMounted(() => {
setActiveLink();
window.addEventListener('scroll', onScroll);
});
onUpdated(() => {
// sidebar update means a route change
activateLink(decode(location.hash));
});
onUnmounted(() => {
window.removeEventListener('scroll', onScroll);
});
}
function throttleAndDebounce(fn, delay) {
let timeout;
let called = false;
return () => {
if (timeout)
clearTimeout(timeout);
if (!called) {
fn();
called = true;
setTimeout(() => {
called = false;
}, delay);
}
else {
timeout = setTimeout(fn, delay);
}
};
}

View File

@@ -0,0 +1,94 @@
export declare namespace DefaultTheme {
interface Config {
logo?: string;
nav?: NavItem[] | false;
sidebar?: SideBarConfig | MultiSideBarConfig;
search?: SearchConfig | false;
/**
* GitHub repository following the format <user>/<project>.
*
* @example vuejs/vue-next
*/
repo?: string;
/**
* Customize the header label. Defaults to GitHub/Gitlab/Bitbucket depending
* on the provided repo
*
* @exampe `"Contribute!"`
*/
repoLabel?: string;
/**
* If your docs are in a different repository from your main project
*
* @example `"vuejs/docs-next"`
*/
docsRepo?: string;
/**
* If your docs are not at the root of the repo.
*
* @example `"docs"`
*/
docsDir?: string;
/**
* If your docs are in a different branch. Defaults to `master`
* @example `"next"`
*/
docsBranch?: string;
/**
* Enable links to edit pages at the bottom of the page
*/
editLinks?: boolean;
/**
* Custom text for edit link. Defaults to "Edit this page"
*/
editLinkText?: string;
lastUpdated?: string | boolean;
prevLink?: boolean;
nextLink?: boolean;
}
type NavItem = NavItemWithLink | NavItemWithChildren;
interface NavItemWithLink extends NavItemBase {
link: string;
}
interface NavItemWithChildren extends NavItemBase {
items: NavItem[];
}
interface NavItemBase {
text: string;
target?: string;
rel?: string;
ariaLabel?: string;
}
type SideBarConfig = SideBarItem[] | 'auto' | false;
interface MultiSideBarConfig {
[path: string]: SideBarConfig;
}
type SideBarItem = SideBarLink | SideBarGroup;
interface SideBarLink {
text: string;
link: string;
}
interface SideBarGroup {
text: string;
link?: string;
/**
* @default false
*/
collapsable?: boolean;
children: SideBarItem[];
}
interface SearchConfig {
/**
* @default 5
*/
maxSuggestions?: number;
/**
* @default ''
*/
placeholder?: string;
algolia?: {
apiKey: string;
indexName: string;
};
}
}

View File

View File

@@ -0,0 +1,7 @@
import './styles/vars.css';
import './styles/layout.css';
import './styles/code.css';
import './styles/custom-blocks.css';
import { Theme } from '../app/theme';
declare const theme: Theme;
export default theme;

View File

@@ -0,0 +1,11 @@
import './styles/vars.css';
import './styles/layout.css';
import './styles/code.css';
import './styles/custom-blocks.css';
import Layout from './Layout.vue';
import NotFound from './NotFound.vue';
const theme = {
Layout,
NotFound
};
export default theme;

View File

@@ -0,0 +1,271 @@
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, Courier New, monospace;
font-size: 0.85em;
color: var(--text-color-light);
background-color: rgba(27, 31, 35, 0.05);
padding: 0.25rem 0.5rem;
border-radius: 3px;
margin: 0;
}
code .token.deleted {
color: #ec5975;
}
code .token.inserted {
color: var(--accent-color);
}
div[class*='language-'] {
line-height: 1.5;
padding: 0.5rem 1.5rem;
background-color: var(--code-bg-color);
border-radius: 6px;
overflow-x: auto;
position: relative;
margin: 0.85rem 0;
}
[class*='language-'] pre {
background: transparent;
position: relative;
z-index: 1;
}
[class*='language-'] code {
color: #eee;
padding: 0;
}
[class*='language-'] code,
[class*='language-'] pre {
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Line highlighting */
.highlight-lines {
font-size: 0.9em;
user-select: none;
padding-top: 1.3rem;
position: absolute;
top: 0;
left: 0;
width: 100%;
line-height: 1.5;
}
.highlight-lines .highlighted {
background-color: rgba(0, 0, 0, 66%);
}
/* Line numbers mode */
div[class*='language-'].line-numbers-mode {
padding-left: 5rem;
}
.line-numbers-wrapper {
position: absolute;
top: 0;
left: 0;
width: 3.5rem;
text-align: center;
color: #888;
line-height: 1.5;
font-size: 0.9em;
padding: 1.3rem 0;
border-right: 1px solid rgba(0,0,0,50%);
z-index: 4;
}
/* Language marker */
[class*='language-']:before {
position: absolute;
z-index: 3;
top: 0.6em;
right: 1em;
font-size: 0.8rem;
color: #888;
}
[class~='language-html']:before,
[class~='language-markup']:before {
content: 'html';
}
[class~='language-md']:before,
[class~='language-markdown']:before {
content: 'md';
}
[class~='language-css']:before {
content: 'css';
}
[class~='language-sass']:before {
content: 'sass';
}
[class~='language-scss']:before {
content: 'scss';
}
[class~='language-less']:before {
content: 'less';
}
[class~='language-stylus']:before {
content: 'styl';
}
[class~='language-js']:before,
[class~='language-typescript']:before {
content: 'js';
}
[class~='language-ts']:before,
[class~='language-typescript']:before {
content: 'ts';
}
[class~='language-json']:before {
content: 'json';
}
[class~='language-rb']:before,
[class~='language-ruby']:before {
content: 'rb';
}
[class~='language-py']:before,
[class~='language-python']:before {
content: 'py';
}
[class~='language-sh']:before,
[class~='language-bash']:before {
content: 'sh';
}
[class~='language-php']:before {
content: 'php';
}
[class~='language-go']:before {
content: 'go';
}
[class~='language-rust']:before {
content: 'rust';
}
[class~='language-java']:before {
content: 'java';
}
[class~='language-c']:before {
content: 'c';
}
[class~='language-yaml']:before {
content: 'yaml';
}
[class~='language-dockerfile']:before {
content: 'dockerfile';
}
/**
* prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
* Based on https://github.com/chriskempson/tomorrow-theme
* @author Rose Pritchard
*/
.token.comment,
.token.block-comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #999;
}
.token.punctuation {
color: #ccc;
}
.token.tag,
.token.attr-name,
.token.namespace,
.token.deleted {
color: #e2777a;
}
.token.function-name {
color: #6196cc;
}
.token.boolean,
.token.number,
.token.function {
color: #f08d49;
}
.token.property,
.token.class-name,
.token.constant,
.token.symbol {
color: #f8c555;
}
.token.selector,
.token.important,
.token.atrule,
.token.keyword,
.token.builtin {
color: #cc99cd;
}
.token.string,
.token.char,
.token.attr-value,
.token.regex,
.token.variable {
color: #7ec699;
}
.token.operator,
.token.entity,
.token.url {
color: #67cdcc;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.token.inserted {
color: green;
}

View File

@@ -0,0 +1,70 @@
.custom-block .custom-block-title {
font-weight: 600;
margin-bottom: -0.4rem;
}
.custom-block.tip,
.custom-block.warning,
.custom-block.danger {
padding: 0.1rem 1.5rem;
border-left-width: 0.5rem;
border-left-style: solid;
margin: 1rem 0;
}
.custom-block.tip {
background-color: #f3f5f7;
border-color: #42b983;
}
.custom-block.warning {
background-color: rgba(255, 229, 100, 0.3);
border-color: #e7c000;
color: #6b5900;
}
.custom-block.warning .custom-block-title {
color: #b29400;
}
.custom-block.warning a {
color: var(--text-color);
}
.custom-block.danger {
background-color: #ffe6e6;
border-color: #c00;
color: #4d0000;
}
.custom-block.danger .custom-block-title {
color: #900;
}
.custom-block.danger a {
color: var(--text-color);
}
.custom-block.details {
display: block;
position: relative;
border-radius: 2px;
margin: 1.6em 0;
padding: 1.6em;
background-color: #eee;
}
.custom-block.details h4 {
margin-top: 0;
}
.custom-block.details figure:last-child,
.custom-block.details p:last-child {
margin-bottom: 0;
padding-bottom: 0;
}
.custom-block.details summary {
outline: none;
cursor: pointer;
}

View File

@@ -0,0 +1,240 @@
body {
padding: 0;
margin: 0;
background-color: #fff;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
* {
box-sizing: border-box;
}
.theme {
font-size: 16px;
color: var(--text-color);
}
.theme .navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: var(--header-height);
background-color: #fff;
border-bottom: 1px solid var(--border-color);
z-index: 4;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.7rem 1.5rem;
}
@media screen and (max-width: 719px) {
.theme .navbar {
padding-left: 4rem;
}
}
.theme aside {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: var(--sidebar-width);
padding: var(--header-height) 0 1.5rem 0;
border-right: 1px solid var(--border-color);
background-color: #fff;
z-index: 3;
overflow-y: auto;
}
.theme.sidebar-open .sidebar-mask {
display: block;
}
.theme.no-navbar > h1,
.theme.no-navbar > h2,
.theme.no-navbar > h3,
.theme.no-navbar > h4,
.theme.no-navbar > h5,
.theme.no-navbar > h6 {
margin-top: 1.5rem;
padding-top: 0;
}
.theme.no-navbar aside {
top: 0;
}
@media screen and (max-width: 959px) {
.theme aside {
width: var(--sidebar-width);
}
}
@media screen and (max-width: 719px) {
.theme aside {
transition: transform 0.2s ease;
transform: translateX(-100%);
}
.theme aside.open {
transform: translateX(0);
}
}
.sidebar-mask {
z-index: 2;
position: fixed;
width: 100vw;
height: 100vh;
display: none;
}
.theme main {
padding-top: var(--header-height);
}
@media screen and (min-width: 960px) {
.theme main {
padding-left: var(--sidebar-width);
}
}
@media screen and (min-width: 720px) {
.theme.no-sidebar aside {
display: none;
}
.theme.no-sidebar main {
margin-left: 0;
}
}
@media screen and (max-width: 959px) {
.theme main {
margin-left: var(--sidebar-width);
}
}
@media screen and (max-width: 719px) {
.theme main {
margin-left: 0;
}
}
.theme main.home {
padding: var(--header-height) 2rem 0;
max-width: 960px;
margin: 0px auto;
display: block;
}
@media screen and (max-width: 429px) {
.theme main.home {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
}
a {
text-decoration: none;
}
h1,
h2,
h3,
h4,
h5,
h6,
strong,
b {
font-weight: 600;
line-height: 1.6;
}
h1 {
font-size: 2.2rem;
}
h2 {
font-size: 1.65rem;
padding-bottom: 0.3rem;
border-bottom: 1px solid var(--border-color);
}
h3 {
font-size: 1.35rem;
}
h4 {
font-size: 1.15rem;
}
a.header-anchor {
font-size: 0.85em;
float: left;
margin-left: -0.87em;
padding-right: 0.23em;
margin-top: 0.125em;
opacity: 0;
}
a.header-anchor:hover {
text-decoration: none;
}
h1:hover .header-anchor,
h2:hover .header-anchor,
h3:hover .header-anchor,
h4:hover .header-anchor,
h5:hover .header-anchor,
h6:hover .header-anchor {
opacity: 1;
}
p,
ol,
ul {
line-height: 1.6;
}
ul,
ol {
padding-left: 1.25em;
}
table {
border-collapse: collapse;
margin: 1rem 0;
display: block;
overflow-x: auto;
}
tr {
border-top: 1px solid #dfe2e5;
}
tr:nth-child(2n) {
background-color: #f6f8fa;
}
th,
td {
border: 1px solid #dfe2e5;
padding: 0.6em 1em;
}
blockquote {
margin: 1rem 0;
border-left: 0.2rem solid #dfe2e5;
padding: 0.25rem 0 0.25rem 1rem;
font-size: 1rem;
color: #999;
}
blockquote > p {
margin: 0;
}

View File

@@ -0,0 +1,14 @@
.theme {
--border-color: rgb(226, 232, 240);
--header-height: 3.6rem;
--sidebar-width: 16.4rem;
--text-color: #2c3e50;
--text-color-light: #476582;
--code-bg-color: #282c34;
--accent-color: #3eaf7c;
/* responsive breakpoints */
/* --mq-narrow: 959px; */
/* --mq-mobile: 719px; */
/* --mq-mobile-narrow: 419px; */
}

View File

@@ -0,0 +1,17 @@
import { Route } from 'vitepress';
export declare const hashRE: RegExp;
export declare const extRE: RegExp;
export declare const endingSlashRE: RegExp;
export declare const outboundRE: RegExp;
export declare function withBase(path: string): string;
export declare function isExternal(path: string): boolean;
export declare function isActive(route: Route, path?: string): boolean;
export declare function normalize(path: string): string;
export declare function joinUrl(base: string, path: string): string;
/**
* 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 declare function getPathDirName(path: string): string;
export declare function ensureEndingSlash(path: string): string;

View File

@@ -0,0 +1,48 @@
import { useSiteData } from 'vitepress';
export const hashRE = /#.*$/;
export const extRE = /(index)?\.(md|html)$/;
export const endingSlashRE = /\/$/;
export const outboundRE = /^[a-z]+:/i;
export function withBase(path) {
return (useSiteData().value.base + path).replace(/\/+/g, '/');
}
export function isExternal(path) {
return outboundRE.test(path);
}
export function isActive(route, path) {
if (path === undefined) {
return false;
}
const routePath = normalize(route.path);
const pagePath = normalize(path);
return routePath === pagePath;
}
export function normalize(path) {
return decodeURI(path).replace(hashRE, '').replace(extRE, '');
}
export function joinUrl(base, path) {
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) {
const segments = path.split('/');
if (segments[segments.length - 1]) {
segments.pop();
}
return ensureEndingSlash(segments.join('/'));
}
export function ensureEndingSlash(path) {
return /(\.html|\/)$/.test(path) ? path : `${path}/`;
}

3
node_modules/vitepress/dist/node/build/build.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { BuildConfig as ViteBuildOptions } from 'vite';
export declare type BuildOptions = Pick<Partial<ViteBuildOptions>, 'root' | 'rollupInputOptions' | 'rollupOutputOptions' | 'rollupPluginVueOptions'>;
export declare function build(buildOptions?: BuildOptions): Promise<void>;

34
node_modules/vitepress/dist/node/build/build.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.build = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const bundle_1 = require("./bundle");
const config_1 = require("../config");
const render_1 = require("./render");
async function build(buildOptions = {}) {
process.env.NODE_ENV = 'production';
const siteConfig = await config_1.resolveConfig(buildOptions.root);
try {
const [clientResult, , pageToHashMap] = await bundle_1.bundle(siteConfig, buildOptions);
console.log('rendering pages...');
const appChunk = clientResult.assets.find((chunk) => chunk.type === 'chunk' && chunk.fileName.match(/^app\.\w+\.js$/));
const cssChunk = clientResult.assets.find((chunk) => chunk.type === 'asset' && chunk.fileName.endsWith('.css'));
// We embed the hash map string into each page directly so that it doesn't
// alter the main chunk's hash on every build. It's also embedded as a
// string and JSON.parsed from the client because it's faster than embedding
// as JS object literal.
const hashMapStirng = JSON.stringify(JSON.stringify(pageToHashMap));
for (const page of siteConfig.pages) {
await render_1.renderPage(siteConfig, page, clientResult, appChunk, cssChunk, pageToHashMap, hashMapStirng);
}
}
finally {
await fs_extra_1.default.remove(siteConfig.tempDir);
}
console.log('done.');
}
exports.build = build;
//# sourceMappingURL=build.js.map

1
node_modules/vitepress/dist/node/build/build.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/node/build/build.ts"],"names":[],"mappings":";;;;;;AAAA,wDAAyB;AACzB,qCAAiC;AAEjC,sCAAyC;AACzC,qCAAqC;AAW9B,KAAK,UAAU,KAAK,CAAC,eAA6B,EAAE;IACzD,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,YAAY,CAAA;IACnC,MAAM,UAAU,GAAG,MAAM,sBAAa,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;IACzD,IAAI;QACF,MAAM,CAAC,YAAY,EAAE,AAAD,EAAG,aAAa,CAAC,GAAG,MAAM,eAAM,CAClD,UAAU,EACV,YAAY,CACb,CAAA;QACD,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QAEjC,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,CACpD,CAAA;QAEhB,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CACtD,CAAA;QAEhB,0EAA0E;QAC1E,sEAAsE;QACtE,4EAA4E;QAC5E,wBAAwB;QACxB,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAA;QAEnE,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK,EAAE;YACnC,MAAM,mBAAU,CACd,UAAU,EACV,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,aAAa,CACd,CAAA;SACF;KACF;YAAS;QACR,MAAM,kBAAE,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;KACpC;IACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AACtB,CAAC;AAxCD,sBAwCC"}

4
node_modules/vitepress/dist/node/build/bundle.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import { BuildOptions } from './build';
import { SiteConfig } from '../config';
import { BuildResult } from 'vite';
export declare function bundle(config: SiteConfig, options: BuildOptions): Promise<[BuildResult, BuildResult, Record<string, string>]>;

133
node_modules/vitepress/dist/node/build/bundle.js generated vendored Normal file
View File

@@ -0,0 +1,133 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.bundle = void 0;
const path_1 = __importDefault(require("path"));
const slash_1 = __importDefault(require("slash"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const resolver_1 = require("../resolver");
const config_1 = require("../config");
const markdownToVue_1 = require("../markdownToVue");
const vite_1 = require("vite");
const hashRE = /\.(\w+)\.js$/;
const staticInjectMarkerRE = /\b(const _hoisted_\d+ = \/\*#__PURE__\*\/createStaticVNode)\("(.*)", (\d+)\)/g;
const staticStripRE = /__VP_STATIC_START__.*?__VP_STATIC_END__/g;
const staticRestoreRE = /__VP_STATIC_(START|END)__/g;
const isPageChunk = (chunk) => !!(chunk.type === 'chunk' &&
chunk.isEntry &&
chunk.facadeModuleId &&
chunk.facadeModuleId.endsWith('.md'));
// bundles the VitePress app for both client AND server.
async function bundle(config, options) {
const root = config.root;
const userConfig = await config_1.resolveUserConfig(root);
const resolver = resolver_1.createResolver(config.themeDir, userConfig);
const markdownToVue = markdownToVue_1.createMarkdownToVueRenderFn(root);
let isClientBuild = true;
const pageToHashMap = Object.create(null);
const VitePressPlugin = {
name: 'vitepress',
resolveId(id) {
if (id === resolver_1.SITE_DATA_REQUEST_PATH) {
return id;
}
},
async load(id) {
if (id === resolver_1.SITE_DATA_REQUEST_PATH) {
return `export default ${JSON.stringify(JSON.stringify(config.site))}`;
}
// compile md into vue src
if (id.endsWith('.md')) {
const content = await fs_extra_1.default.readFile(id, 'utf-8');
// TODO use git timestamp
const lastUpdated = (await fs_extra_1.default.stat(id)).mtimeMs;
const { vueSrc } = markdownToVue(content, id, lastUpdated);
return vueSrc;
}
},
renderChunk(code, chunk) {
if (isClientBuild && isPageChunk(chunk)) {
// For each page chunk, inject marker for start/end of static strings.
// we do this here because in generateBundle the chunks would have been
// minified and we won't be able to safely locate the strings.
// Using a regexp relies on specific output from Vue compiler core,
// which is a reasonable trade-off considering the massive perf win over
// a full AST parse.
code = code.replace(staticInjectMarkerRE, '$1("__VP_STATIC_START__$2__VP_STATIC_END__", $3)');
return code;
}
return null;
},
generateBundle(_options, bundle) {
// for each .md entry chunk, adjust its name to its correct path.
for (const name in bundle) {
const chunk = bundle[name];
if (isPageChunk(chunk) && isClientBuild) {
// record page -> hash relations
const hash = chunk.fileName.match(hashRE)[1];
const pageName = chunk.fileName.replace(hashRE, '');
pageToHashMap[pageName] = hash;
// inject another chunk with the content stripped
bundle[name + '-lean'] = {
...chunk,
fileName: chunk.fileName.replace(/\.js$/, '.lean.js'),
code: chunk.code.replace(staticStripRE, ``)
};
// remove static markers from orginal code
chunk.code = chunk.code.replace(staticRestoreRE, '');
}
}
}
};
// define custom rollup input
// this is a multi-entry build - every page is considered an entry chunk
// the loading is done via filename conversion rules so that the
// metadata doesn't need to be included in the main chunk.
const input = {
app: path_1.default.resolve(resolver_1.APP_PATH, 'index.js')
};
config.pages.forEach((file) => {
// page filename conversion
// foo/bar.md -> foo_bar.md
input[slash_1.default(file).replace(/\//g, '_')] = path_1.default.resolve(root, file);
});
// resolve options to pass to vite
const { rollupInputOptions = {}, rollupOutputOptions = {} } = options;
const viteOptions = {
...options,
base: config.site.base,
resolvers: [resolver],
outDir: config.outDir,
// let rollup-plugin-vue compile .md files as well
rollupPluginVueOptions: {
include: /\.(vue|md)$/
},
rollupInputOptions: {
...rollupInputOptions,
input,
// important so that each page chunk and the index export things for each
// other
preserveEntrySignatures: 'allow-extension',
plugins: [VitePressPlugin, ...(rollupInputOptions.plugins || [])]
},
rollupOutputOptions: {
...rollupOutputOptions,
chunkFileNames: `common-[hash].js`
},
silent: !process.env.DEBUG,
minify: !process.env.DEBUG
};
console.log('building client bundle...');
const clientResult = await vite_1.build(viteOptions);
console.log('building server bundle...');
isClientBuild = false;
const serverResult = await vite_1.ssrBuild({
...viteOptions,
outDir: config.tempDir
});
return [clientResult[0], serverResult[0], pageToHashMap];
}
exports.bundle = bundle;
//# sourceMappingURL=bundle.js.map

1
node_modules/vitepress/dist/node/build/bundle.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../../src/node/build/bundle.ts"],"names":[],"mappings":"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"}

5
node_modules/vitepress/dist/node/build/render.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import { SiteConfig } from '../config';
import { BuildResult } from 'vite';
import { OutputChunk, OutputAsset } from 'rollup';
export declare function renderPage(config: SiteConfig, page: string, // foo.md
result: BuildResult, appChunk: OutputChunk, cssChunk: OutputAsset, pageToHashMap: Record<string, string>, hashMapStirng: string): Promise<void>;

99
node_modules/vitepress/dist/node/build/render.js generated vendored Normal file
View File

@@ -0,0 +1,99 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderPage = void 0;
const path_1 = __importDefault(require("path"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const config_1 = require("../config");
const escape = require('escape-html');
async function renderPage(config, page, // foo.md
result, appChunk, cssChunk, pageToHashMap, hashMapStirng) {
const { createApp } = require(path_1.default.join(config.tempDir, `_assets/app.js`));
const { app, router } = createApp();
const routePath = `/${page.replace(/\.md$/, '')}`;
const siteData = config_1.resolveSiteDataByRoute(config.site, routePath);
router.go(routePath);
// lazy require server-renderer for production build
const content = await require('@vue/server-renderer').renderToString(app);
const pageName = page.replace(/\//g, '_');
// server build doesn't need hash
const pageServerJsFileName = pageName + '.js';
// for any initial page load, we only need the lean version of the page js
// since the static content is already on the page!
const pageHash = pageToHashMap[pageName];
const pageClientJsFileName = pageName + `.` + pageHash + '.lean.js';
// resolve page data so we can render head tags
const { __pageData } = require(path_1.default.join(config.tempDir, `_assets`, pageServerJsFileName));
const pageData = JSON.parse(__pageData);
const assetPath = `${siteData.base}_assets/`;
const preloadLinks = [
// resolve imports for index.js + page.md.js and inject script tags for
// them as well so we fetch everything as early as possible without having
// to wait for entry chunks to parse
...resolvePageImports(config, page, result, appChunk),
pageClientJsFileName,
appChunk.fileName
]
.map((file) => {
return `<link rel="modulepreload" href="${assetPath}${file}">`;
})
.join('\n ');
const html = `
<!DOCTYPE html>
<html lang="${siteData.lang}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>
${pageData.title ? pageData.title + ` | ` : ``}${siteData.title}
</title>
<meta name="description" content="${siteData.description}">
<link rel="stylesheet" href="${assetPath}${cssChunk.fileName}">
${preloadLinks}
${renderHead(siteData.head)}
${renderHead(pageData.frontmatter.head)}
</head>
<body>
<div id="app">${content}</div>
<script>__VP_HASH_MAP__ = JSON.parse(${hashMapStirng})</script>
<script type="module" async src="${assetPath}${appChunk.fileName}"></script>
</body>
</html>`.trim();
const htmlFileName = path_1.default.join(config.outDir, page.replace(/\.md$/, '.html'));
await fs_extra_1.default.ensureDir(path_1.default.dirname(htmlFileName));
await fs_extra_1.default.writeFile(htmlFileName, html);
}
exports.renderPage = renderPage;
function resolvePageImports(config, page, result, indexChunk) {
// find the page's js chunk and inject script tags for its imports so that
// they are start fetching as early as possible
const srcPath = path_1.default.resolve(config.root, page);
const pageChunk = result.assets.find((chunk) => chunk.type === 'chunk' && chunk.facadeModuleId === srcPath);
return Array.from(new Set([...indexChunk.imports, ...pageChunk.imports]));
}
function renderHead(head) {
if (!head || !head.length) {
return '';
}
return head
.map(([tag, attrs = {}, innerHTML = '']) => {
const openTag = `<${tag}${renderAttrs(attrs)}>`;
if (tag !== 'link' && tag !== 'meta') {
return `${openTag}${innerHTML}</${tag}>`;
}
else {
return openTag;
}
})
.join('\n ');
}
function renderAttrs(attrs) {
return Object.keys(attrs)
.map((key) => {
return ` ${key}="${escape(attrs[key])}"`;
})
.join('');
}
//# sourceMappingURL=render.js.map

1
node_modules/vitepress/dist/node/build/render.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/node/build/render.ts"],"names":[],"mappings":"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"}

26
node_modules/vitepress/dist/node/config.d.ts generated vendored Normal file
View File

@@ -0,0 +1,26 @@
import { Resolver } from 'vite';
import { SiteData, HeadConfig, LocaleConfig } from '../../types/shared';
export { resolveSiteDataByRoute } from './shared/config';
export interface UserConfig<ThemeConfig = any> {
lang?: string;
base?: string;
title?: string;
description?: string;
head?: HeadConfig[];
themeConfig?: ThemeConfig;
locales?: Record<string, LocaleConfig>;
alias?: Record<string, string>;
}
export interface SiteConfig<ThemeConfig = any> {
root: string;
site: SiteData<ThemeConfig>;
configPath: string;
themeDir: string;
outDir: string;
tempDir: string;
resolver: Resolver;
pages: string[];
}
export declare function resolveConfig(root?: string): Promise<SiteConfig>;
export declare function resolveUserConfig(root: string): Promise<UserConfig<any>>;
export declare function resolveSiteData(root: string): Promise<SiteData>;

66
node_modules/vitepress/dist/node/config.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveSiteData = exports.resolveUserConfig = exports.resolveConfig = void 0;
const path_1 = __importDefault(require("path"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const chalk_1 = __importDefault(require("chalk"));
const globby_1 = __importDefault(require("globby"));
const resolver_1 = require("./resolver");
var config_1 = require("./shared/config");
Object.defineProperty(exports, "resolveSiteDataByRoute", { enumerable: true, get: function () { return config_1.resolveSiteDataByRoute; } });
const debug = require('debug')('vitepress:config');
const resolve = (root, file) => path_1.default.resolve(root, `.vitepress`, file);
async function resolveConfig(root = process.cwd()) {
const userConfig = await resolveUserConfig(root);
const site = await resolveSiteData(root);
// resolve theme path
const userThemeDir = resolve(root, 'theme');
const themeDir = (await fs_extra_1.default.pathExists(userThemeDir))
? userThemeDir
: path_1.default.join(__dirname, '../client/theme-default');
const config = {
root,
site,
themeDir,
pages: await globby_1.default(['**.md'], { cwd: root, ignore: ['node_modules'] }),
configPath: resolve(root, 'config.js'),
outDir: resolve(root, 'dist'),
tempDir: path_1.default.resolve(resolver_1.APP_PATH, 'temp'),
resolver: resolver_1.createResolver(themeDir, userConfig)
};
return config;
}
exports.resolveConfig = resolveConfig;
async function resolveUserConfig(root) {
// load user config
const configPath = resolve(root, 'config.js');
const hasUserConfig = await fs_extra_1.default.pathExists(configPath);
// always delete cache first before loading config
delete require.cache[configPath];
const userConfig = hasUserConfig ? require(configPath) : {};
if (hasUserConfig) {
debug(`loaded config at ${chalk_1.default.yellow(configPath)}`);
}
else {
debug(`no config file found.`);
}
return userConfig;
}
exports.resolveUserConfig = resolveUserConfig;
async function resolveSiteData(root) {
const userConfig = await resolveUserConfig(root);
return {
lang: userConfig.lang || 'en-US',
title: userConfig.title || 'VitePress',
description: userConfig.description || 'A VitePress site',
base: userConfig.base ? userConfig.base.replace(/([^/])$/, '$1/') : '/',
head: userConfig.head || [],
themeConfig: userConfig.themeConfig || {},
locales: userConfig.locales || {}
};
}
exports.resolveSiteData = resolveSiteData;
//# sourceMappingURL=config.js.map

1
node_modules/vitepress/dist/node/config.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/node/config.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAuB;AACvB,wDAAyB;AACzB,kDAAyB;AACzB,oDAA2B;AAC3B,yCAAqD;AAGrD,0CAAwD;AAA/C,gHAAA,sBAAsB,OAAA;AAE/B,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAAA;AAyBlD,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE,CAC7C,cAAI,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,CAAA;AAEjC,KAAK,UAAU,aAAa,CACjC,OAAe,OAAO,CAAC,GAAG,EAAE;IAE5B,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAChD,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAA;IAExC,qBAAqB;IACrB,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC3C,MAAM,QAAQ,GAAG,CAAC,MAAM,kBAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAClD,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAA;IAEnD,MAAM,MAAM,GAAe;QACzB,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,KAAK,EAAE,MAAM,gBAAM,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;QACvE,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC;QACtC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;QAC7B,OAAO,EAAE,cAAI,CAAC,OAAO,CAAC,mBAAQ,EAAE,MAAM,CAAC;QACvC,QAAQ,EAAE,yBAAc,CAAC,QAAQ,EAAE,UAAU,CAAC;KAC/C,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAxBD,sCAwBC;AAEM,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAClD,mBAAmB;IACnB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IAC7C,MAAM,aAAa,GAAG,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;IACrD,kDAAkD;IAClD,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IAChC,MAAM,UAAU,GAAe,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACvE,IAAI,aAAa,EAAE;QACjB,KAAK,CAAC,oBAAoB,eAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;KACtD;SAAM;QACL,KAAK,CAAC,uBAAuB,CAAC,CAAA;KAC/B;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAdD,8CAcC;AAEM,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAEhD,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,OAAO;QAChC,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,WAAW;QACtC,WAAW,EAAE,UAAU,CAAC,WAAW,IAAI,kBAAkB;QACzD,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG;QACvE,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,EAAE;QAC3B,WAAW,EAAE,UAAU,CAAC,WAAW,IAAI,EAAE;QACzC,OAAO,EAAE,UAAU,CAAC,OAAO,IAAI,EAAE;KAClC,CAAA;AACH,CAAC;AAZD,0CAYC"}

3
node_modules/vitepress/dist/node/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export * from './server';
export * from './build/build';
export * from './config';

16
node_modules/vitepress/dist/node/index.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./server"), exports);
__exportStar(require("./build/build"), exports);
__exportStar(require("./config"), exports);
//# sourceMappingURL=index.js.map

1
node_modules/vitepress/dist/node/index.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAwB;AACxB,gDAA6B;AAC7B,2CAAwB"}

View File

@@ -0,0 +1,26 @@
import MarkdownIt from 'markdown-it';
import { Header } from '../../../types/shared';
export interface MarkdownOptions extends MarkdownIt.Options {
lineNumbers?: boolean;
config?: (md: MarkdownIt) => void;
anchor?: {
permalink?: boolean;
permalinkBefore?: boolean;
permalinkSymbol?: string;
};
toc?: any;
externalLinks?: Record<string, string>;
}
export interface MarkdownParsedData {
hoistedTags?: string[];
links?: string[];
headers?: Header[];
}
export interface MarkdownRenderer {
__data: MarkdownParsedData;
render: (src: string, env?: any) => {
html: string;
data: any;
};
}
export declare const createMarkdownRenderer: (options?: MarkdownOptions) => MarkdownRenderer;

80
node_modules/vitepress/dist/node/markdown/markdown.js generated vendored Normal file
View File

@@ -0,0 +1,80 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMarkdownRenderer = void 0;
const markdown_it_1 = __importDefault(require("markdown-it"));
const parseHeader_1 = require("../utils/parseHeader");
const highlight_1 = require("./plugins/highlight");
const slugify_1 = require("./plugins/slugify");
const highlightLines_1 = require("./plugins/highlightLines");
const lineNumbers_1 = require("./plugins/lineNumbers");
const component_1 = require("./plugins/component");
const containers_1 = require("./plugins/containers");
const snippet_1 = require("./plugins/snippet");
const hoist_1 = require("./plugins/hoist");
const preWrapper_1 = require("./plugins/preWrapper");
const link_1 = require("./plugins/link");
const header_1 = require("./plugins/header");
const emoji = require('markdown-it-emoji');
const anchor = require('markdown-it-anchor');
const toc = require('markdown-it-table-of-contents');
exports.createMarkdownRenderer = (options = {}) => {
const md = markdown_it_1.default({
html: true,
linkify: true,
highlight: highlight_1.highlight,
...options
});
// custom plugins
md.use(component_1.componentPlugin)
.use(highlightLines_1.highlightLinePlugin)
.use(preWrapper_1.preWrapperPlugin)
.use(snippet_1.snippetPlugin)
.use(hoist_1.hoistPlugin)
.use(containers_1.containerPlugin)
.use(header_1.extractHeaderPlugin)
.use(link_1.linkPlugin, {
target: '_blank',
rel: 'noopener noreferrer',
...options.externalLinks
})
// 3rd party plugins
.use(emoji)
.use(anchor, {
slugify: slugify_1.slugify,
permalink: true,
permalinkBefore: true,
permalinkSymbol: '#',
permalinkAttrs: () => ({ 'aria-hidden': true }),
...options.anchor
})
.use(toc, {
slugify: slugify_1.slugify,
includeLevel: [2, 3],
format: parseHeader_1.parseHeader,
...options.toc
});
// apply user config
if (options.config) {
options.config(md);
}
if (options.lineNumbers) {
md.use(lineNumbers_1.lineNumberPlugin);
}
// wrap render so that we can return both the html and extracted data.
const render = md.render;
const wrappedRender = (src) => {
;
md.__data = {};
const html = render.call(md, src);
return {
html,
data: md.__data
};
};
md.render = wrappedRender;
return md;
};
//# sourceMappingURL=markdown.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../src/node/markdown/markdown.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAoC;AACpC,sDAAkD;AAClD,mDAA+C;AAC/C,+CAA2C;AAC3C,6DAA8D;AAC9D,uDAAwD;AACxD,mDAAqD;AACrD,qDAAsD;AACtD,+CAAiD;AACjD,2CAA6C;AAC7C,qDAAuD;AACvD,yCAA2C;AAC3C,6CAAsD;AAGtD,MAAM,KAAK,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;AAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAA;AA0BvC,QAAA,sBAAsB,GAAG,CACpC,UAA2B,EAAE,EACX,EAAE;IACpB,MAAM,EAAE,GAAG,qBAAU,CAAC;QACpB,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI;QACb,SAAS,EAAT,qBAAS;QACT,GAAG,OAAO;KACX,CAAC,CAAA;IAEF,iBAAiB;IACjB,EAAE,CAAC,GAAG,CAAC,2BAAe,CAAC;SACpB,GAAG,CAAC,oCAAmB,CAAC;SACxB,GAAG,CAAC,6BAAgB,CAAC;SACrB,GAAG,CAAC,uBAAa,CAAC;SAClB,GAAG,CAAC,mBAAW,CAAC;SAChB,GAAG,CAAC,4BAAe,CAAC;SACpB,GAAG,CAAC,4BAAmB,CAAC;SACxB,GAAG,CAAC,iBAAU,EAAE;QACf,MAAM,EAAE,QAAQ;QAChB,GAAG,EAAE,qBAAqB;QAC1B,GAAG,OAAO,CAAC,aAAa;KACzB,CAAC;QAEF,oBAAoB;SACnB,GAAG,CAAC,KAAK,CAAC;SACV,GAAG,CAAC,MAAM,EAAE;QACX,OAAO,EAAP,iBAAO;QACP,SAAS,EAAE,IAAI;QACf,eAAe,EAAE,IAAI;QACrB,eAAe,EAAE,GAAG;QACpB,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QAC/C,GAAG,OAAO,CAAC,MAAM;KAClB,CAAC;SACD,GAAG,CAAC,GAAG,EAAE;QACR,OAAO,EAAP,iBAAO;QACP,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACpB,MAAM,EAAE,yBAAW;QACnB,GAAG,OAAO,CAAC,GAAG;KACf,CAAC,CAAA;IAEJ,oBAAoB;IACpB,IAAI,OAAO,CAAC,MAAM,EAAE;QAClB,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;KACnB;IAED,IAAI,OAAO,CAAC,WAAW,EAAE;QACvB,EAAE,CAAC,GAAG,CAAC,8BAAgB,CAAC,CAAA;KACzB;IAED,sEAAsE;IACtE,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAA;IACxB,MAAM,aAAa,GAA+B,CAAC,GAAG,EAAE,EAAE;QACxD,CAAC;QAAC,EAAU,CAAC,MAAM,GAAG,EAAE,CAAA;QACxB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;QACjC,OAAO;YACL,IAAI;YACJ,IAAI,EAAG,EAAU,CAAC,MAAM;SACzB,CAAA;IACH,CAAC,CACA;IAAC,EAAU,CAAC,MAAM,GAAG,aAAa,CAAA;IAEnC,OAAO,EAAS,CAAA;AAClB,CAAC,CAAA"}

View File

@@ -0,0 +1,2 @@
import MarkdownIt from 'markdown-it';
export declare const componentPlugin: (md: MarkdownIt) => void;

View File

@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.componentPlugin = void 0;
// Replacing the default htmlBlock rule to allow using custom components at
// root level
const blockNames = require('markdown-it/lib/common/html_blocks');
const HTML_OPEN_CLOSE_TAG_RE = require('markdown-it/lib/common/html_re')
.HTML_OPEN_CLOSE_TAG_RE;
// An array of opening and corresponding closing sequences for html tags,
// last argument defines whether it can terminate a paragraph or not
const HTML_SEQUENCES = [
[/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true],
[/^<!--/, /-->/, true],
[/^<\?/, /\?>/, true],
[/^<![A-Z]/, />/, true],
[/^<!\[CDATA\[/, /\]\]>/, true],
// PascalCase Components
[/^<[A-Z]/, />/, true],
// custom elements with hyphens
[/^<\w+\-/, />/, true],
[
new RegExp('^</?(' + blockNames.join('|') + ')(?=(\\s|/?>|$))', 'i'),
/^$/,
true
],
[new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + '\\s*$'), /^$/, false]
];
exports.componentPlugin = (md) => {
md.block.ruler.at('html_block', htmlBlock);
};
const htmlBlock = (state, startLine, endLine, silent) => {
let i, nextLine, lineText;
let pos = state.bMarks[startLine] + state.tShift[startLine];
let max = state.eMarks[startLine];
// if it's indented more than 3 spaces, it should be a code block
if (state.sCount[startLine] - state.blkIndent >= 4) {
return false;
}
if (!state.md.options.html) {
return false;
}
if (state.src.charCodeAt(pos) !== 0x3c /* < */) {
return false;
}
lineText = state.src.slice(pos, max);
for (i = 0; i < HTML_SEQUENCES.length; i++) {
if (HTML_SEQUENCES[i][0].test(lineText)) {
break;
}
}
if (i === HTML_SEQUENCES.length) {
return false;
}
if (silent) {
// true if this sequence can be a terminator, false otherwise
return HTML_SEQUENCES[i][2];
}
nextLine = startLine + 1;
// If we are here - we detected HTML block.
// Let's roll down till block end.
if (!HTML_SEQUENCES[i][1].test(lineText)) {
for (; nextLine < endLine; nextLine++) {
if (state.sCount[nextLine] < state.blkIndent) {
break;
}
pos = state.bMarks[nextLine] + state.tShift[nextLine];
max = state.eMarks[nextLine];
lineText = state.src.slice(pos, max);
if (HTML_SEQUENCES[i][1].test(lineText)) {
if (lineText.length !== 0) {
nextLine++;
}
break;
}
}
}
state.line = nextLine;
const token = state.push('html_block', '', 0);
token.map = [startLine, nextLine];
token.content = state.getLines(startLine, nextLine, state.blkIndent, true);
return true;
};
//# sourceMappingURL=component.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/node/markdown/plugins/component.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,2 @@
import MarkdownIt from 'markdown-it';
export declare const containerPlugin: (md: MarkdownIt) => void;

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.containerPlugin = void 0;
const container = require('markdown-it-container');
exports.containerPlugin = (md) => {
md.use(...createContainer('tip', 'TIP'))
.use(...createContainer('warning', 'WARNING'))
.use(...createContainer('danger', 'WARNING'))
// explicitly escape Vue syntax
.use(container, 'v-pre', {
render: (tokens, idx) => tokens[idx].nesting === 1 ? `<div v-pre>\n` : `</div>\n`
});
};
function createContainer(klass, defaultTitle) {
return [
container,
klass,
{
render(tokens, idx) {
const token = tokens[idx];
const info = token.info.trim().slice(klass.length).trim();
if (token.nesting === 1) {
return `<div class="${klass} custom-block"><p class="custom-block-title">${info || defaultTitle}</p>\n`;
}
else {
return `</div>\n`;
}
}
}
];
}
//# sourceMappingURL=containers.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"containers.js","sourceRoot":"","sources":["../../../../src/node/markdown/plugins/containers.ts"],"names":[],"mappings":";;;AAGA,MAAM,SAAS,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;AAErC,QAAA,eAAe,GAAG,CAAC,EAAc,EAAE,EAAE;IAChD,EAAE,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SACrC,GAAG,CAAC,GAAG,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;SAC7C,GAAG,CAAC,GAAG,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7C,+BAA+B;SAC9B,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE;QACvB,MAAM,EAAE,CAAC,MAAe,EAAE,GAAW,EAAE,EAAE,CACvC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU;KAC3D,CAAC,CAAA;AACN,CAAC,CAAA;AAUD,SAAS,eAAe,CAAC,KAAa,EAAE,YAAoB;IAC1D,OAAO;QACL,SAAS;QACT,KAAK;QACL;YACE,MAAM,CAAC,MAAM,EAAE,GAAG;gBAChB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;gBACzB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;gBACzD,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE;oBACvB,OAAO,eAAe,KAAK,gDACzB,IAAI,IAAI,YACV,QAAQ,CAAA;iBACT;qBAAM;oBACL,OAAO,UAAU,CAAA;iBAClB;YACH,CAAC;SACF;KACF,CAAA;AACH,CAAC"}

View File

@@ -0,0 +1,2 @@
import MarkdownIt from 'markdown-it';
export declare const extractHeaderPlugin: (md: MarkdownIt, include?: string[]) => void;

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractHeaderPlugin = void 0;
const parseHeader_1 = require("../../utils/parseHeader");
const slugify_1 = require("./slugify");
exports.extractHeaderPlugin = (md, include = ['h2', 'h3']) => {
md.renderer.rules.heading_open = (tokens, i, options, env, self) => {
const token = tokens[i];
if (include.includes(token.tag)) {
const title = tokens[i + 1].content;
const idAttr = token.attrs.find(([name]) => name === 'id');
const slug = idAttr && idAttr[1];
const data = md.__data;
const headers = data.headers || (data.headers = []);
headers.push({
level: parseInt(token.tag.slice(1), 10),
title: parseHeader_1.deeplyParseHeader(title),
slug: slug || slugify_1.slugify(title)
});
}
return self.renderToken(tokens, i, options);
};
};
//# sourceMappingURL=header.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"header.js","sourceRoot":"","sources":["../../../../src/node/markdown/plugins/header.ts"],"names":[],"mappings":";;;AAEA,yDAA2D;AAC3D,uCAAmC;AAEtB,QAAA,mBAAmB,GAAG,CAAC,EAAc,EAAE,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;IAC5E,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACjE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QACvB,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAA;YACnC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;YAC3D,MAAM,IAAI,GAAG,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAA;YAChC,MAAM,IAAI,GAAI,EAAU,CAAC,MAA4B,CAAA;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,CAAA;YACnD,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBACvC,KAAK,EAAE,+BAAiB,CAAC,KAAK,CAAC;gBAC/B,IAAI,EAAE,IAAI,IAAI,iBAAO,CAAC,KAAK,CAAC;aAC7B,CAAC,CAAA;SACH;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC,CAAA;AACH,CAAC,CAAA"}

View File

@@ -0,0 +1 @@
export declare const highlight: (str: string, lang: string) => string;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.highlight = void 0;
const chalk = require('chalk');
const prism = require('prismjs');
const loadLanguages = require('prismjs/components/index');
const escapeHtml = require('escape-html');
// required to make embedded highlighting work...
loadLanguages(['markup', 'css', 'javascript']);
function wrap(code, lang) {
if (lang === 'text') {
code = escapeHtml(code);
}
return `<pre v-pre><code>${code}</code></pre>`;
}
exports.highlight = (str, lang) => {
if (!lang) {
return wrap(str, 'text');
}
lang = lang.toLowerCase();
const rawLang = lang;
if (lang === 'vue' || lang === 'html') {
lang = 'markup';
}
if (lang === 'md') {
lang = 'markdown';
}
if (lang === 'ts') {
lang = 'typescript';
}
if (lang === 'py') {
lang = 'python';
}
if (!prism.languages[lang]) {
try {
loadLanguages([lang]);
}
catch (e) {
console.warn(chalk.yellow(`[vuepress] Syntax highlight for language "${lang}" is not supported.`));
}
}
if (prism.languages[lang]) {
const code = prism.highlight(str, prism.languages[lang], lang);
return wrap(code, rawLang);
}
return wrap(str, 'text');
};
//# sourceMappingURL=highlight.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"highlight.js","sourceRoot":"","sources":["../../../../src/node/markdown/plugins/highlight.ts"],"names":[],"mappings":";;;AAAA,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;AAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;AAChC,MAAM,aAAa,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAA;AACzD,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;AAEzC,iDAAiD;AACjD,aAAa,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAA;AAE9C,SAAS,IAAI,CAAC,IAAY,EAAE,IAAY;IACtC,IAAI,IAAI,KAAK,MAAM,EAAE;QACnB,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;KACxB;IACD,OAAO,oBAAoB,IAAI,eAAe,CAAA;AAChD,CAAC;AAEY,QAAA,SAAS,GAAG,CAAC,GAAW,EAAE,IAAY,EAAE,EAAE;IACrD,IAAI,CAAC,IAAI,EAAE;QACT,OAAO,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;KACzB;IACD,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IACzB,MAAM,OAAO,GAAG,IAAI,CAAA;IACpB,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM,EAAE;QACrC,IAAI,GAAG,QAAQ,CAAA;KAChB;IACD,IAAI,IAAI,KAAK,IAAI,EAAE;QACjB,IAAI,GAAG,UAAU,CAAA;KAClB;IACD,IAAI,IAAI,KAAK,IAAI,EAAE;QACjB,IAAI,GAAG,YAAY,CAAA;KACpB;IACD,IAAI,IAAI,KAAK,IAAI,EAAE;QACjB,IAAI,GAAG,QAAQ,CAAA;KAChB;IACD,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QAC1B,IAAI;YACF,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;SACtB;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,IAAI,CACV,KAAK,CAAC,MAAM,CACV,6CAA6C,IAAI,qBAAqB,CACvE,CACF,CAAA;SACF;KACF;IACD,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;QAC9D,OAAO,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;KAC3B;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;AAC1B,CAAC,CAAA"}

View File

@@ -0,0 +1,2 @@
import MarkdownIt from 'markdown-it';
export declare const highlightLinePlugin: (md: MarkdownIt) => void;

View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.highlightLinePlugin = void 0;
const RE = /{([\d,-]+)}/;
const wrapperRE = /^<pre .*?><code>/;
exports.highlightLinePlugin = (md) => {
const fence = md.renderer.rules.fence;
md.renderer.rules.fence = (...args) => {
const [tokens, idx, options] = args;
const token = tokens[idx];
const rawInfo = token.info;
if (!rawInfo || !RE.test(rawInfo)) {
return fence(...args);
}
const langName = rawInfo.replace(RE, '').trim();
// ensure the next plugin get the correct lang.
token.info = langName;
const lineNumbers = RE.exec(rawInfo)[1]
.split(',')
.map((v) => v.split('-').map((v) => parseInt(v, 10)));
const code = options.highlight
? options.highlight(token.content, langName)
: token.content;
const rawCode = code.replace(wrapperRE, '');
const highlightLinesCode = rawCode
.split('\n')
.map((split, index) => {
const lineNumber = index + 1;
const inRange = lineNumbers.some(([start, end]) => {
if (start && end) {
return lineNumber >= start && lineNumber <= end;
}
return lineNumber === start;
});
if (inRange) {
return `<div class="highlighted">&nbsp;</div>`;
}
return '<br>';
})
.join('');
const highlightLinesWrapperCode = `<div class="highlight-lines">${highlightLinesCode}</div>`;
return highlightLinesWrapperCode + code;
};
};
//# sourceMappingURL=highlightLines.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"highlightLines.js","sourceRoot":"","sources":["../../../../src/node/markdown/plugins/highlightLines.ts"],"names":[],"mappings":";;;AAGA,MAAM,EAAE,GAAG,aAAa,CAAA;AACxB,MAAM,SAAS,GAAG,kBAAkB,CAAA;AAEvB,QAAA,mBAAmB,GAAG,CAAC,EAAc,EAAE,EAAE;IACpD,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAM,CAAA;IACtC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE;QACpC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;QACnC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;QAEzB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAA;QAC1B,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YACjC,OAAO,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;SACtB;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QAC/C,+CAA+C;QAC/C,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAA;QAErB,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAE,CAAC,CAAC,CAAC;aACrC,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;QAEvD,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS;YAC5B,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC;YAC5C,CAAC,CAAC,KAAK,CAAC,OAAO,CAAA;QAEjB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QAC3C,MAAM,kBAAkB,GAAG,OAAO;aAC/B,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACpB,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAA;YAC5B,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE;gBAChD,IAAI,KAAK,IAAI,GAAG,EAAE;oBAChB,OAAO,UAAU,IAAI,KAAK,IAAI,UAAU,IAAI,GAAG,CAAA;iBAChD;gBACD,OAAO,UAAU,KAAK,KAAK,CAAA;YAC7B,CAAC,CAAC,CAAA;YACF,IAAI,OAAO,EAAE;gBACX,OAAO,uCAAuC,CAAA;aAC/C;YACD,OAAO,MAAM,CAAA;QACf,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC,CAAA;QAEX,MAAM,yBAAyB,GAAG,gCAAgC,kBAAkB,QAAQ,CAAA;QAE5F,OAAO,yBAAyB,GAAG,IAAI,CAAA;IACzC,CAAC,CAAA;AACH,CAAC,CAAA"}

Some files were not shown because too many files have changed in this diff Show More