@vuepress/client 2.0.0-rc.2 → 2.0.0-rc.21

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.
@@ -0,0 +1,445 @@
1
+ // src/composables/clientData.ts
2
+ import { inject } from "vue";
3
+ var clientDataSymbol = Symbol(
4
+ __VUEPRESS_DEV__ ? "clientData" : ""
5
+ );
6
+ var useClientData = () => {
7
+ const clientData = inject(clientDataSymbol);
8
+ if (!clientData) {
9
+ throw new Error("useClientData() is called without provider.");
10
+ }
11
+ return clientData;
12
+ };
13
+
14
+ // src/composables/clientDataUtils.ts
15
+ var useLayouts = () => useClientData().layouts;
16
+ var usePageComponent = () => useClientData().pageComponent;
17
+ var usePageData = () => useClientData().pageData;
18
+ var usePageFrontmatter = () => useClientData().pageFrontmatter;
19
+ var usePageHead = () => useClientData().pageHead;
20
+ var usePageLang = () => useClientData().pageLang;
21
+ var usePageLayout = () => useClientData().pageLayout;
22
+ var useRedirects = () => useClientData().redirects;
23
+ var useRouteLocale = () => useClientData().routeLocale;
24
+ var useRoutePath = () => useClientData().routePath;
25
+ var useRoutes = () => useClientData().routes;
26
+ var useSiteData = () => useClientData().siteData;
27
+ var useSiteLocaleData = () => useClientData().siteLocaleData;
28
+
29
+ // src/composables/onContentUpdated.ts
30
+ import { onUnmounted } from "vue";
31
+
32
+ // src/internal/contentUpdatedCallbacks.ts
33
+ var contentUpdatedCallbacks = /* @__PURE__ */ new Set();
34
+
35
+ // src/composables/onContentUpdated.ts
36
+ var onContentUpdated = (fn) => {
37
+ contentUpdatedCallbacks.add(fn);
38
+ onUnmounted(() => {
39
+ contentUpdatedCallbacks.delete(fn);
40
+ });
41
+ };
42
+
43
+ // src/composables/updateHead.ts
44
+ import { inject as inject2 } from "vue";
45
+ var updateHeadSymbol = Symbol(
46
+ __VUEPRESS_DEV__ ? "updateHead" : ""
47
+ );
48
+ var useUpdateHead = () => {
49
+ const updateHead = inject2(updateHeadSymbol);
50
+ if (!updateHead) {
51
+ throw new Error("useUpdateHead() is called without provider.");
52
+ }
53
+ return updateHead;
54
+ };
55
+
56
+ // src/router/resolveRoutePath.ts
57
+ import { normalizeRoutePath } from "@vuepress/shared";
58
+
59
+ // src/internal/routes.ts
60
+ import {
61
+ redirects as redirectsRaw,
62
+ routes as routesRaw
63
+ } from "@internal/routes";
64
+ import { shallowRef } from "vue";
65
+ var redirects = shallowRef(redirectsRaw);
66
+ var routes = shallowRef(routesRaw);
67
+ if (__VUEPRESS_DEV__ && (import.meta.webpackHot || import.meta.hot)) {
68
+ __VUE_HMR_RUNTIME__.updateRedirects = (data) => {
69
+ redirects.value = data;
70
+ };
71
+ __VUE_HMR_RUNTIME__.updateRoutes = (data) => {
72
+ routes.value = data;
73
+ };
74
+ }
75
+
76
+ // src/router/resolveRoutePath.ts
77
+ var resolveRoutePath = (pathname, currentPath) => {
78
+ const normalizedRoutePath = normalizeRoutePath(pathname, currentPath);
79
+ if (routes.value[normalizedRoutePath]) return normalizedRoutePath;
80
+ const encodedRoutePath = encodeURI(normalizedRoutePath);
81
+ if (routes.value[encodedRoutePath]) {
82
+ return encodedRoutePath;
83
+ }
84
+ const redirectedRoutePath = redirects.value[normalizedRoutePath] || redirects.value[encodedRoutePath];
85
+ if (redirectedRoutePath) {
86
+ return redirectedRoutePath;
87
+ }
88
+ return normalizedRoutePath;
89
+ };
90
+
91
+ // src/router/resolveRoute.ts
92
+ import { splitPath } from "@vuepress/shared";
93
+ var resolveRoute = (path, currentPath) => {
94
+ const { pathname, hashAndQueries } = splitPath(path);
95
+ const routePath = resolveRoutePath(pathname, currentPath);
96
+ const routeFullPath = routePath + hashAndQueries;
97
+ if (!routes.value[routePath]) {
98
+ return {
99
+ ...routes.value["/404.html"],
100
+ path: routeFullPath,
101
+ notFound: true
102
+ };
103
+ }
104
+ return {
105
+ ...routes.value[routePath],
106
+ path: routeFullPath,
107
+ notFound: false
108
+ };
109
+ };
110
+
111
+ // src/router/resolveRouteFullPath.ts
112
+ import { splitPath as splitPath2 } from "@vuepress/shared";
113
+ var resolveRouteFullPath = (path, currentPath) => {
114
+ const { pathname, hashAndQueries } = splitPath2(path);
115
+ return resolveRoutePath(pathname, currentPath) + hashAndQueries;
116
+ };
117
+
118
+ // src/router/index.ts
119
+ import { useRoute, useRouter } from "vue-router";
120
+
121
+ // src/components/RouteLink.ts
122
+ import { computed, defineComponent, h } from "vue";
123
+ import { useRoute as useRoute2, useRouter as useRouter2 } from "vue-router";
124
+ var guardEvent = (event) => {
125
+ if (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) return;
126
+ if (event.defaultPrevented) return;
127
+ if (event.button !== void 0 && event.button !== 0) return;
128
+ if (event.currentTarget) {
129
+ const target = event.currentTarget.getAttribute("target");
130
+ if (target?.match(/\b_blank\b/i)) return;
131
+ }
132
+ event.preventDefault();
133
+ return true;
134
+ };
135
+ var RouteLink = defineComponent({
136
+ name: "RouteLink",
137
+ props: {
138
+ /**
139
+ * The route path to link to
140
+ */
141
+ to: {
142
+ type: String,
143
+ required: true
144
+ },
145
+ /**
146
+ * Whether the link is active to have an active class
147
+ *
148
+ * Notice that the active status is not automatically determined according to the current route.
149
+ */
150
+ active: Boolean,
151
+ /**
152
+ * The class to add when the link is active
153
+ */
154
+ activeClass: {
155
+ type: String,
156
+ default: "route-link-active"
157
+ }
158
+ },
159
+ slots: Object,
160
+ setup(props, { slots }) {
161
+ const router = useRouter2();
162
+ const route = useRoute2();
163
+ const path = computed(
164
+ () => props.to.startsWith("#") || props.to.startsWith("?") ? props.to : `${__VUEPRESS_BASE__}${resolveRouteFullPath(props.to, route.path).substring(1)}`
165
+ );
166
+ return () => h(
167
+ "a",
168
+ {
169
+ class: ["route-link", { [props.activeClass]: props.active }],
170
+ href: path.value,
171
+ onClick: (event = {}) => {
172
+ if (guardEvent(event)) {
173
+ void router.push(props.to).catch();
174
+ }
175
+ }
176
+ },
177
+ slots.default()
178
+ );
179
+ }
180
+ });
181
+
182
+ // src/components/AutoLink.ts
183
+ import { isLinkWithProtocol } from "@vuepress/shared";
184
+ import { computed as computed2, defineComponent as defineComponent2, h as h2, toRef } from "vue";
185
+ import { useRoute as useRoute3 } from "vue-router";
186
+ var AutoLink = defineComponent2({
187
+ name: "AutoLink",
188
+ props: {
189
+ config: {
190
+ type: Object,
191
+ required: true
192
+ }
193
+ },
194
+ slots: Object,
195
+ setup(props, { slots }) {
196
+ const config = toRef(props, "config");
197
+ const route = useRoute3();
198
+ const siteData = useSiteData();
199
+ const withProtocol = computed2(() => isLinkWithProtocol(config.value.link));
200
+ const linkTarget = computed2(
201
+ () => config.value.target || (withProtocol.value ? "_blank" : void 0)
202
+ );
203
+ const isBlankTarget = computed2(() => linkTarget.value === "_blank");
204
+ const isInternal = computed2(
205
+ () => !withProtocol.value && !isBlankTarget.value
206
+ );
207
+ const linkRel = computed2(
208
+ () => config.value.rel || (isBlankTarget.value ? "noopener noreferrer" : null)
209
+ );
210
+ const linkAriaLabel = computed2(
211
+ () => config.value.ariaLabel ?? config.value.text
212
+ );
213
+ const shouldBeActiveInSubpath = computed2(() => {
214
+ if (config.value.exact) return false;
215
+ const localePaths = Object.keys(siteData.value.locales);
216
+ return localePaths.length ? (
217
+ // Check all the locales
218
+ localePaths.every((key) => key !== config.value.link)
219
+ ) : (
220
+ // Check root
221
+ config.value.link !== "/"
222
+ );
223
+ });
224
+ const isActive = computed2(() => {
225
+ if (!isInternal.value) return false;
226
+ if (config.value.activeMatch) {
227
+ return (config.value.activeMatch instanceof RegExp ? config.value.activeMatch : new RegExp(config.value.activeMatch, "u")).test(route.path);
228
+ }
229
+ if (shouldBeActiveInSubpath.value) {
230
+ return route.path.startsWith(config.value.link);
231
+ }
232
+ return route.path === config.value.link;
233
+ });
234
+ return () => {
235
+ const { before, after, default: defaultSlot } = slots;
236
+ const content = defaultSlot?.(config.value) ?? [
237
+ before?.(config.value),
238
+ config.value.text,
239
+ after?.(config.value)
240
+ ];
241
+ return isInternal.value ? h2(
242
+ RouteLink,
243
+ {
244
+ "class": "auto-link",
245
+ "to": config.value.link,
246
+ "active": isActive.value,
247
+ "aria-label": linkAriaLabel.value
248
+ },
249
+ () => content
250
+ ) : h2(
251
+ "a",
252
+ {
253
+ "class": "auto-link external-link",
254
+ "href": config.value.link,
255
+ "aria-label": linkAriaLabel.value,
256
+ "rel": linkRel.value,
257
+ "target": linkTarget.value
258
+ },
259
+ content
260
+ );
261
+ };
262
+ }
263
+ });
264
+
265
+ // src/components/ClientOnly.ts
266
+ import { defineComponent as defineComponent3, onMounted, ref } from "vue";
267
+ var ClientOnly = defineComponent3({
268
+ name: "ClientOnly",
269
+ setup(_, ctx) {
270
+ const isMounted = ref(false);
271
+ onMounted(() => {
272
+ isMounted.value = true;
273
+ });
274
+ return () => isMounted.value ? ctx.slots.default?.() : null;
275
+ }
276
+ });
277
+
278
+ // src/components/Content.ts
279
+ import { computed as computed3, defineAsyncComponent, defineComponent as defineComponent4, h as h3, watch } from "vue";
280
+ var runContentUpdatedCallbacks = (reason) => {
281
+ contentUpdatedCallbacks.forEach((fn) => fn(reason));
282
+ };
283
+ var Content = defineComponent4({
284
+ name: "Content",
285
+ props: {
286
+ path: {
287
+ type: String,
288
+ required: false,
289
+ default: ""
290
+ }
291
+ },
292
+ setup(props) {
293
+ const pageComponent = usePageComponent();
294
+ const ContentComponent = computed3(() => {
295
+ if (!props.path) return pageComponent.value;
296
+ const route = resolveRoute(props.path);
297
+ return defineAsyncComponent(
298
+ async () => route.loader().then(({ comp }) => comp)
299
+ );
300
+ });
301
+ const frontmatter = usePageFrontmatter();
302
+ watch(
303
+ frontmatter,
304
+ () => {
305
+ runContentUpdatedCallbacks("updated");
306
+ },
307
+ { deep: true, flush: "post" }
308
+ );
309
+ return () => h3(ContentComponent.value, {
310
+ onVnodeMounted: () => {
311
+ runContentUpdatedCallbacks("mounted");
312
+ },
313
+ onVnodeUpdated: () => {
314
+ runContentUpdatedCallbacks("updated");
315
+ },
316
+ onVnodeBeforeUnmount: () => {
317
+ runContentUpdatedCallbacks("beforeUnmount");
318
+ }
319
+ });
320
+ }
321
+ });
322
+
323
+ // src/resolvers.ts
324
+ import { dedupeHead, isString, resolveLocalePath } from "@vuepress/shared";
325
+ import { reactive } from "vue";
326
+
327
+ // src/constants.ts
328
+ var LAYOUT_NAME_DEFAULT = "Layout";
329
+ var LANG_DEFAULT = "en-US";
330
+
331
+ // src/resolvers.ts
332
+ var resolvers = reactive({
333
+ /**
334
+ * Resolve layouts component map
335
+ */
336
+ resolveLayouts: (clientConfigs) => clientConfigs.reduce(
337
+ (prev, item) => ({
338
+ ...prev,
339
+ ...item.layouts
340
+ }),
341
+ {}
342
+ ),
343
+ /**
344
+ * Merge the head config in frontmatter and site locale
345
+ *
346
+ * Frontmatter should take priority over site locale
347
+ */
348
+ resolvePageHead: (pageHeadTitle, pageFrontmatter, siteLocaleDate) => {
349
+ const description = isString(pageFrontmatter.description) ? pageFrontmatter.description : siteLocaleDate.description;
350
+ const head = [
351
+ ...Array.isArray(pageFrontmatter.head) ? pageFrontmatter.head : [],
352
+ ...siteLocaleDate.head,
353
+ ["title", {}, pageHeadTitle],
354
+ ["meta", { name: "description", content: description }]
355
+ ];
356
+ return dedupeHead(head);
357
+ },
358
+ /**
359
+ * Resolve the content of page head title
360
+ *
361
+ * It would be used as the content of the `<title>` tag
362
+ */
363
+ resolvePageHeadTitle: (pageData, siteLocaleDate) => [pageData.title, siteLocaleDate.title].filter((item) => !!item).join(" | "),
364
+ /**
365
+ * Resolve page language from page data
366
+ *
367
+ * It would be used as the `lang` attribute of `<html>` tag
368
+ */
369
+ resolvePageLang: (pageData, siteLocaleData) => pageData.lang || siteLocaleData.lang || LANG_DEFAULT,
370
+ /**
371
+ * Resolve layout component of current page
372
+ */
373
+ resolvePageLayout: (pageData, layouts) => {
374
+ const layoutName = isString(pageData.frontmatter.layout) ? pageData.frontmatter.layout : LAYOUT_NAME_DEFAULT;
375
+ if (!layouts[layoutName]) {
376
+ throw new Error(`[vuepress] Cannot resolve layout: ${layoutName}`);
377
+ }
378
+ return layouts[layoutName];
379
+ },
380
+ /**
381
+ * Resolve locale path according to route path and locales config
382
+ */
383
+ resolveRouteLocale: (locales, routePath) => resolveLocalePath(locales, decodeURI(routePath)),
384
+ /**
385
+ * Resolve site data for specific locale
386
+ *
387
+ * It would merge the locales fields to the root fields
388
+ */
389
+ resolveSiteLocaleData: ({ base, locales, ...siteData }, routeLocale) => ({
390
+ ...siteData,
391
+ ...locales[routeLocale],
392
+ head: [
393
+ // when merging head, the locales head should be placed before root head
394
+ // to get higher priority
395
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- unsafe indexed access
396
+ ...locales[routeLocale]?.head ?? [],
397
+ ...siteData.head
398
+ ]
399
+ })
400
+ });
401
+
402
+ // src/utils/defineClientConfig.ts
403
+ var defineClientConfig = (clientConfig = {}) => clientConfig;
404
+
405
+ // src/utils/withBase.ts
406
+ import { isLinkHttp, removeLeadingSlash } from "@vuepress/shared";
407
+ var withBase = (url) => {
408
+ if (isLinkHttp(url)) return url;
409
+ return `${__VUEPRESS_BASE__}${removeLeadingSlash(url)}`;
410
+ };
411
+
412
+ export {
413
+ clientDataSymbol,
414
+ useClientData,
415
+ useLayouts,
416
+ usePageComponent,
417
+ usePageData,
418
+ usePageFrontmatter,
419
+ usePageHead,
420
+ usePageLang,
421
+ usePageLayout,
422
+ useRedirects,
423
+ useRouteLocale,
424
+ useRoutePath,
425
+ useRoutes,
426
+ useSiteData,
427
+ useSiteLocaleData,
428
+ onContentUpdated,
429
+ updateHeadSymbol,
430
+ useUpdateHead,
431
+ redirects,
432
+ routes,
433
+ resolveRoutePath,
434
+ resolveRoute,
435
+ resolveRouteFullPath,
436
+ useRoute,
437
+ useRouter,
438
+ RouteLink,
439
+ AutoLink,
440
+ ClientOnly,
441
+ Content,
442
+ resolvers,
443
+ defineClientConfig,
444
+ withBase
445
+ };
@@ -0,0 +1,66 @@
1
+ import {
2
+ __export
3
+ } from "./chunk-MLKGABMK.js";
4
+
5
+ // src/devtools/constants.ts
6
+ var constants_exports = {};
7
+ __export(constants_exports, {
8
+ COMPONENT_STATE_TYPE: () => COMPONENT_STATE_TYPE,
9
+ INSPECTOR_ID: () => INSPECTOR_ID,
10
+ INSPECTOR_LABEL: () => INSPECTOR_LABEL,
11
+ INSPECTOR_NODES: () => INSPECTOR_NODES,
12
+ INSPECTOR_STATE_SECTION_NAME: () => INSPECTOR_STATE_SECTION_NAME,
13
+ PLUGIN_ID: () => PLUGIN_ID,
14
+ PLUGIN_LABEL: () => PLUGIN_LABEL
15
+ });
16
+ var PLUGIN_ID = "org.vuejs.vuepress";
17
+ var PLUGIN_LABEL = "VuePress";
18
+ var COMPONENT_STATE_TYPE = PLUGIN_LABEL;
19
+ var INSPECTOR_ID = PLUGIN_ID;
20
+ var INSPECTOR_LABEL = PLUGIN_LABEL;
21
+ var INSPECTOR_NODE_INTERNAL = {
22
+ id: "INTERNAL",
23
+ label: "Internal",
24
+ keys: ["layouts", "routes", "redirects"]
25
+ };
26
+ var INSPECTOR_NODE_SITE = {
27
+ id: "SITE",
28
+ label: "Site",
29
+ keys: ["siteData", "siteLocaleData"]
30
+ };
31
+ var INSPECTOR_NODE_ROUTE = {
32
+ id: "ROUTE",
33
+ label: "Route",
34
+ keys: ["routePath", "routeLocale"]
35
+ };
36
+ var INSPECTOR_NODE_PAGE = {
37
+ id: "PAGE",
38
+ label: "Page",
39
+ keys: [
40
+ "pageData",
41
+ "pageFrontmatter",
42
+ "pageLang",
43
+ "pageHead",
44
+ "pageHeadTitle",
45
+ "pageLayout",
46
+ "pageComponent"
47
+ ]
48
+ };
49
+ var INSPECTOR_NODES = {
50
+ [INSPECTOR_NODE_INTERNAL.id]: INSPECTOR_NODE_INTERNAL,
51
+ [INSPECTOR_NODE_SITE.id]: INSPECTOR_NODE_SITE,
52
+ [INSPECTOR_NODE_ROUTE.id]: INSPECTOR_NODE_ROUTE,
53
+ [INSPECTOR_NODE_PAGE.id]: INSPECTOR_NODE_PAGE
54
+ };
55
+ var INSPECTOR_STATE_SECTION_NAME = "State";
56
+
57
+ export {
58
+ PLUGIN_ID,
59
+ PLUGIN_LABEL,
60
+ COMPONENT_STATE_TYPE,
61
+ INSPECTOR_ID,
62
+ INSPECTOR_LABEL,
63
+ INSPECTOR_NODES,
64
+ INSPECTOR_STATE_SECTION_NAME,
65
+ constants_exports
66
+ };