vitepress 1.1.3 → 1.2.0

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.
@@ -108,8 +108,21 @@ function newRouter() {
108
108
  if (isInitialPageLoad || initialPath === pageFilePath) {
109
109
  pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js');
110
110
  }
111
- if (import.meta.env.SSR) {
112
- pageModule = import(/*@vite-ignore*/ pageFilePath + '?t=' + Date.now());
111
+ if (import.meta.env.DEV) {
112
+ pageModule = import(/*@vite-ignore*/ pageFilePath).catch(() => {
113
+ // try with/without trailing slash
114
+ // in prod this is handled in src/client/app/utils.ts#pathToFile
115
+ const url = new URL(pageFilePath, 'http://a.com');
116
+ const path = (url.pathname.endsWith('/index.md')
117
+ ? url.pathname.slice(0, -9) + '.md'
118
+ : url.pathname.slice(0, -3) + '/index.md') +
119
+ url.search +
120
+ url.hash;
121
+ return import(/*@vite-ignore*/ path);
122
+ });
123
+ }
124
+ else if (import.meta.env.SSR) {
125
+ pageModule = import(/*@vite-ignore*/ `${pageFilePath}?t=${Date.now()}`);
113
126
  }
114
127
  else {
115
128
  pageModule = import(/*@vite-ignore*/ pageFilePath);
@@ -102,7 +102,13 @@ export function createRouter(loadPageModule, fallbackComponent) {
102
102
  latestPendingPath = null;
103
103
  route.path = inBrowser ? pendingPath : withBase(pendingPath);
104
104
  route.component = fallbackComponent ? markRaw(fallbackComponent) : null;
105
- route.data = notFoundPageData;
105
+ const relativePath = inBrowser
106
+ ? pendingPath
107
+ .replace(/(^|\/)$/, '$1index')
108
+ .replace(/(\.html)?$/, '.md')
109
+ .replace(/^\//, '')
110
+ : '404.md';
111
+ route.data = { ...notFoundPageData, relativePath };
106
112
  }
107
113
  }
108
114
  }
@@ -5,7 +5,7 @@ const HASH_OR_QUERY_RE = /[?#].*$/;
5
5
  const INDEX_OR_EXT_RE = /(?:(^|\/)index)?\.(?:md|html)$/;
6
6
  export const inBrowser = typeof document !== 'undefined';
7
7
  export const notFoundPageData = {
8
- relativePath: '',
8
+ relativePath: '404.md',
9
9
  filePath: '',
10
10
  title: '404',
11
11
  description: 'Not Found',
@@ -39,13 +39,16 @@ function normalize(path) {
39
39
  export function isExternal(path) {
40
40
  return EXTERNAL_URL_RE.test(path);
41
41
  }
42
+ export function getLocaleForPath(siteData, relativePath) {
43
+ return (Object.keys(siteData?.locales || {}).find((key) => key !== 'root' &&
44
+ !isExternal(key) &&
45
+ isActive(relativePath, `/${key}/`, true)) || 'root');
46
+ }
42
47
  /**
43
48
  * this merges the locales data to the main data by the route
44
49
  */
45
50
  export function resolveSiteDataByRoute(siteData, relativePath) {
46
- const localeIndex = Object.keys(siteData.locales).find((key) => key !== 'root' &&
47
- !isExternal(key) &&
48
- isActive(relativePath, `/${key}/`, true)) || 'root';
51
+ const localeIndex = getLocaleForPath(siteData, relativePath);
49
52
  return Object.assign({}, siteData, {
50
53
  localeIndex,
51
54
  lang: siteData.locales[localeIndex]?.lang ?? siteData.lang,
@@ -1,23 +1,10 @@
1
1
  <script setup lang="ts">
2
- import { onMounted, ref } from 'vue'
3
2
  import { withBase } from 'vitepress'
4
3
  import { useData } from './composables/data'
5
4
  import { useLangs } from './composables/langs'
6
5
 
7
- const { site, theme } = useData()
8
- const { localeLinks } = useLangs({ removeCurrent: false })
9
-
10
- const root = ref('/')
11
- onMounted(() => {
12
- const path = window.location.pathname
13
- .replace(site.value.base, '')
14
- .replace(/(^.*?\/).*$/, '/$1')
15
- if (localeLinks.value.length) {
16
- root.value =
17
- localeLinks.value.find(({ link }) => link.startsWith(path))?.link ||
18
- localeLinks.value[0].link
19
- }
20
- })
6
+ const { theme } = useData()
7
+ const { currentLang } = useLangs()
21
8
  </script>
22
9
 
23
10
  <template>
@@ -35,7 +22,7 @@ onMounted(() => {
35
22
  <div class="action">
36
23
  <a
37
24
  class="link"
38
- :href="withBase(root)"
25
+ :href="withBase(currentLang.link)"
39
26
  :aria-label="theme.notFound?.linkLabel ?? 'go to home'"
40
27
  >
41
28
  {{ theme.notFound?.linkText ?? 'Take me home' }}
@@ -25,7 +25,8 @@ useActiveAnchor(container, marker)
25
25
  </script>
26
26
 
27
27
  <template>
28
- <div
28
+ <nav
29
+ aria-labelledby="doc-outline-aria-label"
29
30
  class="VPDocAsideOutline"
30
31
  :class="{ 'has-outline': headers.length > 0 }"
31
32
  ref="container"
@@ -34,16 +35,18 @@ useActiveAnchor(container, marker)
34
35
  <div class="content">
35
36
  <div class="outline-marker" ref="marker" />
36
37
 
37
- <div class="outline-title" role="heading" aria-level="2">{{ resolveTitle(theme) }}</div>
38
+ <div
39
+ aria-level="2"
40
+ class="outline-title"
41
+ id="doc-outline-aria-label"
42
+ role="heading"
43
+ >
44
+ {{ resolveTitle(theme) }}
45
+ </div>
38
46
 
39
- <nav aria-labelledby="doc-outline-aria-label">
40
- <span class="visually-hidden" id="doc-outline-aria-label">
41
- Table of Contents for current page
42
- </span>
43
- <VPDocOutlineItem :headers="headers" :root="true" />
44
- </nav>
47
+ <VPDocOutlineItem :headers="headers" :root="true" />
45
48
  </div>
46
- </div>
49
+ </nav>
47
50
  </template>
48
51
 
49
52
  <style scoped>
@@ -39,7 +39,13 @@ const showFooter = computed(() => {
39
39
  </div>
40
40
  </div>
41
41
 
42
- <nav v-if="control.prev?.link || control.next?.link" class="prev-next">
42
+ <nav
43
+ v-if="control.prev?.link || control.next?.link"
44
+ class="prev-next"
45
+ aria-labelledby="doc-footer-aria-label"
46
+ >
47
+ <span class="visually-hidden" id="doc-footer-aria-label">Pager</span>
48
+
43
49
  <div class="pager">
44
50
  <VPLink v-if="control.prev?.link" class="pager-link prev" :href="control.prev.link">
45
51
  <span class="desc" v-html="theme.docFooter?.prev || 'Previous page'"></span>
@@ -1,7 +1,10 @@
1
1
  <script setup lang="ts">
2
2
  import { useWindowSize } from '@vueuse/core'
3
3
 
4
- const { width: vw } = useWindowSize({ includeScrollbar: false })
4
+ const { width: vw } = useWindowSize({
5
+ initialWidth: 0,
6
+ includeScrollbar: false
7
+ })
5
8
  </script>
6
9
 
7
10
  <template>
@@ -46,7 +49,7 @@ const { width: vw } = useWindowSize({ includeScrollbar: false })
46
49
  }
47
50
 
48
51
  .vp-doc :deep(.VPHomeSponsors a),
49
- .vp-doc :deep(.VPTeamPage a){
52
+ .vp-doc :deep(.VPTeamPage a) {
50
53
  text-decoration: none;
51
54
  }
52
55
  </style>
@@ -12,7 +12,11 @@ const props = defineProps<{
12
12
  }>()
13
13
 
14
14
  const tag = computed(() => props.tag ?? (props.href ? 'a' : 'span'))
15
- const isExternal = computed(() => props.href && EXTERNAL_URL_RE.test(props.href))
15
+ const isExternal = computed(
16
+ () =>
17
+ (props.href && EXTERNAL_URL_RE.test(props.href)) ||
18
+ props.target === '_blank'
19
+ )
16
20
  </script>
17
21
 
18
22
  <template>
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
- import { onClickOutside, onKeyStroke } from '@vueuse/core'
2
+ import { onKeyStroke } from '@vueuse/core'
3
3
  import { onContentUpdated } from 'vitepress'
4
- import { nextTick, ref } from 'vue'
4
+ import { nextTick, ref, watch } from 'vue'
5
5
  import { useData } from '../composables/data'
6
6
  import { resolveTitle, type MenuItem } from '../composables/outline'
7
7
  import VPDocOutlineItem from './VPDocOutlineItem.vue'
@@ -17,8 +17,18 @@ const vh = ref(0)
17
17
  const main = ref<HTMLDivElement>()
18
18
  const items = ref<HTMLDivElement>()
19
19
 
20
- onClickOutside(main, () => {
21
- open.value = false
20
+ function closeOnClickOutside(e: Event) {
21
+ if (!main.value?.contains(e.target as Node)) {
22
+ open.value = false
23
+ }
24
+ }
25
+
26
+ watch(open, (value) => {
27
+ if (value) {
28
+ document.addEventListener('click', closeOnClickOutside)
29
+ return
30
+ }
31
+ document.removeEventListener('click', closeOnClickOutside)
22
32
  })
23
33
 
24
34
  onKeyStroke('Escape', () => {
@@ -291,11 +291,7 @@ watch(results, (r) => {
291
291
  function scrollToSelectedResult() {
292
292
  nextTick(() => {
293
293
  const selectedEl = document.querySelector('.result.selected')
294
- if (selectedEl) {
295
- selectedEl.scrollIntoView({
296
- block: 'nearest'
297
- })
298
- }
294
+ selectedEl?.scrollIntoView({ block: 'nearest' })
299
295
  })
300
296
  }
301
297
 
@@ -71,6 +71,11 @@ const translate = createSearchTranslate(defaultTranslations)
71
71
  outline: 5px auto -webkit-focus-ring-color;
72
72
  }
73
73
 
74
+ .DocSearch-Button-Key--pressed {
75
+ transform: none;
76
+ box-shadow: none;
77
+ }
78
+
74
79
  .DocSearch-Button:focus:not(:focus-visible) {
75
80
  outline: none !important;
76
81
  }
@@ -1,14 +1,14 @@
1
1
  import { computed } from 'vue';
2
2
  import { ensureStartingSlash } from '../support/utils';
3
3
  import { useData } from './data';
4
- export function useLangs({ removeCurrent = true, correspondingLink = false } = {}) {
4
+ export function useLangs({ correspondingLink = false } = {}) {
5
5
  const { site, localeIndex, page, theme, hash } = useData();
6
6
  const currentLang = computed(() => ({
7
7
  label: site.value.locales[localeIndex.value]?.label,
8
8
  link: site.value.locales[localeIndex.value]?.link ||
9
9
  (localeIndex.value === 'root' ? '/' : `/${localeIndex.value}/`)
10
10
  }));
11
- const localeLinks = computed(() => Object.entries(site.value.locales).flatMap(([key, value]) => removeCurrent && currentLang.value.label === value.label
11
+ const localeLinks = computed(() => Object.entries(site.value.locales).flatMap(([key, value]) => currentLang.value.label === value.label
12
12
  ? []
13
13
  : {
14
14
  text: value.label,
@@ -146,12 +146,40 @@ html body {
146
146
  U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
147
147
  }
148
148
 
149
- /* Chinese quotes rendering fix. 中英文弯引号共享 Unicode 码位,确保引号使用中文字体渲染 */
150
149
  @font-face {
151
- font-family: 'Chinese Quotes';
152
- src: local('PingFang SC Regular'), local('PingFang SC'), local('SimHei'),
153
- local('Source Han Sans SC');
154
- unicode-range: U+2018, U+2019, U+201C, U+201D; /* 分别是 ‘’“” */
150
+ font-family: 'Punctuation SC';
151
+ font-weight: 400;
152
+ src: local('PingFang SC Regular'), local('Noto Sans CJK SC'),
153
+ local('Microsoft YaHei');
154
+ unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026,
155
+ U+00B7, U+007E, U+002F;
156
+ }
157
+
158
+ @font-face {
159
+ font-family: 'Punctuation SC';
160
+ font-weight: 500;
161
+ src: local('PingFang SC Medium'), local('Noto Sans CJK SC'),
162
+ local('Microsoft YaHei');
163
+ unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026,
164
+ U+00B7, U+007E, U+002F;
165
+ }
166
+
167
+ @font-face {
168
+ font-family: 'Punctuation SC';
169
+ font-weight: 600;
170
+ src: local('PingFang SC Semibold'), local('Noto Sans CJK SC Bold'),
171
+ local('Microsoft YaHei Bold');
172
+ unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026,
173
+ U+00B7, U+007E, U+002F;
174
+ }
175
+
176
+ @font-face {
177
+ font-family: 'Punctuation SC';
178
+ font-weight: 700;
179
+ src: local('PingFang SC Semibold'), local('Noto Sans CJK SC Bold'),
180
+ local('Microsoft YaHei Bold');
181
+ unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026,
182
+ U+00B7, U+007E, U+002F;
155
183
  }
156
184
 
157
185
  /* Generate the subsetted fonts using: `pyftsubset <file>.woff2 --unicodes="<range>" --output-file="inter-<style>-<subset>.woff2" --flavor=woff2` */
@@ -261,15 +261,20 @@
261
261
  * -------------------------------------------------------------------------- */
262
262
 
263
263
  :root {
264
- --vp-font-family-base: 'Chinese Quotes', Inter, ui-sans-serif, system-ui,
265
- sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
266
- 'Noto Color Emoji', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
267
- 'Noto Color Emoji';
268
- --vp-font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
264
+ --vp-font-family-base: 'Inter', ui-sans-serif, system-ui, sans-serif,
265
+ 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
266
+ --vp-font-family-mono: ui-monospace, 'Menlo', 'Monaco', 'Consolas',
269
267
  'Liberation Mono', 'Courier New', monospace;
270
268
  font-optical-sizing: auto;
271
269
  }
272
270
 
271
+ :root:where(:lang(zh)) {
272
+ --vp-font-family-base: 'Punctuation SC', 'Inter', ui-sans-serif, system-ui,
273
+ 'PingFang SC', 'Noto Sans CJK SC', 'Noto Sans SC', 'Heiti SC',
274
+ 'Microsoft YaHei', 'DengXian', sans-serif, 'Apple Color Emoji',
275
+ 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
276
+ }
277
+
273
278
  /**
274
279
  * Shadows
275
280
  * -------------------------------------------------------------------------- */
package/dist/node/cli.js CHANGED
@@ -1,6 +1,8 @@
1
- import { a as getDefaultExportFromCjs, q as c, t as clearCache, n as init, b as build, o as serve, v as version, p as createServer } from './serve-DrVGLhCg.js';
1
+ import { a as getDefaultExportFromCjs, q as c, t as clearCache, n as init, b as build, o as serve, v as version, p as createServer } from './serve-DF70M2uf.js';
2
2
  import { createLogger } from 'vite';
3
3
  import 'path';
4
+ import 'shiki';
5
+ import '@shikijs/transformers';
4
6
  import 'url';
5
7
  import 'crypto';
6
8
  import 'module';
@@ -10,16 +12,19 @@ import 'node:fs/promises';
10
12
  import 'node:url';
11
13
  import 'node:fs';
12
14
  import 'fs';
13
- import 'fs/promises';
14
- import 'events';
15
- import 'stream';
16
- import 'string_decoder';
15
+ import 'node:events';
16
+ import 'node:stream';
17
+ import 'node:string_decoder';
17
18
  import 'util';
18
19
  import 'os';
19
20
  import 'assert';
21
+ import 'events';
22
+ import 'stream';
20
23
  import 'readline';
21
24
  import 'child_process';
25
+ import 'string_decoder';
22
26
  import 'zlib';
27
+ import '@vue/shared';
23
28
  import 'node:readline';
24
29
  import 'node:tty';
25
30
  import 'http';
@@ -27,8 +32,6 @@ import 'querystring';
27
32
  import 'tty';
28
33
  import 'constants';
29
34
  import 'node:crypto';
30
- import 'shiki';
31
- import '@shikijs/transformers';
32
35
  import 'minisearch';
33
36
 
34
37
  function hasKey(obj, keys) {
@@ -308,8 +311,7 @@ function bindShortcuts(server, createDevServer) {
308
311
  await server.close().finally(() => process.exit(1));
309
312
  return;
310
313
  }
311
- if (actionRunning)
312
- return;
314
+ if (actionRunning) return;
313
315
  if (input === "h") {
314
316
  server.config.logger.info(
315
317
  [
@@ -322,8 +324,7 @@ function bindShortcuts(server, createDevServer) {
322
324
  );
323
325
  }
324
326
  const shortcut = SHORTCUTS.find((shortcut2) => shortcut2.key === input);
325
- if (!shortcut)
326
- return;
327
+ if (!shortcut) return;
327
328
  actionRunning = true;
328
329
  await shortcut.action(server, createDevServer);
329
330
  actionRunning = false;
@@ -394,6 +395,7 @@ const root = argv._[command ? 1 : 0];
394
395
  if (root) {
395
396
  argv.root = root;
396
397
  }
398
+ let restartPromise;
397
399
  if (!command || command === "dev") {
398
400
  if (argv.force) {
399
401
  delete argv.force;
@@ -401,8 +403,15 @@ if (!command || command === "dev") {
401
403
  }
402
404
  const createDevServer = async () => {
403
405
  const server = await createServer(root, argv, async () => {
404
- await server.close();
405
- await createDevServer();
406
+ if (!restartPromise) {
407
+ restartPromise = (async () => {
408
+ await server.close();
409
+ await createDevServer();
410
+ })().finally(() => {
411
+ restartPromise = void 0;
412
+ });
413
+ }
414
+ return restartPromise;
406
415
  });
407
416
  await server.listen();
408
417
  logVersion(server.config.logger);
@@ -412,6 +421,7 @@ if (!command || command === "dev") {
412
421
  createDevServer().catch((err) => {
413
422
  createLogger().error(
414
423
  `${c.red(`failed to start server. error:`)}
424
+ ${err.message}
415
425
  ${err.stack}`
416
426
  );
417
427
  process.exit(1);
@@ -423,14 +433,18 @@ ${err.stack}`
423
433
  logVersion();
424
434
  if (command === "build") {
425
435
  build(root, argv).catch((err) => {
426
- createLogger().error(`${c.red(`build error:`)}
427
- ${err.stack}`);
436
+ createLogger().error(
437
+ `${c.red(`build error:`)}
438
+ ${err.message}
439
+ ${err.stack}`
440
+ );
428
441
  process.exit(1);
429
442
  });
430
443
  } else if (command === "serve" || command === "preview") {
431
444
  serve(argv).catch((err) => {
432
445
  createLogger().error(
433
446
  `${c.red(`failed to start server. error:`)}
447
+ ${err.message}
434
448
  ${err.stack}`
435
449
  );
436
450
  process.exit(1);