vitepress 1.0.0-draft.8 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/client.d.ts +2 -0
- package/dist/client/app/components/Content.js +15 -4
- package/dist/client/app/composables/codeGroups.js +40 -0
- package/dist/client/app/composables/copyCode.js +71 -0
- package/dist/client/app/composables/head.js +15 -44
- package/dist/client/app/composables/preFetch.js +9 -4
- package/dist/client/app/data.js +13 -16
- package/dist/client/app/devtools.js +28 -0
- package/dist/client/app/index.js +71 -46
- package/dist/client/app/router.js +132 -60
- package/dist/client/app/ssr.js +10 -0
- package/dist/client/app/utils.js +46 -10
- package/dist/client/index.d.ts +81 -87
- package/dist/client/index.js +3 -5
- package/dist/client/shared.js +83 -59
- package/dist/client/theme-default/Layout.vue +48 -9
- package/dist/client/theme-default/NotFound.vue +34 -9
- package/dist/client/theme-default/components/VPAlgoliaSearchBox.vue +46 -73
- package/dist/client/theme-default/components/VPBackdrop.vue +3 -1
- package/dist/client/theme-default/components/VPBadge.vue +74 -0
- package/dist/client/theme-default/components/VPButton.vue +6 -4
- package/dist/client/theme-default/components/VPCarbonAds.vue +30 -19
- package/dist/client/theme-default/components/VPContent.vue +30 -13
- package/dist/client/theme-default/components/VPDoc.vue +55 -36
- package/dist/client/theme-default/components/VPDocAside.vue +4 -4
- package/dist/client/theme-default/components/VPDocAsideCarbonAds.vue +7 -2
- package/dist/client/theme-default/components/VPDocAsideOutline.vue +20 -63
- package/dist/client/theme-default/components/VPDocAsideSponsors.vue +3 -18
- package/dist/client/theme-default/components/VPDocFooter.vue +55 -46
- package/dist/client/theme-default/components/VPDocFooterLastUpdated.vue +48 -0
- package/dist/client/theme-default/components/VPDocOutlineDropdown.vue +85 -0
- package/dist/client/theme-default/components/VPDocOutlineItem.vue +57 -0
- package/dist/client/theme-default/components/VPFeature.vue +113 -0
- package/dist/client/theme-default/components/VPFeatures.vue +119 -0
- package/dist/client/theme-default/components/VPFlyout.vue +20 -24
- package/dist/client/theme-default/components/VPFooter.vue +6 -9
- package/dist/client/theme-default/components/VPHero.vue +48 -29
- package/dist/client/theme-default/components/VPHome.vue +6 -1
- package/dist/client/theme-default/components/VPHomeFeatures.vue +7 -90
- package/dist/client/theme-default/components/VPHomeHero.vue +13 -10
- package/dist/client/theme-default/components/VPHomeSponsors.vue +2 -2
- package/dist/client/theme-default/components/VPImage.vue +46 -0
- package/dist/client/theme-default/components/VPLink.vue +14 -19
- package/dist/client/theme-default/components/VPLocalNav.vue +63 -27
- package/dist/client/theme-default/components/VPLocalNavOutlineDropdown.vue +162 -0
- package/dist/client/theme-default/components/VPLocalSearchBox.vue +924 -0
- package/dist/client/theme-default/components/VPMenu.vue +6 -8
- package/dist/client/theme-default/components/VPMenuGroup.vue +18 -6
- package/dist/client/theme-default/components/VPMenuLink.vue +27 -9
- package/dist/client/theme-default/components/VPNav.vue +15 -21
- package/dist/client/theme-default/components/VPNavBar.vue +150 -40
- package/dist/client/theme-default/components/VPNavBarAppearance.vue +1 -1
- package/dist/client/theme-default/components/VPNavBarExtra.vue +18 -6
- package/dist/client/theme-default/components/VPNavBarHamburger.vue +10 -10
- package/dist/client/theme-default/components/VPNavBarMenu.vue +1 -1
- package/dist/client/theme-default/components/VPNavBarMenuGroup.vue +17 -2
- package/dist/client/theme-default/components/VPNavBarMenuLink.vue +8 -12
- package/dist/client/theme-default/components/VPNavBarSearch.vue +141 -192
- package/dist/client/theme-default/components/VPNavBarSearchButton.vue +208 -0
- package/dist/client/theme-default/components/VPNavBarSocialLinks.vue +1 -1
- package/dist/client/theme-default/components/VPNavBarTitle.vue +18 -25
- package/dist/client/theme-default/components/VPNavBarTranslations.vue +7 -4
- package/dist/client/theme-default/components/VPNavScreen.vue +8 -3
- package/dist/client/theme-default/components/VPNavScreenAppearance.vue +5 -5
- package/dist/client/theme-default/components/VPNavScreenMenu.vue +2 -3
- package/dist/client/theme-default/components/VPNavScreenMenuGroup.vue +3 -5
- package/dist/client/theme-default/components/VPNavScreenMenuGroupLink.vue +12 -6
- package/dist/client/theme-default/components/VPNavScreenMenuGroupSection.vue +2 -3
- package/dist/client/theme-default/components/VPNavScreenMenuLink.vue +12 -6
- package/dist/client/theme-default/components/VPNavScreenSocialLinks.vue +1 -1
- package/dist/client/theme-default/components/VPNavScreenTranslations.vue +11 -7
- package/dist/client/theme-default/components/VPPage.vue +2 -0
- package/dist/client/theme-default/components/VPSidebar.vue +47 -28
- package/dist/client/theme-default/components/VPSidebarItem.vue +237 -0
- package/dist/client/theme-default/components/VPSkipLink.vue +3 -7
- package/dist/client/theme-default/components/VPSocialLink.vue +16 -28
- package/dist/client/theme-default/components/VPSocialLinks.vue +3 -3
- package/dist/client/theme-default/components/VPSponsors.vue +9 -15
- package/dist/client/theme-default/components/VPSponsorsGrid.vue +23 -5
- package/dist/client/theme-default/components/VPSwitch.vue +7 -10
- package/dist/client/theme-default/components/VPSwitchAppearance.vue +43 -7
- package/dist/client/theme-default/components/VPTeamMembers.vue +55 -0
- package/dist/client/theme-default/components/VPTeamMembersItem.vue +220 -0
- package/dist/client/theme-default/components/VPTeamPage.vue +53 -0
- package/dist/client/theme-default/components/VPTeamPageSection.vue +77 -0
- package/dist/client/theme-default/components/VPTeamPageTitle.vue +63 -0
- package/dist/client/theme-default/composables/aside.js +1 -1
- package/dist/client/theme-default/composables/data.js +2 -0
- package/dist/client/theme-default/composables/edit-link.js +10 -16
- package/dist/client/theme-default/composables/flyout.js +2 -1
- package/dist/client/theme-default/composables/langs.js +26 -0
- package/dist/client/theme-default/composables/nav.js +4 -25
- package/dist/client/theme-default/composables/outline.js +73 -35
- package/dist/client/theme-default/composables/prev-next.js +35 -5
- package/dist/client/theme-default/composables/sidebar.js +86 -4
- package/dist/client/theme-default/composables/sponsor-grid.js +2 -2
- package/dist/client/theme-default/fonts/inter-italic-cyrillic-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-italic-cyrillic.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-italic-greek-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-italic-greek.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-italic-latin-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-italic-latin.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-italic-vietnamese.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-roman-cyrillic-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-roman-cyrillic.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-roman-greek-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-roman-greek.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-roman-latin-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-roman-latin.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-roman-vietnamese.woff2 +0 -0
- package/dist/client/theme-default/index.js +2 -17
- package/dist/client/theme-default/styles/base.css +21 -7
- package/dist/client/theme-default/styles/components/custom-block.css +12 -4
- package/dist/client/theme-default/styles/components/vp-code-group.css +84 -0
- package/dist/client/theme-default/styles/components/vp-code.css +7 -0
- package/dist/client/theme-default/styles/components/vp-doc.css +209 -111
- package/dist/client/theme-default/styles/components/vp-sponsor.css +43 -18
- package/dist/client/theme-default/styles/fonts.css +133 -35
- package/dist/client/theme-default/styles/vars.css +328 -180
- package/dist/client/theme-default/support/sidebar.js +57 -11
- package/dist/client/theme-default/support/socialIcons.js +12 -0
- package/dist/client/theme-default/support/translation.js +48 -0
- package/dist/client/theme-default/support/utils.js +10 -36
- package/dist/client/theme-default/without-fonts.js +29 -0
- package/dist/node/cli.js +407 -264
- package/dist/node/index.d.ts +2159 -220
- package/dist/node/index.js +96 -13
- package/dist/node/{serve-9c85885c.js → serve-0989a5bc.js} +49700 -44573
- package/package.json +129 -87
- package/template/.vitepress/config.js +28 -0
- package/template/.vitepress/theme/Layout.vue +21 -0
- package/template/.vitepress/theme/index.js +25 -0
- package/template/.vitepress/theme/style.css +95 -0
- package/template/api-examples.md +49 -0
- package/template/index.md +28 -0
- package/template/markdown-examples.md +85 -0
- package/theme-without-fonts.d.ts +2 -0
- package/theme.d.ts +16 -7
- package/types/default-theme.d.ts +311 -49
- package/types/docsearch.d.ts +143 -0
- package/types/index.d.ts +3 -2
- package/types/local-search.d.ts +27 -0
- package/types/shared.d.ts +58 -36
- package/dist/client/app/components/Debug.vue +0 -86
- package/dist/client/theme-default/components/VPBox.vue +0 -55
- package/dist/client/theme-default/components/VPSidebarGroup.vue +0 -107
- package/dist/client/theme-default/components/VPSidebarLink.vue +0 -50
- package/dist/client/theme-default/components/icons/VPIconDiscord.vue +0 -5
- package/dist/client/theme-default/components/icons/VPIconExternalLink.vue +0 -13
- package/dist/client/theme-default/components/icons/VPIconFacebook.vue +0 -5
- package/dist/client/theme-default/components/icons/VPIconGitHub.vue +0 -5
- package/dist/client/theme-default/components/icons/VPIconInstagram.vue +0 -5
- package/dist/client/theme-default/components/icons/VPIconLinkedIn.vue +0 -5
- package/dist/client/theme-default/components/icons/VPIconSlack.vue +0 -5
- package/dist/client/theme-default/components/icons/VPIconTwitter.vue +0 -5
- package/dist/client/theme-default/components/icons/VPIconYouTube.vue +0 -5
- package/dist/client/theme-default/composables/copy-code.js +0 -33
- package/dist/client/theme-default/config.js +0 -1
- package/dist/client/theme-default/fonts/inter-cyrillic-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-cyrillic.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-greek-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-greek.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-latin-ext.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-latin.woff2 +0 -0
- package/dist/client/theme-default/fonts/inter-vietnamese.woff2 +0 -0
- package/dist/node-cjs/cli.cjs +0 -304
- package/dist/node-cjs/index.cjs +0 -38
- package/dist/node-cjs/serve-a73b4871.cjs +0 -64844
package/README.md
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
# VitePress (
|
|
1
|
+
# VitePress (beta) 📝💨
|
|
2
2
|
|
|
3
3
|
[](https://github.com/vuejs/vitepress/actions)
|
|
4
4
|
[](https://www.npmjs.com/package/vitepress)
|
|
5
|
+
[](https://chat.vuejs.org)
|
|
5
6
|
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
VitePress is [VuePress](https://vuepress.vuejs.org)' spiritual successor, built on top of [vite](https://github.com/vitejs/vite).
|
|
9
10
|
|
|
10
|
-
Currently, it
|
|
11
|
+
Currently, it is in the `beta` stage. It is already suitable for out-of-the-box documentation use. There still might be issues, however, we do not plan to introduce any breaking changes from here on until the stable release.
|
|
11
12
|
|
|
12
13
|
## Documentation
|
|
13
14
|
|
|
14
|
-
To check out docs, visit [vitepress.
|
|
15
|
+
To check out docs, visit [vitepress.dev](https://vitepress.dev).
|
|
15
16
|
|
|
16
17
|
## Changelog
|
|
17
18
|
|
package/client.d.ts
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { defineComponent, h } from 'vue';
|
|
2
|
-
import { useRoute } from '
|
|
2
|
+
import { useData, useRoute } from 'vitepress';
|
|
3
|
+
import { contentUpdatedCallbacks } from '../utils';
|
|
4
|
+
const runCbs = () => contentUpdatedCallbacks.forEach((fn) => fn());
|
|
3
5
|
export const Content = defineComponent({
|
|
4
6
|
name: 'VitePressContent',
|
|
5
|
-
|
|
7
|
+
props: {
|
|
8
|
+
as: { type: [Object, String], default: 'div' }
|
|
9
|
+
},
|
|
10
|
+
setup(props) {
|
|
6
11
|
const route = useRoute();
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
const { site } = useData();
|
|
13
|
+
return () => h(props.as, site.value.contentProps ?? { style: { position: 'relative' } }, [
|
|
14
|
+
route.component
|
|
15
|
+
? h(route.component, {
|
|
16
|
+
onVnodeMounted: runCbs,
|
|
17
|
+
onVnodeUpdated: runCbs
|
|
18
|
+
})
|
|
19
|
+
: '404 Page Not Found'
|
|
9
20
|
]);
|
|
10
21
|
}
|
|
11
22
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { inBrowser, onContentUpdated } from 'vitepress';
|
|
2
|
+
export function useCodeGroups() {
|
|
3
|
+
if (import.meta.env.DEV) {
|
|
4
|
+
onContentUpdated(() => {
|
|
5
|
+
document.querySelectorAll('.vp-code-group > .blocks').forEach((el) => {
|
|
6
|
+
Array.from(el.children).forEach((child) => {
|
|
7
|
+
child.classList.remove('active');
|
|
8
|
+
});
|
|
9
|
+
el.children[0].classList.add('active');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
if (inBrowser) {
|
|
14
|
+
window.addEventListener('click', (e) => {
|
|
15
|
+
const el = e.target;
|
|
16
|
+
if (el.matches('.vp-code-group input')) {
|
|
17
|
+
// input <- .tabs <- .vp-code-group
|
|
18
|
+
const group = el.parentElement?.parentElement;
|
|
19
|
+
if (!group)
|
|
20
|
+
return;
|
|
21
|
+
const i = Array.from(group.querySelectorAll('input')).indexOf(el);
|
|
22
|
+
if (i < 0)
|
|
23
|
+
return;
|
|
24
|
+
const blocks = group.querySelector('.blocks');
|
|
25
|
+
if (!blocks)
|
|
26
|
+
return;
|
|
27
|
+
const current = Array.from(blocks.children).find((child) => child.classList.contains('active'));
|
|
28
|
+
if (!current)
|
|
29
|
+
return;
|
|
30
|
+
const next = blocks.children[i];
|
|
31
|
+
if (!next || current === next)
|
|
32
|
+
return;
|
|
33
|
+
current.classList.remove('active');
|
|
34
|
+
next.classList.add('active');
|
|
35
|
+
const label = group?.querySelector(`label[for="${el.id}"]`);
|
|
36
|
+
label?.scrollIntoView({ block: 'nearest' });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { inBrowser } from 'vitepress';
|
|
2
|
+
export function useCopyCode() {
|
|
3
|
+
if (inBrowser) {
|
|
4
|
+
const timeoutIdMap = new WeakMap();
|
|
5
|
+
window.addEventListener('click', (e) => {
|
|
6
|
+
const el = e.target;
|
|
7
|
+
if (el.matches('div[class*="language-"] > button.copy')) {
|
|
8
|
+
const parent = el.parentElement;
|
|
9
|
+
const sibling = el.nextElementSibling?.nextElementSibling;
|
|
10
|
+
if (!parent || !sibling) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const isShell = /language-(shellscript|shell|bash|sh|zsh)/.test(parent.className);
|
|
14
|
+
let text = '';
|
|
15
|
+
sibling
|
|
16
|
+
.querySelectorAll('span.line:not(.diff.remove)')
|
|
17
|
+
.forEach((node) => (text += (node.textContent || '') + '\n'));
|
|
18
|
+
text = text.slice(0, -1);
|
|
19
|
+
if (isShell) {
|
|
20
|
+
text = text.replace(/^ *(\$|>) /gm, '').trim();
|
|
21
|
+
}
|
|
22
|
+
copyToClipboard(text).then(() => {
|
|
23
|
+
el.classList.add('copied');
|
|
24
|
+
clearTimeout(timeoutIdMap.get(el));
|
|
25
|
+
const timeoutId = setTimeout(() => {
|
|
26
|
+
el.classList.remove('copied');
|
|
27
|
+
el.blur();
|
|
28
|
+
timeoutIdMap.delete(el);
|
|
29
|
+
}, 2000);
|
|
30
|
+
timeoutIdMap.set(el, timeoutId);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function copyToClipboard(text) {
|
|
37
|
+
try {
|
|
38
|
+
return navigator.clipboard.writeText(text);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
const element = document.createElement('textarea');
|
|
42
|
+
const previouslyFocusedElement = document.activeElement;
|
|
43
|
+
element.value = text;
|
|
44
|
+
// Prevent keyboard from showing on mobile
|
|
45
|
+
element.setAttribute('readonly', '');
|
|
46
|
+
element.style.contain = 'strict';
|
|
47
|
+
element.style.position = 'absolute';
|
|
48
|
+
element.style.left = '-9999px';
|
|
49
|
+
element.style.fontSize = '12pt'; // Prevent zooming on iOS
|
|
50
|
+
const selection = document.getSelection();
|
|
51
|
+
const originalRange = selection
|
|
52
|
+
? selection.rangeCount > 0 && selection.getRangeAt(0)
|
|
53
|
+
: null;
|
|
54
|
+
document.body.appendChild(element);
|
|
55
|
+
element.select();
|
|
56
|
+
// Explicit selection workaround for iOS
|
|
57
|
+
element.selectionStart = 0;
|
|
58
|
+
element.selectionEnd = text.length;
|
|
59
|
+
document.execCommand('copy');
|
|
60
|
+
document.body.removeChild(element);
|
|
61
|
+
if (originalRange) {
|
|
62
|
+
selection.removeAllRanges(); // originalRange can't be truthy when selection is falsy
|
|
63
|
+
selection.addRange(originalRange);
|
|
64
|
+
}
|
|
65
|
+
// Get the focus back on the previously focused element, if any
|
|
66
|
+
if (previouslyFocusedElement) {
|
|
67
|
+
;
|
|
68
|
+
previouslyFocusedElement.focus();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { watchEffect } from 'vue';
|
|
2
|
-
import { createTitle } from '../../shared';
|
|
2
|
+
import { createTitle, mergeHead } from '../../shared';
|
|
3
3
|
export function useUpdateHead(route, siteDataByRouteRef) {
|
|
4
4
|
let managedHeadTags = [];
|
|
5
5
|
let isFirstUpdate = true;
|
|
@@ -10,59 +10,30 @@ export function useUpdateHead(route, siteDataByRouteRef) {
|
|
|
10
10
|
isFirstUpdate = false;
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
let el = managedHeadTags[i];
|
|
17
|
-
const [tag, attrs, innerHTML = ''] = newTags[i];
|
|
18
|
-
if (el.tagName.toLocaleLowerCase() === tag) {
|
|
19
|
-
for (const key in attrs) {
|
|
20
|
-
if (el.getAttribute(key) !== attrs[key]) {
|
|
21
|
-
el.setAttribute(key, attrs[key]);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
for (let i = 0; i < el.attributes.length; i++) {
|
|
25
|
-
const name = el.attributes[i].name;
|
|
26
|
-
if (!(name in attrs)) {
|
|
27
|
-
el.removeAttribute(name);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
if (el.innerHTML !== innerHTML) {
|
|
31
|
-
el.innerHTML = innerHTML;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
document.head.removeChild(el);
|
|
36
|
-
el = createHeadElement(newTags[i]);
|
|
37
|
-
document.head.append(el);
|
|
38
|
-
}
|
|
39
|
-
newEls.push(el);
|
|
40
|
-
}
|
|
41
|
-
managedHeadTags
|
|
42
|
-
.slice(commonLength)
|
|
43
|
-
.forEach((el) => document.head.removeChild(el));
|
|
44
|
-
newTags.slice(commonLength).forEach((headConfig) => {
|
|
13
|
+
managedHeadTags.forEach((el) => document.head.removeChild(el));
|
|
14
|
+
managedHeadTags = [];
|
|
15
|
+
newTags.forEach((headConfig) => {
|
|
45
16
|
const el = createHeadElement(headConfig);
|
|
46
17
|
document.head.appendChild(el);
|
|
47
|
-
|
|
18
|
+
managedHeadTags.push(el);
|
|
48
19
|
});
|
|
49
|
-
managedHeadTags = newEls;
|
|
50
20
|
};
|
|
51
21
|
watchEffect(() => {
|
|
52
22
|
const pageData = route.data;
|
|
53
23
|
const siteData = siteDataByRouteRef.value;
|
|
54
24
|
const pageDescription = pageData && pageData.description;
|
|
55
|
-
const frontmatterHead = pageData && pageData.frontmatter.head;
|
|
25
|
+
const frontmatterHead = (pageData && pageData.frontmatter.head) || [];
|
|
56
26
|
// update title and description
|
|
57
27
|
document.title = createTitle(siteData, pageData);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
28
|
+
const description = pageDescription || siteData.description;
|
|
29
|
+
let metaDescriptionElement = document.querySelector(`meta[name=description]`);
|
|
30
|
+
if (metaDescriptionElement) {
|
|
31
|
+
metaDescriptionElement.setAttribute('content', description);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
createHeadElement(['meta', { name: 'description', content: description }]);
|
|
35
|
+
}
|
|
36
|
+
updateHeadTags(mergeHead(siteData.head, filterOutHeadDescription(frontmatterHead)));
|
|
66
37
|
});
|
|
67
38
|
}
|
|
68
39
|
function createHeadElement([tag, attrs, innerHTML]) {
|
|
@@ -52,14 +52,19 @@ export function usePrefetch() {
|
|
|
52
52
|
if (!hasFetched.has(pathname)) {
|
|
53
53
|
hasFetched.add(pathname);
|
|
54
54
|
const pageChunkPath = pathToFile(pathname);
|
|
55
|
-
|
|
55
|
+
if (pageChunkPath)
|
|
56
|
+
doFetch(pageChunkPath);
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
});
|
|
59
60
|
});
|
|
60
61
|
rIC(() => {
|
|
61
|
-
document
|
|
62
|
-
|
|
62
|
+
document
|
|
63
|
+
.querySelectorAll('#app a')
|
|
64
|
+
.forEach((link) => {
|
|
65
|
+
const { hostname, pathname } = new URL(link.href instanceof SVGAnimatedString
|
|
66
|
+
? link.href.animVal
|
|
67
|
+
: link.href, link.baseURI);
|
|
63
68
|
const extMatch = pathname.match(/\.\w+$/);
|
|
64
69
|
if (extMatch && extMatch[0] !== '.html') {
|
|
65
70
|
return;
|
|
@@ -67,7 +72,7 @@ export function usePrefetch() {
|
|
|
67
72
|
if (
|
|
68
73
|
// only prefetch same tab navigation, since a new tab will load
|
|
69
74
|
// the lean js chunk instead.
|
|
70
|
-
target !==
|
|
75
|
+
link.target !== '_blank' &&
|
|
71
76
|
// only prefetch inbound links
|
|
72
77
|
hostname === location.hostname) {
|
|
73
78
|
if (pathname !== location.pathname) {
|
package/dist/client/app/data.js
CHANGED
|
@@ -1,39 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { computed, inject, readonly, ref, shallowRef } from 'vue';
|
|
2
|
+
import siteData from '@siteData';
|
|
3
3
|
import { resolveSiteDataByRoute, createTitle } from '../shared';
|
|
4
|
-
import { withBase } from './utils';
|
|
5
4
|
export const dataSymbol = Symbol();
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const parsed = JSON.parse(data);
|
|
9
|
-
return (import.meta.env.DEV ? readonly(parsed) : parsed);
|
|
10
|
-
}
|
|
5
|
+
// site data is a singleton
|
|
6
|
+
export const siteDataRef = shallowRef((import.meta.env.PROD ? siteData : readonly(siteData)));
|
|
11
7
|
// hmr
|
|
12
8
|
if (import.meta.hot) {
|
|
13
9
|
import.meta.hot.accept('/@siteData', (m) => {
|
|
14
|
-
|
|
10
|
+
if (m) {
|
|
11
|
+
siteDataRef.value = m.default;
|
|
12
|
+
}
|
|
15
13
|
});
|
|
16
14
|
}
|
|
17
15
|
// per-app data
|
|
18
16
|
export function initData(route) {
|
|
19
|
-
const site = computed(() => resolveSiteDataByRoute(siteDataRef.value, route.
|
|
17
|
+
const site = computed(() => resolveSiteDataByRoute(siteDataRef.value, route.data.relativePath));
|
|
20
18
|
return {
|
|
21
19
|
site,
|
|
22
20
|
theme: computed(() => site.value.themeConfig),
|
|
23
21
|
page: computed(() => route.data),
|
|
24
22
|
frontmatter: computed(() => route.data.frontmatter),
|
|
23
|
+
params: computed(() => route.data.params),
|
|
25
24
|
lang: computed(() => site.value.lang),
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const path = Object.keys(langs).find((langPath) => langs[langPath].lang === lang);
|
|
29
|
-
return withBase(path || '/');
|
|
30
|
-
}),
|
|
25
|
+
dir: computed(() => site.value.dir),
|
|
26
|
+
localeIndex: computed(() => site.value.localeIndex || 'root'),
|
|
31
27
|
title: computed(() => {
|
|
32
28
|
return createTitle(site.value, route.data);
|
|
33
29
|
}),
|
|
34
30
|
description: computed(() => {
|
|
35
31
|
return route.data.description || site.value.description;
|
|
36
|
-
})
|
|
32
|
+
}),
|
|
33
|
+
isDark: ref(false)
|
|
37
34
|
};
|
|
38
35
|
}
|
|
39
36
|
export function useData() {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { setupDevtoolsPlugin } from '@vue/devtools-api';
|
|
2
|
+
const COMPONENT_STATE_TYPE = 'VitePress';
|
|
3
|
+
export const setupDevtools = (app, router, data) => {
|
|
4
|
+
setupDevtoolsPlugin({
|
|
5
|
+
// fix recursive reference
|
|
6
|
+
app: app,
|
|
7
|
+
id: 'org.vuejs.vitepress',
|
|
8
|
+
label: 'VitePress',
|
|
9
|
+
packageName: 'vitepress',
|
|
10
|
+
homepage: 'https://vitepress.dev',
|
|
11
|
+
componentStateTypes: [COMPONENT_STATE_TYPE]
|
|
12
|
+
}, (api) => {
|
|
13
|
+
api.on.inspectComponent((payload) => {
|
|
14
|
+
payload.instanceData.state.push({
|
|
15
|
+
type: COMPONENT_STATE_TYPE,
|
|
16
|
+
key: 'route',
|
|
17
|
+
value: router.route,
|
|
18
|
+
editable: false
|
|
19
|
+
});
|
|
20
|
+
payload.instanceData.state.push({
|
|
21
|
+
type: COMPONENT_STATE_TYPE,
|
|
22
|
+
key: 'data',
|
|
23
|
+
value: data,
|
|
24
|
+
editable: false
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
};
|
package/dist/client/app/index.js
CHANGED
|
@@ -1,34 +1,57 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import RawTheme from '@theme/index';
|
|
2
|
+
import { createApp as createClientApp, createSSRApp, defineComponent, h, onMounted, watchEffect } from 'vue';
|
|
3
|
+
import { ClientOnly } from './components/ClientOnly';
|
|
4
|
+
import { Content } from './components/Content';
|
|
5
|
+
import { useCodeGroups } from './composables/codeGroups';
|
|
6
|
+
import { useCopyCode } from './composables/copyCode';
|
|
6
7
|
import { useUpdateHead } from './composables/head';
|
|
7
8
|
import { usePrefetch } from './composables/preFetch';
|
|
8
|
-
import { dataSymbol, initData } from './data';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
import { dataSymbol, initData, siteDataRef, useData } from './data';
|
|
10
|
+
import { RouterSymbol, createRouter, scrollTo } from './router';
|
|
11
|
+
import { inBrowser, pathToFile } from './utils';
|
|
12
|
+
function resolveThemeExtends(theme) {
|
|
13
|
+
if (theme.extends) {
|
|
14
|
+
const base = resolveThemeExtends(theme.extends);
|
|
15
|
+
return {
|
|
16
|
+
...base,
|
|
17
|
+
...theme,
|
|
18
|
+
async enhanceApp(ctx) {
|
|
19
|
+
if (base.enhanceApp)
|
|
20
|
+
await base.enhanceApp(ctx);
|
|
21
|
+
if (theme.enhanceApp)
|
|
22
|
+
await theme.enhanceApp(ctx);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return theme;
|
|
27
|
+
}
|
|
28
|
+
const Theme = resolveThemeExtends(RawTheme);
|
|
29
|
+
const VitePressApp = defineComponent({
|
|
13
30
|
name: 'VitePressApp',
|
|
14
31
|
setup() {
|
|
15
32
|
const { site } = useData();
|
|
16
33
|
// change the language on the HTML element based on the current lang
|
|
17
34
|
onMounted(() => {
|
|
18
|
-
|
|
19
|
-
document.documentElement.lang = lang;
|
|
20
|
-
|
|
35
|
+
watchEffect(() => {
|
|
36
|
+
document.documentElement.lang = site.value.lang;
|
|
37
|
+
document.documentElement.dir = site.value.dir;
|
|
38
|
+
});
|
|
21
39
|
});
|
|
22
40
|
if (import.meta.env.PROD) {
|
|
23
41
|
// in prod mode, enable intersectionObserver based pre-fetch
|
|
24
42
|
usePrefetch();
|
|
25
43
|
}
|
|
44
|
+
// setup global copy code handler
|
|
45
|
+
useCopyCode();
|
|
46
|
+
// setup global code groups handler
|
|
47
|
+
useCodeGroups();
|
|
48
|
+
if (Theme.setup)
|
|
49
|
+
Theme.setup();
|
|
26
50
|
return () => h(Theme.Layout);
|
|
27
51
|
}
|
|
28
|
-
};
|
|
29
|
-
export function createApp() {
|
|
52
|
+
});
|
|
53
|
+
export async function createApp() {
|
|
30
54
|
const router = newRouter();
|
|
31
|
-
handleHMR(router);
|
|
32
55
|
const app = newApp();
|
|
33
56
|
app.provide(RouterSymbol, router);
|
|
34
57
|
const data = initData(router.route);
|
|
@@ -36,22 +59,30 @@ export function createApp() {
|
|
|
36
59
|
// install global components
|
|
37
60
|
app.component('Content', Content);
|
|
38
61
|
app.component('ClientOnly', ClientOnly);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
62
|
+
// expose $frontmatter & $params
|
|
63
|
+
Object.defineProperties(app.config.globalProperties, {
|
|
64
|
+
$frontmatter: {
|
|
65
|
+
get() {
|
|
66
|
+
return data.frontmatter.value;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
$params: {
|
|
70
|
+
get() {
|
|
71
|
+
return data.page.value.params;
|
|
72
|
+
}
|
|
46
73
|
}
|
|
47
74
|
});
|
|
48
75
|
if (Theme.enhanceApp) {
|
|
49
|
-
Theme.enhanceApp({
|
|
76
|
+
await Theme.enhanceApp({
|
|
50
77
|
app,
|
|
51
78
|
router,
|
|
52
79
|
siteData: siteDataRef
|
|
53
80
|
});
|
|
54
81
|
}
|
|
82
|
+
// setup devtools in dev mode
|
|
83
|
+
if (import.meta.env.DEV || __VUE_PROD_DEVTOOLS__) {
|
|
84
|
+
import('./devtools.js').then(({ setupDevtools }) => setupDevtools(app, router, data));
|
|
85
|
+
}
|
|
55
86
|
return { app, router, data };
|
|
56
87
|
}
|
|
57
88
|
function newApp() {
|
|
@@ -64,6 +95,8 @@ function newRouter() {
|
|
|
64
95
|
let initialPath;
|
|
65
96
|
return createRouter((path) => {
|
|
66
97
|
let pageFilePath = pathToFile(path);
|
|
98
|
+
if (!pageFilePath)
|
|
99
|
+
return null;
|
|
67
100
|
if (isInitialPageLoad) {
|
|
68
101
|
initialPath = pageFilePath;
|
|
69
102
|
}
|
|
@@ -77,30 +110,22 @@ function newRouter() {
|
|
|
77
110
|
isInitialPageLoad = false;
|
|
78
111
|
}
|
|
79
112
|
return import(/*@vite-ignore*/ pageFilePath);
|
|
80
|
-
}, NotFound);
|
|
113
|
+
}, Theme.NotFound);
|
|
81
114
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
115
|
+
if (inBrowser) {
|
|
116
|
+
createApp().then(({ app, router, data }) => {
|
|
117
|
+
// wait until page component is fetched before mounting
|
|
118
|
+
router.go().then(() => {
|
|
119
|
+
// dynamically update head tags
|
|
120
|
+
useUpdateHead(router.route, data.site);
|
|
121
|
+
app.mount('#app');
|
|
122
|
+
// scroll to hash on new tab during dev
|
|
123
|
+
if (import.meta.env.DEV && location.hash) {
|
|
124
|
+
const target = document.getElementById(decodeURIComponent(location.hash).slice(1));
|
|
125
|
+
if (target) {
|
|
126
|
+
scrollTo(target, location.hash);
|
|
127
|
+
}
|
|
89
128
|
}
|
|
90
129
|
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function shouldHotReload(payload) {
|
|
94
|
-
const payloadPath = payload.path.replace(/(\bindex)?\.md$/, '');
|
|
95
|
-
const locationPath = location.pathname.replace(/(\bindex)?\.html$/, '');
|
|
96
|
-
return payloadPath === locationPath;
|
|
97
|
-
}
|
|
98
|
-
if (inBrowser) {
|
|
99
|
-
const { app, router, data } = createApp();
|
|
100
|
-
// wait until page component is fetched before mounting
|
|
101
|
-
router.go().then(() => {
|
|
102
|
-
// dynamically update head tags
|
|
103
|
-
useUpdateHead(router.route, data.site);
|
|
104
|
-
app.mount('#app');
|
|
105
130
|
});
|
|
106
131
|
}
|