for-humanity 0.4.4 → 0.6.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/CHANGELOG.md +21 -0
- package/README.md +6 -5
- package/dist/browser.js +39 -0
- package/dist/cli.css +350 -262
- package/dist/cli.js +1174 -364
- package/package.json +8 -11
- package/src/component/widget/{shell → cursor-face}/_constant/cursor-face.ts +5 -0
- package/src/component/widget/cursor-face/wg-cursor-face.css +15 -0
- package/src/component/widget/cursor-face/wg-cursor-face.tsx +153 -0
- package/src/component/widget/navigation/_constant/navigation-data-schema.ts +35 -0
- package/src/component/widget/navigation/_constant/navigation.ts +9 -0
- package/src/component/widget/navigation/_function/restore-navigation-scroll.ts +59 -0
- package/src/{content → component/widget/navigation/_function}/to-doc-groups/_to-doc-branches.ts +2 -2
- package/src/{content → component/widget/navigation/_function}/to-doc-groups/_to-doc-group-branches.ts +3 -3
- package/src/{content → component/widget/navigation/_function}/to-doc-groups/to-doc-groups.ts +1 -1
- package/src/component/widget/navigation/_function/to-navigation-branch-id.ts +6 -0
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +14 -0
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +14 -0
- package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +25 -0
- package/src/component/widget/navigation/_function/to-navigation-json.ts +8 -0
- package/src/component/widget/{shell → navigation}/_function/to-toc-groups.ts +2 -2
- package/src/{type → component/widget/navigation/_type}/doc-group.ts +1 -1
- package/src/component/widget/navigation/_type/navigation-data.ts +83 -0
- package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +21 -0
- package/src/component/widget/navigation/_wg-navigation-branch-toggle.css +28 -0
- package/src/component/widget/navigation/_wg-navigation-branch-toggle.tsx +48 -0
- package/src/component/widget/{shell/_wg-shell-nav-list.css → navigation/_wg-navigation-nav-list.css} +24 -16
- package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +106 -0
- package/src/component/widget/{shell/_wg-shell-nav.css → navigation/_wg-navigation-nav.css} +9 -3
- package/src/component/widget/navigation/_wg-navigation-nav.tsx +43 -0
- package/src/component/widget/navigation/_wg-navigation-scroll.tsx +117 -0
- package/src/component/widget/{shell/_wg-shell-toc.css → navigation/_wg-navigation-toc.css} +39 -24
- package/src/component/widget/navigation/_wg-navigation-toc.tsx +155 -0
- package/src/component/widget/navigation/wg-navigation.css +282 -0
- package/src/component/widget/navigation/wg-navigation.tsx +479 -0
- package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +1 -1
- package/src/component/widget/shell/wg-shell.css +13 -269
- package/src/component/widget/shell/wg-shell.tsx +16 -97
- package/src/component/widget/shell-controls/wg-shell-controls.css +4 -0
- package/src/component/widget/shell-controls/wg-shell-controls.tsx +170 -0
- package/src/constant/asset.ts +0 -5
- package/src/constant/copy.ts +5 -0
- package/src/entry/browser/browser.tsx +22 -0
- package/src/entry/cli/_constant/crawling.ts +14 -0
- package/src/{app.tsx → entry/cli/_function/create-app.tsx} +6 -6
- package/src/{dev.ts → entry/cli/_function/create-dev-app.ts} +9 -1
- package/src/{content → entry/cli/_function/create-processor}/create-processor.ts +3 -3
- package/src/{content → entry/cli/_function}/read-docs.ts +21 -2
- package/src/{content → entry/cli/_function}/read-home.ts +1 -1
- package/src/entry/cli/_function/to-crawling-app.ts +42 -0
- package/src/{content/read-docs.test.ts → entry/cli/cli.test.ts} +211 -31
- package/src/{cli.ts → entry/cli/cli.ts} +31 -15
- package/src/store/navigation/_constant/tree.ts +6 -0
- package/src/store/navigation/create-navigation-stores.test.ts +92 -0
- package/src/store/navigation/create-navigation-stores.ts +73 -0
- package/src/store/navigation/navigation-state.ts +46 -0
- package/src/store/navigation/navigation-storage.ts +14 -0
- package/src/store/navigation/to-navigation-scroll-state.ts +42 -0
- package/src/store/navigation/to-navigation-tree-state.ts +19 -0
- package/src/store/navigation/use-navigation-tree-store.ts +12 -0
- package/src/style/token.css +3 -2
- package/src/type/doc-content.ts +1 -1
- package/src/type/doc-file-data.ts +1 -1
- package/src/{component/widget/shell/_type → type}/doc-outline.ts +1 -1
- package/src/type/site-assets.ts +2 -2
- package/src/type/site-config.ts +10 -1
- package/dist/client.js +0 -7
- package/src/client.ts +0 -335
- package/src/component/widget/shell/_constant/navigation.ts +0 -9
- package/src/component/widget/shell/_function/bind-mobile-navigation.ts +0 -147
- package/src/component/widget/shell/_function/bind-navigation-overflow.ts +0 -47
- package/src/component/widget/shell/_function/bind-navigation-scroll.ts +0 -84
- package/src/component/widget/shell/_function/restore-navigation-scroll.ts +0 -47
- package/src/component/widget/shell/_wg-shell-nav-list.tsx +0 -87
- package/src/component/widget/shell/_wg-shell-nav.tsx +0 -49
- package/src/component/widget/shell/_wg-shell-toc.tsx +0 -57
- /package/src/{constant → component/widget/navigation/_constant}/locale.ts +0 -0
- /package/src/component/widget/{shell → navigation}/_constant/reading-line.ts +0 -0
- /package/src/{type → component/widget/navigation/_type}/doc-branch.ts +0 -0
- /package/src/component/widget/{shell → navigation}/_type/toc-group.ts +0 -0
- /package/src/{constant → entry/cli/_constant}/cli.ts +0 -0
- /package/src/{content/rehype-assets.ts → entry/cli/_function/create-processor/_rehype-assets.ts} +0 -0
- /package/src/{content/rehype-heading-ids.ts → entry/cli/_function/create-processor/_rehype-heading-ids.ts} +0 -0
- /package/src/{content/remark-report.ts → entry/cli/_function/create-processor/_remark-report.ts} +0 -0
- /package/src/{component/widget/prose/_type → type}/doc-section.ts +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,191 +1,42 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// src/cli.ts
|
|
3
|
+
// src/entry/cli/cli.ts
|
|
4
4
|
import { EventEmitter } from "node:events";
|
|
5
|
-
import { existsSync as existsSync3, watch } from "node:fs";
|
|
5
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, watch } from "node:fs";
|
|
6
6
|
import { copyFile, mkdir, rm, writeFile } from "node:fs/promises";
|
|
7
7
|
import { basename as basename2, dirname as dirname4, extname as extname4, join as join4, relative as relative4, resolve as resolve3, sep as sep3 } from "node:path";
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
9
|
import { serve } from "@hono/node-server";
|
|
10
10
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
11
11
|
import { debounce } from "es-toolkit";
|
|
12
|
-
import { Hono as
|
|
12
|
+
import { Hono as Hono4 } from "hono";
|
|
13
13
|
import { toSSG } from "hono/ssg";
|
|
14
14
|
|
|
15
|
-
// src/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// src/component/widget/shell/_constant/navigation.ts
|
|
37
|
-
var navigation_mobile_query = "(width < 1024px)";
|
|
38
|
-
var navigation_scroll_storage_key = "for-humanity:navigation-scroll";
|
|
39
|
-
|
|
40
|
-
// src/component/widget/shell/_function/bind-navigation-overflow.ts
|
|
41
|
-
var bindNavigationOverflow = () => {
|
|
42
|
-
const ports = [...document.querySelectorAll("[data-navigation-scroll]")];
|
|
43
|
-
const frame = { id: 0 };
|
|
44
|
-
const edgeTolerance = 1;
|
|
45
|
-
const updateOverflow = () => {
|
|
46
|
-
frame.id = 0;
|
|
47
|
-
for (const port of ports) {
|
|
48
|
-
port.classList.add("wg_shell__scroll--ready");
|
|
49
|
-
port.classList.toggle("wg_shell__scroll--above", port.scrollTop > edgeTolerance);
|
|
50
|
-
port.classList.toggle("wg_shell__scroll--below", port.scrollHeight - port.clientHeight - port.scrollTop > edgeTolerance);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
const scheduleOverflow = () => {
|
|
54
|
-
if (frame.id === 0) {
|
|
55
|
-
frame.id = requestAnimationFrame(updateOverflow);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
const observer = new ResizeObserver(scheduleOverflow);
|
|
59
|
-
for (const port of ports) {
|
|
60
|
-
port.addEventListener("scroll", scheduleOverflow, { passive: true });
|
|
61
|
-
observer.observe(port);
|
|
62
|
-
if (port.firstElementChild) {
|
|
63
|
-
observer.observe(port.firstElementChild);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
addEventListener("pageshow", scheduleOverflow);
|
|
67
|
-
updateOverflow();
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// src/component/widget/shell/_function/restore-navigation-scroll.ts
|
|
71
|
-
var restoreNavigationScroll = (storageKey) => {
|
|
72
|
-
const navigation = document.querySelector("[data-navigation]");
|
|
73
|
-
const documents = document.querySelector('[data-navigation-scroll="documents"]');
|
|
74
|
-
const outline = document.querySelector('[data-navigation-scroll="outline"]');
|
|
75
|
-
if (!navigation || !documents || !outline) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
try {
|
|
79
|
-
const value = sessionStorage.getItem(storageKey);
|
|
80
|
-
if (value === null) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
const stored = JSON.parse(value);
|
|
84
|
-
const signature = [...navigation.querySelectorAll(".wg_shellNav__root a[href]")].map((link) => `${link.pathname}:${link.textContent}`).join("\n");
|
|
85
|
-
if (typeof stored !== "object" || stored === null || !("navigation" in stored) || stored.navigation !== signature) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
if ("documents" in stored && typeof stored.documents === "number" && Number.isFinite(stored.documents) && stored.documents >= 0) {
|
|
89
|
-
documents.scrollTop = stored.documents;
|
|
90
|
-
}
|
|
91
|
-
if ("pathname" in stored && stored.pathname === location.pathname && "outline" in stored && typeof stored.outline === "number" && Number.isFinite(stored.outline) && stored.outline >= 0) {
|
|
92
|
-
outline.scrollTop = stored.outline;
|
|
93
|
-
}
|
|
94
|
-
} catch {
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// src/component/widget/shell/_function/to-toc-groups.ts
|
|
99
|
-
import { takeWhile } from "es-toolkit/array";
|
|
100
|
-
|
|
101
|
-
// src/component/widget/prose/_constant/section.ts
|
|
102
|
-
var section_heading_depth = {
|
|
103
|
-
section: 2,
|
|
104
|
-
sub: 3
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
// src/component/widget/shell/_function/to-toc-groups.ts
|
|
108
|
-
var toTocGroups = (outline) => {
|
|
109
|
-
const entries = outline.headings.filter((heading) => heading.depth === section_heading_depth.section || heading.depth === section_heading_depth.sub).map((heading, index) => ({ heading, section: outline.sections[index] }));
|
|
110
|
-
const sections = entries.flatMap(
|
|
111
|
-
(entry, index) => entry.heading.depth === section_heading_depth.section ? [
|
|
112
|
-
{
|
|
113
|
-
heading: entry.heading,
|
|
114
|
-
part: entry.section.part,
|
|
115
|
-
subs: takeWhile(entries.slice(index + 1), (sub) => sub.heading.depth !== section_heading_depth.section).map((sub) => ({
|
|
116
|
-
heading: sub.heading
|
|
117
|
-
}))
|
|
118
|
-
}
|
|
119
|
-
] : []
|
|
120
|
-
);
|
|
121
|
-
return sections.flatMap(
|
|
122
|
-
(section, index) => index === 0 || section.part !== void 0 ? [
|
|
123
|
-
{
|
|
124
|
-
part: section.part,
|
|
125
|
-
sections: [section, ...takeWhile(sections.slice(index + 1), (next) => next.part === void 0)]
|
|
126
|
-
}
|
|
127
|
-
] : []
|
|
128
|
-
);
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// src/component/widget/shell/_wg-shell-nav.tsx
|
|
132
|
-
import clsx3 from "clsx";
|
|
133
|
-
|
|
134
|
-
// src/component/widget/shell/_wg-shell-nav-list.tsx
|
|
135
|
-
import clsx2 from "clsx";
|
|
136
|
-
import { Fragment } from "react";
|
|
137
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
138
|
-
var WgShellNavList = (props) => {
|
|
139
|
-
const currentAncestors = new Set(props.currentDoc?.ancestors);
|
|
140
|
-
const entries = [
|
|
141
|
-
...props.group.docs.map((doc) => {
|
|
142
|
-
const active = doc.id === props.currentDoc?.id;
|
|
143
|
-
return { kind: "document", key: `doc:${doc.id}`, doc, active, current: active || currentAncestors.has(doc.id) };
|
|
144
|
-
}),
|
|
145
|
-
...props.group.groups.map((group) => ({
|
|
146
|
-
kind: "group",
|
|
147
|
-
key: `group:${JSON.stringify(group.path)}`,
|
|
148
|
-
group,
|
|
149
|
-
current: group.path.every((name, index) => name === props.currentDoc?.data.group[index])
|
|
150
|
-
}))
|
|
151
|
-
];
|
|
152
|
-
const currentIndex = entries.findIndex((entry) => entry.current);
|
|
153
|
-
return /* @__PURE__ */ jsx2("ul", { className: clsx2("wg_shellNavList__root"), "aria-label": props.group.name, children: entries.map((entry, index) => /* @__PURE__ */ jsxs2(
|
|
154
|
-
"li",
|
|
155
|
-
{
|
|
156
|
-
className: clsx2("wg_shellNavList__item", {
|
|
157
|
-
"wg_shellNavList__item--trail": index < currentIndex,
|
|
158
|
-
"wg_shellNavList__item--current": entry.current
|
|
159
|
-
}),
|
|
160
|
-
children: [
|
|
161
|
-
entry.kind === "document" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
162
|
-
/* @__PURE__ */ jsx2(
|
|
163
|
-
"a",
|
|
164
|
-
{
|
|
165
|
-
className: clsx2("wg_shellNavList__link", { "wg_shellNavList__link--active": entry.active }),
|
|
166
|
-
href: `/${entry.doc.id}/`,
|
|
167
|
-
title: entry.doc.data.label,
|
|
168
|
-
"aria-current": entry.active ? "page" : void 0,
|
|
169
|
-
children: entry.doc.data.name
|
|
170
|
-
}
|
|
171
|
-
),
|
|
172
|
-
entry.doc.children !== void 0 && /* @__PURE__ */ jsx2(
|
|
173
|
-
WgShellNavList,
|
|
174
|
-
{
|
|
175
|
-
group: { name: entry.doc.data.name, path: entry.doc.data.group, docs: entry.doc.children, groups: [] },
|
|
176
|
-
currentDoc: props.currentDoc
|
|
177
|
-
}
|
|
178
|
-
)
|
|
179
|
-
] }),
|
|
180
|
-
entry.kind === "group" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
181
|
-
/* @__PURE__ */ jsx2("span", { className: clsx2("wg_shellNavList__branch"), children: entry.group.name }),
|
|
182
|
-
/* @__PURE__ */ jsx2(WgShellNavList, { group: entry.group, currentDoc: props.currentDoc })
|
|
183
|
-
] })
|
|
184
|
-
]
|
|
185
|
-
},
|
|
186
|
-
entry.key
|
|
187
|
-
)) });
|
|
15
|
+
// src/constant/asset.ts
|
|
16
|
+
var asset_dir = "_fh";
|
|
17
|
+
var asset_style_path = `/${asset_dir}/style.css`;
|
|
18
|
+
var asset_font_dir = `/${asset_dir}/fonts`;
|
|
19
|
+
var asset_reload_path = `/${asset_dir}/reload`;
|
|
20
|
+
var asset_favicon_path = "/favicon.svg";
|
|
21
|
+
var asset_content_types = {
|
|
22
|
+
".css": "text/css; charset=utf-8",
|
|
23
|
+
".js": "text/javascript; charset=utf-8",
|
|
24
|
+
".woff2": "font/woff2",
|
|
25
|
+
".svg": "image/svg+xml",
|
|
26
|
+
".png": "image/png",
|
|
27
|
+
".jpg": "image/jpeg",
|
|
28
|
+
".jpeg": "image/jpeg",
|
|
29
|
+
".gif": "image/gif",
|
|
30
|
+
".webp": "image/webp",
|
|
31
|
+
".avif": "image/avif",
|
|
32
|
+
".pdf": "application/pdf",
|
|
33
|
+
".csv": "text/csv; charset=utf-8",
|
|
34
|
+
".txt": "text/plain; charset=utf-8",
|
|
35
|
+
".zip": "application/zip"
|
|
188
36
|
};
|
|
37
|
+
var asset_content_type_default = "application/octet-stream";
|
|
38
|
+
var asset_media_dir = `/${asset_dir}/media`;
|
|
39
|
+
var asset_media_extensions = /* @__PURE__ */ new Set([".svg", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".avif", ".pdf", ".csv", ".txt", ".zip"]);
|
|
189
40
|
|
|
190
41
|
// src/constant/copy.ts
|
|
191
42
|
var copy_site_title_default = "for humanity";
|
|
@@ -200,6 +51,7 @@ var copy_error_prefix = "for-humanity";
|
|
|
200
51
|
var copy_error_font_preload = "Missing bundled font for preload";
|
|
201
52
|
var copy_error_unknown_command = "\uBAA8\uB974\uB294 \uBA85\uB839\uC774\uB2E4";
|
|
202
53
|
var copy_error_config = "\uC124\uC815\uC774 \uD2C0\uB838\uB2E4";
|
|
54
|
+
var copy_error_site_url = "url\uC740 \uC0AC\uC6A9\uC790 \uC815\uBCF4\xB7\uD558\uC704 \uACBD\uB85C\xB7query\xB7hash\uAC00 \uC5C6\uB294 HTTP(S) \uC0AC\uC774\uD2B8 \uB8E8\uD2B8\uC5EC\uC57C \uD55C\uB2E4";
|
|
203
55
|
var copy_error_frontmatter = "frontmatter\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
|
|
204
56
|
var copy_error_navigation_clash = "navigation\uC758 \uBB36\uC74C\uC774 \uACB9\uCE5C\uB2E4";
|
|
205
57
|
var copy_error_doc_id = "\uBB38\uC11C id\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uB294 \uACBD\uB85C";
|
|
@@ -214,11 +66,57 @@ var copy_warn_broken_link = "\uC5C6\uB294 \uBB38\uC11C\uB85C \uAC74 \uB9C1\uD06C
|
|
|
214
66
|
var copy_warn_unknown_status = "\uC124\uC815\uC5D0 \uC5C6\uB294 \uC0C1\uD0DC \uBB38\uAD6C\uB2E4";
|
|
215
67
|
var copy_error_asset = "\uC790\uC6D0\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
|
|
216
68
|
|
|
217
|
-
// src/constant/
|
|
69
|
+
// src/constant/font.ts
|
|
70
|
+
var font_sans_css = "src/asset/font/pretendard/pretendardvariable-dynamic-subset.css";
|
|
71
|
+
var font_mono_css = "src/asset/font/jetbrains-mono/jetbrains-mono.css";
|
|
72
|
+
var font_brand_css = "src/asset/font/architects-daughter/architects-daughter.css";
|
|
73
|
+
var font_sans_preload_file = "PretendardVariable.subset.91.woff2";
|
|
74
|
+
var font_display_strategy = "optional";
|
|
75
|
+
var font_hash_length = 12;
|
|
76
|
+
var font_cache_control = "public, max-age=31536000, immutable";
|
|
77
|
+
|
|
78
|
+
// src/constant/site.ts
|
|
79
|
+
var site_config_absent = {};
|
|
80
|
+
var site_navigation_default = [];
|
|
81
|
+
|
|
82
|
+
// src/entry/cli/_constant/cli.ts
|
|
83
|
+
var cli_default_command = "dev";
|
|
84
|
+
var cli_default_docs_dir = ".";
|
|
85
|
+
var cli_config_file_name = "for-humanity.config.mjs";
|
|
86
|
+
var cli_dev_port = 4321;
|
|
87
|
+
var cli_reload_delay_ms = 150;
|
|
88
|
+
|
|
89
|
+
// src/entry/cli/_constant/crawling.ts
|
|
90
|
+
var crawling_robots_path = "/robots.txt";
|
|
91
|
+
var crawling_sitemap_path = "/sitemap.xml";
|
|
92
|
+
var crawling_reserved_roots = [crawling_robots_path.slice(1), crawling_sitemap_path.slice(1)];
|
|
93
|
+
|
|
94
|
+
// src/entry/cli/_function/create-app.tsx
|
|
95
|
+
import { Hono } from "hono";
|
|
96
|
+
import { html } from "hono/html";
|
|
97
|
+
import { ssgParams } from "hono/ssg";
|
|
98
|
+
|
|
99
|
+
// src/component/widget/prose/wg-prose.tsx
|
|
100
|
+
import clsx from "clsx";
|
|
101
|
+
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
102
|
+
var WgProse = (props) => {
|
|
103
|
+
if (props.html !== void 0) {
|
|
104
|
+
return /* @__PURE__ */ jsx("article", { className: clsx("wg_prose__root"), dangerouslySetInnerHTML: { __html: props.html } });
|
|
105
|
+
}
|
|
106
|
+
return /* @__PURE__ */ jsx("article", { className: clsx("wg_prose__root"), children: props.head !== void 0 && /* @__PURE__ */ jsxs("header", { className: clsx("wg_prose__head"), children: [
|
|
107
|
+
/* @__PURE__ */ jsx("h1", { children: props.head.title }),
|
|
108
|
+
props.head.lead !== void 0 && /* @__PURE__ */ jsx("p", { children: props.head.lead })
|
|
109
|
+
] }) });
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// src/component/widget/shell/wg-shell.tsx
|
|
113
|
+
import clsx10 from "clsx";
|
|
114
|
+
|
|
115
|
+
// src/component/widget/navigation/_constant/locale.ts
|
|
218
116
|
var locale_doc_name = "en";
|
|
219
117
|
var locale_doc_group = "ko";
|
|
220
118
|
|
|
221
|
-
// src/
|
|
119
|
+
// src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts
|
|
222
120
|
var toDocBranches = (options) => {
|
|
223
121
|
return options.docs.toSorted((a, b) => a.data.order - b.data.order || a.data.name.localeCompare(b.data.name, locale_doc_name) || a.id.localeCompare(b.id, locale_doc_name)).map((doc) => {
|
|
224
122
|
const children = options.children.get(doc.id);
|
|
@@ -226,7 +124,7 @@ var toDocBranches = (options) => {
|
|
|
226
124
|
});
|
|
227
125
|
};
|
|
228
126
|
|
|
229
|
-
// src/
|
|
127
|
+
// src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts
|
|
230
128
|
var toDocGroupBranches = (options) => {
|
|
231
129
|
return [
|
|
232
130
|
...Map.groupBy(
|
|
@@ -260,176 +158,1089 @@ var toDocGroupBranches = (options) => {
|
|
|
260
158
|
});
|
|
261
159
|
};
|
|
262
160
|
|
|
263
|
-
// src/
|
|
161
|
+
// src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts
|
|
264
162
|
var toDocGroups = (options) => {
|
|
265
163
|
const positions = new Map(options.navigation.flatMap((path, index) => path.map((_name, depth) => [JSON.stringify(path.slice(0, depth + 1)), index])).toReversed());
|
|
266
164
|
const children = Map.groupBy(options.docs, (doc) => doc.data.parent);
|
|
267
165
|
return toDocGroupBranches({ docs: options.docs, children, path: [], positions, unlistedPosition: options.navigation.length });
|
|
268
166
|
};
|
|
269
167
|
|
|
270
|
-
// src/component/widget/
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
168
|
+
// src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts
|
|
169
|
+
var toNavigationDocument = (options) => ({
|
|
170
|
+
id: options.doc.id,
|
|
171
|
+
name: options.doc.data.name,
|
|
172
|
+
label: options.doc.data.label,
|
|
173
|
+
active: options.doc.id === options.current,
|
|
174
|
+
current: options.doc.id === options.current || options.ancestors.has(options.doc.id),
|
|
175
|
+
children: options.doc.children === void 0 ? [] : options.doc.children.map((doc) => toNavigationDocument({ ...options, doc }))
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts
|
|
179
|
+
var toNavigationGroup = (options) => ({
|
|
180
|
+
name: options.group.name,
|
|
181
|
+
path: options.group.path,
|
|
182
|
+
current: options.group.path.every((name, index) => name === options.currentGroup?.[index]),
|
|
183
|
+
docs: options.group.docs.map((doc) => toNavigationDocument({ doc, current: options.current, ancestors: options.ancestors })),
|
|
184
|
+
groups: options.group.groups.map((group) => toNavigationGroup({ ...options, group }))
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// src/component/widget/navigation/_function/to-toc-groups.ts
|
|
188
|
+
import { takeWhile } from "es-toolkit/array";
|
|
189
|
+
|
|
190
|
+
// src/component/widget/prose/_constant/section.ts
|
|
191
|
+
var section_heading_depth = {
|
|
192
|
+
section: 2,
|
|
193
|
+
sub: 3
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// src/component/widget/navigation/_function/to-toc-groups.ts
|
|
197
|
+
var toTocGroups = (outline) => {
|
|
198
|
+
const entries = outline.headings.filter((heading) => heading.depth === section_heading_depth.section || heading.depth === section_heading_depth.sub).map((heading, index) => ({ heading, section: outline.sections[index] }));
|
|
199
|
+
const sections = entries.flatMap(
|
|
200
|
+
(entry, index) => entry.heading.depth === section_heading_depth.section ? [
|
|
201
|
+
{
|
|
202
|
+
heading: entry.heading,
|
|
203
|
+
part: entry.section.part,
|
|
204
|
+
subs: takeWhile(entries.slice(index + 1), (sub) => sub.heading.depth !== section_heading_depth.section).map((sub) => ({
|
|
205
|
+
heading: sub.heading
|
|
206
|
+
}))
|
|
207
|
+
}
|
|
208
|
+
] : []
|
|
209
|
+
);
|
|
210
|
+
return sections.flatMap(
|
|
211
|
+
(section, index) => index === 0 || section.part !== void 0 ? [
|
|
212
|
+
{
|
|
213
|
+
part: section.part,
|
|
214
|
+
sections: [section, ...takeWhile(sections.slice(index + 1), (next) => next.part === void 0)]
|
|
215
|
+
}
|
|
216
|
+
] : []
|
|
217
|
+
);
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts
|
|
221
|
+
var toNavigationData = (options) => {
|
|
222
|
+
const currentDoc = options.docs.find((doc) => doc.id === options.current);
|
|
223
|
+
const ancestors = new Set(currentDoc?.ancestors);
|
|
224
|
+
return {
|
|
225
|
+
title: options.site.title,
|
|
226
|
+
groups: toDocGroups({ docs: options.docs, navigation: options.site.navigation }).map(
|
|
227
|
+
(group) => toNavigationGroup({ group, current: options.current, ancestors, currentGroup: currentDoc?.data.group })
|
|
228
|
+
),
|
|
229
|
+
outline: options.outline === void 0 ? [] : toTocGroups(options.outline),
|
|
230
|
+
pageId: options.current === void 0 ? "/" : options.current,
|
|
231
|
+
home: options.current === void 0
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
// src/component/widget/navigation/_function/to-navigation-json.ts
|
|
236
|
+
var toNavigationJson = (data) => {
|
|
237
|
+
return JSON.stringify(data).replaceAll("<", "\\u003c").replaceAll("\u2028", "\\u2028").replaceAll("\u2029", "\\u2029");
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// src/component/widget/shell-controls/wg-shell-controls.tsx
|
|
241
|
+
import clsx9 from "clsx";
|
|
242
|
+
import { Fragment as Fragment3, useEffect, useLayoutEffect as useLayoutEffect5, useRef as useRef4 } from "hono/jsx";
|
|
243
|
+
|
|
244
|
+
// src/component/widget/cursor-face/wg-cursor-face.tsx
|
|
245
|
+
import clsx2 from "clsx";
|
|
246
|
+
import { useLayoutEffect, useRef } from "hono/jsx";
|
|
247
|
+
|
|
248
|
+
// src/component/widget/cursor-face/_constant/cursor-face.ts
|
|
249
|
+
var cursor_face_offset_px = 16;
|
|
250
|
+
var cursor_face_size_px = 24;
|
|
251
|
+
var cursor_face_storage_key = "fh-cursor-face";
|
|
252
|
+
|
|
253
|
+
// src/component/widget/cursor-face/wg-cursor-face.tsx
|
|
254
|
+
import { jsx as jsx2 } from "hono/jsx/jsx-runtime";
|
|
255
|
+
var WgCursorFace = (props) => {
|
|
256
|
+
const faceRef = useRef(null);
|
|
257
|
+
const mediaRef = useRef(null);
|
|
258
|
+
const positionRef = useRef({ x: 0, y: 0, frame: 0 });
|
|
259
|
+
const handleCursorHide = () => {
|
|
260
|
+
cancelAnimationFrame(positionRef.current.frame);
|
|
261
|
+
positionRef.current.frame = 0;
|
|
262
|
+
faceRef.current?.classList.remove("wg_cursorFace__root--visible");
|
|
263
|
+
};
|
|
264
|
+
const handleCursorMediaChange = () => {
|
|
265
|
+
if (!mediaRef.current?.matches) handleCursorHide();
|
|
266
|
+
};
|
|
267
|
+
const renderCursorFace = () => {
|
|
268
|
+
if (positionRef.current.frame !== 0) return;
|
|
269
|
+
positionRef.current.frame = requestAnimationFrame(() => {
|
|
270
|
+
positionRef.current.frame = 0;
|
|
271
|
+
const face = faceRef.current;
|
|
272
|
+
if (face === null) return;
|
|
273
|
+
face.style.transform = `translate3d(
|
|
274
|
+
${Math.max(0, Math.min(positionRef.current.x + cursor_face_offset_px, document.documentElement.clientWidth - face.width - cursor_face_offset_px))}px,
|
|
275
|
+
${Math.max(0, Math.min(positionRef.current.y + cursor_face_offset_px, document.documentElement.clientHeight - face.height - cursor_face_offset_px))}px,
|
|
276
|
+
0
|
|
277
|
+
)`;
|
|
278
|
+
face.classList.add("wg_cursorFace__root--visible");
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
const handleDocumentPointer = (event) => {
|
|
282
|
+
if (!mediaRef.current?.matches || event.pointerType !== "mouse") {
|
|
283
|
+
handleCursorHide();
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
positionRef.current.x = event.clientX;
|
|
287
|
+
positionRef.current.y = event.clientY;
|
|
288
|
+
renderCursorFace();
|
|
289
|
+
};
|
|
290
|
+
const handleCursorResize = () => {
|
|
291
|
+
if (faceRef.current?.classList.contains("wg_cursorFace__root--visible")) renderCursorFace();
|
|
292
|
+
};
|
|
293
|
+
const handlePageHide = () => {
|
|
294
|
+
if (!faceRef.current?.classList.contains("wg_cursorFace__root--visible")) return;
|
|
295
|
+
try {
|
|
296
|
+
sessionStorage.setItem(cursor_face_storage_key, JSON.stringify({ x: positionRef.current.x, y: positionRef.current.y }));
|
|
297
|
+
} catch {
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
const handlePageShow = () => {
|
|
301
|
+
try {
|
|
302
|
+
const stored = sessionStorage.getItem(cursor_face_storage_key);
|
|
303
|
+
sessionStorage.removeItem(cursor_face_storage_key);
|
|
304
|
+
if (stored === null || !mediaRef.current?.matches) return;
|
|
305
|
+
const point = JSON.parse(stored);
|
|
306
|
+
if (typeof point === "object" && point !== null && "x" in point && "y" in point && typeof point.x === "number" && typeof point.y === "number" && Number.isFinite(point.x) && Number.isFinite(point.y)) {
|
|
307
|
+
positionRef.current.x = point.x;
|
|
308
|
+
positionRef.current.y = point.y;
|
|
309
|
+
renderCursorFace();
|
|
310
|
+
}
|
|
311
|
+
} catch {
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
useLayoutEffect(() => {
|
|
315
|
+
if (!props.ready) return;
|
|
316
|
+
const lifetime = new AbortController();
|
|
317
|
+
const media = matchMedia("(hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)");
|
|
318
|
+
mediaRef.current = media;
|
|
319
|
+
handlePageShow();
|
|
320
|
+
document.addEventListener("pointermove", handleDocumentPointer, { passive: true, signal: lifetime.signal });
|
|
321
|
+
document.addEventListener("pointerdown", handleDocumentPointer, { passive: true, signal: lifetime.signal });
|
|
322
|
+
document.documentElement.addEventListener("pointerleave", handleCursorHide, { signal: lifetime.signal });
|
|
323
|
+
addEventListener("blur", handleCursorHide, { signal: lifetime.signal });
|
|
324
|
+
addEventListener("resize", handleCursorResize, { signal: lifetime.signal });
|
|
325
|
+
addEventListener("pagehide", handlePageHide, { signal: lifetime.signal });
|
|
326
|
+
addEventListener("pageshow", handlePageShow, { signal: lifetime.signal });
|
|
327
|
+
media.addEventListener("change", handleCursorMediaChange, { signal: lifetime.signal });
|
|
328
|
+
return () => {
|
|
329
|
+
lifetime.abort();
|
|
330
|
+
mediaRef.current = null;
|
|
331
|
+
handleCursorHide();
|
|
332
|
+
};
|
|
333
|
+
}, [props.ready]);
|
|
334
|
+
return /* @__PURE__ */ jsx2(
|
|
335
|
+
"img",
|
|
336
|
+
{
|
|
337
|
+
ref: props.ready ? faceRef : void 0,
|
|
338
|
+
className: clsx2("wg_cursorFace__root"),
|
|
339
|
+
src: asset_favicon_path,
|
|
340
|
+
width: cursor_face_size_px,
|
|
341
|
+
height: cursor_face_size_px,
|
|
342
|
+
alt: "",
|
|
343
|
+
"aria-hidden": "true",
|
|
344
|
+
draggable: false,
|
|
345
|
+
"data-cursor-face": ""
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// src/component/widget/navigation/wg-navigation.tsx
|
|
351
|
+
import clsx8 from "clsx";
|
|
352
|
+
import { Fragment as Fragment2, useLayoutEffect as useLayoutEffect4, useRef as useRef3, useState as useState3 } from "hono/jsx";
|
|
353
|
+
import { flushSync } from "hono/jsx/dom";
|
|
354
|
+
|
|
355
|
+
// src/component/widget/navigation/_constant/navigation.ts
|
|
356
|
+
var navigation_mobile_query = "(width < 1024px)";
|
|
357
|
+
var navigation_wide_query = "(width >= 1536px)";
|
|
358
|
+
|
|
359
|
+
// src/component/widget/navigation/_function/restore-navigation-scroll.ts
|
|
360
|
+
var restoreNavigationScroll = (options) => {
|
|
361
|
+
const navigation = document.querySelector("[data-navigation]");
|
|
362
|
+
const documents = document.querySelector('[data-navigation-scroll="documents"]');
|
|
363
|
+
const outline = document.querySelector('[data-navigation-scroll="outline"]');
|
|
364
|
+
if (!navigation || !documents || !outline) return;
|
|
365
|
+
navigation.dataset.navigationLayout = options.layout;
|
|
366
|
+
try {
|
|
367
|
+
const value = sessionStorage.getItem(options.key);
|
|
368
|
+
const stored = value === null ? void 0 : JSON.parse(value);
|
|
369
|
+
const state = typeof stored === "object" && stored !== null && "version" in stored && stored.version === options.version && "state" in stored ? options.toState(stored.state) : { positions: {} };
|
|
370
|
+
const legacy = sessionStorage.getItem(`${options.key}:${options.layout === "drawer" ? "drawer" : "desktop"}`);
|
|
371
|
+
const previous = state.positions[options.layout] === void 0 && legacy !== null ? options.toState({ positions: { [options.layout]: JSON.parse(legacy) } }).positions[options.layout] : void 0;
|
|
372
|
+
const position = state.positions[options.layout] ?? previous;
|
|
373
|
+
const signature = [...navigation.querySelectorAll(".wg_navigationNav__root a[href]")].map((link) => `${link.pathname}:${link.textContent}`).join("\n");
|
|
374
|
+
if (position === void 0 || position.navigation !== signature) return;
|
|
375
|
+
documents.scrollTop = position.documents;
|
|
376
|
+
if (position.pathname === location.pathname) outline.scrollTop = position.outline;
|
|
377
|
+
} catch {
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
// src/component/widget/navigation/_wg-navigation-nav.tsx
|
|
382
|
+
import clsx5 from "clsx";
|
|
383
|
+
|
|
384
|
+
// src/component/widget/navigation/_wg-navigation-branch-toggle.tsx
|
|
385
|
+
import clsx3 from "clsx";
|
|
386
|
+
|
|
387
|
+
// src/component/widget/navigation/_function/to-navigation-branch-id.ts
|
|
388
|
+
var toNavigationBranchId = (key) => {
|
|
389
|
+
return `fh-branch-${encodeURIComponent(key)}`;
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
// src/component/widget/navigation/_wg-navigation-branch-toggle.tsx
|
|
393
|
+
import { jsx as jsx3 } from "hono/jsx/jsx-runtime";
|
|
394
|
+
var WgNavigationBranchToggle = (props) => {
|
|
395
|
+
const handleToggleClick = () => props.onToggle?.(props.branchKey);
|
|
396
|
+
return /* @__PURE__ */ jsx3(
|
|
397
|
+
"button",
|
|
398
|
+
{
|
|
399
|
+
className: clsx3("wg_navigationBranchToggle__root"),
|
|
400
|
+
type: "button",
|
|
401
|
+
"aria-label": `${props.collapsed[props.branchKey] === true ? "Expand" : "Collapse"} ${props.label}`,
|
|
402
|
+
"aria-expanded": String(props.collapsed[props.branchKey] !== true),
|
|
403
|
+
"aria-controls": toNavigationBranchId(props.branchKey),
|
|
404
|
+
"data-navigation-toggle": props.branchKey,
|
|
405
|
+
"data-navigation-label": props.label,
|
|
406
|
+
hidden: props.onToggle === void 0,
|
|
407
|
+
onClick: handleToggleClick,
|
|
408
|
+
children: props.collapsed[props.branchKey] === true ? "+" : "\u2212"
|
|
409
|
+
}
|
|
410
|
+
);
|
|
279
411
|
};
|
|
280
412
|
|
|
281
|
-
// src/component/widget/
|
|
413
|
+
// src/component/widget/navigation/_wg-navigation-nav-list.tsx
|
|
282
414
|
import clsx4 from "clsx";
|
|
283
|
-
import { Fragment
|
|
284
|
-
import { jsx as jsx4, jsxs as
|
|
285
|
-
var
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
415
|
+
import { Fragment } from "hono/jsx";
|
|
416
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "hono/jsx/jsx-runtime";
|
|
417
|
+
var WgNavigationNavList = (props) => {
|
|
418
|
+
const entries = [
|
|
419
|
+
...props.group.docs.map((doc) => {
|
|
420
|
+
const active = doc.active;
|
|
421
|
+
return { kind: "document", key: `doc:${doc.id}`, doc, active, current: doc.current };
|
|
422
|
+
}),
|
|
423
|
+
...props.group.groups.map((group) => ({
|
|
424
|
+
kind: "group",
|
|
425
|
+
key: `group:${JSON.stringify(group.path)}`,
|
|
426
|
+
group,
|
|
427
|
+
current: group.current
|
|
428
|
+
}))
|
|
429
|
+
];
|
|
430
|
+
const currentIndex = entries.findIndex((entry) => entry.current);
|
|
431
|
+
return /* @__PURE__ */ jsx4(
|
|
432
|
+
"ul",
|
|
433
|
+
{
|
|
434
|
+
className: clsx4("wg_navigationNavList__root"),
|
|
435
|
+
"aria-label": props.group.name,
|
|
436
|
+
id: toNavigationBranchId(props.branchKey),
|
|
437
|
+
hidden: props.collapsed[props.branchKey] === true,
|
|
438
|
+
children: entries.map((entry, index) => /* @__PURE__ */ jsxs2(
|
|
439
|
+
"li",
|
|
440
|
+
{
|
|
441
|
+
className: clsx4("wg_navigationNavList__item", {
|
|
442
|
+
"wg_navigationNavList__item--trail": index < currentIndex,
|
|
443
|
+
"wg_navigationNavList__item--current": entry.current
|
|
444
|
+
}),
|
|
445
|
+
children: [
|
|
446
|
+
entry.kind === "document" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
447
|
+
/* @__PURE__ */ jsx4(
|
|
448
|
+
"a",
|
|
449
|
+
{
|
|
450
|
+
className: clsx4("wg_navigationNavList__link", { "wg_navigationNavList__link--active": entry.active }),
|
|
451
|
+
href: `/${entry.doc.id}/`,
|
|
452
|
+
title: entry.doc.label,
|
|
453
|
+
"aria-current": entry.active ? "page" : void 0,
|
|
454
|
+
children: entry.doc.name
|
|
455
|
+
}
|
|
456
|
+
),
|
|
457
|
+
entry.doc.children.length > 0 && /* @__PURE__ */ jsx4(WgNavigationBranchToggle, { branchKey: entry.key, label: entry.doc.name, collapsed: props.collapsed, onToggle: props.onToggle }),
|
|
458
|
+
entry.doc.children.length > 0 && /* @__PURE__ */ jsx4(
|
|
459
|
+
WgNavigationNavList,
|
|
460
|
+
{
|
|
461
|
+
group: { name: entry.doc.name, path: props.group.path, current: entry.current, docs: entry.doc.children, groups: [] },
|
|
462
|
+
collapsed: props.collapsed,
|
|
463
|
+
onToggle: props.onToggle,
|
|
464
|
+
branchKey: entry.key
|
|
465
|
+
}
|
|
466
|
+
)
|
|
467
|
+
] }),
|
|
468
|
+
entry.kind === "group" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
469
|
+
/* @__PURE__ */ jsx4("span", { className: clsx4("wg_navigationNavList__branch"), children: entry.group.name }),
|
|
470
|
+
/* @__PURE__ */ jsx4(WgNavigationBranchToggle, { branchKey: entry.key, label: entry.group.name, collapsed: props.collapsed, onToggle: props.onToggle }),
|
|
471
|
+
/* @__PURE__ */ jsx4(WgNavigationNavList, { group: entry.group, collapsed: props.collapsed, onToggle: props.onToggle, branchKey: entry.key })
|
|
472
|
+
] })
|
|
473
|
+
]
|
|
474
|
+
},
|
|
475
|
+
entry.key
|
|
476
|
+
))
|
|
477
|
+
}
|
|
478
|
+
);
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
// src/component/widget/navigation/_wg-navigation-nav.tsx
|
|
482
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "hono/jsx/jsx-runtime";
|
|
483
|
+
var WgNavigationNav = (props) => {
|
|
484
|
+
return /* @__PURE__ */ jsx5("nav", { className: clsx5("wg_navigationNav__root"), "aria-label": copy_nav_aria_label, children: /* @__PURE__ */ jsx5("div", { className: clsx5("wg_navigationNav__docs"), children: props.groups.map((group) => /* @__PURE__ */ jsxs3("section", { className: clsx5("wg_navigationNav__docGroup"), "aria-label": group.name, children: [
|
|
485
|
+
/* @__PURE__ */ jsx5("div", { className: clsx5("wg_navigationNav__group"), children: group.name }),
|
|
486
|
+
/* @__PURE__ */ jsx5(WgNavigationBranchToggle, { branchKey: `group:${JSON.stringify(group.path)}`, label: group.name, collapsed: props.collapsed, onToggle: props.onToggle }),
|
|
487
|
+
/* @__PURE__ */ jsx5(WgNavigationNavList, { group, branchKey: `group:${JSON.stringify(group.path)}`, collapsed: props.collapsed, onToggle: props.onToggle })
|
|
488
|
+
] }, JSON.stringify(group.path))) }) });
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
// src/component/widget/navigation/_wg-navigation-scroll.tsx
|
|
492
|
+
import clsx6 from "clsx";
|
|
493
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState } from "hono/jsx";
|
|
494
|
+
import { jsx as jsx6 } from "hono/jsx/jsx-runtime";
|
|
495
|
+
var WgNavigationScroll = (props) => {
|
|
496
|
+
const [overflow, setOverflow] = useState({ above: false, below: false });
|
|
497
|
+
const frameRef = useRef2(0);
|
|
498
|
+
const updateOverflow = () => {
|
|
499
|
+
frameRef.current = 0;
|
|
500
|
+
if (props.portRef.current === null) return;
|
|
501
|
+
const above = props.portRef.current.scrollTop > 1;
|
|
502
|
+
const below = props.portRef.current.scrollHeight - props.portRef.current.clientHeight - props.portRef.current.scrollTop > 1;
|
|
503
|
+
setOverflow((state) => state.above === above && state.below === below ? state : { above, below });
|
|
504
|
+
};
|
|
505
|
+
const scheduleOverflow = () => {
|
|
506
|
+
if (frameRef.current === 0) frameRef.current = requestAnimationFrame(updateOverflow);
|
|
507
|
+
};
|
|
508
|
+
const handlePortScroll = (_event) => {
|
|
509
|
+
props.onScroll?.();
|
|
510
|
+
scheduleOverflow();
|
|
511
|
+
};
|
|
512
|
+
useLayoutEffect2(() => {
|
|
513
|
+
if (!props.ready || props.portRef.current === null) return;
|
|
514
|
+
const observer = new ResizeObserver(scheduleOverflow);
|
|
515
|
+
observer.observe(props.portRef.current);
|
|
516
|
+
if (props.portRef.current.firstElementChild !== null) observer.observe(props.portRef.current.firstElementChild);
|
|
517
|
+
let active = true;
|
|
518
|
+
addEventListener("pageshow", scheduleOverflow);
|
|
519
|
+
if (props.portRef.current.isConnected) {
|
|
520
|
+
updateOverflow();
|
|
521
|
+
} else {
|
|
522
|
+
queueMicrotask(() => {
|
|
523
|
+
if (active) updateOverflow();
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
return () => {
|
|
527
|
+
active = false;
|
|
528
|
+
observer.disconnect();
|
|
529
|
+
removeEventListener("pageshow", scheduleOverflow);
|
|
530
|
+
cancelAnimationFrame(frameRef.current);
|
|
531
|
+
frameRef.current = 0;
|
|
532
|
+
};
|
|
533
|
+
}, [props.portRef, props.ready]);
|
|
534
|
+
useLayoutEffect2(() => {
|
|
535
|
+
if (props.ready && props.portRef.current?.isConnected) updateOverflow();
|
|
536
|
+
}, [props.children, props.ready]);
|
|
537
|
+
return (
|
|
538
|
+
// biome-ignore lint/a11y/noStaticElementInteractions lint/a11y/useKeyWithClickEvents: 부모의 링크 이벤트 위임이며 자식 a·button의 네이티브 키보드 동작을 그대로 소비한다
|
|
539
|
+
/* @__PURE__ */ jsx6(
|
|
540
|
+
"div",
|
|
541
|
+
{
|
|
542
|
+
ref: props.ready ? props.portRef : void 0,
|
|
543
|
+
className: clsx6(
|
|
544
|
+
"wg_navigation__scroll",
|
|
545
|
+
props.kind === "documents" && "wg_navigation__documents",
|
|
546
|
+
props.kind === "outline" && "wg_navigation__headings",
|
|
547
|
+
props.ready && "wg_navigation__scroll--ready",
|
|
548
|
+
props.ready && overflow.above && "wg_navigation__scroll--above",
|
|
549
|
+
props.ready && overflow.below && "wg_navigation__scroll--below"
|
|
550
|
+
),
|
|
551
|
+
"data-navigation-scroll": props.kind,
|
|
552
|
+
onClick: props.onClick,
|
|
553
|
+
onScroll: handlePortScroll,
|
|
554
|
+
children: props.children
|
|
555
|
+
}
|
|
556
|
+
)
|
|
557
|
+
);
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
// src/component/widget/navigation/_wg-navigation-toc.tsx
|
|
561
|
+
import clsx7 from "clsx";
|
|
562
|
+
import { useLayoutEffect as useLayoutEffect3, useState as useState2 } from "hono/jsx";
|
|
563
|
+
|
|
564
|
+
// src/component/widget/navigation/_constant/reading-line.ts
|
|
565
|
+
var reading_line_slack_px = 1;
|
|
566
|
+
|
|
567
|
+
// src/util/dom/find-hash-target.ts
|
|
568
|
+
var findHashTarget = (hash) => {
|
|
569
|
+
if (!hash) {
|
|
570
|
+
return null;
|
|
571
|
+
}
|
|
572
|
+
try {
|
|
573
|
+
return document.getElementById(decodeURIComponent(hash.slice(1)));
|
|
574
|
+
} catch (error) {
|
|
575
|
+
if (error instanceof URIError) {
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
throw error;
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
// src/component/widget/navigation/_wg-navigation-toc.tsx
|
|
583
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "hono/jsx/jsx-runtime";
|
|
584
|
+
var WgNavigationToc = (props) => {
|
|
585
|
+
const [currentSlug, setCurrentSlug] = useState2();
|
|
586
|
+
useLayoutEffect3(() => {
|
|
587
|
+
const sections = props.groups.flatMap((group) => group.sections);
|
|
588
|
+
const headings = sections.flatMap((section) => [section.heading, ...section.subs.map((sub) => sub.heading)]);
|
|
589
|
+
const frame = { id: 0 };
|
|
590
|
+
const updateCurrentHeading = () => {
|
|
591
|
+
frame.id = 0;
|
|
592
|
+
const visible = headings.flatMap((heading) => {
|
|
593
|
+
const target = findHashTarget(`#${heading.slug}`);
|
|
594
|
+
return target?.checkVisibility() ? [{ slug: heading.slug, top: target.getBoundingClientRect().top - Number.parseFloat(getComputedStyle(target).scrollMarginTop) }] : [];
|
|
595
|
+
});
|
|
596
|
+
setCurrentSlug(visible.findLast((heading) => heading.top <= reading_line_slack_px)?.slug ?? visible[0]?.slug);
|
|
597
|
+
};
|
|
598
|
+
const handleReadingPositionChange = () => {
|
|
599
|
+
if (frame.id === 0) frame.id = requestAnimationFrame(updateCurrentHeading);
|
|
600
|
+
};
|
|
601
|
+
addEventListener("scroll", handleReadingPositionChange, { passive: true });
|
|
602
|
+
addEventListener("resize", handleReadingPositionChange);
|
|
603
|
+
addEventListener("toggle", handleReadingPositionChange, true);
|
|
604
|
+
addEventListener("pageshow", handleReadingPositionChange);
|
|
605
|
+
document.addEventListener("DOMContentLoaded", handleReadingPositionChange);
|
|
606
|
+
if (document.readyState !== "loading") updateCurrentHeading();
|
|
607
|
+
return () => {
|
|
608
|
+
cancelAnimationFrame(frame.id);
|
|
609
|
+
removeEventListener("scroll", handleReadingPositionChange);
|
|
610
|
+
removeEventListener("resize", handleReadingPositionChange);
|
|
611
|
+
removeEventListener("toggle", handleReadingPositionChange, true);
|
|
612
|
+
removeEventListener("pageshow", handleReadingPositionChange);
|
|
613
|
+
document.removeEventListener("DOMContentLoaded", handleReadingPositionChange);
|
|
614
|
+
};
|
|
615
|
+
}, [props.groups]);
|
|
616
|
+
return /* @__PURE__ */ jsxs4("nav", { className: clsx7("wg_navigationToc__root"), "aria-label": copy_nav_toc_label, children: [
|
|
617
|
+
/* @__PURE__ */ jsx7("div", { className: clsx7("wg_navigationToc__label"), children: copy_nav_toc_label }),
|
|
618
|
+
props.groups.map((group) => {
|
|
619
|
+
const currentIndex = group.sections.findIndex((section) => section.heading.slug === currentSlug || section.subs.some((sub) => sub.heading.slug === currentSlug));
|
|
620
|
+
const partKey = `outline:${props.pageId}:part:${group.sections[0].heading.slug}`;
|
|
621
|
+
return /* @__PURE__ */ jsxs4(
|
|
622
|
+
"div",
|
|
623
|
+
{
|
|
624
|
+
className: clsx7("wg_navigationToc__groupSection", { "wg_navigationToc__groupSection--named": group.part !== void 0 }),
|
|
625
|
+
children: [
|
|
626
|
+
group.part !== void 0 && /* @__PURE__ */ jsx7("div", { className: clsx7("wg_navigationToc__group"), children: group.part }),
|
|
627
|
+
group.part !== void 0 && /* @__PURE__ */ jsx7(WgNavigationBranchToggle, { branchKey: partKey, label: group.part, collapsed: props.collapsed, onToggle: props.onToggle }),
|
|
628
|
+
/* @__PURE__ */ jsx7("ul", { className: clsx7("wg_navigationToc__list"), id: toNavigationBranchId(partKey), hidden: props.collapsed[partKey] === true, children: group.sections.map((section, index) => {
|
|
629
|
+
const currentSubIndex = section.subs.findIndex((sub) => sub.heading.slug === currentSlug);
|
|
630
|
+
const sectionKey = `outline:${props.pageId}:heading:${section.heading.slug}`;
|
|
631
|
+
return /* @__PURE__ */ jsxs4(
|
|
632
|
+
"li",
|
|
633
|
+
{
|
|
634
|
+
className: clsx7("wg_navigationToc__item", {
|
|
635
|
+
"wg_navigationToc__item--trail": index < currentIndex,
|
|
636
|
+
"wg_navigationToc__item--current": index === currentIndex
|
|
637
|
+
}),
|
|
638
|
+
children: [
|
|
639
|
+
/* @__PURE__ */ jsx7(
|
|
640
|
+
"a",
|
|
641
|
+
{
|
|
642
|
+
className: clsx7("wg_navigationToc__link", { "wg_navigationToc__link--active": section.heading.slug === currentSlug }),
|
|
643
|
+
href: `#${section.heading.slug}`,
|
|
644
|
+
"data-toc-link": "",
|
|
645
|
+
"aria-current": section.heading.slug === currentSlug ? "location" : void 0,
|
|
646
|
+
children: section.heading.text
|
|
647
|
+
}
|
|
648
|
+
),
|
|
649
|
+
section.subs.length > 0 && /* @__PURE__ */ jsx7(WgNavigationBranchToggle, { branchKey: sectionKey, label: section.heading.text, collapsed: props.collapsed, onToggle: props.onToggle }),
|
|
650
|
+
section.subs.length > 0 && /* @__PURE__ */ jsx7("ul", { className: clsx7("wg_navigationToc__sub"), id: toNavigationBranchId(sectionKey), hidden: props.collapsed[sectionKey] === true, children: section.subs.map((sub, subIndex) => /* @__PURE__ */ jsx7(
|
|
651
|
+
"li",
|
|
652
|
+
{
|
|
653
|
+
className: clsx7("wg_navigationToc__subItem", {
|
|
654
|
+
"wg_navigationToc__subItem--trail": subIndex < currentSubIndex,
|
|
655
|
+
"wg_navigationToc__subItem--current": subIndex === currentSubIndex
|
|
656
|
+
}),
|
|
657
|
+
children: /* @__PURE__ */ jsx7(
|
|
658
|
+
"a",
|
|
659
|
+
{
|
|
660
|
+
className: clsx7("wg_navigationToc__subLink", { "wg_navigationToc__subLink--active": sub.heading.slug === currentSlug }),
|
|
661
|
+
href: `#${sub.heading.slug}`,
|
|
662
|
+
"data-toc-sub-link": "",
|
|
663
|
+
"aria-current": sub.heading.slug === currentSlug ? "location" : void 0,
|
|
664
|
+
children: sub.heading.text
|
|
665
|
+
}
|
|
666
|
+
)
|
|
667
|
+
},
|
|
668
|
+
sub.heading.slug
|
|
669
|
+
)) })
|
|
670
|
+
]
|
|
671
|
+
},
|
|
672
|
+
section.heading.slug
|
|
673
|
+
);
|
|
674
|
+
}) })
|
|
675
|
+
]
|
|
676
|
+
},
|
|
677
|
+
group.sections[0].heading.slug
|
|
678
|
+
);
|
|
679
|
+
})
|
|
295
680
|
] });
|
|
296
681
|
};
|
|
297
682
|
|
|
298
|
-
// src/
|
|
299
|
-
var
|
|
300
|
-
var
|
|
301
|
-
var
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
var
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
"
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
683
|
+
// src/store/navigation/navigation-storage.ts
|
|
684
|
+
var navigation_tree_storage_key = "for-humanity:navigation-tree";
|
|
685
|
+
var navigation_storage_version = 1;
|
|
686
|
+
var navigation_scroll_storage_key = "for-humanity:navigation-scroll";
|
|
687
|
+
|
|
688
|
+
// src/store/navigation/to-navigation-scroll-state.ts
|
|
689
|
+
var toNavigationScrollState = (value) => {
|
|
690
|
+
const toPosition = (position) => {
|
|
691
|
+
if (typeof position !== "object" || position === null || !("navigation" in position) || typeof position.navigation !== "string" || !("pathname" in position) || typeof position.pathname !== "string" || !("documents" in position) || typeof position.documents !== "number" || !Number.isFinite(position.documents) || position.documents < 0 || !("outline" in position) || typeof position.outline !== "number" || !Number.isFinite(position.outline) || position.outline < 0) {
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
return { navigation: position.navigation, pathname: position.pathname, documents: position.documents, outline: position.outline };
|
|
695
|
+
};
|
|
696
|
+
if (typeof value !== "object" || value === null || !("positions" in value) || typeof value.positions !== "object" || value.positions === null) {
|
|
697
|
+
return { positions: {} };
|
|
698
|
+
}
|
|
699
|
+
const positions = {
|
|
700
|
+
wide: toPosition("wide" in value.positions ? value.positions.wide : void 0),
|
|
701
|
+
desktop: toPosition("desktop" in value.positions ? value.positions.desktop : void 0),
|
|
702
|
+
drawer: toPosition("drawer" in value.positions ? value.positions.drawer : void 0)
|
|
703
|
+
};
|
|
704
|
+
return { positions: Object.fromEntries(Object.entries(positions).filter((entry) => entry[1] !== void 0)) };
|
|
320
705
|
};
|
|
321
|
-
var asset_content_type_default = "application/octet-stream";
|
|
322
|
-
var asset_media_dir = `/${asset_dir}/media`;
|
|
323
|
-
var asset_media_extensions = /* @__PURE__ */ new Set([".svg", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".avif", ".pdf", ".csv", ".txt", ".zip"]);
|
|
324
706
|
|
|
325
|
-
// src/
|
|
326
|
-
import {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
var
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
707
|
+
// src/store/navigation/use-navigation-tree-store.ts
|
|
708
|
+
import { useSyncExternalStore } from "hono/jsx";
|
|
709
|
+
|
|
710
|
+
// src/store/navigation/_constant/tree.ts
|
|
711
|
+
var tree_server_state = { collapsed: {} };
|
|
712
|
+
|
|
713
|
+
// src/store/navigation/use-navigation-tree-store.ts
|
|
714
|
+
var useNavigationTreeStore = (tree) => {
|
|
715
|
+
const subscribe = tree === void 0 ? () => () => {
|
|
716
|
+
} : tree.subscribe;
|
|
717
|
+
const getSnapshot = tree === void 0 ? () => tree_server_state : tree.getState;
|
|
718
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
// src/util/dom/reveal-hash-target.ts
|
|
722
|
+
var revealHashTarget = (hash) => {
|
|
723
|
+
const target = findHashTarget(hash);
|
|
724
|
+
for (let fold = target?.closest("details"); fold; fold = fold.parentElement?.closest("details")) {
|
|
725
|
+
fold.open = true;
|
|
726
|
+
}
|
|
727
|
+
return target;
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
// src/component/widget/navigation/wg-navigation.tsx
|
|
731
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "hono/jsx/jsx-runtime";
|
|
732
|
+
var WgNavigation = (props) => {
|
|
733
|
+
const navigationTreeStore = useNavigationTreeStore(props.stores?.tree);
|
|
734
|
+
const [layout, setLayout] = useState3(() => {
|
|
735
|
+
if (props.stores === void 0) return "desktop";
|
|
736
|
+
if (matchMedia(navigation_mobile_query).matches) return "drawer";
|
|
737
|
+
return matchMedia(navigation_wide_query).matches ? "wide" : "desktop";
|
|
738
|
+
});
|
|
739
|
+
const [drawerOpen, setDrawerOpen] = useState3(false);
|
|
740
|
+
const navigationRef = useRef3(null);
|
|
741
|
+
const documentsRef = useRef3(null);
|
|
742
|
+
const drawerNavigationRef = useRef3(null);
|
|
743
|
+
const drawerDocumentsRef = useRef3(null);
|
|
744
|
+
const outlineRef = useRef3(null);
|
|
745
|
+
const dialogRef = useRef3(null);
|
|
746
|
+
const openButtonRef = useRef3(null);
|
|
747
|
+
const brandRef = useRef3(null);
|
|
748
|
+
const mobileRef = useRef3(null);
|
|
749
|
+
const wideRef = useRef3(null);
|
|
750
|
+
const layoutRef = useRef3(layout);
|
|
751
|
+
const focusRef = useRef3(null);
|
|
752
|
+
const restorePendingRef = useRef3(true);
|
|
753
|
+
const getNavigationLayout = () => {
|
|
754
|
+
if (mobileRef.current === null || wideRef.current === null) return layoutRef.current;
|
|
755
|
+
if (mobileRef.current.matches) return "drawer";
|
|
756
|
+
return wideRef.current.matches ? "wide" : "desktop";
|
|
757
|
+
};
|
|
758
|
+
const getNavigationPort = () => {
|
|
759
|
+
return layoutRef.current === "drawer" ? drawerNavigationRef.current : navigationRef.current;
|
|
760
|
+
};
|
|
761
|
+
const getDocumentsPort = () => {
|
|
762
|
+
return layoutRef.current === "drawer" ? drawerDocumentsRef.current : documentsRef.current;
|
|
763
|
+
};
|
|
764
|
+
const getNavigationSignature = () => {
|
|
765
|
+
const navigation = getNavigationPort();
|
|
766
|
+
if (navigation === null) return void 0;
|
|
767
|
+
return [...navigation.querySelectorAll(".wg_navigationNav__root a[href]")].map((link) => `${link.pathname}:${link.textContent}`).join("\n");
|
|
768
|
+
};
|
|
769
|
+
const saveScroll = () => {
|
|
770
|
+
const documents = getDocumentsPort();
|
|
771
|
+
if (props.stores === void 0 || documents === null || outlineRef.current === null || restorePendingRef.current || layoutRef.current !== getNavigationLayout() || layoutRef.current === "drawer" && dialogRef.current?.open !== true) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
const signature = getNavigationSignature();
|
|
775
|
+
if (signature === void 0) return;
|
|
776
|
+
const navigationPosition = {
|
|
777
|
+
navigation: signature,
|
|
778
|
+
pathname: location.pathname,
|
|
779
|
+
documents: documents.scrollTop,
|
|
780
|
+
outline: outlineRef.current.scrollTop
|
|
781
|
+
};
|
|
782
|
+
props.stores.scroll.setState((state) => ({
|
|
783
|
+
positions: {
|
|
784
|
+
...state.positions,
|
|
785
|
+
[layoutRef.current]: navigationPosition
|
|
786
|
+
}
|
|
787
|
+
}));
|
|
788
|
+
};
|
|
789
|
+
const restoreScroll = () => {
|
|
790
|
+
layoutRef.current = getNavigationLayout();
|
|
791
|
+
const documents = getDocumentsPort();
|
|
792
|
+
const navigation = getNavigationPort();
|
|
793
|
+
if (props.stores === void 0 || documents === null || outlineRef.current === null || navigation === null) return;
|
|
794
|
+
if (layoutRef.current === "drawer" && dialogRef.current?.open !== true) return;
|
|
795
|
+
const signature = getNavigationSignature();
|
|
796
|
+
if (signature === void 0) return;
|
|
797
|
+
const position = props.stores.scroll.getState().positions[layoutRef.current];
|
|
798
|
+
documents.scrollTop = 0;
|
|
799
|
+
outlineRef.current.scrollTop = 0;
|
|
800
|
+
if (position === void 0) {
|
|
801
|
+
restoreNavigationScroll({ key: navigation_scroll_storage_key, version: navigation_storage_version, layout: layoutRef.current, toState: toNavigationScrollState });
|
|
802
|
+
} else if (position.navigation === signature) {
|
|
803
|
+
documents.scrollTop = position.documents;
|
|
804
|
+
if (position.pathname === location.pathname) outlineRef.current.scrollTop = position.outline;
|
|
805
|
+
}
|
|
806
|
+
navigation.dataset.navigationLayout = layoutRef.current;
|
|
807
|
+
restorePendingRef.current = false;
|
|
808
|
+
saveScroll();
|
|
809
|
+
documents.dispatchEvent(new Event("scroll"));
|
|
810
|
+
outlineRef.current.dispatchEvent(new Event("scroll"));
|
|
811
|
+
};
|
|
812
|
+
const handleBranchToggle = (key) => {
|
|
813
|
+
props.stores?.tree.setState((state) => ({ collapsed: { ...state.collapsed, [key]: state.collapsed[key] !== true } }));
|
|
814
|
+
};
|
|
815
|
+
const handleDrawerClose = (_event) => {
|
|
816
|
+
if (dialogRef.current?.open === true) return;
|
|
817
|
+
document.body.classList.remove("wg_shell__root--drawerOpen");
|
|
818
|
+
setDrawerOpen(false);
|
|
819
|
+
};
|
|
820
|
+
const closeNavigation = () => {
|
|
821
|
+
saveScroll();
|
|
822
|
+
dialogRef.current?.close();
|
|
823
|
+
document.body.classList.remove("wg_shell__root--drawerOpen");
|
|
824
|
+
setDrawerOpen(false);
|
|
825
|
+
};
|
|
826
|
+
const handleOpenButtonClick = (_event) => {
|
|
827
|
+
if (getNavigationLayout() !== "drawer" || dialogRef.current === null || dialogRef.current.open) return;
|
|
828
|
+
dialogRef.current.showModal();
|
|
829
|
+
document.body.classList.add("wg_shell__root--drawerOpen");
|
|
830
|
+
setDrawerOpen(true);
|
|
831
|
+
restoreScroll();
|
|
832
|
+
};
|
|
833
|
+
const handleCloseButtonClick = (_event) => {
|
|
834
|
+
closeNavigation();
|
|
835
|
+
};
|
|
836
|
+
const handleDrawerCancel = (event) => {
|
|
837
|
+
event.preventDefault();
|
|
838
|
+
closeNavigation();
|
|
839
|
+
};
|
|
840
|
+
const handleDrawerClick = (event) => {
|
|
841
|
+
if (dialogRef.current === null || event.target !== dialogRef.current) return;
|
|
842
|
+
const bounds = dialogRef.current.getBoundingClientRect();
|
|
843
|
+
if (event.clientX < bounds.left || event.clientX > bounds.right || event.clientY < bounds.top || event.clientY > bounds.bottom) closeNavigation();
|
|
844
|
+
};
|
|
845
|
+
const handleNavigationClick = (event) => {
|
|
846
|
+
saveScroll();
|
|
847
|
+
if (dialogRef.current?.open !== true || event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || !(event.target instanceof Element)) {
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
const link = event.target.closest("a[href]");
|
|
851
|
+
if (!(link instanceof HTMLAnchorElement) || link.target !== "" && link.target !== "_self" || link.hasAttribute("download")) return;
|
|
852
|
+
closeNavigation();
|
|
853
|
+
if (link.origin === location.origin && link.pathname === location.pathname && link.search === location.search && link.hash) {
|
|
854
|
+
const target = revealHashTarget(link.hash);
|
|
855
|
+
if (target !== null) {
|
|
856
|
+
target.tabIndex = -1;
|
|
857
|
+
target.focus({ preventScroll: true });
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
const handleLayoutChange = () => {
|
|
862
|
+
const nextLayout = getNavigationLayout();
|
|
863
|
+
if (nextLayout === layoutRef.current) return;
|
|
864
|
+
if (document.activeElement instanceof HTMLElement) {
|
|
865
|
+
focusRef.current = {
|
|
866
|
+
navigation: document.activeElement.closest("[data-navigation]") !== null,
|
|
867
|
+
drawer: document.activeElement === openButtonRef.current || document.activeElement.closest("[data-navigation-drawer]") !== null,
|
|
868
|
+
branch: document.activeElement.getAttribute("data-navigation-toggle"),
|
|
869
|
+
href: document.activeElement.getAttribute("href")
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
if (nextLayout !== "drawer") closeNavigation();
|
|
873
|
+
restorePendingRef.current = true;
|
|
874
|
+
layoutRef.current = nextLayout;
|
|
875
|
+
flushSync(() => setLayout(nextLayout));
|
|
876
|
+
};
|
|
877
|
+
const handlePageShow = (event) => {
|
|
878
|
+
if (!event.persisted || props.stores === void 0) return;
|
|
879
|
+
restorePendingRef.current = true;
|
|
880
|
+
flushSync(() => {
|
|
881
|
+
props.stores?.tree.persist.rehydrate();
|
|
882
|
+
props.stores?.scroll.persist.rehydrate();
|
|
883
|
+
});
|
|
884
|
+
handleLayoutChange();
|
|
885
|
+
restoreScroll();
|
|
886
|
+
};
|
|
887
|
+
const handleStorageChange = (event) => {
|
|
888
|
+
if (event.key === navigation_tree_storage_key || event.key === null) {
|
|
889
|
+
flushSync(() => props.stores?.tree.persist.rehydrate());
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
const handleTreeChange = (state) => {
|
|
893
|
+
if (!(document.activeElement instanceof HTMLElement)) return;
|
|
894
|
+
for (const button of document.querySelectorAll("[data-navigation-toggle]")) {
|
|
895
|
+
const key = button.dataset.navigationToggle;
|
|
896
|
+
const controls = button.getAttribute("aria-controls");
|
|
897
|
+
if (key === void 0 || controls === null || state.collapsed[key] !== true) continue;
|
|
898
|
+
const branch = document.getElementById(controls);
|
|
899
|
+
if (branch?.contains(document.activeElement)) button.focus({ preventScroll: true });
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
useLayoutEffect4(() => {
|
|
903
|
+
if (props.stores === void 0) return;
|
|
904
|
+
mobileRef.current = matchMedia(navigation_mobile_query);
|
|
905
|
+
wideRef.current = matchMedia(navigation_wide_query);
|
|
906
|
+
mobileRef.current.addEventListener("change", handleLayoutChange);
|
|
907
|
+
wideRef.current.addEventListener("change", handleLayoutChange);
|
|
908
|
+
addEventListener("pagehide", saveScroll);
|
|
909
|
+
addEventListener("pageshow", handlePageShow);
|
|
910
|
+
addEventListener("storage", handleStorageChange);
|
|
911
|
+
const unsubscribeTree = props.stores.tree.subscribe(handleTreeChange);
|
|
912
|
+
return () => {
|
|
913
|
+
mobileRef.current?.removeEventListener("change", handleLayoutChange);
|
|
914
|
+
wideRef.current?.removeEventListener("change", handleLayoutChange);
|
|
915
|
+
mobileRef.current = null;
|
|
916
|
+
wideRef.current = null;
|
|
917
|
+
removeEventListener("pagehide", saveScroll);
|
|
918
|
+
removeEventListener("pageshow", handlePageShow);
|
|
919
|
+
removeEventListener("storage", handleStorageChange);
|
|
920
|
+
unsubscribeTree();
|
|
921
|
+
document.body.classList.remove("wg_shell__root--drawerOpen");
|
|
922
|
+
};
|
|
923
|
+
}, [props.stores]);
|
|
924
|
+
useLayoutEffect4(() => {
|
|
925
|
+
if (props.stores === void 0) return;
|
|
926
|
+
let active = true;
|
|
927
|
+
const restoreNavigation = () => {
|
|
928
|
+
if (!active) return;
|
|
929
|
+
restoreScroll();
|
|
930
|
+
if (focusRef.current === null) return;
|
|
931
|
+
const navigation = getNavigationPort();
|
|
932
|
+
if (layout === "drawer") {
|
|
933
|
+
if (focusRef.current.navigation) openButtonRef.current?.focus({ preventScroll: true });
|
|
934
|
+
} else if (focusRef.current.navigation && navigation !== null) {
|
|
935
|
+
const target = [...navigation.querySelectorAll("a[href], button")].find((element) => {
|
|
936
|
+
if (focusRef.current === null) return false;
|
|
937
|
+
return focusRef.current.branch !== null ? element.getAttribute("data-navigation-toggle") === focusRef.current.branch : focusRef.current.href !== null && element.getAttribute("href") === focusRef.current.href;
|
|
938
|
+
});
|
|
939
|
+
target?.focus({ preventScroll: true });
|
|
940
|
+
} else if (focusRef.current.drawer) {
|
|
941
|
+
brandRef.current?.focus({ preventScroll: true });
|
|
942
|
+
}
|
|
943
|
+
focusRef.current = null;
|
|
944
|
+
};
|
|
945
|
+
if (getDocumentsPort()?.isConnected) {
|
|
946
|
+
restoreNavigation();
|
|
947
|
+
} else {
|
|
948
|
+
queueMicrotask(restoreNavigation);
|
|
949
|
+
}
|
|
950
|
+
return () => {
|
|
951
|
+
active = false;
|
|
952
|
+
};
|
|
953
|
+
}, [layout, props.stores]);
|
|
954
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
955
|
+
/* @__PURE__ */ jsxs5("div", { className: clsx8("wg_navigation__sidebar", props.stores !== void 0 && "wg_navigation__sidebar--navigationReady"), children: [
|
|
956
|
+
/* @__PURE__ */ jsxs5("div", { className: clsx8("wg_navigation__brandRow"), children: [
|
|
957
|
+
/* @__PURE__ */ jsx8(
|
|
958
|
+
"a",
|
|
959
|
+
{
|
|
960
|
+
ref: props.stores === void 0 ? void 0 : brandRef,
|
|
961
|
+
className: clsx8("wg_navigation__brand"),
|
|
962
|
+
href: "/",
|
|
963
|
+
"aria-current": props.data.home ? "page" : void 0,
|
|
964
|
+
children: props.data.title
|
|
965
|
+
}
|
|
966
|
+
),
|
|
967
|
+
/* @__PURE__ */ jsx8(
|
|
968
|
+
"button",
|
|
969
|
+
{
|
|
970
|
+
ref: props.stores === void 0 ? void 0 : openButtonRef,
|
|
971
|
+
className: clsx8("wg_navigation__menuToggle", props.stores !== void 0 && layout === "drawer" && "wg_navigation__menuToggle--visible"),
|
|
972
|
+
type: "button",
|
|
973
|
+
"aria-label": copy_nav_open,
|
|
974
|
+
"aria-controls": "fh-navigation-drawer",
|
|
975
|
+
"aria-expanded": String(drawerOpen),
|
|
976
|
+
"data-navigation-open": "",
|
|
977
|
+
onClick: handleOpenButtonClick,
|
|
978
|
+
children: /* @__PURE__ */ jsx8("svg", { className: clsx8("wg_navigation__menuIcon"), viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx8("path", { d: "M4 6h16M4 12h16M4 18h16" }) })
|
|
979
|
+
}
|
|
980
|
+
)
|
|
981
|
+
] }),
|
|
982
|
+
layout !== "drawer" && /* @__PURE__ */ jsx8("div", { ref: props.stores === void 0 ? void 0 : navigationRef, className: clsx8("wg_navigation__navigation"), "data-navigation": "", children: /* @__PURE__ */ jsx8(WgNavigationScroll, { portRef: documentsRef, kind: "documents", ready: props.stores !== void 0, onScroll: saveScroll, onClick: handleNavigationClick, children: /* @__PURE__ */ jsx8(
|
|
983
|
+
WgNavigationNav,
|
|
984
|
+
{
|
|
985
|
+
groups: props.data.groups,
|
|
986
|
+
collapsed: navigationTreeStore.collapsed,
|
|
987
|
+
onToggle: props.stores === void 0 ? void 0 : handleBranchToggle
|
|
988
|
+
}
|
|
989
|
+
) }) })
|
|
343
990
|
] }),
|
|
344
|
-
/* @__PURE__ */
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
991
|
+
/* @__PURE__ */ jsx8("aside", { className: clsx8("wg_navigation__tocRail"), "data-navigation-rail": "", children: /* @__PURE__ */ jsx8("div", { className: clsx8("wg_navigation__outline"), "data-navigation-outline": "", children: /* @__PURE__ */ jsx8(WgNavigationScroll, { portRef: outlineRef, kind: "outline", ready: props.stores !== void 0, onScroll: saveScroll, onClick: handleNavigationClick, children: props.data.outline.length > 0 && /* @__PURE__ */ jsx8(
|
|
992
|
+
WgNavigationToc,
|
|
993
|
+
{
|
|
994
|
+
groups: props.data.outline,
|
|
995
|
+
pageId: props.data.pageId,
|
|
996
|
+
collapsed: navigationTreeStore.collapsed,
|
|
997
|
+
onToggle: props.stores === void 0 ? void 0 : handleBranchToggle
|
|
998
|
+
}
|
|
999
|
+
) }) }) }),
|
|
1000
|
+
/* @__PURE__ */ jsxs5(
|
|
1001
|
+
"dialog",
|
|
1002
|
+
{
|
|
1003
|
+
ref: props.stores === void 0 ? void 0 : dialogRef,
|
|
1004
|
+
className: clsx8("wg_navigation__drawer"),
|
|
1005
|
+
id: "fh-navigation-drawer",
|
|
1006
|
+
"aria-labelledby": "fh-navigation-title",
|
|
1007
|
+
"data-navigation-drawer": "",
|
|
1008
|
+
onClose: handleDrawerClose,
|
|
1009
|
+
onCancel: handleDrawerCancel,
|
|
1010
|
+
onClick: handleDrawerClick,
|
|
1011
|
+
children: [
|
|
1012
|
+
/* @__PURE__ */ jsxs5("div", { className: clsx8("wg_navigation__drawerHeader"), children: [
|
|
1013
|
+
/* @__PURE__ */ jsx8("h2", { className: clsx8("wg_navigation__drawerTitle"), id: "fh-navigation-title", children: copy_nav_title }),
|
|
1014
|
+
/* @__PURE__ */ jsx8("button", { className: clsx8("wg_navigation__drawerClose"), type: "button", "aria-label": copy_nav_close, "data-navigation-close": "", onClick: handleCloseButtonClick, children: /* @__PURE__ */ jsx8("svg", { className: clsx8("wg_navigation__menuIcon"), viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx8("path", { d: "m6 6 12 12M18 6 6 18" }) }) })
|
|
1015
|
+
] }),
|
|
1016
|
+
/* @__PURE__ */ jsx8("div", { className: clsx8("wg_navigation__drawerContent"), "data-navigation-content": "", children: layout === "drawer" && /* @__PURE__ */ jsx8("div", { ref: props.stores === void 0 ? void 0 : drawerNavigationRef, className: clsx8("wg_navigation__navigation"), "data-navigation": "", children: /* @__PURE__ */ jsx8(
|
|
1017
|
+
WgNavigationScroll,
|
|
350
1018
|
{
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
1019
|
+
portRef: drawerDocumentsRef,
|
|
1020
|
+
kind: "documents",
|
|
1021
|
+
ready: props.stores !== void 0,
|
|
1022
|
+
onScroll: saveScroll,
|
|
1023
|
+
onClick: handleNavigationClick,
|
|
1024
|
+
children: /* @__PURE__ */ jsx8(
|
|
1025
|
+
WgNavigationNav,
|
|
1026
|
+
{
|
|
1027
|
+
groups: props.data.groups,
|
|
1028
|
+
collapsed: navigationTreeStore.collapsed,
|
|
1029
|
+
onToggle: props.stores === void 0 ? void 0 : handleBranchToggle
|
|
1030
|
+
}
|
|
1031
|
+
)
|
|
358
1032
|
}
|
|
359
|
-
)
|
|
360
|
-
]
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
1033
|
+
) }) })
|
|
1034
|
+
]
|
|
1035
|
+
}
|
|
1036
|
+
)
|
|
1037
|
+
] });
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
// src/component/widget/prose/_constant/heading-highlight.ts
|
|
1041
|
+
var heading_highlight_hold_ms = 3e3;
|
|
1042
|
+
|
|
1043
|
+
// src/component/widget/shell-controls/wg-shell-controls.tsx
|
|
1044
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "hono/jsx/jsx-runtime";
|
|
1045
|
+
var WgShellControls = (props) => {
|
|
1046
|
+
const headingRef = useRef4(null);
|
|
1047
|
+
const timerRef = useRef4(0);
|
|
1048
|
+
const arrivalRef = useRef4(null);
|
|
1049
|
+
const lifetimeRef = useRef4(null);
|
|
1050
|
+
const userScrollRef = useRef4(null);
|
|
1051
|
+
const clearHeadingHighlight = () => {
|
|
1052
|
+
clearTimeout(timerRef.current);
|
|
1053
|
+
timerRef.current = 0;
|
|
1054
|
+
arrivalRef.current?.abort();
|
|
1055
|
+
arrivalRef.current = null;
|
|
1056
|
+
headingRef.current?.classList.remove("wg_prose__headingText--highlighted");
|
|
1057
|
+
headingRef.current = null;
|
|
1058
|
+
};
|
|
1059
|
+
const handleHighlightArrival = (event) => {
|
|
1060
|
+
if (event.target !== document) return;
|
|
1061
|
+
clearTimeout(timerRef.current);
|
|
1062
|
+
arrivalRef.current?.abort();
|
|
1063
|
+
arrivalRef.current = null;
|
|
1064
|
+
timerRef.current = window.setTimeout(clearHeadingHighlight, heading_highlight_hold_ms);
|
|
1065
|
+
};
|
|
1066
|
+
const highlightHeading = (target) => {
|
|
1067
|
+
clearHeadingHighlight();
|
|
1068
|
+
headingRef.current = target === null ? null : target.querySelector(".wg_prose__headingText");
|
|
1069
|
+
if (headingRef.current === null) return;
|
|
1070
|
+
headingRef.current.classList.add("wg_prose__headingText--highlighted");
|
|
1071
|
+
timerRef.current = window.setTimeout(clearHeadingHighlight, heading_highlight_hold_ms);
|
|
1072
|
+
arrivalRef.current = new AbortController();
|
|
1073
|
+
document.addEventListener("scrollend", handleHighlightArrival, { signal: arrivalRef.current.signal });
|
|
1074
|
+
};
|
|
1075
|
+
const handleHashClick = (event) => {
|
|
1076
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
1077
|
+
const link = event.target instanceof Element ? event.target.closest("a[href]") : null;
|
|
1078
|
+
if (link instanceof HTMLAnchorElement && (link.target === "" || link.target === "_self") && !link.hasAttribute("download") && link.origin === location.origin && link.pathname === location.pathname && link.search === location.search && link.hash) {
|
|
1079
|
+
const target = revealHashTarget(link.hash);
|
|
1080
|
+
if (link.hash === location.hash) highlightHeading(target);
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
const handleHashChange = () => {
|
|
1084
|
+
const target = revealHashTarget(location.hash);
|
|
1085
|
+
target?.scrollIntoView();
|
|
1086
|
+
highlightHeading(target);
|
|
1087
|
+
};
|
|
1088
|
+
const handleUserScroll = () => {
|
|
1089
|
+
userScrollRef.current?.abort();
|
|
1090
|
+
};
|
|
1091
|
+
const handlePageLoad = async () => {
|
|
1092
|
+
const lifetime = lifetimeRef.current;
|
|
1093
|
+
const hash = location.hash;
|
|
1094
|
+
const target = revealHashTarget(hash);
|
|
1095
|
+
await document.fonts.ready;
|
|
1096
|
+
if (lifetime === null || lifetime.signal.aborted) return;
|
|
1097
|
+
if (target !== null && !userScrollRef.current?.signal.aborted && hash === location.hash) {
|
|
1098
|
+
target.scrollIntoView({ behavior: "instant" });
|
|
1099
|
+
highlightHeading(target);
|
|
1100
|
+
}
|
|
1101
|
+
document.documentElement.style.removeProperty("scroll-behavior");
|
|
1102
|
+
};
|
|
1103
|
+
const handleBodyReady = () => {
|
|
1104
|
+
revealHashTarget(location.hash);
|
|
1105
|
+
if (document.readyState === "complete") void handlePageLoad();
|
|
1106
|
+
};
|
|
1107
|
+
useLayoutEffect5(() => {
|
|
1108
|
+
const lifetime = new AbortController();
|
|
1109
|
+
lifetimeRef.current = lifetime;
|
|
1110
|
+
userScrollRef.current = new AbortController();
|
|
1111
|
+
document.documentElement.style.scrollBehavior = "auto";
|
|
1112
|
+
document.addEventListener("click", handleHashClick, { signal: lifetime.signal });
|
|
1113
|
+
addEventListener("hashchange", handleHashChange, { signal: lifetime.signal });
|
|
1114
|
+
addEventListener("load", handlePageLoad, { once: true, signal: lifetime.signal });
|
|
1115
|
+
for (const type of ["wheel", "touchmove", "keydown", "mousedown"]) {
|
|
1116
|
+
addEventListener(type, handleUserScroll, { once: true, passive: true, signal: lifetime.signal });
|
|
1117
|
+
}
|
|
1118
|
+
if (document.readyState === "loading") {
|
|
1119
|
+
document.addEventListener("DOMContentLoaded", handleBodyReady, { once: true, signal: lifetime.signal });
|
|
1120
|
+
} else {
|
|
1121
|
+
handleBodyReady();
|
|
1122
|
+
}
|
|
1123
|
+
return () => {
|
|
1124
|
+
lifetime.abort();
|
|
1125
|
+
lifetimeRef.current = null;
|
|
1126
|
+
userScrollRef.current?.abort();
|
|
1127
|
+
userScrollRef.current = null;
|
|
1128
|
+
clearHeadingHighlight();
|
|
1129
|
+
document.documentElement.style.removeProperty("scroll-behavior");
|
|
1130
|
+
};
|
|
1131
|
+
}, []);
|
|
1132
|
+
useEffect(() => {
|
|
1133
|
+
if (!props.reload || lifetimeRef.current === null) return;
|
|
1134
|
+
const source = new EventSource(asset_reload_path);
|
|
1135
|
+
source.onmessage = () => location.reload();
|
|
1136
|
+
return () => source.close();
|
|
1137
|
+
}, [props.reload]);
|
|
1138
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1139
|
+
/* @__PURE__ */ jsx9("div", { className: clsx9("wg_shellControls__navigation"), children: /* @__PURE__ */ jsx9(WgNavigation, { data: props.data, stores: props.stores }) }),
|
|
1140
|
+
/* @__PURE__ */ jsx9(WgCursorFace, { ready: props.stores !== void 0 })
|
|
1141
|
+
] });
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
// src/component/widget/shell/wg-shell.tsx
|
|
1145
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "hono/jsx/jsx-runtime";
|
|
1146
|
+
var WgShell = (props) => {
|
|
1147
|
+
const navigationData = toNavigationData({ site: props.site, docs: props.docs, current: props.current, outline: props.outline });
|
|
1148
|
+
return /* @__PURE__ */ jsxs7("html", { lang: "ko", children: [
|
|
1149
|
+
/* @__PURE__ */ jsxs7("head", { children: [
|
|
1150
|
+
/* @__PURE__ */ jsx10("meta", { charSet: "utf-8" }),
|
|
1151
|
+
/* @__PURE__ */ jsx10("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
|
|
1152
|
+
props.site.description !== void 0 && /* @__PURE__ */ jsx10("meta", { name: "description", content: props.site.description }),
|
|
1153
|
+
/* @__PURE__ */ jsx10("title", { children: props.title === void 0 ? props.site.title : `${props.title} \xB7 ${props.site.title}` }),
|
|
1154
|
+
/* @__PURE__ */ jsx10("link", { rel: "icon", href: asset_favicon_path, type: "image/svg+xml" }),
|
|
1155
|
+
/* @__PURE__ */ jsx10("style", { dangerouslySetInnerHTML: { __html: props.assets.fontCss } }),
|
|
1156
|
+
props.assets.preload.map((href) => /* @__PURE__ */ jsx10("link", { rel: "preload", href, as: "font", type: "font/woff2", crossOrigin: "" }, href)),
|
|
1157
|
+
/* @__PURE__ */ jsx10("link", { rel: "stylesheet", href: props.assets.stylePath })
|
|
1158
|
+
] }),
|
|
1159
|
+
/* @__PURE__ */ jsxs7("body", { className: clsx10("wg_shell__root"), children: [
|
|
1160
|
+
/* @__PURE__ */ jsx10("div", { className: clsx10("wg_shell__browserRoot"), "data-shell-browser-root": "", "data-shell-reload": props.assets.reload ? "" : void 0, children: /* @__PURE__ */ jsx10(WgShellControls, { data: navigationData, reload: props.assets.reload }) }),
|
|
1161
|
+
/* @__PURE__ */ jsx10("script", { type: "application/json", id: "fh-navigation-data", dangerouslySetInnerHTML: { __html: toNavigationJson(navigationData) } }),
|
|
1162
|
+
/* @__PURE__ */ jsx10("script", { dangerouslySetInnerHTML: { __html: props.assets.browserScript } }),
|
|
1163
|
+
/* @__PURE__ */ jsx10("main", { className: clsx10("wg_shell__main"), children: props.children })
|
|
377
1164
|
] })
|
|
378
1165
|
] });
|
|
379
1166
|
};
|
|
380
1167
|
|
|
381
1168
|
// src/page/doc/pg-doc.tsx
|
|
382
|
-
import { jsx as
|
|
1169
|
+
import { jsx as jsx11 } from "hono/jsx/jsx-runtime";
|
|
383
1170
|
var PgDoc = (props) => {
|
|
384
|
-
return /* @__PURE__ */
|
|
1171
|
+
return /* @__PURE__ */ jsx11(WgShell, { site: props.site, docs: props.docs, assets: props.assets, title: props.doc.data.name, current: props.doc.id, outline: props.doc.outline, children: /* @__PURE__ */ jsx11(WgProse, { html: props.doc.html }) });
|
|
385
1172
|
};
|
|
386
1173
|
|
|
387
1174
|
// src/page/home/pg-home.tsx
|
|
388
|
-
import { jsx as
|
|
1175
|
+
import { jsx as jsx12 } from "hono/jsx/jsx-runtime";
|
|
389
1176
|
var PgHome = (props) => {
|
|
390
|
-
return /* @__PURE__ */
|
|
1177
|
+
return /* @__PURE__ */ jsx12(WgShell, { site: props.site, docs: props.docs, assets: props.assets, outline: props.home?.outline, children: props.home === void 0 ? /* @__PURE__ */ jsx12(WgProse, { head: { title: props.site.title, lead: copy_home_missing } }) : /* @__PURE__ */ jsx12(WgProse, { html: props.home.html }) });
|
|
391
1178
|
};
|
|
392
1179
|
|
|
393
|
-
// src/app.tsx
|
|
394
|
-
import { jsx as
|
|
1180
|
+
// src/entry/cli/_function/create-app.tsx
|
|
1181
|
+
import { jsx as jsx13 } from "hono/jsx/jsx-runtime";
|
|
395
1182
|
var toHtml = (page) => {
|
|
396
|
-
return `<!DOCTYPE html>${
|
|
1183
|
+
return html`<!DOCTYPE html>${page}`;
|
|
397
1184
|
};
|
|
398
1185
|
var createApp = (options) => {
|
|
399
1186
|
const app = new Hono();
|
|
400
|
-
app.get("/", (c) => c.html(toHtml(/* @__PURE__ */
|
|
1187
|
+
app.get("/", (c) => c.html(toHtml(/* @__PURE__ */ jsx13(PgHome, { site: options.site, docs: options.store.docs, assets: options.assets, home: options.store.home }))));
|
|
401
1188
|
app.get(
|
|
402
1189
|
"/:slug{.+}/",
|
|
403
1190
|
ssgParams(() => options.store.docs.map((doc) => ({ slug: doc.id }))),
|
|
404
1191
|
(c) => {
|
|
405
1192
|
const doc = options.store.docs.find((entry) => entry.id === c.req.param("slug"));
|
|
406
|
-
return doc === void 0 ? c.notFound() : c.html(toHtml(/* @__PURE__ */
|
|
1193
|
+
return doc === void 0 ? c.notFound() : c.html(toHtml(/* @__PURE__ */ jsx13(PgDoc, { site: options.site, docs: options.store.docs, assets: options.assets, doc })));
|
|
407
1194
|
}
|
|
408
1195
|
);
|
|
409
1196
|
return app;
|
|
410
1197
|
};
|
|
411
1198
|
|
|
412
|
-
// src/
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
var
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
1199
|
+
// src/entry/cli/_function/create-dev-app.ts
|
|
1200
|
+
import { readFile } from "node:fs/promises";
|
|
1201
|
+
import { extname } from "node:path";
|
|
1202
|
+
import { Hono as Hono2 } from "hono";
|
|
1203
|
+
import { streamSSE } from "hono/streaming";
|
|
1204
|
+
var createDevApp = (options) => {
|
|
1205
|
+
const app = new Hono2();
|
|
1206
|
+
const handleAsset = async (c) => {
|
|
1207
|
+
const file = options.files.get(c.req.path);
|
|
1208
|
+
if (file === void 0) {
|
|
1209
|
+
return c.notFound();
|
|
1210
|
+
}
|
|
1211
|
+
c.header("content-type", asset_content_types[extname(file).toLowerCase()] ?? asset_content_type_default);
|
|
1212
|
+
if (extname(file) === ".woff2") {
|
|
1213
|
+
c.header("Cache-Control", font_cache_control);
|
|
1214
|
+
}
|
|
1215
|
+
return c.body(await readFile(file));
|
|
1216
|
+
};
|
|
1217
|
+
app.get(
|
|
1218
|
+
asset_reload_path,
|
|
1219
|
+
(c) => streamSSE(
|
|
1220
|
+
c,
|
|
1221
|
+
(stream) => new Promise((done) => {
|
|
1222
|
+
const handleChange = async () => {
|
|
1223
|
+
await stream.writeSSE({ data: "change" });
|
|
1224
|
+
done();
|
|
1225
|
+
};
|
|
1226
|
+
options.reload.once("change", handleChange);
|
|
1227
|
+
stream.onAbort(() => {
|
|
1228
|
+
options.reload.off("change", handleChange);
|
|
1229
|
+
done();
|
|
1230
|
+
});
|
|
1231
|
+
})
|
|
1232
|
+
)
|
|
1233
|
+
);
|
|
1234
|
+
app.get(`/${asset_dir}/*`, handleAsset);
|
|
1235
|
+
app.get(asset_favicon_path, handleAsset);
|
|
1236
|
+
if (options.crawling !== void 0) {
|
|
1237
|
+
app.on("GET", [crawling_robots_path, crawling_sitemap_path], (c) => options.crawling?.fetch(c.req.raw, c.env) ?? c.notFound());
|
|
1238
|
+
}
|
|
1239
|
+
app.all("/*", (c) => options.pages.fetch(c.req.raw, c.env));
|
|
1240
|
+
return app;
|
|
1241
|
+
};
|
|
431
1242
|
|
|
432
|
-
// src/
|
|
1243
|
+
// src/entry/cli/_function/create-processor/create-processor.ts
|
|
433
1244
|
import rehypeShiki from "@shikijs/rehype";
|
|
434
1245
|
import rehypeRaw from "rehype-raw";
|
|
435
1246
|
import rehypeStringify from "rehype-stringify";
|
|
@@ -1047,9 +1858,9 @@ var remarkUnknownDirectives = () => (tree, file) => {
|
|
|
1047
1858
|
});
|
|
1048
1859
|
};
|
|
1049
1860
|
|
|
1050
|
-
// src/
|
|
1861
|
+
// src/entry/cli/_function/create-processor/_rehype-assets.ts
|
|
1051
1862
|
import { existsSync as existsSync2, realpathSync, statSync } from "node:fs";
|
|
1052
|
-
import { dirname as dirname2, extname, isAbsolute, relative as relative2, resolve as resolve2, sep } from "node:path";
|
|
1863
|
+
import { dirname as dirname2, extname as extname2, isAbsolute, relative as relative2, resolve as resolve2, sep } from "node:path";
|
|
1053
1864
|
import { visit as visit7 } from "unist-util-visit";
|
|
1054
1865
|
|
|
1055
1866
|
// src/util/file/to-asset-path.ts
|
|
@@ -1061,7 +1872,7 @@ var toAssetPath = (options) => {
|
|
|
1061
1872
|
return `${posix2.dirname(options.path)}/${posix2.basename(options.path, extension)}.${createHash("sha256").update(readFileSync(options.file)).digest("hex")}${extension}`;
|
|
1062
1873
|
};
|
|
1063
1874
|
|
|
1064
|
-
// src/
|
|
1875
|
+
// src/entry/cli/_function/create-processor/_rehype-assets.ts
|
|
1065
1876
|
var rehypeAssets = (options) => (tree, file) => {
|
|
1066
1877
|
visit7(tree, "element", (node) => {
|
|
1067
1878
|
const property = node.tagName === "img" ? "src" : "href";
|
|
@@ -1074,7 +1885,7 @@ var rehypeAssets = (options) => (tree, file) => {
|
|
|
1074
1885
|
return;
|
|
1075
1886
|
}
|
|
1076
1887
|
const path = decodeURIComponent(match[1]);
|
|
1077
|
-
const extension =
|
|
1888
|
+
const extension = extname2(path).toLowerCase();
|
|
1078
1889
|
if (!asset_media_extensions.has(extension)) {
|
|
1079
1890
|
if (node.tagName === "img") {
|
|
1080
1891
|
file.fail(`${copy_error_asset}: \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC774\uBBF8\uC9C0 \uD615\uC2DD \xB7 ${url}`, node);
|
|
@@ -1100,7 +1911,7 @@ var rehypeAssets = (options) => (tree, file) => {
|
|
|
1100
1911
|
});
|
|
1101
1912
|
};
|
|
1102
1913
|
|
|
1103
|
-
// src/
|
|
1914
|
+
// src/entry/cli/_function/create-processor/_rehype-heading-ids.ts
|
|
1104
1915
|
import Slugger from "github-slugger";
|
|
1105
1916
|
import { toString as toPlainText3 } from "hast-util-to-string";
|
|
1106
1917
|
import { visit as visit8 } from "unist-util-visit";
|
|
@@ -1122,7 +1933,7 @@ var rehypeHeadingIds = () => (tree, file) => {
|
|
|
1122
1933
|
}
|
|
1123
1934
|
};
|
|
1124
1935
|
|
|
1125
|
-
// src/
|
|
1936
|
+
// src/entry/cli/_function/create-processor/_remark-report.ts
|
|
1126
1937
|
import { relative as relative3 } from "node:path";
|
|
1127
1938
|
var remarkReport = (options) => (_tree, file) => {
|
|
1128
1939
|
const path = relative3(options.root, file.path);
|
|
@@ -1131,13 +1942,13 @@ var remarkReport = (options) => (_tree, file) => {
|
|
|
1131
1942
|
}
|
|
1132
1943
|
};
|
|
1133
1944
|
|
|
1134
|
-
// src/
|
|
1945
|
+
// src/entry/cli/_function/create-processor/create-processor.ts
|
|
1135
1946
|
var createProcessor = (options) => {
|
|
1136
1947
|
return unified().use(remarkParse).use(remarkFrontmatter, ["yaml"]).use(remarkGfm).use(remarkSmartypants).use(remarkDirective).use(remarkBlocks).use(remarkParts).use(remarkFlow).use(remarkStatus, { status: options.site.status }).use(remarkSwatch).use(remarkLinks, { root: options.root }).use(remarkUnknownDirectives).use(remarkReport, { root: options.root }).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeShiki, { theme: createCssVariablesTheme({ name: "for-humanity", variablePrefix: "--app-code-" }) }).use(rehypeHead).use(rehypeHeadingIds).use(rehypeSections).use(rehypeTables).use(rehypeRaw).use(rehypeAssets, { root: options.root, files: options.files ?? /* @__PURE__ */ new Map() }).use(rehypeStringify, { allowDangerousHtml: true });
|
|
1137
1948
|
};
|
|
1138
1949
|
|
|
1139
|
-
// src/
|
|
1140
|
-
import { readdir, readFile } from "node:fs/promises";
|
|
1950
|
+
// src/entry/cli/_function/read-docs.ts
|
|
1951
|
+
import { readdir, readFile as readFile2 } from "node:fs/promises";
|
|
1141
1952
|
import { join, posix as posix3, sep as sep2 } from "node:path";
|
|
1142
1953
|
import { VFile } from "vfile";
|
|
1143
1954
|
import { parse as parseYaml } from "yaml";
|
|
@@ -1184,7 +1995,7 @@ var docDataSchema = z2.object({
|
|
|
1184
1995
|
order: z2.number().int().nonnegative().default(doc_order_default)
|
|
1185
1996
|
});
|
|
1186
1997
|
|
|
1187
|
-
// src/
|
|
1998
|
+
// src/entry/cli/_function/read-docs.ts
|
|
1188
1999
|
var readDocs = async (options) => {
|
|
1189
2000
|
const paths = (await readdir(options.root, { recursive: true })).filter(
|
|
1190
2001
|
(path) => /\.mdx?$/i.test(path) && !/^(readme|agents|claude)\.md$/i.test(path) && !path.split(sep2).includes("node_modules") && !path.startsWith(`dist${sep2}`)
|
|
@@ -1193,10 +2004,10 @@ var readDocs = async (options) => {
|
|
|
1193
2004
|
paths.map(async (path) => {
|
|
1194
2005
|
const id = path.replace(/\.mdx?$/i, "").split(sep2).join("/").toLowerCase();
|
|
1195
2006
|
const segments = id.split("/");
|
|
1196
|
-
if (segments.some((segment) => segment === "" || segment === "." || segment === ".." || segment === "index.html") || /[#?%*:\\]/.test(id) || /[\p{Cc}]/u.test(id) || segments[0] === asset_dir || segments[0] === asset_favicon_path.slice(1)) {
|
|
2007
|
+
if (segments.some((segment) => segment === "" || segment === "." || segment === ".." || segment === "index.html") || /[#?%*:\\]/.test(id) || /[\p{Cc}]/u.test(id) || options.reserved?.includes(segments[0]) === true || segments[0] === asset_dir || segments[0] === asset_favicon_path.slice(1)) {
|
|
1197
2008
|
throw new Error(`${copy_error_doc_id}: ${path}`);
|
|
1198
2009
|
}
|
|
1199
|
-
const source = await
|
|
2010
|
+
const source = await readFile2(join(options.root, path), "utf8");
|
|
1200
2011
|
const file = new VFile({ value: source.replace(/^\uFEFF/, ""), path: join(options.root, path) });
|
|
1201
2012
|
const tree = options.processor.parse(file);
|
|
1202
2013
|
const frontmatter = tree.children[0];
|
|
@@ -1246,8 +2057,8 @@ var readDocs = async (options) => {
|
|
|
1246
2057
|
});
|
|
1247
2058
|
};
|
|
1248
2059
|
|
|
1249
|
-
// src/
|
|
1250
|
-
import { readdir as readdir2, readFile as
|
|
2060
|
+
// src/entry/cli/_function/read-home.ts
|
|
2061
|
+
import { readdir as readdir2, readFile as readFile3 } from "node:fs/promises";
|
|
1251
2062
|
import { join as join2 } from "node:path";
|
|
1252
2063
|
import { VFile as VFile2 } from "vfile";
|
|
1253
2064
|
var readHome = async (options) => {
|
|
@@ -1260,49 +2071,32 @@ var readHome = async (options) => {
|
|
|
1260
2071
|
}
|
|
1261
2072
|
const path = join2(options.root, paths[0]);
|
|
1262
2073
|
const fh = { headings: [], sections: [] };
|
|
1263
|
-
const file = new VFile2({ value: (await
|
|
2074
|
+
const file = new VFile2({ value: (await readFile3(path, "utf8")).replace(/^\uFEFF/, ""), path, data: { fh } });
|
|
1264
2075
|
await options.processor.process(file);
|
|
1265
2076
|
return { html: String(file), outline: { headings: fh.headings, sections: fh.sections } };
|
|
1266
2077
|
};
|
|
1267
2078
|
|
|
1268
|
-
// src/
|
|
1269
|
-
import {
|
|
1270
|
-
import {
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
return c.notFound();
|
|
1279
|
-
}
|
|
1280
|
-
c.header("content-type", asset_content_types[extname2(file).toLowerCase()] ?? asset_content_type_default);
|
|
1281
|
-
if (extname2(file) === ".woff2") {
|
|
1282
|
-
c.header("Cache-Control", font_cache_control);
|
|
1283
|
-
}
|
|
1284
|
-
return c.body(await readFile3(file));
|
|
1285
|
-
};
|
|
2079
|
+
// src/entry/cli/_function/to-crawling-app.ts
|
|
2080
|
+
import { Hono as Hono3 } from "hono";
|
|
2081
|
+
import { html as html2 } from "hono/html";
|
|
2082
|
+
var toCrawlingApp = (params) => {
|
|
2083
|
+
const app = new Hono3();
|
|
2084
|
+
app.get(crawling_robots_path, (c) => c.text(`User-agent: *
|
|
2085
|
+
Allow: /
|
|
2086
|
+
|
|
2087
|
+
Sitemap: ${params.url}${crawling_sitemap_path}
|
|
2088
|
+
`));
|
|
1286
2089
|
app.get(
|
|
1287
|
-
|
|
1288
|
-
(
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
options.reload.once("change", handleChange);
|
|
1296
|
-
stream.onAbort(() => {
|
|
1297
|
-
options.reload.off("change", handleChange);
|
|
1298
|
-
done();
|
|
1299
|
-
});
|
|
1300
|
-
})
|
|
2090
|
+
crawling_sitemap_path,
|
|
2091
|
+
(_c) => new Response(
|
|
2092
|
+
html2`<?xml version="1.0" encoding="UTF-8"?>
|
|
2093
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
2094
|
+
<url><loc>${params.url}/</loc></url>
|
|
2095
|
+
${params.store.docs.map((doc) => html2`<url><loc>${params.url}/${doc.id.split("/").map(encodeURIComponent).join("/")}/</loc></url>`)}
|
|
2096
|
+
</urlset>`.toString(),
|
|
2097
|
+
{ headers: { "Content-Type": "application/xml; charset=utf-8" } }
|
|
1301
2098
|
)
|
|
1302
2099
|
);
|
|
1303
|
-
app.get(`/${asset_dir}/*`, handleAsset);
|
|
1304
|
-
app.get(asset_favicon_path, handleAsset);
|
|
1305
|
-
app.all("/*", (c) => options.pages.fetch(c.req.raw, c.env));
|
|
1306
2100
|
return app;
|
|
1307
2101
|
};
|
|
1308
2102
|
|
|
@@ -1329,6 +2123,10 @@ var siteConfigSchema = z3.object({
|
|
|
1329
2123
|
* HTML 설명 메타데이터 · 선택
|
|
1330
2124
|
*/
|
|
1331
2125
|
description: z3.string().optional(),
|
|
2126
|
+
/**
|
|
2127
|
+
* 공개 사이트 루트 URL · 지정할 때만 robots.txt와 sitemap.xml 생성
|
|
2128
|
+
*/
|
|
2129
|
+
url: z3.url({ protocol: /^https?$/ }).transform((value) => new URL(value)).refine((value) => value.username === "" && value.password === "" && value.pathname === "/" && value.search === "" && value.hash === "", copy_error_site_url).transform((value) => value.origin).optional(),
|
|
1332
2130
|
/**
|
|
1333
2131
|
* 탐색 묶음 경로의 읽는 순서 · 미지정 형제 묶음은 뒤에서 이름순
|
|
1334
2132
|
*/
|
|
@@ -1407,7 +2205,7 @@ var toFontCss = (options) => {
|
|
|
1407
2205
|
return { css, files };
|
|
1408
2206
|
};
|
|
1409
2207
|
|
|
1410
|
-
// src/cli.ts
|
|
2208
|
+
// src/entry/cli/cli.ts
|
|
1411
2209
|
var commands = ["dev", "build", "preview"];
|
|
1412
2210
|
var [command = cli_default_command, docsDir = cli_default_docs_dir] = process.argv.slice(2);
|
|
1413
2211
|
var main = async () => {
|
|
@@ -1418,7 +2216,7 @@ var main = async () => {
|
|
|
1418
2216
|
const docsRoot = resolve3(docsDir);
|
|
1419
2217
|
const outDir = join4(docsRoot, "dist");
|
|
1420
2218
|
if (command === "preview") {
|
|
1421
|
-
const app2 = new
|
|
2219
|
+
const app2 = new Hono4();
|
|
1422
2220
|
app2.use(
|
|
1423
2221
|
"/*",
|
|
1424
2222
|
serveStatic({
|
|
@@ -1448,10 +2246,9 @@ var main = async () => {
|
|
|
1448
2246
|
}
|
|
1449
2247
|
const fontCss = [sans.css, mono.css, brand.css].join("\n");
|
|
1450
2248
|
const stylePath = toAssetPath({ path: asset_style_path, file: join4(kitRoot, "dist/cli.css") });
|
|
1451
|
-
const
|
|
2249
|
+
const browserScript = readFileSync3(join4(kitRoot, "dist/browser.js"), "utf8");
|
|
1452
2250
|
const kitFiles = new Map([
|
|
1453
2251
|
[stylePath, join4(kitRoot, "dist/cli.css")],
|
|
1454
|
-
[clientPath, join4(kitRoot, "dist/client.js")],
|
|
1455
2252
|
[asset_favicon_path, join4(kitRoot, "src/asset/favicon.svg")],
|
|
1456
2253
|
...sans.files,
|
|
1457
2254
|
...mono.files,
|
|
@@ -1459,12 +2256,16 @@ var main = async () => {
|
|
|
1459
2256
|
]);
|
|
1460
2257
|
const files = new Map(kitFiles);
|
|
1461
2258
|
const processor = createProcessor({ site: siteConfig, root: docsRoot, files });
|
|
1462
|
-
const [docs, home] = await Promise.all([
|
|
2259
|
+
const [docs, home] = await Promise.all([
|
|
2260
|
+
readDocs({ root: docsRoot, processor, reserved: siteConfig.url === void 0 ? void 0 : crawling_reserved_roots }),
|
|
2261
|
+
readHome({ root: docsRoot, processor })
|
|
2262
|
+
]);
|
|
1463
2263
|
const store = { docs, home };
|
|
2264
|
+
const crawling = siteConfig.url === void 0 ? void 0 : toCrawlingApp({ url: siteConfig.url, store });
|
|
1464
2265
|
const app = createApp({
|
|
1465
2266
|
site: siteConfig,
|
|
1466
2267
|
store,
|
|
1467
|
-
assets: { stylePath,
|
|
2268
|
+
assets: { stylePath, browserScript, fontCss, preload: [...brand.files.keys(), sansPreload[0], ...mono.files.keys()], reload: command === "dev" }
|
|
1468
2269
|
});
|
|
1469
2270
|
if (command === "build") {
|
|
1470
2271
|
await rm(outDir, { recursive: true, force: true });
|
|
@@ -1472,23 +2273,32 @@ var main = async () => {
|
|
|
1472
2273
|
if (!result.success) {
|
|
1473
2274
|
throw result.error;
|
|
1474
2275
|
}
|
|
2276
|
+
const crawlerResult = crawling === void 0 ? void 0 : await toSSG(crawling, { writeFile, mkdir }, { dir: outDir });
|
|
2277
|
+
if (crawlerResult?.success === false) {
|
|
2278
|
+
throw crawlerResult.error;
|
|
2279
|
+
}
|
|
1475
2280
|
for (const [url, file] of files) {
|
|
1476
2281
|
await mkdir(dirname4(join4(outDir, url)), { recursive: true });
|
|
1477
2282
|
await copyFile(file, join4(outDir, url));
|
|
1478
2283
|
}
|
|
1479
|
-
console.log(
|
|
2284
|
+
console.log(
|
|
2285
|
+
`${crawlerResult === void 0 ? result.files.length : result.files.length + crawlerResult.files.length} files, ${files.size} assets \u2192 ${relative4(process.cwd(), outDir)}`
|
|
2286
|
+
);
|
|
1480
2287
|
return;
|
|
1481
2288
|
}
|
|
1482
2289
|
const reload = new EventEmitter();
|
|
1483
2290
|
let generation = 0;
|
|
1484
|
-
serve({ fetch: createDevApp({ pages: app, files, reload }).fetch, port: cli_dev_port }, (info) => console.log(`http://localhost:${info.port}/`));
|
|
2291
|
+
serve({ fetch: createDevApp({ pages: app, crawling, files, reload }).fetch, port: cli_dev_port }, (info) => console.log(`http://localhost:${info.port}/`));
|
|
1485
2292
|
const reloadDocs = debounce(
|
|
1486
2293
|
toChangeQueue({
|
|
1487
2294
|
run: async () => {
|
|
1488
2295
|
const currentGeneration = generation;
|
|
1489
2296
|
const nextFiles = new Map(kitFiles);
|
|
1490
2297
|
const nextProcessor = createProcessor({ site: siteConfig, root: docsRoot, files: nextFiles });
|
|
1491
|
-
const [docs2, home2] = await Promise.all([
|
|
2298
|
+
const [docs2, home2] = await Promise.all([
|
|
2299
|
+
readDocs({ root: docsRoot, processor: nextProcessor, reserved: siteConfig.url === void 0 ? void 0 : crawling_reserved_roots }),
|
|
2300
|
+
readHome({ root: docsRoot, processor: nextProcessor })
|
|
2301
|
+
]);
|
|
1492
2302
|
if (currentGeneration !== generation) {
|
|
1493
2303
|
return;
|
|
1494
2304
|
}
|