initial vitepress site with basic nav
This commit is contained in:
parent
a7df2e049d
commit
2029f16583
1900 changed files with 1014692 additions and 0 deletions
19
node_modules/vitepress/dist/client/app/composables/codeGroups.js
generated
vendored
Normal file
19
node_modules/vitepress/dist/client/app/composables/codeGroups.js
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { inBrowser } from 'vitepress';
|
||||
export function useCodeGroups() {
|
||||
if (inBrowser) {
|
||||
window.addEventListener('click', (e) => {
|
||||
const el = e.target;
|
||||
if (el.matches('.vp-code-group input')) {
|
||||
// input <- .tabs <- .vp-code-group
|
||||
const group = el.parentElement?.parentElement;
|
||||
const i = Array.from(group?.querySelectorAll('input') || []).indexOf(el);
|
||||
const current = group?.querySelector('div[class*="language-"].active');
|
||||
const next = group?.querySelectorAll('div[class*="language-"]:not(.language-id)')?.[i];
|
||||
if (current && next && current !== next) {
|
||||
current.classList.remove('active');
|
||||
next.classList.add('active');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
72
node_modules/vitepress/dist/client/app/composables/copyCode.js
generated
vendored
Normal file
72
node_modules/vitepress/dist/client/app/composables/copyCode.js
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
import { inBrowser } from 'vitepress';
|
||||
export function useCopyCode() {
|
||||
if (inBrowser) {
|
||||
const timeoutIdMap = new Map();
|
||||
window.addEventListener('click', (e) => {
|
||||
const el = e.target;
|
||||
if (el.matches('div[class*="language-"] > button.copy')) {
|
||||
const parent = el.parentElement;
|
||||
const sibling = el.nextElementSibling
|
||||
?.nextElementSibling;
|
||||
if (!parent || !sibling) {
|
||||
return;
|
||||
}
|
||||
const isShell = /language-(shellscript|shell|bash|sh|zsh)/.test(parent.className);
|
||||
let text = '';
|
||||
sibling
|
||||
.querySelectorAll('span.line:not(.diff.remove)')
|
||||
.forEach((node) => (text += (node.textContent || '') + '\n'));
|
||||
text = text.slice(0, -1);
|
||||
if (isShell) {
|
||||
text = text.replace(/^ *(\$|>) /gm, '').trim();
|
||||
}
|
||||
copyToClipboard(text).then(() => {
|
||||
el.classList.add('copied');
|
||||
clearTimeout(timeoutIdMap.get(el));
|
||||
const timeoutId = setTimeout(() => {
|
||||
el.classList.remove('copied');
|
||||
el.blur();
|
||||
timeoutIdMap.delete(el);
|
||||
}, 2000);
|
||||
timeoutIdMap.set(el, timeoutId);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
async function copyToClipboard(text) {
|
||||
try {
|
||||
return navigator.clipboard.writeText(text);
|
||||
}
|
||||
catch {
|
||||
const element = document.createElement('textarea');
|
||||
const previouslyFocusedElement = document.activeElement;
|
||||
element.value = text;
|
||||
// Prevent keyboard from showing on mobile
|
||||
element.setAttribute('readonly', '');
|
||||
element.style.contain = 'strict';
|
||||
element.style.position = 'absolute';
|
||||
element.style.left = '-9999px';
|
||||
element.style.fontSize = '12pt'; // Prevent zooming on iOS
|
||||
const selection = document.getSelection();
|
||||
const originalRange = selection
|
||||
? selection.rangeCount > 0 && selection.getRangeAt(0)
|
||||
: null;
|
||||
document.body.appendChild(element);
|
||||
element.select();
|
||||
// Explicit selection workaround for iOS
|
||||
element.selectionStart = 0;
|
||||
element.selectionEnd = text.length;
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(element);
|
||||
if (originalRange) {
|
||||
selection.removeAllRanges(); // originalRange can't be truthy when selection is falsy
|
||||
selection.addRange(originalRange);
|
||||
}
|
||||
// Get the focus back on the previously focused element, if any
|
||||
if (previouslyFocusedElement) {
|
||||
;
|
||||
previouslyFocusedElement.focus();
|
||||
}
|
||||
}
|
||||
}
|
51
node_modules/vitepress/dist/client/app/composables/head.js
generated
vendored
Normal file
51
node_modules/vitepress/dist/client/app/composables/head.js
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
import { watchEffect } from 'vue';
|
||||
import { createTitle, mergeHead } from '../../shared';
|
||||
export function useUpdateHead(route, siteDataByRouteRef) {
|
||||
let managedHeadTags = [];
|
||||
let isFirstUpdate = true;
|
||||
const updateHeadTags = (newTags) => {
|
||||
if (import.meta.env.PROD && isFirstUpdate) {
|
||||
// in production, the initial meta tags are already pre-rendered so we
|
||||
// skip the first update.
|
||||
isFirstUpdate = false;
|
||||
return;
|
||||
}
|
||||
managedHeadTags.forEach((el) => document.head.removeChild(el));
|
||||
managedHeadTags = [];
|
||||
newTags.forEach((headConfig) => {
|
||||
const el = createHeadElement(headConfig);
|
||||
document.head.appendChild(el);
|
||||
managedHeadTags.push(el);
|
||||
});
|
||||
};
|
||||
watchEffect(() => {
|
||||
const pageData = route.data;
|
||||
const siteData = siteDataByRouteRef.value;
|
||||
const pageDescription = pageData && pageData.description;
|
||||
const frontmatterHead = (pageData && pageData.frontmatter.head) || [];
|
||||
// update title and description
|
||||
document.title = createTitle(siteData, pageData);
|
||||
document
|
||||
.querySelector(`meta[name=description]`)
|
||||
.setAttribute('content', pageDescription || siteData.description);
|
||||
updateHeadTags(mergeHead(siteData.head, filterOutHeadDescription(frontmatterHead)));
|
||||
});
|
||||
}
|
||||
function createHeadElement([tag, attrs, innerHTML]) {
|
||||
const el = document.createElement(tag);
|
||||
for (const key in attrs) {
|
||||
el.setAttribute(key, attrs[key]);
|
||||
}
|
||||
if (innerHTML) {
|
||||
el.innerHTML = innerHTML;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
function isMetaDescription(headConfig) {
|
||||
return (headConfig[0] === 'meta' &&
|
||||
headConfig[1] &&
|
||||
headConfig[1].name === 'description');
|
||||
}
|
||||
function filterOutHeadDescription(head) {
|
||||
return head.filter((h) => !isMetaDescription(h));
|
||||
}
|
99
node_modules/vitepress/dist/client/app/composables/preFetch.js
generated
vendored
Normal file
99
node_modules/vitepress/dist/client/app/composables/preFetch.js
generated
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
// Customized pre-fetch for page chunks based on
|
||||
// https://github.com/GoogleChromeLabs/quicklink
|
||||
import { useRoute } from '../router';
|
||||
import { onMounted, onUnmounted, watch } 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('#app a')
|
||||
.forEach((link) => {
|
||||
const { target } = link;
|
||||
const { hostname, pathname } = new URL(link.href instanceof SVGAnimatedString
|
||||
? link.href.animVal
|
||||
: link.href, link.baseURI);
|
||||
const extMatch = pathname.match(/\.\w+$/);
|
||||
if (extMatch && extMatch[0] !== '.html') {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
// only prefetch same tab navigation, since a new tab will load
|
||||
// the lean js chunk instead.
|
||||
target !== `_blank` &&
|
||||
// only prefetch inbound links
|
||||
hostname === location.hostname) {
|
||||
if (pathname !== location.pathname) {
|
||||
observer.observe(link);
|
||||
}
|
||||
else {
|
||||
// No need to prefetch chunk for the current page, but also mark
|
||||
// it as already fetched. This is because the initial page uses its
|
||||
// lean chunk, and if we don't mark it, navigation to another page
|
||||
// with a link back to the first page will fetch its full chunk
|
||||
// which isn't needed.
|
||||
hasFetched.add(pathname);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
onMounted(observeLinks);
|
||||
const route = useRoute();
|
||||
watch(() => route.path, observeLinks);
|
||||
onUnmounted(() => {
|
||||
observer && observer.disconnect();
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue