@brillout/docpress 0.13.2 → 0.15.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.
- package/+config.ts +11 -16
- package/EditLink.tsx +1 -1
- package/ExternalLinks.tsx +8 -16
- package/Layout.tsx +26 -26
- package/MenuModal.tsx +1 -1
- package/NavItemComponent.tsx +1 -1
- package/components/Link.tsx +4 -4
- package/components/RepoLink.tsx +2 -3
- package/{renderer/determineNavItemsColumnLayout.ts → determineNavItemsColumnLayout.ts} +2 -3
- package/dist/+config.d.ts +9 -20
- package/dist/+config.js +3 -11
- package/dist/NavItemComponent.js +1 -1
- package/dist/components/Link.js +1 -1
- package/dist/components/RepoLink.js +2 -3
- package/dist/{renderer/determineNavItemsColumnLayout.d.ts → determineNavItemsColumnLayout.d.ts} +1 -1
- package/dist/{renderer/determineNavItemsColumnLayout.js → determineNavItemsColumnLayout.js} +1 -2
- package/dist/parsePageSections.js +1 -1
- package/dist/renderer/usePageContext.d.ts +17 -10
- package/dist/renderer/usePageContext.js +11 -19
- package/dist/resolveConf.d.ts +19 -0
- package/dist/{config/resolveHeadingsData.js → resolveConf.js} +25 -30
- package/dist/types/Config.d.ts +19 -24
- package/dist/types/Heading.d.ts +9 -14
- package/docsearch/DocSearchInstall.tsx +1 -1
- package/index.ts +5 -1
- package/installSectionUrlHashs.ts +1 -0
- package/package.json +7 -9
- package/parsePageSections.ts +1 -1
- package/renderer/getPageElement.tsx +7 -15
- package/renderer/onCreatePageContext.ts +8 -0
- package/renderer/onRenderClient.tsx +2 -8
- package/renderer/onRenderHtml.tsx +56 -29
- package/renderer/usePageContext.tsx +12 -28
- package/{config/resolveHeadingsData.ts → resolveConf.ts} +31 -53
- package/tsconfig.config.json +1 -4
- package/tsconfig.json +1 -0
- package/types/Config.ts +24 -24
- package/types/Heading.ts +13 -20
- package/config/resolveConfig/resolveHeading.ts +0 -0
- package/config/resolvePageContext.ts +0 -49
- package/dist/config/resolveHeadingsData.d.ts +0 -24
- package/dist/config/resolvePageContext.d.ts +0 -41
- package/dist/config/resolvePageContext.js +0 -25
- package/renderer/onBeforeRender.ts +0 -12
|
@@ -18,15 +18,17 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
18
18
|
}
|
|
19
19
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
20
20
|
};
|
|
21
|
-
export {
|
|
22
|
-
import { assert
|
|
21
|
+
export { resolveConf };
|
|
22
|
+
import { assert } from './utils/assert';
|
|
23
|
+
import { jsxToTextContent } from './utils/jsxToTextContent';
|
|
23
24
|
import pc from '@brillout/picocolors';
|
|
24
|
-
import { parseMarkdownMini } from '
|
|
25
|
-
import { determineNavItemsColumnLayout } from '
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
var
|
|
29
|
-
var
|
|
25
|
+
import { parseMarkdownMini } from './parseMarkdownMini';
|
|
26
|
+
import { determineNavItemsColumnLayout } from './determineNavItemsColumnLayout';
|
|
27
|
+
function resolveConf(pageContext) {
|
|
28
|
+
var _a;
|
|
29
|
+
var config = pageContext.globalContext.config.docpress;
|
|
30
|
+
var urlPathname = pageContext.urlPathname;
|
|
31
|
+
var pageSections = (_a = pageContext.config.pageSectionsExport) !== null && _a !== void 0 ? _a : [];
|
|
30
32
|
{
|
|
31
33
|
var headings = config.headings, headingsDetached = config.headingsDetached;
|
|
32
34
|
assertHeadingsDefinition(__spreadArray(__spreadArray([], headings, true), headingsDetached, true));
|
|
@@ -34,10 +36,12 @@ function resolveHeadingsData(pageContext) {
|
|
|
34
36
|
var resolved = getHeadingsResolved(config);
|
|
35
37
|
var headingsDetachedResolved = resolved.headingsDetachedResolved;
|
|
36
38
|
var headingsResolved = resolved.headingsResolved;
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var pageSectionsResolved = getPageSectionsResolved(
|
|
40
|
-
var
|
|
39
|
+
var _b = getActiveHeading(headingsResolved, headingsDetachedResolved, urlPathname), activeHeading = _b.activeHeading, isDetachedPage = _b.isDetachedPage, activeCategoryName = _b.activeCategoryName;
|
|
40
|
+
var _c = getTitles(activeHeading, urlPathname, config), documentTitle = _c.documentTitle, isLandingPage = _c.isLandingPage, pageTitle = _c.pageTitle;
|
|
41
|
+
var pageSectionsResolved = getPageSectionsResolved(pageSections, activeHeading);
|
|
42
|
+
var linksGlobal = __spreadArray(__spreadArray([], headingsResolved.map(headingToLinkData), true), headingsDetachedResolved.map(headingToLinkData), true);
|
|
43
|
+
var linksPage = pageSectionsResolved.map(pageSectionToLinkData);
|
|
44
|
+
var linksAll = __spreadArray(__spreadArray([], linksPage, true), linksGlobal, true);
|
|
41
45
|
var navItemsAll;
|
|
42
46
|
var navItemsDetached;
|
|
43
47
|
{
|
|
@@ -50,18 +54,14 @@ function resolveHeadingsData(pageContext) {
|
|
|
50
54
|
navItemsDetached = __spreadArray([headingToNavItem(activeHeading)], navItemsPageSections, true);
|
|
51
55
|
}
|
|
52
56
|
else {
|
|
53
|
-
var activeHeadingIndex_1 = navItemsAll.findIndex(function (navItem) { return navItem.url ===
|
|
57
|
+
var activeHeadingIndex_1 = navItemsAll.findIndex(function (navItem) { return navItem.url === urlPathname; });
|
|
54
58
|
assert(activeHeadingIndex_1 >= 0);
|
|
55
59
|
navItemsPageSections.forEach(function (navItem, i) {
|
|
56
60
|
navItemsAll.splice(activeHeadingIndex_1 + 1 + i, 0, navItem);
|
|
57
61
|
});
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
|
-
var
|
|
61
|
-
name: activeCategoryName,
|
|
62
|
-
order: 99999999999,
|
|
63
|
-
};
|
|
64
|
-
var pageContextAddendum = {
|
|
64
|
+
var conf = {
|
|
65
65
|
navItemsAll: navItemsAll,
|
|
66
66
|
navItemsDetached: navItemsDetached,
|
|
67
67
|
pageDesign: activeHeading.pageDesign,
|
|
@@ -69,10 +69,9 @@ function resolveHeadingsData(pageContext) {
|
|
|
69
69
|
isLandingPage: isLandingPage,
|
|
70
70
|
pageTitle: pageTitle,
|
|
71
71
|
documentTitle: documentTitle,
|
|
72
|
-
|
|
73
|
-
activeCategory: activeCategory,
|
|
72
|
+
activeCategoryName: activeCategoryName,
|
|
74
73
|
};
|
|
75
|
-
return
|
|
74
|
+
return conf;
|
|
76
75
|
}
|
|
77
76
|
function headingToNavItem(heading) {
|
|
78
77
|
return {
|
|
@@ -109,26 +108,24 @@ function pageSectionToLinkData(pageSection) {
|
|
|
109
108
|
linkBreadcrumb: pageSection.linkBreadcrumb,
|
|
110
109
|
};
|
|
111
110
|
}
|
|
112
|
-
function getTitles(activeHeading,
|
|
113
|
-
var
|
|
114
|
-
var isLandingPage = url === '/';
|
|
111
|
+
function getTitles(activeHeading, urlPathname, config) {
|
|
112
|
+
var isLandingPage = urlPathname === '/';
|
|
115
113
|
var title = activeHeading.title;
|
|
116
114
|
var pageTitle = isLandingPage ? null : title;
|
|
117
115
|
var documentTitle = activeHeading.titleDocument || jsxToTextContent(parseMarkdownMini(title));
|
|
118
116
|
if (!isLandingPage) {
|
|
119
|
-
documentTitle += ' | ' + config.
|
|
117
|
+
documentTitle += ' | ' + config.name;
|
|
120
118
|
}
|
|
121
119
|
if (isLandingPage) {
|
|
122
120
|
pageTitle = null;
|
|
123
121
|
}
|
|
124
122
|
return { documentTitle: documentTitle, isLandingPage: isLandingPage, pageTitle: pageTitle };
|
|
125
123
|
}
|
|
126
|
-
function getActiveHeading(headingsResolved, headingsDetachedResolved,
|
|
124
|
+
function getActiveHeading(headingsResolved, headingsDetachedResolved, urlPathname) {
|
|
127
125
|
var _a;
|
|
128
126
|
var activeHeading = null;
|
|
129
127
|
var activeCategoryName = 'Miscellaneous';
|
|
130
128
|
var headingCategory;
|
|
131
|
-
var urlPathname = pageContext.urlPathname;
|
|
132
129
|
assert(urlPathname);
|
|
133
130
|
for (var _i = 0, headingsResolved_1 = headingsResolved; _i < headingsResolved_1.length; _i++) {
|
|
134
131
|
var heading = headingsResolved_1[_i];
|
|
@@ -164,9 +161,7 @@ function getActiveHeading(headingsResolved, headingsDetachedResolved, pageContex
|
|
|
164
161
|
activeCategoryName = activeHeading.category;
|
|
165
162
|
return { activeHeading: activeHeading, isDetachedPage: isDetachedPage, activeCategoryName: activeCategoryName };
|
|
166
163
|
}
|
|
167
|
-
function getPageSectionsResolved(
|
|
168
|
-
var _a;
|
|
169
|
-
var pageSections = (_a = pageContext.exports.pageSectionsExport) !== null && _a !== void 0 ? _a : [];
|
|
164
|
+
function getPageSectionsResolved(pageSections, activeHeading) {
|
|
170
165
|
var pageSectionsResolved = pageSections.map(function (pageSection) {
|
|
171
166
|
var _a;
|
|
172
167
|
var pageSectionTitle = pageSection.pageSectionTitle;
|
package/dist/types/Config.d.ts
CHANGED
|
@@ -1,36 +1,31 @@
|
|
|
1
1
|
export type { Config };
|
|
2
2
|
import type { HeadingDefinition, HeadingDetachedDefinition } from './Heading';
|
|
3
3
|
type Config = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
name: string;
|
|
5
|
+
version: string;
|
|
6
|
+
url: string;
|
|
7
|
+
/** Sets `<meta name="description" content="${tagline}" />` */
|
|
8
|
+
tagline: string;
|
|
9
|
+
logo: string;
|
|
10
|
+
favicon?: string;
|
|
11
|
+
banner?: string;
|
|
12
|
+
github: string;
|
|
13
|
+
discord?: string;
|
|
14
|
+
twitter?: string;
|
|
15
|
+
bluesky?: string;
|
|
16
|
+
headings: HeadingDefinition[];
|
|
17
|
+
headingsDetached: HeadingDetachedDefinition[];
|
|
18
|
+
categories?: Category[];
|
|
19
|
+
algolia?: {
|
|
18
20
|
appId: string;
|
|
19
21
|
apiKey: string;
|
|
20
22
|
indexName: string;
|
|
21
23
|
};
|
|
22
|
-
headings: HeadingDefinition[];
|
|
23
|
-
headingsDetached: HeadingDetachedDefinition[];
|
|
24
|
-
categories?: Category[];
|
|
25
|
-
/** Sets `<meta name="description" content="${tagline}" />` */
|
|
26
|
-
tagline: string;
|
|
27
|
-
websiteUrl: string;
|
|
28
|
-
bannerUrl?: string;
|
|
29
|
-
twitterHandle: string;
|
|
30
|
-
globalNote?: React.ReactNode;
|
|
31
24
|
i18n?: true;
|
|
32
25
|
pressKit?: true;
|
|
33
|
-
|
|
26
|
+
docsDir?: string;
|
|
27
|
+
globalNote?: React.ReactNode;
|
|
28
|
+
topNavigation?: React.ReactNode;
|
|
34
29
|
navMaxWidth?: number;
|
|
35
30
|
navLogoSize?: number;
|
|
36
31
|
navLogoStyle?: React.CSSProperties;
|
package/dist/types/Heading.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ type HeadingResolved = {
|
|
|
15
15
|
color?: string;
|
|
16
16
|
titleIcon?: string;
|
|
17
17
|
titleIconStyle?: React.CSSProperties;
|
|
18
|
-
|
|
18
|
+
titleDocument?: string;
|
|
19
|
+
};
|
|
19
20
|
type PageDesign = {
|
|
20
21
|
hideTitle?: true;
|
|
21
22
|
hideMenuLeft?: true;
|
|
@@ -35,16 +36,7 @@ type HeadingDetachedDefinition = HeadingDefinitionCommon & {
|
|
|
35
36
|
sectionTitles?: string[];
|
|
36
37
|
category?: string;
|
|
37
38
|
};
|
|
38
|
-
type HeadingDefinition = HeadingDefinitionCommon & {
|
|
39
|
-
url?: null | string;
|
|
40
|
-
titleInNav?: string;
|
|
41
|
-
} & HeadingDefinitionLevel & Tmp;
|
|
42
|
-
type IsCategory = {
|
|
43
|
-
url?: undefined;
|
|
44
|
-
titleDocument?: undefined;
|
|
45
|
-
titleInNav?: undefined;
|
|
46
|
-
};
|
|
47
|
-
type HeadingDefinitionLevel = ({
|
|
39
|
+
type HeadingDefinition = HeadingDefinitionCommon & {} & (({
|
|
48
40
|
level: 1;
|
|
49
41
|
color: string;
|
|
50
42
|
titleIcon?: string;
|
|
@@ -53,9 +45,12 @@ type HeadingDefinitionLevel = ({
|
|
|
53
45
|
level: 4;
|
|
54
46
|
} & IsCategory) | {
|
|
55
47
|
level: 2;
|
|
48
|
+
titleInNav?: string;
|
|
49
|
+
titleDocument?: string;
|
|
56
50
|
sectionTitles?: string[];
|
|
57
51
|
url: null | string;
|
|
58
|
-
};
|
|
59
|
-
type
|
|
60
|
-
|
|
52
|
+
});
|
|
53
|
+
type IsCategory = {
|
|
54
|
+
url?: undefined;
|
|
55
|
+
titleInNav?: undefined;
|
|
61
56
|
};
|
|
@@ -7,7 +7,7 @@ import { Hit } from '../components/Algolia/Hit'
|
|
|
7
7
|
|
|
8
8
|
function DocSearchInstall() {
|
|
9
9
|
const pageContext = usePageContext()
|
|
10
|
-
const { algolia } = pageContext.
|
|
10
|
+
const { algolia } = pageContext.globalContext.config.docpress
|
|
11
11
|
if (!algolia) return null
|
|
12
12
|
return (
|
|
13
13
|
<div style={{ display: 'none' }}>
|
package/index.ts
CHANGED
|
@@ -8,7 +8,11 @@ export {
|
|
|
8
8
|
Emoji,
|
|
9
9
|
} from './components'
|
|
10
10
|
export { MenuToggle } from './Layout'
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
// The only place usePageContext() is used at:
|
|
13
|
+
// https://github.com/vikejs/vike/blob/0b1b109f64aafbed23a1c2ac2630e6146a270ec0/packages/vike.dev/components/CommunityNote.tsx#L4
|
|
14
|
+
export { usePageContext } from './renderer/usePageContext'
|
|
15
|
+
|
|
12
16
|
export * from './components/Note'
|
|
13
17
|
export * from './icons/index'
|
|
14
18
|
export { assert } from './utils/assert'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brillout/docpress",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@brillout/picocolors": "^1.0.10",
|
|
@@ -10,18 +10,18 @@
|
|
|
10
10
|
"@mdx-js/react": "3.0.1",
|
|
11
11
|
"@mdx-js/rollup": "3.0.1",
|
|
12
12
|
"@shikijs/transformers": "1.2.0",
|
|
13
|
-
"@vitejs/plugin-react-swc": "
|
|
13
|
+
"@vitejs/plugin-react-swc": "^3.10.2",
|
|
14
14
|
"rehype-pretty-code": "0.13.0",
|
|
15
15
|
"remark-gfm": "4.0.0",
|
|
16
16
|
"shiki": "1.2.0",
|
|
17
|
-
"vite": "
|
|
17
|
+
"vite": "^6.3.5"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@vitejs/plugin-react-swc": ">=3.0.0",
|
|
21
21
|
"react": ">=18.0.0",
|
|
22
22
|
"react-dom": ">=18.0.0",
|
|
23
23
|
"typescript": ">=5.0.0",
|
|
24
|
-
"vike": ">=0.4.
|
|
24
|
+
"vike": ">=0.4.234",
|
|
25
25
|
"vite": ">=5.2.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependenciesMeta": {
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
"exports": {
|
|
36
36
|
"./renderer/onRenderHtml": "./renderer/onRenderHtml.tsx",
|
|
37
37
|
"./renderer/onRenderClient": "./renderer/onRenderClient.tsx",
|
|
38
|
-
"./renderer/
|
|
39
|
-
"./Layout": "./Layout.tsx",
|
|
38
|
+
"./renderer/onCreatePageContext": "./renderer/onCreatePageContext.ts",
|
|
40
39
|
".": "./index.ts",
|
|
41
40
|
"./config": "./dist/+config.js",
|
|
42
41
|
"./style": "./css/index.css",
|
|
@@ -73,9 +72,8 @@
|
|
|
73
72
|
"// Build vite.config.ts and +config.ts (other files don't need to be built as @brillout/docpress is noExternal)": "",
|
|
74
73
|
"build": "rm -rf dist/ && tsc --project tsconfig.config.json",
|
|
75
74
|
"======== Develop": "",
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"typecheck": "tsc --noEmit --watch",
|
|
75
|
+
"// Typecheck + build vite.config.ts and +config.ts": "",
|
|
76
|
+
"dev": "tsc --watch",
|
|
79
77
|
"========= Release": "",
|
|
80
78
|
"release": "release-me patch",
|
|
81
79
|
"release:minor": "release-me minor",
|
package/parsePageSections.ts
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
export { getPageElement }
|
|
2
2
|
|
|
3
3
|
import type { PageContext } from 'vike/types'
|
|
4
|
-
import
|
|
5
|
-
import { PageContextProvider, PageContextProvider2 } from './usePageContext'
|
|
4
|
+
import { PageContextProvider } from './usePageContext'
|
|
6
5
|
import React from 'react'
|
|
7
6
|
import { DocSearchInstall } from '../docsearch/DocSearchInstall'
|
|
8
|
-
import {
|
|
7
|
+
import { Layout } from '../Layout'
|
|
9
8
|
|
|
10
|
-
function getPageElement(pageContext: PageContext
|
|
9
|
+
function getPageElement(pageContext: PageContext) {
|
|
11
10
|
const { Page } = pageContext
|
|
12
|
-
const Layout = pageContext.config.Layout || PassThrough
|
|
13
11
|
const page = (
|
|
14
|
-
<Wrapper {...{ pageContext
|
|
15
|
-
<Layout
|
|
12
|
+
<Wrapper {...{ pageContext }}>
|
|
13
|
+
<Layout>
|
|
16
14
|
<Page />
|
|
17
15
|
</Layout>
|
|
18
16
|
<DocSearchInstall />
|
|
@@ -21,16 +19,10 @@ function getPageElement(pageContext: PageContext, pageContextResolved: PageConte
|
|
|
21
19
|
return page
|
|
22
20
|
}
|
|
23
21
|
|
|
24
|
-
function Wrapper({
|
|
25
|
-
children,
|
|
26
|
-
pageContext,
|
|
27
|
-
pageContextResolved,
|
|
28
|
-
}: { children: React.ReactNode; pageContext: PageContext; pageContextResolved: PageContextResolved }) {
|
|
22
|
+
function Wrapper({ children, pageContext }: { children: React.ReactNode; pageContext: PageContext }) {
|
|
29
23
|
return (
|
|
30
24
|
<React.StrictMode>
|
|
31
|
-
<
|
|
32
|
-
<PageContextProvider pageContext={pageContextResolved}>{children}</PageContextProvider>
|
|
33
|
-
</PageContextProvider2>
|
|
25
|
+
<PageContextProvider pageContext={pageContext}>{children}</PageContextProvider>
|
|
34
26
|
</React.StrictMode>
|
|
35
27
|
)
|
|
36
28
|
}
|
|
@@ -3,7 +3,6 @@ export { onRenderClient }
|
|
|
3
3
|
import React, { useEffect } from 'react'
|
|
4
4
|
import type { PageContextClient } from 'vike/types'
|
|
5
5
|
import ReactDOM from 'react-dom/client'
|
|
6
|
-
import { PageContextResolved } from '../config/resolvePageContext'
|
|
7
6
|
import { getPageElement } from './getPageElement'
|
|
8
7
|
import { closeMenuModal } from '../MenuModal/toggleMenuModal'
|
|
9
8
|
import '../css/index.css'
|
|
@@ -25,13 +24,11 @@ initOnNavigation()
|
|
|
25
24
|
async function onRenderClient(pageContext: PageContextClient) {
|
|
26
25
|
onRenderStart()
|
|
27
26
|
|
|
28
|
-
// TODO: stop using any
|
|
29
|
-
const pageContextResolved: PageContextResolved = (pageContext as any).pageContextResolved
|
|
30
27
|
let renderPromiseResolve!: () => void
|
|
31
28
|
const renderPromise = new Promise<void>((r) => {
|
|
32
29
|
renderPromiseResolve = r
|
|
33
30
|
})
|
|
34
|
-
let page = getPageElement(pageContext
|
|
31
|
+
let page = getPageElement(pageContext)
|
|
35
32
|
page = <OnRenderDoneHook renderPromiseResolve={renderPromiseResolve}>{page}</OnRenderDoneHook>
|
|
36
33
|
const container = document.getElementById('page-view')!
|
|
37
34
|
if (pageContext.isHydration) {
|
|
@@ -49,9 +46,7 @@ async function onRenderClient(pageContext: PageContextClient) {
|
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
function applyHead(pageContext: PageContextClient) {
|
|
52
|
-
|
|
53
|
-
const pageContextResolved: PageContextResolved = (pageContext as any).pageContextResolved
|
|
54
|
-
document.title = pageContextResolved.documentTitle
|
|
49
|
+
document.title = pageContext.conf.documentTitle
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
function onRenderStart() {
|
|
@@ -61,7 +56,6 @@ function onRenderStart() {
|
|
|
61
56
|
|
|
62
57
|
function onRenderDone(renderPromiseResolve: () => void) {
|
|
63
58
|
autoScrollNav()
|
|
64
|
-
// TODO/refactor: use React?
|
|
65
59
|
installSectionUrlHashs()
|
|
66
60
|
setHydrationIsFinished()
|
|
67
61
|
renderPromiseResolve()
|
|
@@ -2,38 +2,37 @@ export { onRenderHtml }
|
|
|
2
2
|
|
|
3
3
|
import ReactDOMServer from 'react-dom/server'
|
|
4
4
|
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
|
|
5
|
-
import { assert } from '../utils/server'
|
|
6
|
-
import type { PageContextResolved } from '../config/resolvePageContext'
|
|
5
|
+
import { assert, assertUsage } from '../utils/server'
|
|
7
6
|
import { getPageElement } from './getPageElement'
|
|
8
|
-
import type {
|
|
9
|
-
import {
|
|
7
|
+
import type { PageContextServer } from 'vike/types'
|
|
8
|
+
import type { Config } from '../types/Config'
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
pageContext
|
|
13
|
-
): // TODO: Why is Promise<Awaited<>> needed?
|
|
14
|
-
Promise<Awaited<ReturnType<OnRenderHtmlAsync>>> => {
|
|
15
|
-
const pageContextResolved: PageContextResolved = (pageContext as any).pageContextResolved
|
|
10
|
+
async function onRenderHtml(pageContext: PageContextServer): Promise<any> {
|
|
11
|
+
const page = getPageElement(pageContext)
|
|
16
12
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
const { isLandingPage } = pageContext.conf
|
|
14
|
+
assert(typeof isLandingPage === 'boolean')
|
|
15
|
+
const { tagline } = pageContext.globalContext.config.docpress
|
|
16
|
+
assert(tagline)
|
|
17
|
+
const descriptionTag = isLandingPage ? escapeInject`<meta name="description" content="${tagline}" />` : ''
|
|
22
18
|
|
|
23
19
|
const pageHtml = ReactDOMServer.renderToString(page)
|
|
24
20
|
|
|
25
|
-
const faviconUrl =
|
|
21
|
+
const faviconUrl = pageContext.globalContext.config.docpress.favicon ?? pageContext.globalContext.config.docpress.logo
|
|
22
|
+
assert(faviconUrl)
|
|
26
23
|
|
|
24
|
+
const { documentTitle } = pageContext.conf
|
|
25
|
+
assert(documentTitle)
|
|
27
26
|
return escapeInject`<!DOCTYPE html>
|
|
28
27
|
<html>
|
|
29
28
|
<head>
|
|
30
29
|
<meta charset="UTF-8" />
|
|
31
30
|
<link rel="icon" href="${faviconUrl ?? ''}" />
|
|
32
|
-
<title>${
|
|
31
|
+
<title>${documentTitle}</title>
|
|
33
32
|
${descriptionTag}
|
|
34
33
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
35
|
-
${getOpenGraphTags(pageContext.urlPathname,
|
|
36
|
-
${getAlgoliaTags(
|
|
34
|
+
${getOpenGraphTags(pageContext.urlPathname, documentTitle, pageContext.globalContext.config.docpress)}
|
|
35
|
+
${getAlgoliaTags(pageContext)}
|
|
37
36
|
</head>
|
|
38
37
|
<body>
|
|
39
38
|
<div id="page-view">${dangerouslySkipEscape(pageHtml)}</div>
|
|
@@ -41,7 +40,8 @@ Promise<Awaited<ReturnType<OnRenderHtmlAsync>>> => {
|
|
|
41
40
|
</html>`
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
function getAlgoliaTags(
|
|
43
|
+
function getAlgoliaTags(pageContext: PageContextServer) {
|
|
44
|
+
const activeCategory = getActiveCategory(pageContext)
|
|
45
45
|
const categoryNameTag = escapeInject`<meta name="algolia:category" content="${activeCategory.name}">`
|
|
46
46
|
if (activeCategory.hide) {
|
|
47
47
|
return escapeInject`${categoryNameTag}<meta name="algolia:category:hide"> `
|
|
@@ -49,25 +49,52 @@ function getAlgoliaTags(activeCategory: ActiveCategory) {
|
|
|
49
49
|
return escapeInject`${categoryNameTag}<meta name="algolia:category:order" content="${activeCategory.order.toString()}"> `
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
type ActiveCategory = {
|
|
53
|
+
name: string
|
|
54
|
+
order: number
|
|
55
|
+
hide?: boolean
|
|
56
|
+
}
|
|
57
|
+
function getActiveCategory(pageContext: PageContextServer) {
|
|
58
|
+
const config = pageContext.globalContext.config.docpress
|
|
59
|
+
const { activeCategoryName } = pageContext.conf
|
|
52
60
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
const activeCategory: ActiveCategory = config.categories
|
|
62
|
+
// normalize
|
|
63
|
+
?.map((c, i) => ({
|
|
64
|
+
order: i,
|
|
65
|
+
...(typeof c === 'string' ? { name: c } : c),
|
|
66
|
+
}))
|
|
67
|
+
.find((c) => c.name === activeCategoryName) ?? {
|
|
68
|
+
name: activeCategoryName,
|
|
69
|
+
order: 99999999999,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return activeCategory
|
|
73
|
+
}
|
|
59
74
|
|
|
75
|
+
function getOpenGraphTags(url: string, documentTitle: string, config: Config) {
|
|
76
|
+
const { tagline, url: websiteUrl, twitter, banner } = config
|
|
60
77
|
assert(url.startsWith('/'))
|
|
61
|
-
|
|
78
|
+
assertUsage(!twitter || twitter.startsWith('@'), `twitter handle must start with @`)
|
|
62
79
|
|
|
80
|
+
const metaBanner = !banner
|
|
81
|
+
? ''
|
|
82
|
+
: escapeInject`
|
|
83
|
+
<meta property="og:image" content="${banner}">
|
|
84
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
85
|
+
`
|
|
86
|
+
const metaTwitter = !twitter
|
|
87
|
+
? ''
|
|
88
|
+
: escapeInject`
|
|
89
|
+
<meta name="twitter:site" content="${twitter}">
|
|
90
|
+
`
|
|
63
91
|
// See view-source:https://vitejs.dev/
|
|
64
92
|
return escapeInject`
|
|
65
93
|
<meta property="og:type" content="website">
|
|
66
94
|
<meta property="og:title" content="${documentTitle}">
|
|
67
|
-
<meta property="og:image" content="${bannerUrl}">
|
|
68
95
|
<meta property="og:url" content="${websiteUrl}">
|
|
69
96
|
<meta property="og:description" content="${tagline}">
|
|
70
|
-
|
|
71
|
-
|
|
97
|
+
${metaBanner}
|
|
98
|
+
${metaTwitter}
|
|
72
99
|
`
|
|
73
100
|
}
|
|
@@ -1,48 +1,32 @@
|
|
|
1
|
-
export { usePageContext }
|
|
2
1
|
export { PageContextProvider }
|
|
2
|
+
export { usePageContext }
|
|
3
|
+
export { usePageContextLegacy }
|
|
3
4
|
|
|
4
5
|
import React, { useContext } from 'react'
|
|
5
|
-
import type { PageContextResolved } from '../config/resolvePageContext'
|
|
6
6
|
import type { PageContext } from 'vike/types'
|
|
7
7
|
import { getGlobalObject } from '../utils/getGlobalObject'
|
|
8
8
|
|
|
9
9
|
const globalObject = getGlobalObject('usePageContext.ts', {
|
|
10
|
-
|
|
11
|
-
Context2: React.createContext<PageContext>(undefined as any),
|
|
10
|
+
Ctx: React.createContext<PageContext>(undefined as any),
|
|
12
11
|
})
|
|
13
12
|
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
pageContext: PageContextResolved
|
|
19
|
-
children: React.ReactNode
|
|
20
|
-
}) {
|
|
21
|
-
const { Context } = globalObject
|
|
22
|
-
return <Context.Provider value={pageContext}>{children}</Context.Provider>
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function usePageContext(): PageContextResolved {
|
|
26
|
-
const { Context } = globalObject
|
|
27
|
-
const pageContext = useContext(Context)
|
|
28
|
-
return pageContext
|
|
13
|
+
function usePageContextLegacy() {
|
|
14
|
+
const { Ctx } = globalObject
|
|
15
|
+
const pageContext = useContext(Ctx)
|
|
16
|
+
return pageContext.conf
|
|
29
17
|
}
|
|
30
18
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
export { usePageContext2 }
|
|
34
|
-
|
|
35
|
-
function usePageContext2(): PageContext {
|
|
36
|
-
const pageContext = useContext(globalObject.Context2)
|
|
19
|
+
function usePageContext(): PageContext {
|
|
20
|
+
const pageContext = useContext(globalObject.Ctx)
|
|
37
21
|
return pageContext
|
|
38
22
|
}
|
|
39
|
-
function
|
|
23
|
+
function PageContextProvider({
|
|
40
24
|
pageContext,
|
|
41
25
|
children,
|
|
42
26
|
}: {
|
|
43
27
|
pageContext: PageContext
|
|
44
28
|
children: React.ReactNode
|
|
45
29
|
}) {
|
|
46
|
-
const {
|
|
47
|
-
return <
|
|
30
|
+
const { Ctx } = globalObject
|
|
31
|
+
return <Ctx.Provider value={pageContext}>{children}</Ctx.Provider>
|
|
48
32
|
}
|