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

147
node_modules/vitepress/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,147 @@
## [0.7.4](https://github.com/vuejs/vitepress/compare/v0.7.3...v0.7.4) (2020-11-11)
### Bug Fixes
- **css:** fix padding on mobile ([9c7293b](https://github.com/vuejs/vitepress/commit/9c7293b6cbdbcabb4257793e1b1f3fea2388c31e)), closes [#121](https://github.com/vuejs/vitepress/issues/121)
## [0.7.3](https://github.com/vuejs/vitepress/compare/v0.7.2...v0.7.3) (2020-11-06)
### Bug Fixes
- Fix sidebar page switch layout shifting
- Fix production hydration mismatch
## [0.7.2](https://github.com/vuejs/vitepress/compare/v0.7.1...v0.7.2) (2020-11-02)
### Bug Fixes
- adapt to vite fix of ssr build asset paths ([6b3fbe3](https://github.com/vuejs/vitepress/commit/6b3fbe31a31adad2a836c45905bde86332e4f1f6))
### Features
- add home page feature ([#108](https://github.com/vuejs/vitepress/issues/108)) ([3a0af0b](https://github.com/vuejs/vitepress/commit/3a0af0b6141ed739aa4a2d72f43d0fa63739c695))
## [0.7.1](https://github.com/vuejs/vitepress/compare/v0.7.0...v0.7.1) (2020-10-30)
### Bug Fixes
- compat with latest vite + handle no export default script tags in md ([b10da2f](https://github.com/vuejs/vitepress/commit/b10da2f47b456a10e62f16e2cd08d6983da041c0))
- fix switch language error ([#103](https://github.com/vuejs/vitepress/issues/103), [#106](https://github.com/vuejs/vitepress/issues/106)) ([#104](https://github.com/vuejs/vitepress/issues/104)) ([d354d1e](https://github.com/vuejs/vitepress/commit/d354d1ef2211cc8734a7228d56f27b014af7a4f9))
# [0.7.0](https://github.com/vuejs/vitepress/compare/v0.6.0...v0.7.0) (2020-10-19)
### Bug Fixes
- **css:** theme specific ([6891092](https://github.com/vuejs/vitepress/commit/6891092b90d5a405a718b08b30c7be5260adef47))
- **router:** remove fakeHost when fixing url extenions ([2eb3135](https://github.com/vuejs/vitepress/commit/2eb31358bf4790a08f43c102691df75023382ce5))
### Features
- **client:** add slot for a searchbar ([68d9b18](https://github.com/vuejs/vitepress/commit/68d9b18f391b9ad1dd8d800296a6117119e397b5))
- **i18n:** add nav dropdown language selector feature ([#91](https://github.com/vuejs/vitepress/issues/91)) ([294836c](https://github.com/vuejs/vitepress/commit/294836ce40afcb9e3af8146575d06bf386bfe1a1))
- **sidebar:** close when navigating ([2094d53](https://github.com/vuejs/vitepress/commit/2094d534dbe9f84d308fbf130dabbf6155a33005))
- add doctype html ([02f2e10](https://github.com/vuejs/vitepress/commit/02f2e10f89881d99bf3c016477da788c25ef207f))
- add some space between 2 code blocks ([5daa8d2](https://github.com/vuejs/vitepress/commit/5daa8d2c38d3c8352b340ad1f5fd4a67d1fdb09b))
# [0.6.0](https://github.com/vuejs/vitepress/compare/v0.5.0...v0.6.0) (2020-09-17)
### Bug Fixes
- **client:** use relative import ([725a04c](https://github.com/vuejs/vitepress/commit/725a04cdf02f208c85de01e4f1e74168511b95aa))
- **links:** keep relative hash links as is ([a90d971](https://github.com/vuejs/vitepress/commit/a90d971b40d775e2bac19bcfd17cbeafbc878d34))
- **router:** allow open new tab with ctrl + click ([#69](https://github.com/vuejs/vitepress/issues/69)) ([092ee77](https://github.com/vuejs/vitepress/commit/092ee772dafa78a66c2e35524bd921eb0aa31b16))
- **sidebar:** no margin on mobile ([#89](https://github.com/vuejs/vitepress/issues/89)) ([218c729](https://github.com/vuejs/vitepress/commit/218c72915489e25e1d6ca7b09979c45abf64a3a3))
- sidebar not working correctly when path starts with slash ([610cc17](https://github.com/vuejs/vitepress/commit/610cc17af0624d82d0eb3ed652f0b5fa1c2402f0))
- **sidebar:** fix sidebar when you open a nested link ([#73](https://github.com/vuejs/vitepress/issues/73)) ([d2b6d39](https://github.com/vuejs/vitepress/commit/d2b6d39228a03ad122ab09420dab2cba2c2b4167))
### Features
- add blockquote styling ([8c1aada](https://github.com/vuejs/vitepress/commit/8c1aada6288609c2f01c14f353359a14d1264244))
- add charset and viewport meta tags ([#77](https://github.com/vuejs/vitepress/issues/77)) ([2e8e1f5](https://github.com/vuejs/vitepress/commit/2e8e1f57cc7618c4cbc198153dde3927b076b08c))
- add git repo link and edit links ([#55](https://github.com/vuejs/vitepress/issues/55)) ([0ea34cb](https://github.com/vuejs/vitepress/commit/0ea34cbb1de0db8a2ff34bb858c2904c89369ccd))
- add prev/next links ([#56](https://github.com/vuejs/vitepress/issues/56)) ([f52b1d5](https://github.com/vuejs/vitepress/commit/f52b1d576b024443f737604d2220a0edb1571355))
- add responsive sidebar support ([#75](https://github.com/vuejs/vitepress/issues/75)) ([39dbd78](https://github.com/vuejs/vitepress/commit/39dbd7806e96e18e60de87311ae7b162ebb61c3c))
- add table css from vuepress ([#88](https://github.com/vuejs/vitepress/issues/88)) ([8435e36](https://github.com/vuejs/vitepress/commit/8435e36374e2d5c96bbab781f378602e2372f5d4))
- close the sidebar when clicking outside of the sidebar ([#78](https://github.com/vuejs/vitepress/issues/78)) ([e93ee09](https://github.com/vuejs/vitepress/commit/e93ee094ea5696d692323546738d0643ed82f154))
- navlinks in sidebar ([#80](https://github.com/vuejs/vitepress/issues/80)) ([a20bcf3](https://github.com/vuejs/vitepress/commit/a20bcf3cd7c4d8e243d6547f099b9fdc702ee350))
- overwrite prev/next link ([#61](https://github.com/vuejs/vitepress/issues/61)) ([1b96f63](https://github.com/vuejs/vitepress/commit/1b96f631b83585591a1436b8a7dadf52fad61c25))
- support config alias ([#59](https://github.com/vuejs/vitepress/issues/59)) ([63a3691](https://github.com/vuejs/vitepress/commit/63a36919601df678a0f8225627d66dff67c81c3a))
- top and bottom slots for sidebar and page ([#90](https://github.com/vuejs/vitepress/issues/90)) ([1106013](https://github.com/vuejs/vitepress/commit/11060136c4bf2ec1d39e0d0d6951b9093e3edc06))
- **sidebar:** use base when creating link ([#74](https://github.com/vuejs/vitepress/issues/74)) ([79bc9fb](https://github.com/vuejs/vitepress/commit/79bc9fb15a9560932228f22e7bd152272d577da6))
# [0.5.0](https://github.com/vuejs/vitepress/compare/v0.4.1...v0.5.0) (2020-07-21)
### Bug Fixes
- decode hash before selecting ([e782c4c](https://github.com/vuejs/vitepress/commit/e782c4cb86dbb8ff294d0670e171692651618a0e))
- fix navbar withBase ([e9ab56b](https://github.com/vuejs/vitepress/commit/e9ab56b0dbe859c0a147e2a2755bfcf2c0b92904))
- typings field in package.json ([#48](https://github.com/vuejs/vitepress/issues/48)) ([692a490](https://github.com/vuejs/vitepress/commit/692a490986ab81eb5be5bc7fdce0434ce84aa620))
### Features
- add external link support for nav items ([#46](https://github.com/vuejs/vitepress/issues/46)) ([44e91bb](https://github.com/vuejs/vitepress/commit/44e91bb98631c843f9accad1cffd24fbc6337fe0))
- add multi sidebar support ([#38](https://github.com/vuejs/vitepress/issues/38)) ([#49](https://github.com/vuejs/vitepress/issues/49)) ([050fa4c](https://github.com/vuejs/vitepress/commit/050fa4cf245f9f33d25684f8bcf218a6b5d6dedb))
- i18n support ([#50](https://github.com/vuejs/vitepress/issues/50)) ([7802cb5](https://github.com/vuejs/vitepress/commit/7802cb55c2a82cc1878fc1ebc4dc2fcf1f2f1ff0))
- nav dropdown ([#51](https://github.com/vuejs/vitepress/issues/51)) ([5780461](https://github.com/vuejs/vitepress/commit/578046145ff4ef445f7a7704016ab791a4ef330f))
## [0.4.1](https://github.com/vuejs/vitepress/compare/v0.4.0...v0.4.1) (2020-07-02)
### Bug Fixes
- avoid error when requesting non-existing md file ([e77ea63](https://github.com/vuejs/vitepress/commit/e77ea6323720f19d7401cb1a9fa94d1963f29e15))
- resolve relative path on windows ([#27](https://github.com/vuejs/vitepress/issues/27)) ([9116c9c](https://github.com/vuejs/vitepress/commit/9116c9c3e06071f34b523cb488d9e5d963808a3c))
- use resolve instead of join ([#33](https://github.com/vuejs/vitepress/issues/33)) ([6f10ed6](https://github.com/vuejs/vitepress/commit/6f10ed6c63b7486f678fdd7eedc888925feb473c))
### Features
- add array sidebar support ([#35](https://github.com/vuejs/vitepress/issues/35)) ([4a8388e](https://github.com/vuejs/vitepress/commit/4a8388e113f978f6afc6936a86b06effc42a8304))
# [0.4.0](https://github.com/vuejs/vitepress/compare/v0.3.1...v0.4.0) (2020-06-19)
## [0.3.1](https://github.com/vuejs/vitepress/compare/v0.3.0...v0.3.1) (2020-06-05)
### Bug Fixes
- avoid using **DEV** + throttle active header link ([a63b0cf](https://github.com/vuejs/vitepress/commit/a63b0cf69a4d1f8b1b7e44f76c6283f28d437b59))
# [0.3.0](https://github.com/vuejs/vitepress/compare/v0.2.0...v0.3.0) (2020-06-02)
### Bug Fixes
- lazy load @vue/server-render for production build ([382e1b6](https://github.com/vuejs/vitepress/commit/382e1b6514035f69dc9e505fad38a781cd35166e))
### Features
- active sidebar links ([d2ea963](https://github.com/vuejs/vitepress/commit/d2ea9637eeafc1c1510d038f1f749e650a086a32))
# [0.2.0](https://github.com/vuejs/vitepress/compare/v0.1.1...v0.2.0) (2020-05-22)
### Bug Fixes
- avoid unnecessary prefetches ([0a81525](https://github.com/vuejs/vitepress/commit/0a815255b9f226ec5ac032d6db5b151caa9c58fb))
- handle links that embed other elements ([#2](https://github.com/vuejs/vitepress/issues/2)) ([4cbfc60](https://github.com/vuejs/vitepress/commit/4cbfc60a58f7b7ef0d82c6a2b1a48b67ace3d924))
### Features
- copy public dir ([ddc9d51](https://github.com/vuejs/vitepress/commit/ddc9d519c60423e2432c1f3c0ab5b2ccbabd34a6))
- lean builds ([b61e239](https://github.com/vuejs/vitepress/commit/b61e2398fc40be98cd8372834fa3b1e5277c8e1f))
- prefetch in viewport inbound page chunks ([da4852a](https://github.com/vuejs/vitepress/commit/da4852a61bd73a8b46c4971c330f95761237c733))
- use hashed page file names ([a873564](https://github.com/vuejs/vitepress/commit/a8735646e8aae04d7091decc8c4fd54025ceb181))
- use modulepreload links ([0025af1](https://github.com/vuejs/vitepress/commit/0025af12f4ec8e021ea1b7b9d48b0b4025924d83))
### Performance Improvements
- inject script tags for page common chunk imports ([57d900d](https://github.com/vuejs/vitepress/commit/57d900d4b357f15f3dec28e822bd5fd8d100d589))
## 0.1.1 (2020-04-30)
- fix dependency versions
# 0.1.0 (2020-04-30)
### Features
- add markdown processing ([5c47bbb](https://github.com/vuejs/vitepress/commit/5c47bbb4638d7f78ae38fe02732f5b639654c134))
- spa navigation ([21d3cd8](https://github.com/vuejs/vitepress/commit/21d3cd8cbe4102293d2903c3d060764d86a8f785))
- update head tags during dev ([bdbbdd5](https://github.com/vuejs/vitepress/commit/bdbbdd556fe7e3906a5997291ff692cf2b78d632))
- update title & description during dev ([0b9bf27](https://github.com/vuejs/vitepress/commit/0b9bf273ef4f31bf448f7813c50e474b4035b7dc))

21
node_modules/vitepress/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-present, Yuxi (Evan) You
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

99
node_modules/vitepress/README.md generated vendored Normal file
View File

@@ -0,0 +1,99 @@
# (WIP) VitePress 📝💨
[![npm](https://img.shields.io/npm/v/vitepress)](https://www.npmjs.com/package/vitepress)
> [VuePress](http://vuepress.vuejs.org/)' little brother, built on top of [vite](https://github.com/vuejs/vite)
**Note this is early WIP! Currently the focus is on making Vite stable and feature complete first. It is not recommended to use this for anything serious yet.**
``` bash
npm install -D vitepress
echo '# Hello VitePress' > index.md
# starts dev server
npx vitepress
# build > .vitepress/dist
npx vitepress build
```
## Customization
Configuration can be done via `.vitepress/config.js` (see `src/node/config.ts`)
You can develop your custom theme by adding the following files:
`.vitepress/theme/Layout.vue`
```vue
<template>
<h1>Custom Layout!</h1>
<Content/><!-- make sure to include markdown outlet -->
</template>
```
`.vitepress/theme/index.js`
```js
import Layout from './Layout.vue'
export default {
Layout,
NotFound: () => 'custom 404', // <- this is a Vue 3 functional component
enhanceApp({ app, router, siteData }) {
// app is the Vue 3 app instance from createApp()
// router is VitePress' custom router (see `lib/app/router.js`)
// siteData is a ref of current site-level metadata.
}
}
```
Unlike VuePress, the only file with a fixed location in a theme is `index.js` - everything else is imported and exported there like in a normal application.
## Motivation
I love VuePress, but being built on top of webpack, the time it takes to spin up the dev server for a simple doc site with a few pages is just becoming unbearable. Even HMR updates can take up to seconds to reflect in the browser!
As a reference, the [Composition API RFC repo](https://github.com/vuejs/composition-api-rfc) is just two pages, but it takes 4 seconds to spin up the server, and almost 2 seconds for any edit to reflect in the browser.
Fundamentally, this is because VuePress is a webpack app under the hood. Even with just two pages, it's a full on webpack project (including all the theme source files) being compiled. It gets even worse when the project has many pages - every page must first be fully compiled before the server can even display anything!
Incidentally, [vite](https://github.com/vuejs/vite) solves these problems really well: nearly instant server start, on-demand compilation that only compiles the page being served, and lightning fast HMR. Plus, there are a few additional design issues I have noted in VuePress over time, but never had the time to fix due to the amount of refactoring it would require.
Now, with `vite` and Vue 3, it is time to rethink what a "Vue-powered static site generator" can really be.
## Improvements over VuePress
- Uses Vue 3.
- Leverages Vue 3's improved template static analysis to stringify static content as much as possible. Static content is sent as string literals instead of JavaScript render function code - the JS payload is therefore *much* cheaper to parse, and hydration also becomes faster.
Note the optimization is applied while still allowing the user to freely mix Vue components inside markdown content - the compiler does the static/dynamic separation for you automatically and you never need to think about it.
- Uses `vite` under the hood:
- Faster dev server start
- Faster hot updates
- Faster build (uses Rollup internally)
- Lighter page weight.
- Vue 3 tree-shaking + Rollup code splitting
- Does not ship metadata for every page on every request. This decouples page weight from total number of pages. Only the current page's metadata is sent. Client side navigation fetches the new page's component and metadata together.
- Does not use `vue-router` because the need of VitePress is very simple and specific - a simple custom router (under 200 LOC) is used instead.
- (WIP) i18n locale data should also be fetched on demand.
## Other Differences
- More opinionated and less configurable: VitePress aims to scale back the complexity in the current VuePress and restart from its minimalist roots.
- Future oriented: VitePress only targets browsers that support native ES module imports. It encourages the use of native JavaScript without transpilation, and CSS variables for theming.
## Will this become the next VuePress in the future?
Maybe! It's currently under a different name so that we don't over commit to the compatibility with the current VuePress ecosystem (mostly themes and plugins). We'll see how close we can get without compromising the design goals listed above. But the overall idea is that VitePress will have a drastically more minimal theming API (preferring JavaScript APIs instead of file layout conventions) and likely no plugins (all customization is done in themes).
## Want to contribute?
Check out our [contributing guide](https://github.com/vuejs/vitepress/blob/master/CONTRIBUTING.md) for more information!
## License
MIT

34
node_modules/vitepress/bin/vitepress.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
#!/usr/bin/env node
const chalk = require('chalk')
const argv = require('minimist')(process.argv.slice(2))
console.log(chalk.cyan(`vitepress v${require('../package.json').version}`))
console.log(chalk.cyan(`vite v${require('vite/package.json').version}`))
const command = argv._[0]
const root = argv._[command ? 1 : 0]
if (root) {
argv.root = root
}
if (!command || command === 'dev') {
const port = argv.port || 3000
require('../dist/node')
.createServer(argv)
.then((server) => {
server.listen(port, () => {
console.log(`listening at http://localhost:${port}`)
})
})
.catch((err) => {
console.error(chalk.red(`failed to start server. error:\n`), err)
})
} else if (command === 'build') {
require('../dist/node')
.build(argv)
.catch((err) => {
console.error(chalk.red(`build error:\n`), err)
})
} else {
console.log(chalk.red(`unknown command "${command}".`))
}

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":"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"}

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

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