sourcey 3.5.10 → 3.6.1
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 +24 -97
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +130 -0
- package/dist/adapters/mkdocs.d.ts +5 -0
- package/dist/adapters/mkdocs.d.ts.map +1 -0
- package/dist/adapters/mkdocs.js +367 -0
- package/dist/adapters/shared.d.ts +12 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/shared.js +134 -0
- package/dist/adapters/types.d.ts +74 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +1 -0
- package/dist/cli.js +28 -34
- package/dist/client/search.js +213 -82
- package/dist/client/tabs.js +23 -0
- package/dist/components/layout/Head.js +17 -4
- package/dist/components/layout/TableOfContents.d.ts.map +1 -1
- package/dist/components/layout/TableOfContents.js +4 -2
- package/dist/components/openapi/Introduction.d.ts.map +1 -1
- package/dist/components/openapi/Introduction.js +16 -1
- package/dist/components/openapi/Security.d.ts.map +1 -1
- package/dist/components/openapi/Security.js +18 -2
- package/dist/config.d.ts +101 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +95 -143
- package/dist/core/api-rendering.d.ts +47 -0
- package/dist/core/api-rendering.d.ts.map +1 -0
- package/dist/core/api-rendering.js +76 -0
- package/dist/core/doxygen-loader.d.ts.map +1 -1
- package/dist/core/doxygen-loader.js +36 -17
- package/dist/core/godoc-loader.d.ts.map +1 -1
- package/dist/core/godoc-loader.js +17 -6
- package/dist/core/markdown-loader.d.ts +14 -0
- package/dist/core/markdown-loader.d.ts.map +1 -1
- package/dist/core/markdown-loader.js +70 -26
- package/dist/core/mcp-normalizer.d.ts.map +1 -1
- package/dist/core/mcp-normalizer.js +48 -34
- package/dist/core/navigation.d.ts.map +1 -1
- package/dist/core/navigation.js +8 -7
- package/dist/core/parser.d.ts.map +1 -1
- package/dist/core/parser.js +75 -4
- package/dist/core/rustdoc-introspector.d.ts +29 -0
- package/dist/core/rustdoc-introspector.d.ts.map +1 -0
- package/dist/core/rustdoc-introspector.js +236 -0
- package/dist/core/rustdoc-loader.d.ts +25 -0
- package/dist/core/rustdoc-loader.d.ts.map +1 -0
- package/dist/core/rustdoc-loader.js +469 -0
- package/dist/core/rustdoc-render.d.ts +76 -0
- package/dist/core/rustdoc-render.d.ts.map +1 -0
- package/dist/core/rustdoc-render.js +785 -0
- package/dist/core/rustdoc-types.d.ts +314 -0
- package/dist/core/rustdoc-types.d.ts.map +1 -0
- package/dist/core/rustdoc-types.js +18 -0
- package/dist/core/search-indexer.d.ts +10 -0
- package/dist/core/search-indexer.d.ts.map +1 -1
- package/dist/core/search-indexer.js +6 -1
- package/dist/core/sourcey-rustdoc/Cargo.lock +705 -0
- package/dist/core/sourcey-rustdoc/Cargo.toml +38 -0
- package/dist/core/sourcey-rustdoc/README.md +59 -0
- package/dist/core/sourcey-rustdoc/src/diagnostics.rs +42 -0
- package/dist/core/sourcey-rustdoc/src/doctest.rs +268 -0
- package/dist/core/sourcey-rustdoc/src/extract.rs +492 -0
- package/dist/core/sourcey-rustdoc/src/lib.rs +58 -0
- package/dist/core/sourcey-rustdoc/src/links.rs +126 -0
- package/dist/core/sourcey-rustdoc/src/main.rs +256 -0
- package/dist/core/sourcey-rustdoc/src/signature.rs +415 -0
- package/dist/core/sourcey-rustdoc/src/spec.rs +390 -0
- package/dist/core/sourcey-rustdoc/tests/format_version.rs +45 -0
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +109 -33
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -14
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +21 -16
- package/dist/renderer/changelog-feed.d.ts.map +1 -1
- package/dist/renderer/changelog-feed.js +27 -19
- package/dist/renderer/html-builder.d.ts.map +1 -1
- package/dist/renderer/html-builder.js +4 -3
- package/dist/renderer/llms.js +57 -2
- package/dist/site-assembly.d.ts +5 -0
- package/dist/site-assembly.d.ts.map +1 -1
- package/dist/site-assembly.js +161 -25
- package/dist/themes/default/sourcey.css +300 -0
- package/dist/utils/code-samples.d.ts +1 -0
- package/dist/utils/code-samples.d.ts.map +1 -1
- package/dist/utils/code-samples.js +30 -22
- package/dist/utils/html.d.ts +10 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +152 -0
- package/dist/utils/http.d.ts +0 -2
- package/dist/utils/http.d.ts.map +1 -1
- package/dist/utils/http.js +19 -34
- package/dist/utils/markdown.d.ts.map +1 -1
- package/dist/utils/markdown.js +115 -39
- package/dist/vite-plugin.d.ts +2 -0
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +71 -1
- package/package.json +11 -5
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { loadConfig } from "./config.js";
|
|
|
7
7
|
import { runIntrospector, GodocIntrospectorError } from "./core/godoc-introspector.js";
|
|
8
8
|
import { GODOC_SCHEMA_VERSION } from "./core/godoc-types.js";
|
|
9
9
|
import { init } from "./init.js";
|
|
10
|
-
import { formatChangelogDiagnostic, formatGodocDiagnostic } from "./site-assembly.js";
|
|
10
|
+
import { formatChangelogDiagnostic, formatGodocDiagnostic, formatRustdocDiagnostic, } from "./site-assembly.js";
|
|
11
11
|
import pkg from "../package.json" with { type: "json" };
|
|
12
12
|
const build = defineCommand({
|
|
13
13
|
meta: {
|
|
@@ -84,6 +84,7 @@ const build = defineCommand({
|
|
|
84
84
|
if (!args.quiet) {
|
|
85
85
|
logChangelogDiagnostics(result.changelogDiagnostics);
|
|
86
86
|
logGodocDiagnostics(result.godocDiagnostics);
|
|
87
|
+
logRustdocDiagnostics(result.rustdocDiagnostics);
|
|
87
88
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
88
89
|
console.log(` Pages: ${result.pageCount}`);
|
|
89
90
|
console.log(` Output: ${result.outputDir}`);
|
|
@@ -129,8 +130,9 @@ const dev = defineCommand({
|
|
|
129
130
|
},
|
|
130
131
|
async run({ args }) {
|
|
131
132
|
const { startDevServer } = await import("./dev-server.js");
|
|
133
|
+
const port = parsePort(args.port);
|
|
132
134
|
await startDevServer({
|
|
133
|
-
port
|
|
135
|
+
port,
|
|
134
136
|
host: args.host ?? process.env.HOST,
|
|
135
137
|
config: args.config,
|
|
136
138
|
strictChangelog: args.strictChangelog,
|
|
@@ -214,9 +216,15 @@ const godoc = defineCommand({
|
|
|
214
216
|
},
|
|
215
217
|
async run({ args }) {
|
|
216
218
|
const moduleDir = resolve(process.cwd(), args.module);
|
|
217
|
-
const patterns = args.packages
|
|
219
|
+
const patterns = args.packages
|
|
220
|
+
.split(",")
|
|
221
|
+
.map((p) => p.trim())
|
|
222
|
+
.filter(Boolean);
|
|
218
223
|
const exclude = args.exclude
|
|
219
|
-
? args.exclude
|
|
224
|
+
? args.exclude
|
|
225
|
+
.split(",")
|
|
226
|
+
.map((p) => p.trim())
|
|
227
|
+
.filter(Boolean)
|
|
220
228
|
: [];
|
|
221
229
|
const outputPath = resolve(process.cwd(), args.out);
|
|
222
230
|
try {
|
|
@@ -282,36 +290,6 @@ const main = defineCommand({
|
|
|
282
290
|
validate,
|
|
283
291
|
godoc,
|
|
284
292
|
},
|
|
285
|
-
args: {
|
|
286
|
-
spec: {
|
|
287
|
-
type: "positional",
|
|
288
|
-
description: "Path to an OpenAPI spec (shorthand for 'sourcey build <spec>')",
|
|
289
|
-
required: false,
|
|
290
|
-
},
|
|
291
|
-
},
|
|
292
|
-
async run({ args, rawArgs }) {
|
|
293
|
-
if (rawArgs.includes("init") ||
|
|
294
|
-
rawArgs.includes("build") ||
|
|
295
|
-
rawArgs.includes("dev") ||
|
|
296
|
-
rawArgs.includes("validate") ||
|
|
297
|
-
rawArgs.includes("godoc"))
|
|
298
|
-
return;
|
|
299
|
-
if (args.spec) {
|
|
300
|
-
await build.run({
|
|
301
|
-
args: {
|
|
302
|
-
_: [],
|
|
303
|
-
spec: args.spec,
|
|
304
|
-
output: "dist",
|
|
305
|
-
embed: false,
|
|
306
|
-
config: undefined,
|
|
307
|
-
quiet: false,
|
|
308
|
-
strictChangelog: false,
|
|
309
|
-
},
|
|
310
|
-
rawArgs: [],
|
|
311
|
-
cmd: build,
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
},
|
|
315
293
|
});
|
|
316
294
|
function logChangelogDiagnostics(diagnostics) {
|
|
317
295
|
for (const diagnostic of diagnostics) {
|
|
@@ -324,4 +302,20 @@ function logGodocDiagnostics(diagnostics) {
|
|
|
324
302
|
writer(` ${formatGodocDiagnostic(diagnostic)}`);
|
|
325
303
|
}
|
|
326
304
|
}
|
|
305
|
+
function logRustdocDiagnostics(diagnostics) {
|
|
306
|
+
for (const diagnostic of diagnostics) {
|
|
307
|
+
const writer = diagnostic.severity === "error" ? console.error : console.log;
|
|
308
|
+
writer(` ${formatRustdocDiagnostic(diagnostic)}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function parsePort(value) {
|
|
312
|
+
if (!/^\d+$/.test(value)) {
|
|
313
|
+
throw new Error(`Invalid port "${value}". Expected an integer from 1 to 65535.`);
|
|
314
|
+
}
|
|
315
|
+
const port = Number(value);
|
|
316
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
317
|
+
throw new Error(`Invalid port "${value}". Expected an integer from 1 to 65535.`);
|
|
318
|
+
}
|
|
319
|
+
return port;
|
|
320
|
+
}
|
|
327
321
|
runMain(main);
|
package/dist/client/search.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Search — client-side search dialog with keyboard navigation
|
|
2
2
|
(function () {
|
|
3
3
|
function init() {
|
|
4
|
-
var dialog = document.getElementById(
|
|
5
|
-
var input = document.getElementById(
|
|
6
|
-
var results = document.getElementById(
|
|
7
|
-
var openBtn = document.getElementById(
|
|
4
|
+
var dialog = document.getElementById("search-dialog");
|
|
5
|
+
var input = document.getElementById("search-input");
|
|
6
|
+
var results = document.getElementById("search-results");
|
|
7
|
+
var openBtn = document.getElementById("search-open");
|
|
8
8
|
if (!dialog || !input || !results) return;
|
|
9
9
|
|
|
10
10
|
var entries = [];
|
|
@@ -16,127 +16,254 @@
|
|
|
16
16
|
var searchMeta = document.querySelector('meta[name="sourcey-search"]');
|
|
17
17
|
|
|
18
18
|
function loadJsonIndex(callback) {
|
|
19
|
-
if (indexLoaded) {
|
|
20
|
-
if (!searchMeta) { indexLoaded = true; callback(); return; }
|
|
21
|
-
var url = searchMeta.getAttribute('content');
|
|
22
|
-
fetch(url).then(function (r) { return r.json(); }).then(function (data) {
|
|
23
|
-
entries = data.map(function (e) {
|
|
24
|
-
return {
|
|
25
|
-
url: e.url,
|
|
26
|
-
method: e.method || '',
|
|
27
|
-
path: e.path || '',
|
|
28
|
-
summary: e.title || '',
|
|
29
|
-
tag: e.tab || '',
|
|
30
|
-
content: e.content || '',
|
|
31
|
-
category: e.category || '',
|
|
32
|
-
featured: !!e.featured,
|
|
33
|
-
searchText: [e.method || '', e.path || '', e.title || '', e.content || '', e.tab || ''].join(' ').toLowerCase()
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
indexLoaded = true;
|
|
19
|
+
if (indexLoaded) {
|
|
37
20
|
callback();
|
|
38
|
-
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!searchMeta) {
|
|
39
24
|
indexLoaded = true;
|
|
40
25
|
callback();
|
|
41
|
-
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
var url = searchMeta.getAttribute("content");
|
|
29
|
+
fetch(url)
|
|
30
|
+
.then(function (r) {
|
|
31
|
+
return r.json();
|
|
32
|
+
})
|
|
33
|
+
.then(function (data) {
|
|
34
|
+
entries = data.map(function (e) {
|
|
35
|
+
var title = e.title || "";
|
|
36
|
+
var qualifiedName = e.qualifiedName || "";
|
|
37
|
+
var owner = e.owner || "";
|
|
38
|
+
var tab = e.tab || "";
|
|
39
|
+
return {
|
|
40
|
+
url: e.url,
|
|
41
|
+
method: e.method || "",
|
|
42
|
+
path: e.path || "",
|
|
43
|
+
title: title,
|
|
44
|
+
summary: qualifiedName || title,
|
|
45
|
+
tag: owner ? owner : tab,
|
|
46
|
+
content: e.content || "",
|
|
47
|
+
category: e.category || "",
|
|
48
|
+
featured: !!e.featured,
|
|
49
|
+
symbolKind: e.symbolKind || "",
|
|
50
|
+
owner: owner,
|
|
51
|
+
ownerKind: e.ownerKind || "",
|
|
52
|
+
namespace: e.namespace || "",
|
|
53
|
+
qualifiedName: qualifiedName,
|
|
54
|
+
titleLower: title.toLowerCase(),
|
|
55
|
+
pathLower: (e.path || "").toLowerCase(),
|
|
56
|
+
qualifiedLower: qualifiedName.toLowerCase(),
|
|
57
|
+
ownerLower: owner.toLowerCase(),
|
|
58
|
+
searchText: [
|
|
59
|
+
e.method || "",
|
|
60
|
+
e.path || "",
|
|
61
|
+
title,
|
|
62
|
+
qualifiedName,
|
|
63
|
+
owner,
|
|
64
|
+
e.ownerKind || "",
|
|
65
|
+
e.namespace || "",
|
|
66
|
+
e.symbolKind || "",
|
|
67
|
+
e.content || "",
|
|
68
|
+
tab,
|
|
69
|
+
]
|
|
70
|
+
.join(" ")
|
|
71
|
+
.toLowerCase(),
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
indexLoaded = true;
|
|
75
|
+
callback();
|
|
76
|
+
})
|
|
77
|
+
.catch(function () {
|
|
78
|
+
indexLoaded = true;
|
|
79
|
+
callback();
|
|
80
|
+
});
|
|
42
81
|
}
|
|
43
82
|
|
|
44
|
-
var dialogInner = dialog.querySelector(
|
|
83
|
+
var dialogInner = dialog.querySelector(".search-dialog-inner");
|
|
45
84
|
|
|
46
85
|
function positionDialog() {
|
|
47
86
|
if (!openBtn || !dialogInner) return;
|
|
48
87
|
var rect = openBtn.getBoundingClientRect();
|
|
49
|
-
dialogInner.style.position =
|
|
50
|
-
dialogInner.style.top =
|
|
88
|
+
dialogInner.style.position = "absolute";
|
|
89
|
+
dialogInner.style.top = rect.top - 4 + "px";
|
|
51
90
|
var extraWidth = Math.min(rect.width * 0.5, 200);
|
|
52
|
-
dialogInner.style.left =
|
|
53
|
-
dialogInner.style.width =
|
|
54
|
-
dialogInner.style.maxWidth =
|
|
55
|
-
dialogInner.style.transform =
|
|
56
|
-
dialogInner.style.margin =
|
|
91
|
+
dialogInner.style.left = rect.left - extraWidth / 2 + "px";
|
|
92
|
+
dialogInner.style.width = rect.width + extraWidth + "px";
|
|
93
|
+
dialogInner.style.maxWidth = "none";
|
|
94
|
+
dialogInner.style.transform = "none";
|
|
95
|
+
dialogInner.style.margin = "0";
|
|
57
96
|
}
|
|
58
97
|
|
|
59
98
|
function open() {
|
|
60
99
|
positionDialog();
|
|
61
|
-
dialog.classList.add(
|
|
62
|
-
input.value =
|
|
100
|
+
dialog.classList.add("open");
|
|
101
|
+
input.value = "";
|
|
63
102
|
input.focus();
|
|
64
103
|
if (!indexLoaded) {
|
|
65
104
|
results.innerHTML = '<div class="search-loading">Loading…</div>';
|
|
66
|
-
loadJsonIndex(function () {
|
|
105
|
+
loadJsonIndex(function () {
|
|
106
|
+
showResults("");
|
|
107
|
+
});
|
|
67
108
|
} else {
|
|
68
|
-
showResults(
|
|
109
|
+
showResults("");
|
|
69
110
|
}
|
|
70
|
-
document.addEventListener(
|
|
111
|
+
document.addEventListener("keydown", onDialogKey);
|
|
71
112
|
}
|
|
72
113
|
|
|
73
114
|
function close() {
|
|
74
|
-
dialog.classList.remove(
|
|
75
|
-
document.removeEventListener(
|
|
115
|
+
dialog.classList.remove("open");
|
|
116
|
+
document.removeEventListener("keydown", onDialogKey);
|
|
76
117
|
}
|
|
77
118
|
|
|
78
119
|
function showResults(query) {
|
|
79
120
|
var q = query.toLowerCase().trim();
|
|
80
121
|
if (!q) {
|
|
81
122
|
// Show featured pages first, then endpoints
|
|
82
|
-
var featured = entries.filter(function (e) {
|
|
83
|
-
|
|
123
|
+
var featured = entries.filter(function (e) {
|
|
124
|
+
return e.featured;
|
|
125
|
+
});
|
|
126
|
+
var rest = entries.filter(function (e) {
|
|
127
|
+
return !e.featured && e.category !== "Sections";
|
|
128
|
+
});
|
|
84
129
|
filtered = featured.concat(rest).slice(0, 30);
|
|
85
130
|
} else {
|
|
86
131
|
var terms = q.split(/\s+/);
|
|
87
|
-
filtered = entries
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
132
|
+
filtered = entries
|
|
133
|
+
.map(function (e) {
|
|
134
|
+
return { entry: e, score: scoreEntry(e, q, terms) };
|
|
135
|
+
})
|
|
136
|
+
.filter(function (result) {
|
|
137
|
+
return result.score > 0;
|
|
138
|
+
});
|
|
139
|
+
var categoryOrder = {
|
|
140
|
+
Pages: 0,
|
|
141
|
+
Endpoints: 1,
|
|
142
|
+
Models: 2,
|
|
143
|
+
Functions: 3,
|
|
144
|
+
Types: 4,
|
|
145
|
+
Enums: 5,
|
|
146
|
+
"Enum Values": 6,
|
|
147
|
+
Variables: 7,
|
|
148
|
+
Friends: 8,
|
|
149
|
+
Properties: 9,
|
|
150
|
+
Members: 10,
|
|
151
|
+
Sections: 20,
|
|
152
|
+
};
|
|
92
153
|
filtered.sort(function (a, b) {
|
|
93
|
-
|
|
154
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
155
|
+
return (categoryOrder[a.entry.category] || 19) - (categoryOrder[b.entry.category] || 19);
|
|
94
156
|
});
|
|
157
|
+
filtered = filtered
|
|
158
|
+
.map(function (result) {
|
|
159
|
+
return result.entry;
|
|
160
|
+
})
|
|
161
|
+
.slice(0, 50);
|
|
95
162
|
}
|
|
96
163
|
|
|
97
164
|
activeIndex = filtered.length ? 0 : -1;
|
|
98
165
|
render();
|
|
99
166
|
}
|
|
100
167
|
|
|
168
|
+
function scoreEntry(e, q, terms) {
|
|
169
|
+
if (
|
|
170
|
+
!terms.every(function (t) {
|
|
171
|
+
return e.searchText.indexOf(t) !== -1;
|
|
172
|
+
})
|
|
173
|
+
)
|
|
174
|
+
return 0;
|
|
175
|
+
|
|
176
|
+
var compactQuery = q.replace(/\s+/g, "");
|
|
177
|
+
var qualified = e.qualifiedLower || "";
|
|
178
|
+
var title = e.titleLower || "";
|
|
179
|
+
var path = e.pathLower || "";
|
|
180
|
+
var owner = e.ownerLower || "";
|
|
181
|
+
var score = 1;
|
|
182
|
+
|
|
183
|
+
if (qualified && qualified === compactQuery) score += 1200;
|
|
184
|
+
if (title && title === q) score += 900;
|
|
185
|
+
if (path && path === q) score += 850;
|
|
186
|
+
if (qualified && qualified.endsWith("::" + compactQuery)) score += 780;
|
|
187
|
+
if (owner && compactQuery === owner + "::" + title) score += 760;
|
|
188
|
+
if (qualified && compactQuery.indexOf("::") !== -1 && qualified.indexOf(compactQuery) !== -1)
|
|
189
|
+
score += 700;
|
|
190
|
+
if (title && title.indexOf(q) === 0) score += 500;
|
|
191
|
+
if (qualified && qualified.indexOf(compactQuery) !== -1) score += 420;
|
|
192
|
+
if (owner && owner.indexOf(compactQuery) !== -1) score += 240;
|
|
193
|
+
if (path && path.indexOf(q) !== -1) score += 180;
|
|
194
|
+
if (e.content.toLowerCase().indexOf(q) !== -1) score += 80;
|
|
195
|
+
|
|
196
|
+
if (e.category === "Sections") score -= 70;
|
|
197
|
+
if (e.symbolKind) score += 35;
|
|
198
|
+
if (e.featured) score += 20;
|
|
199
|
+
return score;
|
|
200
|
+
}
|
|
201
|
+
|
|
101
202
|
function render() {
|
|
102
|
-
var html =
|
|
103
|
-
var lastCategory =
|
|
203
|
+
var html = "";
|
|
204
|
+
var lastCategory = "";
|
|
104
205
|
|
|
105
206
|
for (var i = 0; i < filtered.length; i++) {
|
|
106
207
|
var e = filtered[i];
|
|
107
|
-
var cat = e.category ||
|
|
208
|
+
var cat = e.category || "Results";
|
|
108
209
|
|
|
109
210
|
if (cat !== lastCategory) {
|
|
110
|
-
html += '<div class="search-category">' + escapeHtml(cat) +
|
|
211
|
+
html += '<div class="search-category">' + escapeHtml(cat) + "</div>";
|
|
111
212
|
lastCategory = cat;
|
|
112
213
|
}
|
|
113
214
|
|
|
114
|
-
var cls =
|
|
215
|
+
var cls = "search-result" + (i === activeIndex ? " active" : "");
|
|
115
216
|
var label = e.method
|
|
116
|
-
? '<span class="search-result-method method-' +
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
217
|
+
? '<span class="search-result-method method-' +
|
|
218
|
+
e.method.toLowerCase() +
|
|
219
|
+
'">' +
|
|
220
|
+
e.method +
|
|
221
|
+
"</span> " +
|
|
222
|
+
'<span class="search-result-path">' +
|
|
223
|
+
escapeHtml(e.path) +
|
|
224
|
+
"</span>"
|
|
225
|
+
: '<span class="search-result-path">' + escapeHtml(e.summary) + "</span>";
|
|
226
|
+
var tagLine = e.tag
|
|
227
|
+
? '<span class="search-result-tag">' + escapeHtml(e.tag) + "</span>"
|
|
228
|
+
: "";
|
|
229
|
+
var summaryLine =
|
|
230
|
+
e.method && e.summary
|
|
231
|
+
? '<span class="search-result-summary">' + escapeHtml(e.summary) + "</span>"
|
|
232
|
+
: "";
|
|
233
|
+
|
|
234
|
+
html +=
|
|
235
|
+
'<a href="' +
|
|
236
|
+
escapeAttr(e.url) +
|
|
237
|
+
'" class="' +
|
|
238
|
+
cls +
|
|
239
|
+
'" data-index="' +
|
|
240
|
+
i +
|
|
241
|
+
'">' +
|
|
242
|
+
'<div class="search-result-main">' +
|
|
243
|
+
label +
|
|
244
|
+
summaryLine +
|
|
245
|
+
"</div>" +
|
|
246
|
+
tagLine +
|
|
247
|
+
"</a>";
|
|
125
248
|
}
|
|
126
249
|
|
|
127
250
|
results.innerHTML = html;
|
|
128
251
|
|
|
129
252
|
// Scroll active result into view
|
|
130
|
-
var activeEl = results.querySelector(
|
|
131
|
-
if (activeEl) activeEl.scrollIntoView({ block:
|
|
253
|
+
var activeEl = results.querySelector(".search-result.active");
|
|
254
|
+
if (activeEl) activeEl.scrollIntoView({ block: "nearest" });
|
|
132
255
|
}
|
|
133
256
|
|
|
134
257
|
function escapeHtml(s) {
|
|
135
|
-
var el = document.createElement(
|
|
258
|
+
var el = document.createElement("span");
|
|
136
259
|
el.textContent = s;
|
|
137
260
|
return el.innerHTML;
|
|
138
261
|
}
|
|
139
262
|
|
|
263
|
+
function escapeAttr(s) {
|
|
264
|
+
return escapeHtml(s).replace(/"/g, """).replace(/'/g, "'");
|
|
265
|
+
}
|
|
266
|
+
|
|
140
267
|
function navigate(index) {
|
|
141
268
|
if (index < 0 || index >= filtered.length) return;
|
|
142
269
|
var entry = filtered[index];
|
|
@@ -145,71 +272,75 @@
|
|
|
145
272
|
}
|
|
146
273
|
|
|
147
274
|
function onDialogKey(e) {
|
|
148
|
-
if (e.key ===
|
|
149
|
-
|
|
275
|
+
if (e.key === "Escape") {
|
|
276
|
+
close();
|
|
277
|
+
e.preventDefault();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (e.key === "ArrowDown") {
|
|
150
281
|
e.preventDefault();
|
|
151
282
|
activeIndex = Math.min(activeIndex + 1, filtered.length - 1);
|
|
152
283
|
render();
|
|
153
284
|
return;
|
|
154
285
|
}
|
|
155
|
-
if (e.key ===
|
|
286
|
+
if (e.key === "ArrowUp") {
|
|
156
287
|
e.preventDefault();
|
|
157
288
|
activeIndex = Math.max(activeIndex - 1, 0);
|
|
158
289
|
render();
|
|
159
290
|
return;
|
|
160
291
|
}
|
|
161
|
-
if (e.key ===
|
|
292
|
+
if (e.key === "Enter") {
|
|
162
293
|
e.preventDefault();
|
|
163
294
|
if (activeIndex >= 0) navigate(activeIndex);
|
|
164
295
|
return;
|
|
165
296
|
}
|
|
166
297
|
}
|
|
167
298
|
|
|
168
|
-
input.addEventListener(
|
|
299
|
+
input.addEventListener("input", function () {
|
|
169
300
|
showResults(input.value);
|
|
170
301
|
});
|
|
171
302
|
|
|
172
|
-
results.addEventListener(
|
|
173
|
-
var result = e.target.closest(
|
|
303
|
+
results.addEventListener("click", function (e) {
|
|
304
|
+
var result = e.target.closest(".search-result");
|
|
174
305
|
if (result) {
|
|
175
306
|
e.preventDefault();
|
|
176
|
-
navigate(parseInt(result.getAttribute(
|
|
307
|
+
navigate(parseInt(result.getAttribute("data-index"), 10));
|
|
177
308
|
}
|
|
178
309
|
});
|
|
179
310
|
|
|
180
311
|
// Open search
|
|
181
|
-
if (openBtn) openBtn.addEventListener(
|
|
312
|
+
if (openBtn) openBtn.addEventListener("click", open);
|
|
182
313
|
|
|
183
314
|
// Also bind mobile search button
|
|
184
|
-
var mobileBtn = document.getElementById(
|
|
185
|
-
if (mobileBtn) mobileBtn.addEventListener(
|
|
315
|
+
var mobileBtn = document.getElementById("search-open-mobile");
|
|
316
|
+
if (mobileBtn) mobileBtn.addEventListener("click", open);
|
|
186
317
|
|
|
187
318
|
// Keyboard shortcut: Ctrl+K or /
|
|
188
|
-
document.addEventListener(
|
|
189
|
-
if ((e.ctrlKey || e.metaKey) && e.key ===
|
|
319
|
+
document.addEventListener("keydown", function (e) {
|
|
320
|
+
if ((e.ctrlKey || e.metaKey) && e.key === "k") {
|
|
190
321
|
e.preventDefault();
|
|
191
322
|
open();
|
|
192
323
|
}
|
|
193
|
-
if (e.key ===
|
|
324
|
+
if (e.key === "/" && !isEditable(e.target)) {
|
|
194
325
|
e.preventDefault();
|
|
195
326
|
open();
|
|
196
327
|
}
|
|
197
328
|
});
|
|
198
329
|
|
|
199
330
|
// Close on backdrop click
|
|
200
|
-
dialog.addEventListener(
|
|
331
|
+
dialog.addEventListener("click", function (e) {
|
|
201
332
|
if (e.target === dialog) close();
|
|
202
333
|
});
|
|
203
334
|
|
|
204
335
|
function isEditable(el) {
|
|
205
336
|
var tag = el.tagName;
|
|
206
|
-
return tag ===
|
|
337
|
+
return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || el.isContentEditable;
|
|
207
338
|
}
|
|
208
339
|
}
|
|
209
340
|
|
|
210
|
-
if (
|
|
341
|
+
if ("requestIdleCallback" in window) {
|
|
211
342
|
window.requestIdleCallback(init, { timeout: 250 });
|
|
212
343
|
} else {
|
|
213
|
-
window.addEventListener(
|
|
344
|
+
window.addEventListener("load", init, { once: true });
|
|
214
345
|
}
|
|
215
346
|
})();
|
package/dist/client/tabs.js
CHANGED
|
@@ -156,6 +156,29 @@
|
|
|
156
156
|
});
|
|
157
157
|
});
|
|
158
158
|
|
|
159
|
+
// ── Rust Doctest Hidden-Line Toggle ──────────────────────────────
|
|
160
|
+
// (Copy is handled by the shared .copy-btn inside each code block.)
|
|
161
|
+
|
|
162
|
+
document.addEventListener('click', function (e) {
|
|
163
|
+
var toggleBtn = e.target.closest('.rust-doctest-toggle-hidden');
|
|
164
|
+
if (!toggleBtn) return;
|
|
165
|
+
var fullSel = toggleBtn.getAttribute('data-target');
|
|
166
|
+
var displaySel = toggleBtn.getAttribute('data-display');
|
|
167
|
+
var fullEl = fullSel ? document.getElementById(fullSel.replace(/^#/, '')) : null;
|
|
168
|
+
var displayEl = displaySel ? document.getElementById(displaySel.replace(/^#/, '')) : null;
|
|
169
|
+
if (!fullEl || !displayEl) return;
|
|
170
|
+
var fullHidden = fullEl.hasAttribute('hidden');
|
|
171
|
+
if (fullHidden) {
|
|
172
|
+
fullEl.removeAttribute('hidden');
|
|
173
|
+
displayEl.setAttribute('hidden', '');
|
|
174
|
+
toggleBtn.textContent = 'Hide hidden lines';
|
|
175
|
+
} else {
|
|
176
|
+
fullEl.setAttribute('hidden', '');
|
|
177
|
+
displayEl.removeAttribute('hidden');
|
|
178
|
+
toggleBtn.textContent = 'Show hidden lines';
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
159
182
|
// Close dropdowns on Escape
|
|
160
183
|
document.addEventListener('keydown', function (e) {
|
|
161
184
|
if (e.key === 'Escape') {
|
|
@@ -13,15 +13,15 @@ export function Head() {
|
|
|
13
13
|
: undefined;
|
|
14
14
|
const siteName = site.name || spec.info.title || "";
|
|
15
15
|
const pageTitle = page.kind === "markdown"
|
|
16
|
-
? (
|
|
16
|
+
? composePageTitle(page.markdown.title, siteName)
|
|
17
17
|
: page.kind === "changelog"
|
|
18
18
|
? (() => {
|
|
19
19
|
const baseTitle = changelogVersion
|
|
20
|
-
? `${changelogVersion.version ?? "Unreleased"}
|
|
20
|
+
? `${changelogVersion.version ?? "Unreleased"} - ${page.changelog.title}`
|
|
21
21
|
: page.changelog.title;
|
|
22
|
-
return
|
|
22
|
+
return composePageTitle(baseTitle, siteName);
|
|
23
23
|
})()
|
|
24
|
-
:
|
|
24
|
+
: composePageTitle(siteName, "API Reference");
|
|
25
25
|
const pageDescription = page.kind === "markdown"
|
|
26
26
|
? page.markdown.description || pageTitle
|
|
27
27
|
: page.kind === "changelog"
|
|
@@ -58,3 +58,16 @@ export function Head() {
|
|
|
58
58
|
`;
|
|
59
59
|
return (_jsxs("head", { children: [_jsx("meta", { charset: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: pageTitle }), _jsx("meta", { name: "description", content: pageDescription }), _jsx("meta", { name: "generator", content: `Sourcey ${pkg.version}` }), options.pageUrl && _jsx("link", { rel: "canonical", href: options.pageUrl }), _jsx("meta", { property: "og:title", content: pageTitle }), _jsx("meta", { property: "og:description", content: pageDescription }), _jsx("meta", { property: "og:type", content: "website" }), siteName && _jsx("meta", { property: "og:site_name", content: siteName }), options.pageUrl && _jsx("meta", { property: "og:url", content: options.pageUrl }), options.ogImageUrl && _jsx("meta", { property: "og:image", content: options.ogImageUrl }), options.ogImageUrl && _jsx("meta", { property: "og:image:width", content: "1200" }), options.ogImageUrl && _jsx("meta", { property: "og:image:height", content: "630" }), options.ogImageUrl && _jsx("meta", { property: "og:image:type", content: "image/png" }), _jsx("meta", { name: "twitter:card", content: options.ogImageUrl ? "summary_large_image" : "summary" }), _jsx("meta", { name: "twitter:title", content: pageTitle }), _jsx("meta", { name: "twitter:description", content: pageDescription }), options.ogImageUrl && _jsx("meta", { name: "twitter:image", content: options.ogImageUrl }), _jsx("meta", { name: "sourcey-search", content: `${options.assetBase}search-index.json` }), options.alternateLinks?.map((link) => (_jsx("link", { rel: "alternate", type: link.type, href: link.href, title: link.title }, `${link.type}-${link.href}`))), _jsx("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }), _jsx("link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: "anonymous" }), _jsx("link", { rel: "stylesheet", href: `https://fonts.googleapis.com/css2?family=${encodeURIComponent(fonts.googleFont)}:wght@100..900&display=swap` }), _jsx("style", { dangerouslySetInnerHTML: { __html: themeCSS } }), showLangIconCSS && _jsx("style", { dangerouslySetInnerHTML: { __html: langIconCSS() } }), site.customCSS && _jsx("style", { dangerouslySetInnerHTML: { __html: site.customCSS } }), _jsx("script", { dangerouslySetInnerHTML: { __html: `(function(){var t=localStorage.getItem('sourcey-theme');if(t==='dark')document.documentElement.classList.add('dark')})()` } }), _jsx("link", { rel: "stylesheet", href: `${options.assetBase}sourcey.css` }), site.favicon && _jsx("link", { rel: "icon", href: site.favicon })] }));
|
|
60
60
|
}
|
|
61
|
+
function composePageTitle(title, siteName) {
|
|
62
|
+
if (!siteName)
|
|
63
|
+
return title;
|
|
64
|
+
if (!title)
|
|
65
|
+
return siteName;
|
|
66
|
+
return sameTitle(title, siteName) ? title : `${title} - ${siteName}`;
|
|
67
|
+
}
|
|
68
|
+
function sameTitle(left, right) {
|
|
69
|
+
return normalizeTitle(left) === normalizeTitle(right);
|
|
70
|
+
}
|
|
71
|
+
function normalizeTitle(value) {
|
|
72
|
+
return value.trim().replace(/\s+/g, " ").toLowerCase();
|
|
73
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableOfContents.d.ts","sourceRoot":"","sources":["../../../src/components/layout/TableOfContents.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"TableOfContents.d.ts","sourceRoot":"","sources":["../../../src/components/layout/TableOfContents.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AA2CjE,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,WAAW,EAAE,CAAA;CAAE,uCAuBxE"}
|
|
@@ -7,10 +7,12 @@ import { iconPath } from "../../utils/icons.js";
|
|
|
7
7
|
*/
|
|
8
8
|
const tocLink = "toc-item break-words block hover:text-[rgb(var(--color-gray-900))] dark:hover:text-[rgb(var(--color-gray-300))] dark:text-[rgb(var(--color-gray-400))] transition-colors";
|
|
9
9
|
function TocList({ headings }) {
|
|
10
|
-
// Group
|
|
10
|
+
// Group by the shallowest heading present. Moxygen C++ pages often use
|
|
11
|
+
// h1 for the page title and h3 for sections, with no h2 in between.
|
|
12
|
+
const rootLevel = Math.min(...headings.map((h) => h.level));
|
|
11
13
|
const groups = [];
|
|
12
14
|
for (const h of headings) {
|
|
13
|
-
if (h.level
|
|
15
|
+
if (h.level <= rootLevel) {
|
|
14
16
|
groups.push({ root: h, children: [] });
|
|
15
17
|
}
|
|
16
18
|
else if (groups.length) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Introduction.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Introduction.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Introduction.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Introduction.tsx"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,YAAY,iCAmE3B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { useContext } from "preact/hooks";
|
|
3
3
|
import { SpecContext } from "../../renderer/context.js";
|
|
4
|
+
import { safeUrl } from "../../utils/html.js";
|
|
4
5
|
import { Markdown } from "../ui/Markdown.js";
|
|
5
6
|
/**
|
|
6
7
|
* API introduction: description, contact info, server URLs.
|
|
@@ -9,5 +10,19 @@ import { Markdown } from "../ui/Markdown.js";
|
|
|
9
10
|
export function Introduction() {
|
|
10
11
|
const spec = useContext(SpecContext);
|
|
11
12
|
const { info, servers } = spec;
|
|
12
|
-
|
|
13
|
+
const termsUrl = info.termsOfService
|
|
14
|
+
? safeUrl(info.termsOfService, {
|
|
15
|
+
allowedProtocols: ["http:", "https:"],
|
|
16
|
+
allowRelative: false,
|
|
17
|
+
allowAnchor: false,
|
|
18
|
+
})
|
|
19
|
+
: null;
|
|
20
|
+
const contactEmailUrl = info.contact?.email
|
|
21
|
+
? safeUrl(`mailto:${info.contact.email}`, {
|
|
22
|
+
allowedProtocols: ["mailto:"],
|
|
23
|
+
allowRelative: false,
|
|
24
|
+
allowAnchor: false,
|
|
25
|
+
})
|
|
26
|
+
: null;
|
|
27
|
+
return (_jsxs("div", { id: "introduction", "data-traverse-target": "introduction", class: "mb-8", children: [termsUrl && (_jsx("p", { class: "mt-4 text-sm text-[rgb(var(--color-gray-500))]", children: _jsx("a", { href: termsUrl, class: "text-[rgb(var(--color-primary-ink))] dark:text-[rgb(var(--color-primary-light))]", children: "Terms of Service" }) })), info.contact?.email && contactEmailUrl && (_jsxs("p", { class: "mt-2 text-sm text-[rgb(var(--color-gray-500))]", children: ["Contact:", " ", _jsx("a", { href: contactEmailUrl, class: "text-[rgb(var(--color-primary-ink))] dark:text-[rgb(var(--color-primary-light))]", children: info.contact.email })] })), servers.length > 0 && (_jsxs("div", { class: "mt-6 rounded-[var(--radius)] border border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)] overflow-x-auto", children: [_jsxs("div", { class: "px-4 py-2.5 text-xs font-semibold text-[rgb(var(--color-gray-600))] dark:text-[rgb(var(--color-gray-300))] border-b border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)]", children: ["Base URL", servers.length > 1 ? "s" : ""] }), servers.map((s, i) => (_jsxs("div", { class: `flex items-baseline gap-3 px-4 py-2 ${i > 0 ? "border-t border-[rgb(var(--color-gray-100))] dark:border-[rgb(var(--color-gray-800))]" : ""}`, children: [_jsx("code", { class: "font-mono text-sm text-[rgb(var(--color-gray-800))] dark:text-[rgb(var(--color-gray-200))]", children: s.url }), s.description && (_jsx("span", { class: "text-xs text-[rgb(var(--color-gray-500))]", children: s.description }))] }, i)))] })), info.description && _jsx(Markdown, { content: info.description, class: "max-w-none mt-8" })] }));
|
|
13
28
|
}
|