@dooc-dev/dooc 0.0.0-stage → 0.0.2
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/README.md +26 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +311 -0
- package/dist/code.global.js +285 -0
- package/dist/compiler/bundle-urls.d.ts +3 -0
- package/dist/compiler/bundle-urls.js +294 -0
- package/dist/compiler/bundle.d.ts +2 -0
- package/dist/compiler/bundle.js +100 -0
- package/dist/compiler/check-prose.d.ts +11 -0
- package/dist/compiler/check-prose.js +138 -0
- package/dist/compiler/check-types.d.ts +44 -0
- package/dist/compiler/check-types.js +1 -0
- package/dist/compiler/check.d.ts +5 -0
- package/dist/compiler/check.js +450 -0
- package/dist/compiler/code-blocks.d.ts +17 -0
- package/dist/compiler/code-blocks.js +198 -0
- package/dist/compiler/code-languages.d.ts +10 -0
- package/dist/compiler/code-languages.js +109 -0
- package/dist/compiler/compile.d.ts +95 -0
- package/dist/compiler/compile.js +410 -0
- package/dist/compiler/config.d.ts +7 -0
- package/dist/compiler/config.js +52 -0
- package/dist/compiler/dialect.d.ts +24 -0
- package/dist/compiler/dialect.js +198 -0
- package/dist/compiler/drawio.d.ts +26 -0
- package/dist/compiler/drawio.js +176 -0
- package/dist/compiler/figures.d.ts +14 -0
- package/dist/compiler/figures.js +221 -0
- package/dist/compiler/file-cache.d.ts +14 -0
- package/dist/compiler/file-cache.js +61 -0
- package/dist/compiler/files.d.ts +29 -0
- package/dist/compiler/files.js +431 -0
- package/dist/compiler/fonts.d.ts +10 -0
- package/dist/compiler/fonts.js +54 -0
- package/dist/compiler/format.d.ts +1 -0
- package/dist/compiler/format.js +42 -0
- package/dist/compiler/from-mdast.d.ts +16 -0
- package/dist/compiler/from-mdast.js +142 -0
- package/dist/compiler/icons.d.ts +14 -0
- package/dist/compiler/icons.js +85 -0
- package/dist/compiler/language-codes.d.ts +7 -0
- package/dist/compiler/language-codes.js +17 -0
- package/dist/compiler/locales.d.ts +7 -0
- package/dist/compiler/locales.js +67 -0
- package/dist/compiler/manifest.d.ts +6 -0
- package/dist/compiler/manifest.js +30 -0
- package/dist/compiler/ops.d.ts +44 -0
- package/dist/compiler/ops.js +362 -0
- package/dist/compiler/public-file.d.ts +2 -0
- package/dist/compiler/public-file.js +93 -0
- package/dist/compiler/serialize.d.ts +3 -0
- package/dist/compiler/serialize.js +16 -0
- package/dist/compiler/terms.d.ts +9 -0
- package/dist/compiler/terms.js +44 -0
- package/dist/compiler/textfile-remote.d.ts +12 -0
- package/dist/compiler/textfile-remote.js +124 -0
- package/dist/compiler/textfile.d.ts +9 -0
- package/dist/compiler/textfile.js +113 -0
- package/dist/compiler/theme-variants.d.ts +4 -0
- package/dist/compiler/theme-variants.js +22 -0
- package/dist/compiler/zip.d.ts +6 -0
- package/dist/compiler/zip.js +48 -0
- package/dist/core/blocks.d.ts +99 -0
- package/dist/core/blocks.js +29 -0
- package/dist/core/code-file.d.ts +12 -0
- package/dist/core/code-file.js +68 -0
- package/dist/core/content-metadata.d.ts +48 -0
- package/dist/core/content-metadata.js +264 -0
- package/dist/core/content-types.d.ts +45 -0
- package/dist/core/content-types.js +1 -0
- package/dist/core/extension-package.d.ts +34 -0
- package/dist/core/extension-package.js +147 -0
- package/dist/core/figure-frame.d.ts +12 -0
- package/dist/core/figure-frame.js +108 -0
- package/dist/core/file-embed.d.ts +13 -0
- package/dist/core/file-embed.js +43 -0
- package/dist/core/files.d.ts +15 -0
- package/dist/core/files.js +59 -0
- package/dist/core/flow-base-css.generated.d.ts +1 -0
- package/dist/core/flow-base-css.generated.js +4 -0
- package/dist/core/flow-css.d.ts +9 -0
- package/dist/core/flow-css.js +54 -0
- package/dist/core/graph-common.d.ts +32 -0
- package/dist/core/graph-common.js +113 -0
- package/dist/core/graph.d.ts +117 -0
- package/dist/core/graph.js +480 -0
- package/dist/core/html.d.ts +29 -0
- package/dist/core/html.js +444 -0
- package/dist/core/icons.d.ts +2 -0
- package/dist/core/icons.js +2 -0
- package/dist/core/inline.d.ts +27 -0
- package/dist/core/inline.js +42 -0
- package/dist/core/language.d.ts +41 -0
- package/dist/core/language.js +44 -0
- package/dist/core/languages/ja.d.ts +2 -0
- package/dist/core/languages/ja.js +5 -0
- package/dist/core/markdown.d.ts +27 -0
- package/dist/core/markdown.js +154 -0
- package/dist/core/previewers.d.ts +37 -0
- package/dist/core/previewers.js +103 -0
- package/dist/core/routing.d.ts +20 -0
- package/dist/core/routing.js +64 -0
- package/dist/core/schema-comments.d.ts +14 -0
- package/dist/core/schema-comments.js +52 -0
- package/dist/core/schema-graph-flow.d.ts +9 -0
- package/dist/core/schema-graph-flow.js +379 -0
- package/dist/core/schema-graph-mount.d.ts +9 -0
- package/dist/core/schema-graph-mount.js +105 -0
- package/dist/core/schema-graph.d.ts +254 -0
- package/dist/core/schema-graph.js +981 -0
- package/dist/core/table-ui.d.ts +2 -0
- package/dist/core/table-ui.js +180 -0
- package/dist/core/taxonomy.d.ts +12 -0
- package/dist/core/taxonomy.js +49 -0
- package/dist/core/term-reference.d.ts +5 -0
- package/dist/core/term-reference.js +19 -0
- package/dist/core/terms-ui.d.ts +6 -0
- package/dist/core/terms-ui.js +22 -0
- package/dist/core/textfile.d.ts +10 -0
- package/dist/core/textfile.js +39 -0
- package/dist/core/theme-variants.d.ts +3 -0
- package/dist/core/theme-variants.js +37 -0
- package/dist/core/toc-ui.d.ts +2 -0
- package/dist/core/toc-ui.js +161 -0
- package/dist/core/video-ui.d.ts +2 -0
- package/dist/core/video-ui.js +253 -0
- package/dist/core/workspace.d.ts +15 -0
- package/dist/core/workspace.js +28 -0
- package/dist/edit.global.js +306 -0
- package/dist/flow.global.js +4959 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +31 -0
- package/dist/mcp.d.ts +24 -0
- package/dist/mcp.js +467 -0
- package/dist/plugins/actions.d.ts +45 -0
- package/dist/plugins/actions.js +125 -0
- package/dist/plugins/blocks.d.ts +93 -0
- package/dist/plugins/blocks.js +100 -0
- package/dist/plugins/index.d.ts +4 -0
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/local-storage.d.ts +18 -0
- package/dist/plugins/local-storage.js +115 -0
- package/dist/plugins/oauth.d.ts +14 -0
- package/dist/plugins/oauth.js +170 -0
- package/dist/plugins/runtime.d.ts +26 -0
- package/dist/plugins/runtime.js +395 -0
- package/dist/plugins/types.d.ts +59 -0
- package/dist/plugins/types.js +1 -0
- package/dist/plugins/view.d.ts +7 -0
- package/dist/plugins/view.js +21 -0
- package/dist/ui.global.js +78 -0
- package/dist/viewer/assets.d.ts +2 -0
- package/dist/viewer/assets.js +3 -0
- package/dist/viewer/build.d.ts +12 -0
- package/dist/viewer/build.js +55 -0
- package/dist/viewer/bundle-network.d.ts +2 -0
- package/dist/viewer/bundle-network.js +88 -0
- package/dist/viewer/code-file.d.ts +20 -0
- package/dist/viewer/code-file.js +42 -0
- package/dist/viewer/editor-tools.d.ts +38 -0
- package/dist/viewer/editor-tools.js +211 -0
- package/dist/viewer/extension-pack.d.ts +2 -0
- package/dist/viewer/extension-pack.js +36 -0
- package/dist/viewer/extensions.d.ts +10 -0
- package/dist/viewer/extensions.js +302 -0
- package/dist/viewer/file-references.d.ts +14 -0
- package/dist/viewer/file-references.js +38 -0
- package/dist/viewer/font-picker.d.ts +4 -0
- package/dist/viewer/font-picker.js +145 -0
- package/dist/viewer/font-settings.d.ts +11 -0
- package/dist/viewer/font-settings.js +50 -0
- package/dist/viewer/fonts/LICENSE.txt +119 -0
- package/dist/viewer/fonts/udev-gothic-regular.woff2 +0 -0
- package/dist/viewer/fonts.d.ts +2 -0
- package/dist/viewer/fonts.js +13 -0
- package/dist/viewer/git-diff.d.ts +3 -0
- package/dist/viewer/git-diff.js +33 -0
- package/dist/viewer/git-types.d.ts +73 -0
- package/dist/viewer/git-types.js +1 -0
- package/dist/viewer/git.d.ts +5 -0
- package/dist/viewer/git.js +337 -0
- package/dist/viewer/hmr.d.ts +53 -0
- package/dist/viewer/hmr.js +337 -0
- package/dist/viewer/i18n.d.ts +6 -0
- package/dist/viewer/i18n.js +65 -0
- package/dist/viewer/ja-lint.d.ts +3 -0
- package/dist/viewer/ja-lint.js +44 -0
- package/dist/viewer/language-picker.d.ts +2 -0
- package/dist/viewer/language-picker.js +233 -0
- package/dist/viewer/languages.d.ts +11 -0
- package/dist/viewer/languages.js +20 -0
- package/dist/viewer/locales/eng.json +317 -0
- package/dist/viewer/locales/jpn.json +317 -0
- package/dist/viewer/locales/zho.json +317 -0
- package/dist/viewer/nav-focus.d.ts +2 -0
- package/dist/viewer/nav-focus.js +64 -0
- package/dist/viewer/plugin-blocks.d.ts +3 -0
- package/dist/viewer/plugin-blocks.js +115 -0
- package/dist/viewer/plugin-config.d.ts +35 -0
- package/dist/viewer/plugin-config.js +57 -0
- package/dist/viewer/plugin-view.d.ts +2 -0
- package/dist/viewer/plugin-view.js +6 -0
- package/dist/viewer/plugins.d.ts +12 -0
- package/dist/viewer/plugins.js +267 -0
- package/dist/viewer/resize.d.ts +4 -0
- package/dist/viewer/resize.js +238 -0
- package/dist/viewer/resource-library.d.ts +29 -0
- package/dist/viewer/resource-library.js +104 -0
- package/dist/viewer/search.d.ts +16 -0
- package/dist/viewer/search.js +358 -0
- package/dist/viewer/serve.d.ts +210 -0
- package/dist/viewer/serve.js +3312 -0
- package/dist/viewer/site-icon.d.ts +8 -0
- package/dist/viewer/site-icon.js +56 -0
- package/dist/viewer/textfile.d.ts +9 -0
- package/dist/viewer/textfile.js +50 -0
- package/dist/viewer/theme-picker.d.ts +2 -0
- package/dist/viewer/theme-picker.js +135 -0
- package/dist/viewer/workspace.d.ts +4 -0
- package/dist/viewer/workspace.js +47 -0
- package/package.json +128 -5
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/** Shared by editor, preview, and published pages; keep this function self-contained. */
|
|
2
|
+
export const mountPanelResize = () => {
|
|
3
|
+
const sidebar = document.getElementById("sidebar");
|
|
4
|
+
const editor = document.getElementById("panel");
|
|
5
|
+
const closed = () => document.body.classList.contains("sidebar-closed");
|
|
6
|
+
const contentWidth = () => Math.min(240, Math.max(0, window.innerWidth - (closed() ? 52 : 200) - (editor ? 320 : 0)));
|
|
7
|
+
const panels = [
|
|
8
|
+
{
|
|
9
|
+
element: sidebar,
|
|
10
|
+
handle: "sidebar-resize",
|
|
11
|
+
key: "docs:sidebar-width",
|
|
12
|
+
min: 200,
|
|
13
|
+
max: 480,
|
|
14
|
+
direction: 1,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
element: editor,
|
|
18
|
+
handle: "resize",
|
|
19
|
+
key: "docs-edit:panelw",
|
|
20
|
+
min: 320,
|
|
21
|
+
max: 960,
|
|
22
|
+
direction: -1,
|
|
23
|
+
},
|
|
24
|
+
].flatMap((options) => {
|
|
25
|
+
const element = options.element;
|
|
26
|
+
const handle = document.getElementById(options.handle);
|
|
27
|
+
if (!element || !handle)
|
|
28
|
+
return [];
|
|
29
|
+
let preferred;
|
|
30
|
+
try {
|
|
31
|
+
const saved = Number(localStorage.getItem(options.key));
|
|
32
|
+
if (Number.isFinite(saved) && saved > 0)
|
|
33
|
+
preferred = saved;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
/* Width persistence is optional. */
|
|
37
|
+
}
|
|
38
|
+
const property = options.direction === 1 ? "--sidebar-width" : "--panel-width";
|
|
39
|
+
const requested = () => preferred ?? (options.direction === 1 ? 260 : Math.min(760, window.innerWidth * 0.52));
|
|
40
|
+
const apply = (width) => {
|
|
41
|
+
const other = options.direction === 1 ? editor : sidebar;
|
|
42
|
+
const max = Math.max(0, Math.min(options.max, window.innerWidth -
|
|
43
|
+
(other?.getBoundingClientRect().width ?? 0) -
|
|
44
|
+
contentWidth()));
|
|
45
|
+
const min = Math.min(options.min, max);
|
|
46
|
+
const value = Math.round(Math.max(min, Math.min(width, max)));
|
|
47
|
+
element.style.setProperty(property, `${value}px`);
|
|
48
|
+
handle.setAttribute("aria-valuemin", String(min));
|
|
49
|
+
handle.setAttribute("aria-valuemax", String(max));
|
|
50
|
+
handle.setAttribute("aria-valuenow", String(value));
|
|
51
|
+
};
|
|
52
|
+
const persist = () => {
|
|
53
|
+
preferred = element.getBoundingClientRect().width;
|
|
54
|
+
try {
|
|
55
|
+
localStorage.setItem(options.key, String(preferred));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* Optional. */
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
let drag;
|
|
62
|
+
handle.addEventListener("pointerdown", (event) => {
|
|
63
|
+
if (event.button !== 0 || drag)
|
|
64
|
+
return;
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
handle.focus();
|
|
67
|
+
drag = {
|
|
68
|
+
id: event.pointerId,
|
|
69
|
+
x: event.clientX,
|
|
70
|
+
width: element.getBoundingClientRect().width,
|
|
71
|
+
};
|
|
72
|
+
handle.setPointerCapture(event.pointerId);
|
|
73
|
+
handle.classList.add("drag");
|
|
74
|
+
document.body.classList.add("resizing");
|
|
75
|
+
});
|
|
76
|
+
handle.addEventListener("pointermove", (event) => {
|
|
77
|
+
if (drag?.id !== event.pointerId)
|
|
78
|
+
return;
|
|
79
|
+
apply(drag.width + options.direction * (event.clientX - drag.x));
|
|
80
|
+
});
|
|
81
|
+
const stop = (event) => {
|
|
82
|
+
if (drag?.id !== event.pointerId)
|
|
83
|
+
return;
|
|
84
|
+
drag = undefined;
|
|
85
|
+
handle.classList.remove("drag");
|
|
86
|
+
document.body.classList.remove("resizing");
|
|
87
|
+
persist();
|
|
88
|
+
};
|
|
89
|
+
handle.addEventListener("pointerup", stop);
|
|
90
|
+
handle.addEventListener("pointercancel", stop);
|
|
91
|
+
handle.addEventListener("lostpointercapture", stop);
|
|
92
|
+
handle.addEventListener("dblclick", () => {
|
|
93
|
+
preferred = undefined;
|
|
94
|
+
try {
|
|
95
|
+
localStorage.removeItem(options.key);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
/* Optional. */
|
|
99
|
+
}
|
|
100
|
+
apply(requested());
|
|
101
|
+
});
|
|
102
|
+
handle.addEventListener("keydown", (event) => {
|
|
103
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight")
|
|
104
|
+
return;
|
|
105
|
+
event.preventDefault();
|
|
106
|
+
apply(element.getBoundingClientRect().width +
|
|
107
|
+
options.direction * (event.key === "ArrowRight" ? 20 : -20));
|
|
108
|
+
persist();
|
|
109
|
+
});
|
|
110
|
+
return [{ ...options, element, apply, requested, persist, property }];
|
|
111
|
+
});
|
|
112
|
+
const layout = () => {
|
|
113
|
+
// On a smaller viewport, make room for the navigation before clamping both panels.
|
|
114
|
+
const right = panels.find((panel) => panel.direction === -1);
|
|
115
|
+
if (right) {
|
|
116
|
+
const available = Math.max(0, window.innerWidth - (closed() ? 52 : 200) - contentWidth());
|
|
117
|
+
right.element.style.setProperty(right.property, `${Math.min(right.requested(), available)}px`);
|
|
118
|
+
}
|
|
119
|
+
for (const panel of panels) {
|
|
120
|
+
if (panel.direction === 1 && closed())
|
|
121
|
+
continue;
|
|
122
|
+
panel.apply(panel.requested());
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
window.addEventListener("resize", layout);
|
|
126
|
+
document.getElementById("sidebar-toggle")?.addEventListener("click", layout);
|
|
127
|
+
window.addEventListener("keydown", (event) => {
|
|
128
|
+
if (event.defaultPrevented || !(event.ctrlKey || event.metaKey) || !event.altKey)
|
|
129
|
+
return;
|
|
130
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight")
|
|
131
|
+
return;
|
|
132
|
+
const right = panels.find((panel) => panel.direction === -1);
|
|
133
|
+
if (!right)
|
|
134
|
+
return;
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
right.apply(right.element.getBoundingClientRect().width + (event.key === "ArrowLeft" ? 40 : -40));
|
|
137
|
+
right.persist();
|
|
138
|
+
});
|
|
139
|
+
layout();
|
|
140
|
+
};
|
|
141
|
+
/** The navigation is replaced on refresh; keep listeners and height on its stable sidebar. */
|
|
142
|
+
export const mountToolsResize = () => {
|
|
143
|
+
const sidebar = document.getElementById("sidebar");
|
|
144
|
+
if (!sidebar || !document.getElementById("nav-tools"))
|
|
145
|
+
return () => { };
|
|
146
|
+
const key = "docs:tools-height";
|
|
147
|
+
let preferred;
|
|
148
|
+
try {
|
|
149
|
+
const saved = Number(localStorage.getItem(key));
|
|
150
|
+
if (Number.isFinite(saved) && saved > 0)
|
|
151
|
+
preferred = saved;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
/* Persistence is optional. */
|
|
155
|
+
}
|
|
156
|
+
const apply = (height = preferred ?? Math.min(220, innerHeight * 0.4)) => {
|
|
157
|
+
const handle = document.getElementById("tools-resize");
|
|
158
|
+
if (!handle)
|
|
159
|
+
return;
|
|
160
|
+
const max = Math.max(80, sidebar.clientHeight - 100);
|
|
161
|
+
const min = Math.min(144, max);
|
|
162
|
+
const value = Math.round(Math.max(min, Math.min(height, max)));
|
|
163
|
+
sidebar.style.setProperty("--tools-height", `${value}px`);
|
|
164
|
+
handle.setAttribute("aria-valuemin", String(min));
|
|
165
|
+
handle.setAttribute("aria-valuemax", String(max));
|
|
166
|
+
handle.setAttribute("aria-valuenow", String(value));
|
|
167
|
+
};
|
|
168
|
+
const persist = () => {
|
|
169
|
+
preferred = Number.parseFloat(sidebar.style.getPropertyValue("--tools-height"));
|
|
170
|
+
try {
|
|
171
|
+
localStorage.setItem(key, String(preferred));
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
/* Optional. */
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const isHandle = (event) => event.target instanceof Element && !!event.target.closest("#tools-resize");
|
|
178
|
+
const height = () => document.getElementById("nav-tools")?.getBoundingClientRect().height ?? 0;
|
|
179
|
+
let drag;
|
|
180
|
+
sidebar.addEventListener("pointerdown", (event) => {
|
|
181
|
+
if (!isHandle(event) || event.button !== 0 || drag)
|
|
182
|
+
return;
|
|
183
|
+
const handle = document.getElementById("tools-resize");
|
|
184
|
+
if (!handle)
|
|
185
|
+
return;
|
|
186
|
+
event.preventDefault();
|
|
187
|
+
handle.focus({ preventScroll: true });
|
|
188
|
+
drag = { id: event.pointerId, y: event.clientY, height: height(), handle };
|
|
189
|
+
handle.setPointerCapture(event.pointerId);
|
|
190
|
+
document.body.classList.add("resizing-tools");
|
|
191
|
+
});
|
|
192
|
+
sidebar.addEventListener("pointermove", (event) => {
|
|
193
|
+
if (drag?.id === event.pointerId)
|
|
194
|
+
apply(drag.height + drag.y - event.clientY);
|
|
195
|
+
});
|
|
196
|
+
const stop = () => {
|
|
197
|
+
if (!drag)
|
|
198
|
+
return;
|
|
199
|
+
drag = undefined;
|
|
200
|
+
document.body.classList.remove("resizing-tools");
|
|
201
|
+
persist();
|
|
202
|
+
};
|
|
203
|
+
for (const type of ["pointerup", "pointercancel", "lostpointercapture"])
|
|
204
|
+
sidebar.addEventListener(type, (event) => {
|
|
205
|
+
if (drag?.id === event.pointerId)
|
|
206
|
+
stop();
|
|
207
|
+
});
|
|
208
|
+
sidebar.addEventListener("keydown", (event) => {
|
|
209
|
+
if (!isHandle(event) || (event.key !== "ArrowUp" && event.key !== "ArrowDown"))
|
|
210
|
+
return;
|
|
211
|
+
event.preventDefault();
|
|
212
|
+
apply(height() + (event.key === "ArrowUp" ? 20 : -20));
|
|
213
|
+
persist();
|
|
214
|
+
});
|
|
215
|
+
sidebar.addEventListener("dblclick", (event) => {
|
|
216
|
+
if (!isHandle(event))
|
|
217
|
+
return;
|
|
218
|
+
preferred = undefined;
|
|
219
|
+
try {
|
|
220
|
+
localStorage.removeItem(key);
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
/* Optional. */
|
|
224
|
+
}
|
|
225
|
+
apply();
|
|
226
|
+
});
|
|
227
|
+
window.addEventListener("resize", () => apply());
|
|
228
|
+
const restore = () => {
|
|
229
|
+
if (drag && !drag.handle.isConnected)
|
|
230
|
+
stop();
|
|
231
|
+
apply();
|
|
232
|
+
};
|
|
233
|
+
const nav = document.getElementById("nav-groups");
|
|
234
|
+
if (nav)
|
|
235
|
+
new MutationObserver(restore).observe(nav, { childList: true });
|
|
236
|
+
restore();
|
|
237
|
+
return restore;
|
|
238
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { TermEntry } from "../core/content-types.js";
|
|
2
|
+
interface SourceLocation {
|
|
3
|
+
file: string;
|
|
4
|
+
line: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ResourceIndex {
|
|
7
|
+
terms: {
|
|
8
|
+
entry: TermEntry;
|
|
9
|
+
source: SourceLocation;
|
|
10
|
+
}[];
|
|
11
|
+
code: {
|
|
12
|
+
language: string;
|
|
13
|
+
caption: string;
|
|
14
|
+
content: string;
|
|
15
|
+
source: SourceLocation;
|
|
16
|
+
}[];
|
|
17
|
+
urls: {
|
|
18
|
+
url: string;
|
|
19
|
+
host: string;
|
|
20
|
+
sources: SourceLocation[];
|
|
21
|
+
}[];
|
|
22
|
+
errors: string[];
|
|
23
|
+
}
|
|
24
|
+
/** Index authored content, including files not referenced by any document. */
|
|
25
|
+
export declare const resourceIndex: (root: string, files: readonly string[]) => ResourceIndex;
|
|
26
|
+
export type ResourceView = "files" | "dictionary" | "code" | "urls";
|
|
27
|
+
export declare const resourceTabs: (view: ResourceView) => string;
|
|
28
|
+
export declare const resourceLibraryHtml: (index: ResourceIndex, view: Exclude<ResourceView, "files">) => string;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { visit } from "unist-util-visit";
|
|
2
|
+
import { parseTermSource } from "../compiler/terms.js";
|
|
3
|
+
import { readTextfile } from "../compiler/textfile.js";
|
|
4
|
+
import { blocksHtml, escapeHtml } from "../core/html.js";
|
|
5
|
+
import { parseMdast } from "../core/markdown.js";
|
|
6
|
+
/** Index authored content, including files not referenced by any document. */
|
|
7
|
+
export const resourceIndex = (root, files) => {
|
|
8
|
+
const result = { terms: [], code: [], urls: [], errors: [] };
|
|
9
|
+
const urls = new Map();
|
|
10
|
+
const terms = (raw, source) => {
|
|
11
|
+
const parsed = parseTermSource(`${source.file}#L${source.line}`, raw);
|
|
12
|
+
result.terms.push(...parsed.entries.map((entry) => ({ entry, source })));
|
|
13
|
+
result.errors.push(...parsed.errors.map((error) => `${source.file}:L${source.line + error.line}: ${error.message}`));
|
|
14
|
+
};
|
|
15
|
+
const scan = (tree, file, offset = 0) => {
|
|
16
|
+
const definitions = new Map();
|
|
17
|
+
visit(tree, "definition", (node) => {
|
|
18
|
+
definitions.set(node.identifier, node.url);
|
|
19
|
+
});
|
|
20
|
+
visit(tree, (node) => {
|
|
21
|
+
const source = { file, line: offset + (node.position?.start.line ?? 1) };
|
|
22
|
+
if (node.type === "code") {
|
|
23
|
+
const language = node.lang?.toLowerCase() || "text";
|
|
24
|
+
result.code.push({
|
|
25
|
+
language,
|
|
26
|
+
caption: node.meta ?? "",
|
|
27
|
+
content: node.value,
|
|
28
|
+
source,
|
|
29
|
+
});
|
|
30
|
+
if (language === "termth")
|
|
31
|
+
terms(node.value, { ...source, line: source.line + 1 });
|
|
32
|
+
if (language === "callouth")
|
|
33
|
+
scan(parseMdast(node.value), file, source.line);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const target = node.type === "link" || node.type === "image"
|
|
37
|
+
? node.url
|
|
38
|
+
: node.type === "linkReference" || node.type === "imageReference"
|
|
39
|
+
? definitions.get(node.identifier)
|
|
40
|
+
: undefined;
|
|
41
|
+
if (!target)
|
|
42
|
+
return;
|
|
43
|
+
try {
|
|
44
|
+
const url = new URL(target);
|
|
45
|
+
if (!["http:", "https:", "mailto:"].includes(url.protocol))
|
|
46
|
+
return;
|
|
47
|
+
const key = url.href;
|
|
48
|
+
const entry = urls.get(key) ?? {
|
|
49
|
+
url: key,
|
|
50
|
+
host: url.host || url.protocol,
|
|
51
|
+
sources: [],
|
|
52
|
+
};
|
|
53
|
+
entry.sources.push(source);
|
|
54
|
+
urls.set(key, entry);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Local paths and anchors are not external URL resources.
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
for (const file of new Set(files)) {
|
|
62
|
+
if (!/\.(?:md|termth)$/i.test(file))
|
|
63
|
+
continue;
|
|
64
|
+
try {
|
|
65
|
+
const raw = readTextfile(root, file);
|
|
66
|
+
if (/\.termth$/i.test(file))
|
|
67
|
+
terms(raw, { file, line: 1 });
|
|
68
|
+
else
|
|
69
|
+
scan(parseMdast(raw), file);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
result.errors.push(`${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
result.terms.sort((a, b) => a.entry.name.localeCompare(b.entry.name, undefined, { numeric: true }));
|
|
76
|
+
result.urls = [...urls.values()].sort((a, b) => a.url.localeCompare(b.url));
|
|
77
|
+
return result;
|
|
78
|
+
};
|
|
79
|
+
export const resourceTabs = (view) => view === "files"
|
|
80
|
+
? ""
|
|
81
|
+
: `<nav class="resource-tabs" aria-label="Resource views" data-i18n-aria-label="Resource views">${[
|
|
82
|
+
["dictionary", "Dictionary"],
|
|
83
|
+
["code", "Code blocks"],
|
|
84
|
+
["urls", "URLs"],
|
|
85
|
+
]
|
|
86
|
+
.map(([key, label]) => `<a href="/_statics${key === "dictionary" ? "" : `/${key}`}"${view === key ? ' aria-current="page"' : ""} data-i18n="${label}">${label}</a>`)
|
|
87
|
+
.join("")}</nav>`;
|
|
88
|
+
const sourceLink = ({ file, line }) => `<a class="resource-source" href="/_files/file/${encodeURIComponent(file)}#L${line}" data-resource-source="${escapeHtml(file)}" data-resource-line="${line}" title="${escapeHtml(file)}:L${line}"><span class="resource-source-file">${escapeHtml(file)}</span><span>L${line}</span></a>`;
|
|
89
|
+
export const resourceLibraryHtml = (index, view) => {
|
|
90
|
+
const groupLabel = view === "code" ? "Code language" : "Domain";
|
|
91
|
+
const groups = view === "dictionary"
|
|
92
|
+
? []
|
|
93
|
+
: [
|
|
94
|
+
...new Set(view === "code"
|
|
95
|
+
? index.code.map((item) => item.language)
|
|
96
|
+
: index.urls.map((item) => item.host)),
|
|
97
|
+
].sort();
|
|
98
|
+
const items = view === "dictionary"
|
|
99
|
+
? index.terms.map(({ entry, source }) => `<details class="resource-item resource-term" data-resource-item><summary><span class="resource-name" title="${escapeHtml(entry.name)}">${escapeHtml(entry.name)}</span>${sourceLink(source)}</summary><div class="resource-body"><p class="term-definition">${escapeHtml(entry.definition)}</p>${entry.description ? `<p class="resource-description">${escapeHtml(entry.description)}</p>` : ""}</div></details>`)
|
|
100
|
+
: view === "code"
|
|
101
|
+
? index.code.map(({ language, caption, content, source }) => `<details class="resource-item resource-code" data-resource-item data-resource-group="${escapeHtml(language)}"><summary><span class="resource-badge">${escapeHtml(language)}</span>${caption ? `<span class="resource-name" title="${escapeHtml(caption)}">${escapeHtml(caption)}</span>` : ""}${sourceLink(source)}</summary><div class="resource-body">${blocksHtml([{ type: "code", lang: language === "mermaid" ? "text" : language, lines: content.split("\n") }])}</div></details>`)
|
|
102
|
+
: index.urls.map(({ url, host, sources }) => `<details class="resource-item resource-url" data-resource-item data-resource-group="${escapeHtml(host)}"><summary><a class="resource-name" href="${escapeHtml(url)}" title="${escapeHtml(url)}" target="_blank" rel="noopener noreferrer">${escapeHtml(url)}</a><span class="resource-usage" title="references" data-i18n-title="references">${sources.length}</span></summary><div class="resource-body resource-sources">${sources.map(sourceLink).join("")}</div></details>`);
|
|
103
|
+
return `<section class="resource-results" data-resource-results><div class="resource-toolbar"><span data-i18n="Name">Name</span><label class="resource-search"><svg width="13" height="13" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M14 14l4 4M15 9a6 6 0 1 1-12 0 6 6 0 0 1 12 0"/></svg><input type="search" data-resource-search placeholder="Search resources" aria-label="Search resources" data-i18n-placeholder="Search resources" data-i18n-aria-label="Search resources"></label>${groups.length ? `<select data-resource-filter aria-label="${groupLabel}" data-i18n-aria-label="${groupLabel}"><option value="" data-i18n="All">All</option>${groups.map((group) => `<option value="${escapeHtml(group)}">${escapeHtml(group)}</option>`).join("")}</select>` : ""}<span class="resource-count" data-resource-count role="status" aria-live="polite">${items.length}</span></div>${index.errors.length ? `<details class="resource-errors"><summary><span data-i18n="Files with errors">Files with errors</span> (${index.errors.length})</summary><ul>${index.errors.map((error) => `<li>${escapeHtml(error)}</li>`).join("")}</ul></details>` : ""}<div class="resource-items resource-${view}">${items.join("")}</div><p class="resource-empty" data-resource-empty${items.length ? " hidden" : ""} data-i18n="No matching resources">No matching resources</p></section>`;
|
|
104
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Site } from "./serve.js";
|
|
2
|
+
export interface SearchSection {
|
|
3
|
+
path: string;
|
|
4
|
+
file: string;
|
|
5
|
+
folder: boolean;
|
|
6
|
+
title: string;
|
|
7
|
+
heading: string;
|
|
8
|
+
anchor: string;
|
|
9
|
+
text: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const searchIndex: (site: Site) => SearchSection[];
|
|
12
|
+
export declare const searchSections: (index: SearchSection[], query: string, currentPath?: string) => (SearchSection & {
|
|
13
|
+
snippet: string;
|
|
14
|
+
})[];
|
|
15
|
+
export declare const SEARCH_LABELS: string[];
|
|
16
|
+
export declare const mountSearch: (initial: SearchSection[], search: typeof searchSections, labels: Record<string, string>, published: boolean) => void;
|