vitepress 1.6.3 → 2.0.0-alpha.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/dist/client/app/index.js +2 -5
- package/dist/client/app/router.js +77 -72
- package/dist/client/index.d.ts +6 -5
- package/dist/client/theme-default/components/VPAlgoliaSearchBox.vue +2 -24
- package/dist/node/{chunk-Zsoi3j4v.js → chunk-CxQfvv8o.js} +196 -4339
- package/dist/node/cli.js +1 -1
- package/dist/node/index.d.ts +5 -5
- package/dist/node/index.js +2 -2
- package/package.json +12 -12
package/dist/client/app/index.js
CHANGED
|
@@ -128,16 +128,13 @@ function newRouter() {
|
|
|
128
128
|
if (inBrowser) {
|
|
129
129
|
createApp().then(({ app, router, data }) => {
|
|
130
130
|
// wait until page component is fetched before mounting
|
|
131
|
-
router.go().then(() => {
|
|
131
|
+
router.go(location.href, { initialLoad: true }).then(() => {
|
|
132
132
|
// dynamically update head tags
|
|
133
133
|
useUpdateHead(router.route, data.site);
|
|
134
134
|
app.mount('#app');
|
|
135
135
|
// scroll to hash on new tab during dev
|
|
136
136
|
if (import.meta.env.DEV && location.hash) {
|
|
137
|
-
|
|
138
|
-
if (target) {
|
|
139
|
-
scrollTo(target, location.hash);
|
|
140
|
-
}
|
|
137
|
+
scrollTo(location.hash);
|
|
141
138
|
}
|
|
142
139
|
});
|
|
143
140
|
});
|
|
@@ -8,6 +8,8 @@ export const RouterSymbol = Symbol();
|
|
|
8
8
|
const fakeHost = 'http://a.com';
|
|
9
9
|
const getDefaultRoute = () => ({
|
|
10
10
|
path: '/',
|
|
11
|
+
hash: '',
|
|
12
|
+
query: '',
|
|
11
13
|
component: null,
|
|
12
14
|
data: notFoundPageData
|
|
13
15
|
});
|
|
@@ -15,20 +17,16 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
15
17
|
const route = reactive(getDefaultRoute());
|
|
16
18
|
const router = {
|
|
17
19
|
route,
|
|
18
|
-
go
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
history.replaceState({ scrollPosition: window.scrollY }, '');
|
|
27
|
-
history.pushState({}, '', href);
|
|
20
|
+
async go(href, options) {
|
|
21
|
+
href = normalizeHref(href);
|
|
22
|
+
if ((await router.onBeforeRouteChange?.(href)) === false)
|
|
23
|
+
return;
|
|
24
|
+
if (!inBrowser || (await changeRoute(href, options)))
|
|
25
|
+
await loadPage(href);
|
|
26
|
+
syncRouteQueryAndHash();
|
|
27
|
+
await router.onAfterRouteChange?.(href);
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
await (router.onAfterRouteChange ?? router.onAfterRouteChanged)?.(href);
|
|
31
|
-
}
|
|
29
|
+
};
|
|
32
30
|
let latestPendingPath = null;
|
|
33
31
|
async function loadPage(href, scrollPosition = 0, isRetry = false) {
|
|
34
32
|
if ((await router.onBeforePageLoad?.(href)) === false)
|
|
@@ -37,21 +35,20 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
37
35
|
const pendingPath = (latestPendingPath = targetLoc.pathname);
|
|
38
36
|
try {
|
|
39
37
|
let page = await loadPageModule(pendingPath);
|
|
40
|
-
if (!page)
|
|
38
|
+
if (!page)
|
|
41
39
|
throw new Error(`Page not found: ${pendingPath}`);
|
|
42
|
-
}
|
|
43
40
|
if (latestPendingPath === pendingPath) {
|
|
44
41
|
latestPendingPath = null;
|
|
45
42
|
const { default: comp, __pageData } = page;
|
|
46
|
-
if (!comp)
|
|
43
|
+
if (!comp)
|
|
47
44
|
throw new Error(`Invalid route component: ${comp}`);
|
|
48
|
-
}
|
|
49
45
|
await router.onAfterPageLoad?.(href);
|
|
50
46
|
route.path = inBrowser ? pendingPath : withBase(pendingPath);
|
|
51
47
|
route.component = markRaw(comp);
|
|
52
48
|
route.data = import.meta.env.PROD
|
|
53
49
|
? markRaw(__pageData)
|
|
54
50
|
: readonly(__pageData);
|
|
51
|
+
syncRouteQueryAndHash(targetLoc);
|
|
55
52
|
if (inBrowser) {
|
|
56
53
|
nextTick(() => {
|
|
57
54
|
let actualPathname = siteDataRef.value.base +
|
|
@@ -64,20 +61,7 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
64
61
|
href = actualPathname + targetLoc.search + targetLoc.hash;
|
|
65
62
|
history.replaceState({}, '', href);
|
|
66
63
|
}
|
|
67
|
-
|
|
68
|
-
let target = null;
|
|
69
|
-
try {
|
|
70
|
-
target = document.getElementById(decodeURIComponent(targetLoc.hash).slice(1));
|
|
71
|
-
}
|
|
72
|
-
catch (e) {
|
|
73
|
-
console.warn(e);
|
|
74
|
-
}
|
|
75
|
-
if (target) {
|
|
76
|
-
scrollTo(target, targetLoc.hash);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
window.scrollTo(0, scrollPosition);
|
|
64
|
+
return scrollTo(targetLoc.hash, false, scrollPosition);
|
|
81
65
|
});
|
|
82
66
|
}
|
|
83
67
|
}
|
|
@@ -110,13 +94,19 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
110
94
|
.replace(/^\//, '')
|
|
111
95
|
: '404.md';
|
|
112
96
|
route.data = { ...notFoundPageData, relativePath };
|
|
97
|
+
syncRouteQueryAndHash(targetLoc);
|
|
113
98
|
}
|
|
114
99
|
}
|
|
115
100
|
}
|
|
101
|
+
function syncRouteQueryAndHash(loc = inBrowser
|
|
102
|
+
? location
|
|
103
|
+
: { search: '', hash: '' }) {
|
|
104
|
+
route.query = loc.search;
|
|
105
|
+
route.hash = decodeURIComponent(loc.hash);
|
|
106
|
+
}
|
|
116
107
|
if (inBrowser) {
|
|
117
|
-
if (history.state === null)
|
|
108
|
+
if (history.state === null)
|
|
118
109
|
history.replaceState({}, '');
|
|
119
|
-
}
|
|
120
110
|
window.addEventListener('click', (e) => {
|
|
121
111
|
if (e.defaultPrevented ||
|
|
122
112
|
!(e.target instanceof Element) ||
|
|
@@ -125,46 +115,29 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
125
115
|
e.ctrlKey ||
|
|
126
116
|
e.shiftKey ||
|
|
127
117
|
e.altKey ||
|
|
128
|
-
e.metaKey)
|
|
118
|
+
e.metaKey) {
|
|
129
119
|
return;
|
|
120
|
+
}
|
|
130
121
|
const link = e.target.closest('a');
|
|
131
122
|
if (!link ||
|
|
132
123
|
link.closest('.vp-raw') ||
|
|
133
124
|
link.hasAttribute('download') ||
|
|
134
|
-
link.hasAttribute('target'))
|
|
125
|
+
link.hasAttribute('target')) {
|
|
135
126
|
return;
|
|
127
|
+
}
|
|
136
128
|
const linkHref = link.getAttribute('href') ??
|
|
137
129
|
(link instanceof SVGAElement ? link.getAttribute('xlink:href') : null);
|
|
138
130
|
if (linkHref == null)
|
|
139
131
|
return;
|
|
140
|
-
const { href, origin, pathname
|
|
141
|
-
const
|
|
132
|
+
const { href, origin, pathname } = new URL(linkHref, link.baseURI);
|
|
133
|
+
const currentLoc = new URL(location.href); // copy to keep old data
|
|
142
134
|
// only intercept inbound html links
|
|
143
|
-
if (origin ===
|
|
135
|
+
if (origin === currentLoc.origin && treatAsHtml(pathname)) {
|
|
144
136
|
e.preventDefault();
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (hash !== currentUrl.hash) {
|
|
150
|
-
history.pushState({}, '', href);
|
|
151
|
-
// still emit the event so we can listen to it in themes
|
|
152
|
-
window.dispatchEvent(new HashChangeEvent('hashchange', {
|
|
153
|
-
oldURL: currentUrl.href,
|
|
154
|
-
newURL: href
|
|
155
|
-
}));
|
|
156
|
-
}
|
|
157
|
-
if (hash) {
|
|
158
|
-
// use smooth scroll when clicking on header anchor links
|
|
159
|
-
scrollTo(link, hash, link.classList.contains('header-anchor'));
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
window.scrollTo(0, 0);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
go(href);
|
|
167
|
-
}
|
|
137
|
+
router.go(href, {
|
|
138
|
+
// use smooth scroll when clicking on header anchor links
|
|
139
|
+
smoothScroll: link.classList.contains('header-anchor')
|
|
140
|
+
});
|
|
168
141
|
}
|
|
169
142
|
}, { capture: true });
|
|
170
143
|
window.addEventListener('popstate', async (e) => {
|
|
@@ -172,10 +145,12 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
172
145
|
return;
|
|
173
146
|
const href = normalizeHref(location.href);
|
|
174
147
|
await loadPage(href, (e.state && e.state.scrollPosition) || 0);
|
|
175
|
-
|
|
148
|
+
syncRouteQueryAndHash();
|
|
149
|
+
await router.onAfterRouteChange?.(href);
|
|
176
150
|
});
|
|
177
151
|
window.addEventListener('hashchange', (e) => {
|
|
178
152
|
e.preventDefault();
|
|
153
|
+
syncRouteQueryAndHash();
|
|
179
154
|
});
|
|
180
155
|
}
|
|
181
156
|
handleHMR(route);
|
|
@@ -183,20 +158,21 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
183
158
|
}
|
|
184
159
|
export function useRouter() {
|
|
185
160
|
const router = inject(RouterSymbol);
|
|
186
|
-
if (!router)
|
|
161
|
+
if (!router)
|
|
187
162
|
throw new Error('useRouter() is called without provider.');
|
|
188
|
-
}
|
|
189
163
|
return router;
|
|
190
164
|
}
|
|
191
165
|
export function useRoute() {
|
|
192
166
|
return useRouter().route;
|
|
193
167
|
}
|
|
194
|
-
export function scrollTo(
|
|
168
|
+
export function scrollTo(hash, smooth = false, scrollPosition = 0) {
|
|
169
|
+
if (!hash || scrollPosition) {
|
|
170
|
+
window.scrollTo(0, scrollPosition);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
195
173
|
let target = null;
|
|
196
174
|
try {
|
|
197
|
-
target =
|
|
198
|
-
? el
|
|
199
|
-
: document.getElementById(decodeURIComponent(hash).slice(1));
|
|
175
|
+
target = document.getElementById(decodeURIComponent(hash).slice(1));
|
|
200
176
|
}
|
|
201
177
|
catch (e) {
|
|
202
178
|
console.warn(e);
|
|
@@ -222,9 +198,8 @@ function handleHMR(route) {
|
|
|
222
198
|
if (import.meta.hot) {
|
|
223
199
|
// hot reload pageData
|
|
224
200
|
import.meta.hot.on('vitepress:pageData', (payload) => {
|
|
225
|
-
if (shouldHotReload(payload))
|
|
201
|
+
if (shouldHotReload(payload))
|
|
226
202
|
route.data = payload.pageData;
|
|
227
|
-
}
|
|
228
203
|
});
|
|
229
204
|
}
|
|
230
205
|
}
|
|
@@ -239,9 +214,39 @@ function normalizeHref(href) {
|
|
|
239
214
|
const url = new URL(href, fakeHost);
|
|
240
215
|
url.pathname = url.pathname.replace(/(^|\/)index(\.html)?$/, '$1');
|
|
241
216
|
// ensure correct deep link so page refresh lands on correct files.
|
|
242
|
-
if (siteDataRef.value.cleanUrls)
|
|
217
|
+
if (siteDataRef.value.cleanUrls) {
|
|
243
218
|
url.pathname = url.pathname.replace(/\.html$/, '');
|
|
244
|
-
|
|
219
|
+
}
|
|
220
|
+
else if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html')) {
|
|
245
221
|
url.pathname += '.html';
|
|
222
|
+
}
|
|
246
223
|
return url.pathname + url.search + url.hash;
|
|
247
224
|
}
|
|
225
|
+
async function changeRoute(href, { smoothScroll = false, initialLoad = false } = {}) {
|
|
226
|
+
const loc = normalizeHref(location.href);
|
|
227
|
+
const { pathname, hash } = new URL(href, fakeHost);
|
|
228
|
+
const currentLoc = new URL(loc, fakeHost);
|
|
229
|
+
if (href === loc) {
|
|
230
|
+
if (!initialLoad) {
|
|
231
|
+
scrollTo(hash, smoothScroll);
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// save scroll position before changing URL
|
|
237
|
+
history.replaceState({ scrollPosition: window.scrollY }, '');
|
|
238
|
+
history.pushState({}, '', href);
|
|
239
|
+
if (pathname === currentLoc.pathname) {
|
|
240
|
+
// scroll between hash anchors on the same page, avoid duplicate entries
|
|
241
|
+
if (hash !== currentLoc.hash) {
|
|
242
|
+
window.dispatchEvent(new HashChangeEvent('hashchange', {
|
|
243
|
+
oldURL: currentLoc.href,
|
|
244
|
+
newURL: href
|
|
245
|
+
}));
|
|
246
|
+
scrollTo(hash, smoothScroll);
|
|
247
|
+
}
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return true;
|
|
252
|
+
}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ declare function escapeHtml(str: string): string;
|
|
|
11
11
|
|
|
12
12
|
interface Route {
|
|
13
13
|
path: string;
|
|
14
|
+
hash: string;
|
|
15
|
+
query: string;
|
|
14
16
|
data: PageData;
|
|
15
17
|
component: Component | null;
|
|
16
18
|
}
|
|
@@ -22,7 +24,10 @@ interface Router {
|
|
|
22
24
|
/**
|
|
23
25
|
* Navigate to a new URL.
|
|
24
26
|
*/
|
|
25
|
-
go: (to
|
|
27
|
+
go: (to: string, options?: {
|
|
28
|
+
initialLoad?: boolean;
|
|
29
|
+
smoothScroll?: boolean;
|
|
30
|
+
}) => Promise<void>;
|
|
26
31
|
/**
|
|
27
32
|
* Called before the route changes. Return `false` to cancel the navigation.
|
|
28
33
|
*/
|
|
@@ -40,10 +45,6 @@ interface Router {
|
|
|
40
45
|
* Called after the route changes.
|
|
41
46
|
*/
|
|
42
47
|
onAfterRouteChange?: (to: string) => Awaitable<void>;
|
|
43
|
-
/**
|
|
44
|
-
* @deprecated use `onAfterRouteChange` instead
|
|
45
|
-
*/
|
|
46
|
-
onAfterRouteChanged?: (to: string) => Awaitable<void>;
|
|
47
48
|
}
|
|
48
49
|
declare function useRouter(): Router;
|
|
49
50
|
declare function useRoute(): Route;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import docsearch from '@docsearch/js'
|
|
3
|
-
import {
|
|
3
|
+
import { useRouter } from 'vitepress'
|
|
4
4
|
import type { DefaultTheme } from 'vitepress/theme'
|
|
5
5
|
import { nextTick, onMounted, watch } from 'vue'
|
|
6
6
|
import { useData } from '../composables/data'
|
|
@@ -10,7 +10,6 @@ const props = defineProps<{
|
|
|
10
10
|
}>()
|
|
11
11
|
|
|
12
12
|
const router = useRouter()
|
|
13
|
-
const route = useRoute()
|
|
14
13
|
const { site, localeIndex, lang } = useData()
|
|
15
14
|
|
|
16
15
|
type DocSearchProps = Parameters<typeof docsearch>[0]
|
|
@@ -51,17 +50,7 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
|
|
|
51
50
|
|
|
52
51
|
navigator: {
|
|
53
52
|
navigate({ itemUrl }) {
|
|
54
|
-
|
|
55
|
-
window.location.origin + itemUrl
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
// router doesn't handle same-page navigation so we use the native
|
|
59
|
-
// browser location API for anchor navigation
|
|
60
|
-
if (route.path === hitPathname) {
|
|
61
|
-
window.location.assign(window.location.origin + itemUrl)
|
|
62
|
-
} else {
|
|
63
|
-
router.go(itemUrl)
|
|
64
|
-
}
|
|
53
|
+
router.go(itemUrl)
|
|
65
54
|
}
|
|
66
55
|
},
|
|
67
56
|
|
|
@@ -71,17 +60,6 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
|
|
|
71
60
|
url: getRelativePath(item.url)
|
|
72
61
|
})
|
|
73
62
|
})
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
hitComponent({ hit, children }) {
|
|
77
|
-
return {
|
|
78
|
-
__v: null,
|
|
79
|
-
type: 'a',
|
|
80
|
-
ref: undefined,
|
|
81
|
-
constructor: undefined,
|
|
82
|
-
key: undefined,
|
|
83
|
-
props: { href: hit.url, children }
|
|
84
|
-
}
|
|
85
63
|
}
|
|
86
64
|
}) as DocSearchProps
|
|
87
65
|
|