@vuepress/client 2.0.0-rc.0 → 2.0.0-rc.10

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