@mandolin/jsdoc-theme-hia 0.1.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 +29 -0
- package/LICENSE +21 -0
- package/README.md +176 -0
- package/RELEASE_CHECKLIST.md +43 -0
- package/THIRD_PARTY_NOTICES.md +23 -0
- package/examples/basic/README.md +29 -0
- package/examples/basic/jsdoc.conf.json +52 -0
- package/examples/basic/src/demo.js +65 -0
- package/package.json +58 -0
- package/publish.js +110 -0
- package/src/metadata-reader.cjs +262 -0
- package/src/render.cjs +1366 -0
- package/static/hia-theme.css +798 -0
- package/static/hia-theme.js +394 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
(() => {
|
|
4
|
+
const input = document.getElementById("hia-symbol-search");
|
|
5
|
+
const dataElement = document.getElementById("hia-search-data");
|
|
6
|
+
const i18nElement = document.getElementById("hia-i18n-data");
|
|
7
|
+
const themeElement = document.getElementById("hia-theme-data");
|
|
8
|
+
|
|
9
|
+
if (!input || !dataElement) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let searchData = [];
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
searchData = JSON.parse(dataElement.textContent || "[]");
|
|
17
|
+
} catch (_error) {
|
|
18
|
+
searchData = [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const records = searchData.map((entry) => ({
|
|
22
|
+
id: entry.id,
|
|
23
|
+
text: [
|
|
24
|
+
entry.kind,
|
|
25
|
+
entry.name,
|
|
26
|
+
entry.longname,
|
|
27
|
+
entry.memberof,
|
|
28
|
+
entry.summary,
|
|
29
|
+
...Object.values(entry.localizedSummaries || {})
|
|
30
|
+
].join(" ").toLowerCase()
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
const links = Array.from(document.querySelectorAll(".nav-group a"));
|
|
34
|
+
const groups = Array.from(document.querySelectorAll(".nav-group"));
|
|
35
|
+
const articles = Array.from(document.querySelectorAll(".doclet"));
|
|
36
|
+
|
|
37
|
+
function setVisible(element, visible) {
|
|
38
|
+
element.hidden = !visible;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function update() {
|
|
42
|
+
const query = input.value.trim().toLowerCase();
|
|
43
|
+
const visibleIds = new Set(
|
|
44
|
+
records
|
|
45
|
+
.filter((record) => !query || record.text.includes(query))
|
|
46
|
+
.map((record) => record.id)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
for (const article of articles) {
|
|
50
|
+
setVisible(article, visibleIds.has(article.id));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for (const link of links) {
|
|
54
|
+
const targetId = decodeURIComponent((link.getAttribute("href") || "").replace(/^#/, ""));
|
|
55
|
+
setVisible(link, visibleIds.has(targetId));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const group of groups) {
|
|
59
|
+
const hasVisibleLink = Array.from(group.querySelectorAll("a")).some((link) => !link.hidden);
|
|
60
|
+
setVisible(group, hasVisibleLink);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
input.addEventListener("input", update);
|
|
65
|
+
|
|
66
|
+
let themeData = {};
|
|
67
|
+
|
|
68
|
+
if (themeElement) {
|
|
69
|
+
try {
|
|
70
|
+
themeData = JSON.parse(themeElement.textContent || "{}");
|
|
71
|
+
} catch (_error) {
|
|
72
|
+
themeData = {};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const codeFontFamilies = {
|
|
77
|
+
cascadia: "\"Cascadia Code\", \"Cascadia Mono\", Consolas, monospace",
|
|
78
|
+
consolas: "Consolas, \"Courier New\", monospace",
|
|
79
|
+
mono: "ui-monospace, \"SFMono-Regular\", Menlo, Monaco, Consolas, monospace",
|
|
80
|
+
system: "monospace"
|
|
81
|
+
};
|
|
82
|
+
const codeStorageKey = "hia-docs-code-display";
|
|
83
|
+
const codeControls = document.querySelector("[data-hia-code-controls]");
|
|
84
|
+
|
|
85
|
+
function clampNumber(value, fallback, min, max) {
|
|
86
|
+
const number = Number(value);
|
|
87
|
+
|
|
88
|
+
if (!Number.isFinite(number)) {
|
|
89
|
+
return fallback;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return Math.min(max, Math.max(min, number));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function normalizeCodeSettings(value) {
|
|
96
|
+
const source = value && typeof value === "object" ? value : {};
|
|
97
|
+
const fontFamily = codeFontFamilies[source.fontFamily] ? source.fontFamily : "cascadia";
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
fontFamily,
|
|
101
|
+
fontSize: clampNumber(source.fontSize, 12, 10, 20),
|
|
102
|
+
lineHeight: clampNumber(source.lineHeight, 1.55, 1.2, 2.2),
|
|
103
|
+
tabSize: Math.round(clampNumber(source.tabSize, 2, 2, 8)),
|
|
104
|
+
wrap: Boolean(source.wrap)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function readStoredCodeSettings() {
|
|
109
|
+
try {
|
|
110
|
+
if (!window.localStorage) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const raw = window.localStorage.getItem(codeStorageKey);
|
|
115
|
+
return raw ? JSON.parse(raw) : null;
|
|
116
|
+
} catch (_error) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function writeStoredCodeSettings(settings) {
|
|
122
|
+
try {
|
|
123
|
+
if (window.localStorage) {
|
|
124
|
+
window.localStorage.setItem(codeStorageKey, JSON.stringify(settings));
|
|
125
|
+
}
|
|
126
|
+
} catch (_error) {
|
|
127
|
+
// Ignore storage failures; code display controls still work for the page.
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function clearStoredCodeSettings() {
|
|
132
|
+
try {
|
|
133
|
+
if (window.localStorage) {
|
|
134
|
+
window.localStorage.removeItem(codeStorageKey);
|
|
135
|
+
}
|
|
136
|
+
} catch (_error) {
|
|
137
|
+
// Ignore storage failures.
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function applyCodeSettings(settings) {
|
|
142
|
+
const normalized = normalizeCodeSettings(settings);
|
|
143
|
+
const body = document.body;
|
|
144
|
+
|
|
145
|
+
body.style.setProperty("--code-font-family", codeFontFamilies[normalized.fontFamily]);
|
|
146
|
+
body.style.setProperty("--code-font-size", `${normalized.fontSize}px`);
|
|
147
|
+
body.style.setProperty("--code-line-height", String(normalized.lineHeight));
|
|
148
|
+
body.style.setProperty("--code-tab-size", String(normalized.tabSize));
|
|
149
|
+
body.classList.toggle("hia-code-wrap", normalized.wrap);
|
|
150
|
+
|
|
151
|
+
if (codeControls) {
|
|
152
|
+
const fontFamilyInput = codeControls.querySelector("[data-hia-code-font-family]");
|
|
153
|
+
const fontSizeInput = codeControls.querySelector("[data-hia-code-font-size]");
|
|
154
|
+
const lineHeightInput = codeControls.querySelector("[data-hia-code-line-height]");
|
|
155
|
+
const tabSizeInput = codeControls.querySelector("[data-hia-code-tab-size]");
|
|
156
|
+
const wrapInput = codeControls.querySelector("[data-hia-code-wrap]");
|
|
157
|
+
|
|
158
|
+
if (fontFamilyInput) {
|
|
159
|
+
fontFamilyInput.value = normalized.fontFamily;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (fontSizeInput) {
|
|
163
|
+
fontSizeInput.value = String(normalized.fontSize);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (lineHeightInput) {
|
|
167
|
+
lineHeightInput.value = String(normalized.lineHeight);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (tabSizeInput) {
|
|
171
|
+
tabSizeInput.value = String(normalized.tabSize);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (wrapInput) {
|
|
175
|
+
wrapInput.checked = normalized.wrap;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return normalized;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function initCodeControls() {
|
|
183
|
+
if (!codeControls) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const defaults = normalizeCodeSettings(themeData.code || {});
|
|
188
|
+
const stored = readStoredCodeSettings();
|
|
189
|
+
let current = applyCodeSettings(stored ? { ...defaults, ...stored } : defaults);
|
|
190
|
+
|
|
191
|
+
function updateCodeSettings(next) {
|
|
192
|
+
current = applyCodeSettings({ ...current, ...next });
|
|
193
|
+
writeStoredCodeSettings(current);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const fontFamilyInput = codeControls.querySelector("[data-hia-code-font-family]");
|
|
197
|
+
const fontSizeInput = codeControls.querySelector("[data-hia-code-font-size]");
|
|
198
|
+
const lineHeightInput = codeControls.querySelector("[data-hia-code-line-height]");
|
|
199
|
+
const tabSizeInput = codeControls.querySelector("[data-hia-code-tab-size]");
|
|
200
|
+
const wrapInput = codeControls.querySelector("[data-hia-code-wrap]");
|
|
201
|
+
const resetButton = codeControls.querySelector("[data-hia-code-reset]");
|
|
202
|
+
|
|
203
|
+
if (fontFamilyInput) {
|
|
204
|
+
fontFamilyInput.addEventListener("change", () => {
|
|
205
|
+
updateCodeSettings({ fontFamily: fontFamilyInput.value });
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (fontSizeInput) {
|
|
210
|
+
fontSizeInput.addEventListener("input", () => {
|
|
211
|
+
updateCodeSettings({ fontSize: fontSizeInput.value });
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (lineHeightInput) {
|
|
216
|
+
lineHeightInput.addEventListener("input", () => {
|
|
217
|
+
updateCodeSettings({ lineHeight: lineHeightInput.value });
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (tabSizeInput) {
|
|
222
|
+
tabSizeInput.addEventListener("input", () => {
|
|
223
|
+
updateCodeSettings({ tabSize: tabSizeInput.value });
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (wrapInput) {
|
|
228
|
+
wrapInput.addEventListener("change", () => {
|
|
229
|
+
updateCodeSettings({ wrap: wrapInput.checked });
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (resetButton) {
|
|
234
|
+
resetButton.addEventListener("click", () => {
|
|
235
|
+
clearStoredCodeSettings();
|
|
236
|
+
current = applyCodeSettings(defaults);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
initCodeControls();
|
|
242
|
+
|
|
243
|
+
let i18nData = {};
|
|
244
|
+
|
|
245
|
+
if (i18nElement) {
|
|
246
|
+
try {
|
|
247
|
+
i18nData = JSON.parse(i18nElement.textContent || "{}");
|
|
248
|
+
} catch (_error) {
|
|
249
|
+
i18nData = {};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (!i18nData.enabled || !Array.isArray(i18nData.locales) || !i18nData.locales.length) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const localePageSelects = Array.from(document.querySelectorAll("[data-hia-locale-page-select]"));
|
|
258
|
+
|
|
259
|
+
for (const select of localePageSelects) {
|
|
260
|
+
select.addEventListener("change", () => {
|
|
261
|
+
if (select.value) {
|
|
262
|
+
window.location.href = select.value;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (i18nData.runtimeSwitch === false) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const localeControls = Array.from(document.querySelectorAll("[data-hia-locale-control]"));
|
|
272
|
+
const localeSelects = Array.from(document.querySelectorAll("[data-hia-locale-select]"));
|
|
273
|
+
const localizedBlocks = Array.from(document.querySelectorAll("[data-hia-locale]"));
|
|
274
|
+
const storageKey = "hia-docs-locale";
|
|
275
|
+
|
|
276
|
+
function readStoredLocale() {
|
|
277
|
+
try {
|
|
278
|
+
return window.localStorage ? window.localStorage.getItem(storageKey) : "";
|
|
279
|
+
} catch (_error) {
|
|
280
|
+
return "";
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function writeStoredLocale(locale) {
|
|
285
|
+
try {
|
|
286
|
+
if (window.localStorage) {
|
|
287
|
+
window.localStorage.setItem(storageKey, locale);
|
|
288
|
+
}
|
|
289
|
+
} catch (_error) {
|
|
290
|
+
// Ignore storage failures; language switching still works for the page.
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function getInitialLocale() {
|
|
295
|
+
const stored = readStoredLocale();
|
|
296
|
+
|
|
297
|
+
if (stored && i18nData.locales.includes(stored)) {
|
|
298
|
+
return stored;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (i18nData.locales.includes(i18nData.defaultLocale)) {
|
|
302
|
+
return i18nData.defaultLocale;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return i18nData.locales[0];
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function getLabels(locale) {
|
|
309
|
+
const labels = i18nData.labels || {};
|
|
310
|
+
const normalized = String(locale || "");
|
|
311
|
+
const baseLocale = normalized.split("-")[0];
|
|
312
|
+
|
|
313
|
+
return Object.assign(
|
|
314
|
+
{},
|
|
315
|
+
labels.en || {},
|
|
316
|
+
labels[baseLocale] || {},
|
|
317
|
+
labels[normalized] || {}
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function formatLabel(template, element) {
|
|
322
|
+
return String(template || "").replace(/\{([a-zA-Z0-9_]+)\}/g, (_match, name) => {
|
|
323
|
+
const value = element.getAttribute(`data-hia-label-${name}`);
|
|
324
|
+
return value === null ? "" : value;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function applyLabels(locale) {
|
|
329
|
+
const labels = getLabels(locale);
|
|
330
|
+
|
|
331
|
+
for (const element of document.querySelectorAll("[data-hia-label]")) {
|
|
332
|
+
const key = element.getAttribute("data-hia-label");
|
|
333
|
+
|
|
334
|
+
if (labels[key]) {
|
|
335
|
+
element.textContent = formatLabel(labels[key], element);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
for (const element of document.querySelectorAll("[data-hia-label-aria]")) {
|
|
340
|
+
const key = element.getAttribute("data-hia-label-aria");
|
|
341
|
+
|
|
342
|
+
if (labels[key]) {
|
|
343
|
+
element.setAttribute("aria-label", formatLabel(labels[key], element));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
for (const element of document.querySelectorAll("[data-hia-label-placeholder]")) {
|
|
348
|
+
const key = element.getAttribute("data-hia-label-placeholder");
|
|
349
|
+
|
|
350
|
+
if (labels[key]) {
|
|
351
|
+
element.setAttribute("placeholder", formatLabel(labels[key], element));
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function setLocale(locale) {
|
|
357
|
+
if (!i18nData.locales.includes(locale)) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
document.documentElement.lang = locale;
|
|
362
|
+
applyLabels(locale);
|
|
363
|
+
|
|
364
|
+
writeStoredLocale(locale);
|
|
365
|
+
|
|
366
|
+
for (const block of localizedBlocks) {
|
|
367
|
+
setVisible(block, block.getAttribute("data-hia-locale") === locale);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
for (const control of localeControls) {
|
|
371
|
+
const active = control.getAttribute("data-hia-locale-control") === locale;
|
|
372
|
+
control.classList.toggle("active", active);
|
|
373
|
+
control.setAttribute("aria-pressed", active ? "true" : "false");
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
for (const select of localeSelects) {
|
|
377
|
+
select.value = locale;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
for (const control of localeControls) {
|
|
382
|
+
control.addEventListener("click", () => {
|
|
383
|
+
setLocale(control.getAttribute("data-hia-locale-control"));
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
for (const select of localeSelects) {
|
|
388
|
+
select.addEventListener("change", () => {
|
|
389
|
+
setLocale(select.value);
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
setLocale(getInitialLocale());
|
|
394
|
+
})();
|