@vuepress/client 2.0.0-beta.24 → 2.0.0-beta.28

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.
Files changed (40) hide show
  1. package/lib/app.js +13 -41
  2. package/lib/components/ClientOnly.d.ts +1 -1
  3. package/lib/components/ClientOnly.js +1 -1
  4. package/lib/components/Content.js +3 -3
  5. package/lib/components/OutboundLink.js +9 -9
  6. package/lib/components/Vuepress.d.ts +1 -1
  7. package/lib/components/Vuepress.js +3 -3
  8. package/lib/{injections → composables}/index.d.ts +0 -0
  9. package/lib/{injections → composables}/index.js +0 -0
  10. package/lib/{injections → composables}/pageData.d.ts +13 -1
  11. package/lib/{injections → composables}/pageData.js +14 -4
  12. package/lib/{injections → composables}/pageFrontmatter.d.ts +13 -1
  13. package/lib/{injections → composables}/pageFrontmatter.js +10 -1
  14. package/lib/{injections → composables}/pageHead.d.ts +13 -1
  15. package/lib/{injections → composables}/pageHead.js +8 -2
  16. package/lib/{injections → composables}/pageHeadTitle.d.ts +15 -1
  17. package/lib/{injections → composables}/pageHeadTitle.js +10 -2
  18. package/lib/{injections → composables}/pageLang.d.ts +15 -4
  19. package/lib/{injections → composables}/pageLang.js +9 -4
  20. package/lib/{injections → composables}/pagesData.d.ts +16 -1
  21. package/lib/{injections → composables}/pagesData.js +8 -4
  22. package/lib/{injections → composables}/routeLocale.d.ts +14 -2
  23. package/lib/{injections → composables}/routeLocale.js +9 -3
  24. package/lib/{injections → composables}/siteData.d.ts +10 -1
  25. package/lib/{injections → composables}/siteData.js +7 -1
  26. package/lib/{injections → composables}/siteLocaleData.d.ts +16 -3
  27. package/lib/{injections → composables}/siteLocaleData.js +10 -3
  28. package/lib/composables/updateHead.d.ts +26 -0
  29. package/lib/{injections → composables}/updateHead.js +60 -45
  30. package/lib/index.d.ts +3 -2
  31. package/lib/index.js +2 -1
  32. package/lib/provideGlobalComputed.d.ts +20 -0
  33. package/lib/provideGlobalComputed.js +33 -0
  34. package/lib/registerGlobalComponents.d.ts +5 -0
  35. package/lib/registerGlobalComponents.js +11 -0
  36. package/lib/types/clientAppEnhance.d.ts +1 -1
  37. package/lib/utils/withBase.js +1 -1
  38. package/package.json +7 -7
  39. package/types.d.ts +3 -3
  40. package/lib/injections/updateHead.d.ts +0 -15
package/lib/app.js CHANGED
@@ -1,31 +1,31 @@
1
- import { createApp, createSSRApp, computed, h } from 'vue';
2
- import { createRouter, createWebHistory, createMemoryHistory, RouterView, START_LOCATION, } from 'vue-router';
3
- import { removeEndingSlash } from '@vuepress/shared';
4
1
  import { clientAppEnhances } from '@internal/clientAppEnhances';
5
2
  import { clientAppRootComponents } from '@internal/clientAppRootComponents';
6
3
  import { clientAppSetups } from '@internal/clientAppSetups';
7
4
  import { pagesComponents } from '@internal/pagesComponents';
8
5
  import { pagesRoutes } from '@internal/pagesRoutes';
9
- import { siteData, pageData, resolvePageData, pageFrontmatterSymbol, resolvePageFrontmatter, pageHeadSymbol, resolvePageHead, pageHeadTitleSymbol, resolvePageHeadTitle, pageLangSymbol, resolvePageLang, routeLocaleSymbol, resolveRouteLocale, siteLocaleDataSymbol, resolveSiteLocaleData, useUpdateHead, } from './injections';
10
- import { ClientOnly, Content, OutboundLink } from './components';
11
- import { withBase } from './utils';
6
+ import { removeEndingSlash } from '@vuepress/shared';
7
+ import { createApp, createSSRApp, h } from 'vue';
8
+ import { createMemoryHistory, createRouter, createWebHistory, RouterView, START_LOCATION, } from 'vue-router';
9
+ import { pageData, resolvePageData, setupUpdateHead, siteData, } from './composables';
10
+ import { provideGlobalComputed } from './provideGlobalComputed';
11
+ import { registerGlobalComponents } from './registerGlobalComponents';
12
12
  /**
13
13
  * - use `createApp` in dev mode
14
14
  * - use `createSSRApp` in build mode
15
15
  */
16
- const appCreator = __DEV__ ? createApp : createSSRApp;
16
+ const appCreator = __VUEPRESS_DEV__ ? createApp : createSSRApp;
17
17
  /**
18
18
  * - use `createWebHistory` in dev mode and build mode client bundle
19
19
  * - use `createMemoryHistory` in build mode server bundle
20
20
  */
21
- const historyCreator = __SSR__ ? createMemoryHistory : createWebHistory;
21
+ const historyCreator = __VUEPRESS_SSR__ ? createMemoryHistory : createWebHistory;
22
22
  export const createVueApp = async () => {
23
23
  // create vue app
24
24
  const app = appCreator({
25
25
  name: 'VuepressApp',
26
26
  setup() {
27
27
  // auto update head
28
- useUpdateHead();
28
+ setupUpdateHead();
29
29
  // invoke all clientAppSetups
30
30
  for (const clientAppSetup of clientAppSetups) {
31
31
  clientAppSetup();
@@ -60,37 +60,9 @@ export const createVueApp = async () => {
60
60
  ]);
61
61
  }
62
62
  });
63
- // create global computed
64
- const routeLocale = computed(() => resolveRouteLocale(siteData.value.locales, router.currentRoute.value.path));
65
- const siteLocaleData = computed(() => resolveSiteLocaleData(siteData.value, routeLocale.value));
66
- const pageFrontmatter = computed(() => resolvePageFrontmatter(pageData.value));
67
- const pageHeadTitle = computed(() => resolvePageHeadTitle(pageData.value, siteLocaleData.value));
68
- const pageHead = computed(() => resolvePageHead(pageHeadTitle.value, pageFrontmatter.value, siteLocaleData.value));
69
- const pageLang = computed(() => resolvePageLang(pageData.value));
70
- // provide global computed
71
- app.provide(routeLocaleSymbol, routeLocale);
72
- app.provide(siteLocaleDataSymbol, siteLocaleData);
73
- app.provide(pageFrontmatterSymbol, pageFrontmatter);
74
- app.provide(pageHeadTitleSymbol, pageHeadTitle);
75
- app.provide(pageHeadSymbol, pageHead);
76
- app.provide(pageLangSymbol, pageLang);
77
- // provide global data & helpers
78
- Object.defineProperties(app.config.globalProperties, {
79
- $routeLocale: { get: () => routeLocale.value },
80
- $site: { get: () => siteData.value },
81
- $siteLocale: { get: () => siteLocaleData.value },
82
- $page: { get: () => pageData.value },
83
- $frontmatter: { get: () => pageFrontmatter.value },
84
- $lang: { get: () => pageLang.value },
85
- $headTitle: { get: () => pageHeadTitle.value },
86
- $withBase: { get: () => withBase },
87
- });
88
- // register built-in components
89
- /* eslint-disable vue/match-component-file-name */
90
- app.component('ClientOnly', ClientOnly);
91
- app.component('Content', Content);
92
- app.component('OutboundLink', OutboundLink);
93
- /* eslint-enable vue/match-component-file-name */
63
+ // global computed and global components
64
+ provideGlobalComputed(app, router);
65
+ registerGlobalComponents(app);
94
66
  // invoke all clientAppEnhances
95
67
  for (const clientAppEnhance of clientAppEnhances) {
96
68
  await clientAppEnhance({ app, router, siteData });
@@ -107,7 +79,7 @@ export const createVueApp = async () => {
107
79
  };
108
80
  };
109
81
  // mount app in client bundle
110
- if (!__SSR__) {
82
+ if (!__VUEPRESS_SSR__) {
111
83
  createVueApp().then(({ app, router }) => {
112
84
  router.isReady().then(() => {
113
85
  app.mount('#app');
@@ -1,3 +1,3 @@
1
1
  export declare const ClientOnly: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
2
2
  [key: string]: any;
3
- }>[] | null | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{} & {} & {}> & ({} | {}), {}>;
3
+ }>[] | null | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{} & {} & {}>, {}>;
@@ -1,4 +1,4 @@
1
- import { ref, onMounted, defineComponent } from 'vue';
1
+ import { defineComponent, onMounted, ref } from 'vue';
2
2
  export const ClientOnly = defineComponent({
3
3
  setup(_, ctx) {
4
4
  const isMounted = ref(false);
@@ -1,6 +1,6 @@
1
- import { h } from 'vue';
2
1
  import { pagesComponents } from '@internal/pagesComponents';
3
- import { usePageData } from '../injections';
2
+ import { h } from 'vue';
3
+ import { usePageData } from '../composables';
4
4
  /**
5
5
  * Markdown rendered content
6
6
  */
@@ -21,7 +21,7 @@ export const Content = (props) => {
21
21
  return h(component);
22
22
  }
23
23
  // fallback
24
- return h('div', __DEV__
24
+ return h('div', __VUEPRESS_DEV__
25
25
  ? 'Page does not exist. This is a fallback content.'
26
26
  : '404 Not Found');
27
27
  };
@@ -1,15 +1,15 @@
1
1
  import { h } from 'vue';
2
2
  import './OutboundLink.css';
3
3
  const svg = h('svg', {
4
- class: 'icon outbound',
5
- xmlns: 'http://www.w3.org/2000/svg',
6
- ariaHidden: 'true',
7
- focusable: 'false',
8
- x: '0px',
9
- y: '0px',
10
- viewBox: '0 0 100 100',
11
- width: '15',
12
- height: '15',
4
+ 'class': 'icon outbound',
5
+ 'xmlns': 'http://www.w3.org/2000/svg',
6
+ 'aria-hidden': 'true',
7
+ 'focusable': 'false',
8
+ 'x': '0px',
9
+ 'y': '0px',
10
+ 'viewBox': '0 0 100 100',
11
+ 'width': '15',
12
+ 'height': '15',
13
13
  }, [
14
14
  h('path', {
15
15
  fill: 'currentColor',
@@ -3,4 +3,4 @@
3
3
  */
4
4
  export declare const Vuepress: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
5
5
  [key: string]: any;
6
- }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{} & {} & {}> & ({} | {}), {}>;
6
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{} & {} & {}>, {}>;
@@ -1,7 +1,7 @@
1
- import { computed, defineComponent, h, resolveComponent } from 'vue';
2
- import { isString } from '@vuepress/shared';
3
1
  import { layoutComponents } from '@internal/layoutComponents';
4
- import { usePageData } from '../injections';
2
+ import { isString } from '@vuepress/shared';
3
+ import { computed, defineComponent, h, resolveComponent } from 'vue';
4
+ import { usePageData } from '../composables';
5
5
  /**
6
6
  * Global Layout
7
7
  */
File without changes
File without changes
@@ -1,7 +1,19 @@
1
- import type { Ref } from 'vue';
2
1
  import type { PageData } from '@vuepress/shared';
2
+ import type { Ref } from 'vue';
3
3
  export type { PageData };
4
+ /**
5
+ * Ref wrapper of `PageData`
6
+ */
4
7
  export declare type PageDataRef<T extends Record<any, any> = Record<never, never>> = Ref<PageData<T>>;
8
+ /**
9
+ * Global page data ref
10
+ */
5
11
  export declare const pageData: PageDataRef;
12
+ /**
13
+ * Returns the ref of the data of current page
14
+ */
6
15
  export declare const usePageData: <T extends Record<any, any> = Record<never, never>>() => PageDataRef<T>;
16
+ /**
17
+ * Resolve page data according to page key
18
+ */
7
19
  export declare const resolvePageData: (pageKey: string) => Promise<PageData>;
@@ -1,5 +1,8 @@
1
- import { ref, readonly } from 'vue';
1
+ import { readonly, ref } from 'vue';
2
2
  import { pagesData } from './pagesData';
3
+ /**
4
+ * Empty page data to be used as the fallback value
5
+ */
3
6
  const pageDataEmpty = readonly({
4
7
  key: '',
5
8
  path: '',
@@ -9,10 +12,17 @@ const pageDataEmpty = readonly({
9
12
  excerpt: '',
10
13
  headers: [],
11
14
  });
15
+ /**
16
+ * Global page data ref
17
+ */
12
18
  export const pageData = ref(pageDataEmpty);
13
- export const usePageData = () => {
14
- return pageData;
15
- };
19
+ /**
20
+ * Returns the ref of the data of current page
21
+ */
22
+ export const usePageData = () => pageData;
23
+ /**
24
+ * Resolve page data according to page key
25
+ */
16
26
  export const resolvePageData = async (pageKey) => {
17
27
  const pageDataResolver = pagesData.value[pageKey];
18
28
  if (!pageDataResolver) {
@@ -1,7 +1,19 @@
1
- import type { ComputedRef, InjectionKey } from 'vue';
2
1
  import type { PageData, PageFrontmatter } from '@vuepress/shared';
2
+ import type { ComputedRef, InjectionKey } from 'vue';
3
3
  export type { PageFrontmatter };
4
+ /**
5
+ * Ref wrapper of `PageFrontmatter`
6
+ */
4
7
  export declare type PageFrontmatterRef<T extends Record<any, any> = Record<string, unknown>> = ComputedRef<PageFrontmatter<T>>;
8
+ /**
9
+ * Injection key for page frontmatter
10
+ */
5
11
  export declare const pageFrontmatterSymbol: InjectionKey<PageFrontmatterRef>;
12
+ /**
13
+ * Returns the ref of the frontmatter of current page
14
+ */
6
15
  export declare const usePageFrontmatter: <T extends Record<any, any> = Record<string, unknown>>() => PageFrontmatterRef<T>;
16
+ /**
17
+ * Resolve page frontmatter from page data
18
+ */
7
19
  export declare const resolvePageFrontmatter: (pageData: PageData) => PageFrontmatter;
@@ -1,5 +1,11 @@
1
1
  import { inject } from 'vue';
2
- export const pageFrontmatterSymbol = Symbol(__DEV__ ? 'pageFrontmatter' : '');
2
+ /**
3
+ * Injection key for page frontmatter
4
+ */
5
+ export const pageFrontmatterSymbol = Symbol(__VUEPRESS_DEV__ ? 'pageFrontmatter' : '');
6
+ /**
7
+ * Returns the ref of the frontmatter of current page
8
+ */
3
9
  export const usePageFrontmatter = () => {
4
10
  const pageFrontmatter = inject(pageFrontmatterSymbol);
5
11
  if (!pageFrontmatter) {
@@ -7,4 +13,7 @@ export const usePageFrontmatter = () => {
7
13
  }
8
14
  return pageFrontmatter;
9
15
  };
16
+ /**
17
+ * Resolve page frontmatter from page data
18
+ */
10
19
  export const resolvePageFrontmatter = (pageData) => pageData.frontmatter;
@@ -1,11 +1,23 @@
1
- import type { ComputedRef, InjectionKey } from 'vue';
2
1
  import type { HeadConfig } from '@vuepress/shared';
2
+ import type { ComputedRef, InjectionKey } from 'vue';
3
3
  import type { PageFrontmatter } from './pageFrontmatter';
4
4
  import type { PageHeadTitle } from './pageHeadTitle';
5
5
  import type { SiteLocaleData } from './siteLocaleData';
6
+ /**
7
+ * Page head config, which would be used for generate html tags in `<head>`
8
+ */
6
9
  export declare type PageHead = HeadConfig[];
10
+ /**
11
+ * Ref wrapper of `PageHead`
12
+ */
7
13
  export declare type PageHeadRef = ComputedRef<PageHead>;
14
+ /**
15
+ * Injection key for page head
16
+ */
8
17
  export declare const pageHeadSymbol: InjectionKey<PageHeadRef>;
18
+ /**
19
+ * Returns the ref of the head config of current page
20
+ */
9
21
  export declare const usePageHead: () => PageHeadRef;
10
22
  /**
11
23
  * Merge the head config in frontmatter and site locale
@@ -1,6 +1,12 @@
1
- import { inject } from 'vue';
2
1
  import { dedupeHead, isArray, isString } from '@vuepress/shared';
3
- export const pageHeadSymbol = Symbol(__DEV__ ? 'pageHead' : '');
2
+ import { inject } from 'vue';
3
+ /**
4
+ * Injection key for page head
5
+ */
6
+ export const pageHeadSymbol = Symbol(__VUEPRESS_DEV__ ? 'pageHead' : '');
7
+ /**
8
+ * Returns the ref of the head config of current page
9
+ */
4
10
  export const usePageHead = () => {
5
11
  const pageHead = inject(pageHeadSymbol);
6
12
  if (!pageHead) {
@@ -1,11 +1,25 @@
1
1
  import type { ComputedRef, InjectionKey } from 'vue';
2
2
  import type { PageData } from './pageData';
3
3
  import type { SiteLocaleData } from './siteLocaleData';
4
+ /**
5
+ * Page head title, which would be used as the content of `head > title` tag
6
+ */
4
7
  export declare type PageHeadTitle = string;
8
+ /**
9
+ * Ref wrapper of `PageHeadTitle`
10
+ */
5
11
  export declare type PageHeadTitleRef = ComputedRef<PageHeadTitle>;
12
+ /**
13
+ * Injection key for page head title
14
+ */
6
15
  export declare const pageHeadTitleSymbol: InjectionKey<PageHeadTitleRef>;
16
+ /**
17
+ * Returns the ref of the head title of current page
18
+ */
7
19
  export declare const usePageHeadTitle: () => PageHeadTitleRef;
8
20
  /**
9
- * Title to displayed in `<head>` tag
21
+ * Resolve the content of page head title
22
+ *
23
+ * It would be used as the content of the `<title>` tag
10
24
  */
11
25
  export declare const resolvePageHeadTitle: (page: PageData, siteLocale: SiteLocaleData) => PageHeadTitle;
@@ -1,5 +1,11 @@
1
1
  import { inject } from 'vue';
2
- export const pageHeadTitleSymbol = Symbol(__DEV__ ? 'pageHeadTitle' : '');
2
+ /**
3
+ * Injection key for page head title
4
+ */
5
+ export const pageHeadTitleSymbol = Symbol(__VUEPRESS_DEV__ ? 'pageHeadTitle' : '');
6
+ /**
7
+ * Returns the ref of the head title of current page
8
+ */
3
9
  export const usePageHeadTitle = () => {
4
10
  const pageHeadTitle = inject(pageHeadTitleSymbol);
5
11
  if (!pageHeadTitle) {
@@ -8,6 +14,8 @@ export const usePageHeadTitle = () => {
8
14
  return pageHeadTitle;
9
15
  };
10
16
  /**
11
- * Title to displayed in `<head>` tag
17
+ * Resolve the content of page head title
18
+ *
19
+ * It would be used as the content of the `<title>` tag
12
20
  */
13
21
  export const resolvePageHeadTitle = (page, siteLocale) => `${page.title ? `${page.title} | ` : ``}${siteLocale.title}`;
@@ -1,13 +1,24 @@
1
- import type { ComputedRef, InjectionKey } from 'vue';
2
1
  import type { PageData } from '@vuepress/shared';
2
+ import type { ComputedRef, InjectionKey } from 'vue';
3
+ /**
4
+ * Page language
5
+ */
3
6
  export declare type PageLang = string;
7
+ /**
8
+ * Ref wrapper of `PageLang`
9
+ */
4
10
  export declare type PageLangRef = ComputedRef<PageLang>;
11
+ /**
12
+ * Injection key for page language
13
+ */
5
14
  export declare const pageLangSymbol: InjectionKey<PageLangRef>;
15
+ /**
16
+ * Returns the ref of the language of current page
17
+ */
6
18
  export declare const usePageLang: () => PageLangRef;
7
19
  /**
8
- * Resolve language of current page
20
+ * Resolve page language from page data
9
21
  *
10
- * It's mainly used for the `lang` attribute of `<html>` tag,
11
- * which should not be empty
22
+ * It would be used as the `lang` attribute of `<html>` tag
12
23
  */
13
24
  export declare const resolvePageLang: (pageData: PageData) => PageLang;
@@ -1,5 +1,11 @@
1
1
  import { inject } from 'vue';
2
- export const pageLangSymbol = Symbol(__DEV__ ? 'pageLang' : '');
2
+ /**
3
+ * Injection key for page language
4
+ */
5
+ export const pageLangSymbol = Symbol(__VUEPRESS_DEV__ ? 'pageLang' : '');
6
+ /**
7
+ * Returns the ref of the language of current page
8
+ */
3
9
  export const usePageLang = () => {
4
10
  const pageLang = inject(pageLangSymbol);
5
11
  if (!pageLang) {
@@ -8,9 +14,8 @@ export const usePageLang = () => {
8
14
  return pageLang;
9
15
  };
10
16
  /**
11
- * Resolve language of current page
17
+ * Resolve page language from page data
12
18
  *
13
- * It's mainly used for the `lang` attribute of `<html>` tag,
14
- * which should not be empty
19
+ * It would be used as the `lang` attribute of `<html>` tag
15
20
  */
16
21
  export const resolvePageLang = (pageData) => pageData.lang || 'en';
@@ -1,6 +1,21 @@
1
- import type { Ref } from 'vue';
2
1
  import type { PageData } from '@vuepress/shared';
2
+ import type { Ref } from 'vue';
3
+ /**
4
+ * Data resolvers of all pages
5
+ *
6
+ * The key is page key, and the value is an async function that
7
+ * returns the page data
8
+ */
3
9
  export declare type PagesData = Record<string, () => Promise<PageData>>;
10
+ /**
11
+ * Ref wrapper of `PagesData`
12
+ */
4
13
  export declare type PagesDataRef = Ref<PagesData>;
14
+ /**
15
+ * Global pages data ref
16
+ */
5
17
  export declare const pagesData: PagesDataRef;
18
+ /**
19
+ * Returns the ref of data resolvers of all pages
20
+ */
6
21
  export declare const usePagesData: () => PagesDataRef;
@@ -1,6 +1,10 @@
1
- import { ref } from 'vue';
2
1
  import { pagesData as pagesDataRaw } from '@internal/pagesData';
2
+ import { ref } from 'vue';
3
+ /**
4
+ * Global pages data ref
5
+ */
3
6
  export const pagesData = ref(pagesDataRaw);
4
- export const usePagesData = () => {
5
- return pagesData;
6
- };
7
+ /**
8
+ * Returns the ref of data resolvers of all pages
9
+ */
10
+ export const usePagesData = () => pagesData;
@@ -1,10 +1,22 @@
1
- import type { ComputedRef, InjectionKey } from 'vue';
2
1
  import type { SiteData } from '@vuepress/shared';
2
+ import type { ComputedRef, InjectionKey } from 'vue';
3
+ /**
4
+ * Route locale path
5
+ */
3
6
  export declare type RouteLocale = string;
7
+ /**
8
+ * Ref wrapper of `RouteLocale`
9
+ */
4
10
  export declare type RouteLocaleRef = ComputedRef<RouteLocale>;
11
+ /**
12
+ * Injection key for page route locale path
13
+ */
5
14
  export declare const routeLocaleSymbol: InjectionKey<RouteLocaleRef>;
15
+ /**
16
+ * Returns the ref of the route locale path of current page
17
+ */
6
18
  export declare const useRouteLocale: () => RouteLocaleRef;
7
19
  /**
8
- * Resolve locale path of the route path
20
+ * Resolve locale path according to route path and locales config
9
21
  */
10
22
  export declare const resolveRouteLocale: (locales: SiteData['locales'], routePath: string) => RouteLocale;
@@ -1,6 +1,12 @@
1
- import { inject } from 'vue';
2
1
  import { resolveLocalePath } from '@vuepress/shared';
3
- export const routeLocaleSymbol = Symbol(__DEV__ ? 'routeLocale' : '');
2
+ import { inject } from 'vue';
3
+ /**
4
+ * Injection key for page route locale path
5
+ */
6
+ export const routeLocaleSymbol = Symbol(__VUEPRESS_DEV__ ? 'routeLocale' : '');
7
+ /**
8
+ * Returns the ref of the route locale path of current page
9
+ */
4
10
  export const useRouteLocale = () => {
5
11
  const routeLocale = inject(routeLocaleSymbol);
6
12
  if (!routeLocale) {
@@ -9,6 +15,6 @@ export const useRouteLocale = () => {
9
15
  return routeLocale;
10
16
  };
11
17
  /**
12
- * Resolve locale path of the route path
18
+ * Resolve locale path according to route path and locales config
13
19
  */
14
20
  export const resolveRouteLocale = (locales, routePath) => resolveLocalePath(locales, routePath);
@@ -1,6 +1,15 @@
1
- import type { Ref } from 'vue';
2
1
  import type { SiteData } from '@vuepress/shared';
2
+ import type { Ref } from 'vue';
3
3
  export type { SiteData };
4
+ /**
5
+ * Ref wrapper of `SiteData`
6
+ */
4
7
  export declare type SiteDataRef = Ref<SiteData>;
8
+ /**
9
+ * Global site data ref
10
+ */
5
11
  export declare const siteData: SiteDataRef;
12
+ /**
13
+ * Returns the ref of the site data
14
+ */
6
15
  export declare const useSiteData: () => SiteDataRef;
@@ -1,6 +1,12 @@
1
- import { ref } from 'vue';
2
1
  import { siteData as siteDataRaw } from '@internal/siteData';
2
+ import { ref } from 'vue';
3
+ /**
4
+ * Global site data ref
5
+ */
3
6
  export const siteData = ref(siteDataRaw);
7
+ /**
8
+ * Returns the ref of the site data
9
+ */
4
10
  export const useSiteData = () => siteData;
5
11
  if (import.meta.webpackHot || import.meta.hot) {
6
12
  // reuse vue HMR runtime
@@ -1,12 +1,25 @@
1
- import type { ComputedRef, InjectionKey } from 'vue';
2
1
  import type { SiteData } from '@vuepress/shared';
2
+ import type { ComputedRef, InjectionKey } from 'vue';
3
3
  import type { RouteLocale } from './routeLocale';
4
+ /**
5
+ * Site data of current locale
6
+ */
4
7
  export declare type SiteLocaleData = SiteData;
8
+ /**
9
+ * Ref wrapper of `SiteLocaleData`
10
+ */
5
11
  export declare type SiteLocaleDataRef = ComputedRef<SiteLocaleData>;
12
+ /**
13
+ * Injection key for site locale data
14
+ */
6
15
  export declare const siteLocaleDataSymbol: InjectionKey<SiteLocaleDataRef>;
16
+ /**
17
+ * Returns the ref of the site data of current locale
18
+ */
7
19
  export declare const useSiteLocaleData: () => SiteLocaleDataRef;
8
20
  /**
9
- * Merge the locales fields to the root fields
10
- * according to the route path
21
+ * Resolve site data for specific locale
22
+ *
23
+ * It would merge the locales fields to the root fields
11
24
  */
12
25
  export declare const resolveSiteLocaleData: (site: SiteData, routeLocale: RouteLocale) => SiteLocaleData;
@@ -1,5 +1,11 @@
1
1
  import { inject } from 'vue';
2
- export const siteLocaleDataSymbol = Symbol(__DEV__ ? 'siteLocaleData' : '');
2
+ /**
3
+ * Injection key for site locale data
4
+ */
5
+ export const siteLocaleDataSymbol = Symbol(__VUEPRESS_DEV__ ? 'siteLocaleData' : '');
6
+ /**
7
+ * Returns the ref of the site data of current locale
8
+ */
3
9
  export const useSiteLocaleData = () => {
4
10
  const siteLocaleData = inject(siteLocaleDataSymbol);
5
11
  if (!siteLocaleData) {
@@ -8,8 +14,9 @@ export const useSiteLocaleData = () => {
8
14
  return siteLocaleData;
9
15
  };
10
16
  /**
11
- * Merge the locales fields to the root fields
12
- * according to the route path
17
+ * Resolve site data for specific locale
18
+ *
19
+ * It would merge the locales fields to the root fields
13
20
  */
14
21
  export const resolveSiteLocaleData = (site, routeLocale) => ({
15
22
  ...site,
@@ -0,0 +1,26 @@
1
+ import type { HeadConfig } from '@vuepress/shared';
2
+ import type { InjectionKey } from 'vue';
3
+ /**
4
+ * A util function to force update `<head>` of current page
5
+ */
6
+ export declare type UpdateHead = () => void;
7
+ /**
8
+ * Injection key for `updateHead` util
9
+ */
10
+ export declare const updateHeadSymbol: InjectionKey<UpdateHead>;
11
+ /**
12
+ * Returns the `updateHead` util
13
+ */
14
+ export declare const useUpdateHead: () => UpdateHead;
15
+ /**
16
+ * Auto update head and provide as global util in setup
17
+ */
18
+ export declare const setupUpdateHead: () => void;
19
+ /**
20
+ * Query the matched head tag of head config
21
+ */
22
+ export declare const queryHeadTag: ([tagName, attrs, content,]: HeadConfig) => HTMLElement | null;
23
+ /**
24
+ * Create head tag from head config
25
+ */
26
+ export declare const createHeadTag: ([tagName, attrs, content,]: HeadConfig) => HTMLElement | null;
@@ -1,63 +1,31 @@
1
- import { onMounted, ref, useSSRContext, watch } from 'vue';
2
- import { useRoute } from 'vue-router';
3
1
  import { isPlainObject, isString } from '@vuepress/shared';
2
+ import { inject, onMounted, provide, ref, useSSRContext, watch } from 'vue';
3
+ import { useRoute } from 'vue-router';
4
4
  import { usePageHead } from './pageHead';
5
5
  import { usePageLang } from './pageLang';
6
6
  /**
7
- * Query the matched head tag of head config
7
+ * Injection key for `updateHead` util
8
8
  */
9
- export const queryHeadTag = ([tagName, attrs, content = '',]) => {
10
- const attrsSelector = Object.entries(attrs).map(([key, value]) => {
11
- if (isString(value)) {
12
- return `[${key}="${value}"]`;
13
- }
14
- if (value === true) {
15
- return `[${key}]`;
16
- }
17
- return '';
18
- });
19
- const selector = `head > ${tagName}${attrsSelector}`;
20
- const tags = Array.from(document.querySelectorAll(selector));
21
- const matchedTag = tags.find((item) => item.innerText === content);
22
- return matchedTag || null;
23
- };
9
+ export const updateHeadSymbol = Symbol(__VUEPRESS_DEV__ ? 'updateHead' : '');
24
10
  /**
25
- * Create head tag from head config
11
+ * Returns the `updateHead` util
26
12
  */
27
- export const createHeadTag = ([tagName, attrs, content,]) => {
28
- if (!isString(tagName)) {
29
- return null;
30
- }
31
- // create element
32
- const tag = document.createElement(tagName);
33
- // set attributes
34
- if (isPlainObject(attrs)) {
35
- Object.entries(attrs).forEach(([key, value]) => {
36
- if (isString(value)) {
37
- tag.setAttribute(key, value);
38
- }
39
- else if (value === true) {
40
- tag.setAttribute(key, '');
41
- }
42
- });
43
- }
44
- // set content
45
- if (isString(content)) {
46
- tag.appendChild(document.createTextNode(content));
13
+ export const useUpdateHead = () => {
14
+ const updateHead = inject(updateHeadSymbol);
15
+ if (!updateHead) {
16
+ throw new Error('useUpdateHead() is called without provider.');
47
17
  }
48
- return tag;
18
+ return updateHead;
49
19
  };
50
20
  /**
51
- * Auto update head
52
- *
53
- * This composable function should be used only once in the root app
21
+ * Auto update head and provide as global util in setup
54
22
  */
55
- export const useUpdateHead = () => {
23
+ export const setupUpdateHead = () => {
56
24
  const route = useRoute();
57
25
  const head = usePageHead();
58
26
  const lang = usePageLang();
59
27
  // ssr-only, extract page meta info to ssrContext
60
- if (__SSR__) {
28
+ if (__VUEPRESS_SSR__) {
61
29
  const ssrContext = useSSRContext();
62
30
  if (ssrContext) {
63
31
  ssrContext.head = head.value;
@@ -92,6 +60,7 @@ export const useUpdateHead = () => {
92
60
  }
93
61
  });
94
62
  };
63
+ provide(updateHeadSymbol, updateHead);
95
64
  onMounted(() => {
96
65
  loadHead();
97
66
  updateHead();
@@ -99,3 +68,49 @@ export const useUpdateHead = () => {
99
68
  watch(() => route.path, () => updateHead());
100
69
  });
101
70
  };
71
+ /**
72
+ * Query the matched head tag of head config
73
+ */
74
+ export const queryHeadTag = ([tagName, attrs, content = '',]) => {
75
+ const attrsSelector = Object.entries(attrs)
76
+ .map(([key, value]) => {
77
+ if (isString(value)) {
78
+ return `[${key}="${value}"]`;
79
+ }
80
+ if (value === true) {
81
+ return `[${key}]`;
82
+ }
83
+ return '';
84
+ })
85
+ .join('');
86
+ const selector = `head > ${tagName}${attrsSelector}`;
87
+ const tags = Array.from(document.querySelectorAll(selector));
88
+ const matchedTag = tags.find((item) => item.innerText === content);
89
+ return matchedTag || null;
90
+ };
91
+ /**
92
+ * Create head tag from head config
93
+ */
94
+ export const createHeadTag = ([tagName, attrs, content,]) => {
95
+ if (!isString(tagName)) {
96
+ return null;
97
+ }
98
+ // create element
99
+ const tag = document.createElement(tagName);
100
+ // set attributes
101
+ if (isPlainObject(attrs)) {
102
+ Object.entries(attrs).forEach(([key, value]) => {
103
+ if (isString(value)) {
104
+ tag.setAttribute(key, value);
105
+ }
106
+ else if (value === true) {
107
+ tag.setAttribute(key, '');
108
+ }
109
+ });
110
+ }
111
+ // set content
112
+ if (isString(content)) {
113
+ tag.appendChild(document.createTextNode(content));
114
+ }
115
+ return tag;
116
+ };
package/lib/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
+ export type { PageHeader } from '@vuepress/shared';
2
+ export { useRoute, useRouter } from 'vue-router';
1
3
  export * from './app';
2
4
  export * from './components';
3
- export * from './injections';
5
+ export * from './composables';
4
6
  export * from './types';
5
7
  export * from './utils';
6
- export type { PageHeader } from '@vuepress/shared';
package/lib/index.js CHANGED
@@ -1,5 +1,6 @@
1
+ export { useRoute, useRouter } from 'vue-router';
1
2
  export * from './app';
2
3
  export * from './components';
3
- export * from './injections';
4
+ export * from './composables';
4
5
  export * from './types';
5
6
  export * from './utils';
@@ -0,0 +1,20 @@
1
+ import type { App } from 'vue';
2
+ import type { Router } from 'vue-router';
3
+ import type { PageData, PageFrontmatter, PageHeadTitle, PageLang, RouteLocale, SiteData, SiteLocaleData } from './composables';
4
+ import { withBase } from './utils';
5
+ /**
6
+ * Create and provide global computed
7
+ */
8
+ export declare const provideGlobalComputed: (app: App, router: Router) => void;
9
+ declare module '@vue/runtime-core' {
10
+ interface ComponentCustomProperties {
11
+ $frontmatter: PageFrontmatter;
12
+ $headTitle: PageHeadTitle;
13
+ $lang: PageLang;
14
+ $page: PageData;
15
+ $routeLocale: RouteLocale;
16
+ $site: SiteData;
17
+ $siteLocale: SiteLocaleData;
18
+ $withBase: typeof withBase;
19
+ }
20
+ }
@@ -0,0 +1,33 @@
1
+ import { computed } from 'vue';
2
+ import { pageData, pageFrontmatterSymbol, pageHeadSymbol, pageHeadTitleSymbol, pageLangSymbol, resolvePageFrontmatter, resolvePageHead, resolvePageHeadTitle, resolvePageLang, resolveRouteLocale, resolveSiteLocaleData, routeLocaleSymbol, siteData, siteLocaleDataSymbol, } from './composables';
3
+ import { withBase } from './utils';
4
+ /**
5
+ * Create and provide global computed
6
+ */
7
+ export const provideGlobalComputed = (app, router) => {
8
+ // create global computed
9
+ const routeLocale = computed(() => resolveRouteLocale(siteData.value.locales, router.currentRoute.value.path));
10
+ const siteLocaleData = computed(() => resolveSiteLocaleData(siteData.value, routeLocale.value));
11
+ const pageFrontmatter = computed(() => resolvePageFrontmatter(pageData.value));
12
+ const pageHeadTitle = computed(() => resolvePageHeadTitle(pageData.value, siteLocaleData.value));
13
+ const pageHead = computed(() => resolvePageHead(pageHeadTitle.value, pageFrontmatter.value, siteLocaleData.value));
14
+ const pageLang = computed(() => resolvePageLang(pageData.value));
15
+ // provide global computed
16
+ app.provide(routeLocaleSymbol, routeLocale);
17
+ app.provide(siteLocaleDataSymbol, siteLocaleData);
18
+ app.provide(pageFrontmatterSymbol, pageFrontmatter);
19
+ app.provide(pageHeadTitleSymbol, pageHeadTitle);
20
+ app.provide(pageHeadSymbol, pageHead);
21
+ app.provide(pageLangSymbol, pageLang);
22
+ // provide global helpers
23
+ Object.defineProperties(app.config.globalProperties, {
24
+ $frontmatter: { get: () => pageFrontmatter.value },
25
+ $headTitle: { get: () => pageHeadTitle.value },
26
+ $lang: { get: () => pageLang.value },
27
+ $page: { get: () => pageData.value },
28
+ $routeLocale: { get: () => routeLocale.value },
29
+ $site: { get: () => siteData.value },
30
+ $siteLocale: { get: () => siteLocaleData.value },
31
+ $withBase: { get: () => withBase },
32
+ });
33
+ };
@@ -0,0 +1,5 @@
1
+ import type { App } from 'vue';
2
+ /**
3
+ * Register global built-in components
4
+ */
5
+ export declare const registerGlobalComponents: (app: App) => void;
@@ -0,0 +1,11 @@
1
+ import { ClientOnly, Content, OutboundLink } from './components';
2
+ /**
3
+ * Register global built-in components
4
+ */
5
+ export const registerGlobalComponents = (app) => {
6
+ /* eslint-disable vue/match-component-file-name */
7
+ app.component('ClientOnly', ClientOnly);
8
+ app.component('Content', Content);
9
+ app.component('OutboundLink', OutboundLink);
10
+ /* eslint-enable vue/match-component-file-name */
11
+ };
@@ -1,6 +1,6 @@
1
1
  import type { App } from 'vue';
2
2
  import type { Router } from 'vue-router';
3
- import type { SiteDataRef } from '../injections';
3
+ import type { SiteDataRef } from '../composables';
4
4
  export declare type ClientAppEnhance = (context: {
5
5
  app: App;
6
6
  router: Router;
@@ -1,5 +1,5 @@
1
1
  import { isLinkHttp, removeLeadingSlash } from '@vuepress/shared';
2
- import { useSiteData } from '../injections';
2
+ import { useSiteData } from '../composables';
3
3
  /**
4
4
  * Prefix url with site base
5
5
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuepress/client",
3
- "version": "2.0.0-beta.24",
3
+ "version": "2.0.0-beta.28",
4
4
  "description": "Client package of VuePress",
5
5
  "keywords": [
6
6
  "vuepress",
@@ -29,16 +29,16 @@
29
29
  "copy": "cpx \"src/**/*.{d.ts,css}\" lib"
30
30
  },
31
31
  "dependencies": {
32
- "@vuepress/shared": "2.0.0-beta.24",
33
- "vue": "^3.2.2",
34
- "vue-router": "^4.0.10"
32
+ "@vuepress/shared": "2.0.0-beta.28",
33
+ "vue": "^3.2.24",
34
+ "vue-router": "^4.0.12"
35
35
  },
36
36
  "devDependencies": {
37
- "@types/webpack-env": "^1.16.2",
38
- "vite": "^2.4.4"
37
+ "@types/webpack-env": "^1.16.3",
38
+ "vite": "^2.7.1"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"
42
42
  },
43
- "gitHead": "dd9588128c4b8e62bb96ed8581322e8901e22b90"
43
+ "gitHead": "71c34816a79263c7dcba3ff0c103e264abdbf0d2"
44
44
  }
package/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare const __VERSION__: string
2
- declare const __DEV__: boolean
3
- declare const __SSR__: boolean
1
+ declare const __VUEPRESS_VERSION__: string
2
+ declare const __VUEPRESS_DEV__: boolean
3
+ declare const __VUEPRESS_SSR__: boolean
4
4
  declare const __VUE_HMR_RUNTIME__: Record<string, any>
@@ -1,15 +0,0 @@
1
- import type { HeadConfig } from '@vuepress/shared';
2
- /**
3
- * Query the matched head tag of head config
4
- */
5
- export declare const queryHeadTag: ([tagName, attrs, content,]: HeadConfig) => HTMLElement | null;
6
- /**
7
- * Create head tag from head config
8
- */
9
- export declare const createHeadTag: ([tagName, attrs, content,]: HeadConfig) => HTMLElement | null;
10
- /**
11
- * Auto update head
12
- *
13
- * This composable function should be used only once in the root app
14
- */
15
- export declare const useUpdateHead: () => void;