@takazudo/zudo-doc 4.4.13 → 5.0.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 +65 -0
- package/dist/category-nav/index.d.ts +31 -0
- package/dist/category-nav/index.js +15 -3
- package/dist/category-tree-nav/index.d.ts +32 -0
- package/dist/category-tree-nav/index.js +16 -4
- package/dist/chrome/derive.d.ts +32 -3
- package/dist/chrome/derive.js +26 -7
- package/dist/code-syntax/mermaid-init-script.d.ts +6 -7
- package/dist/config.d.ts +22 -5
- package/dist/config.js +11 -0
- package/dist/content.css +1 -0
- package/dist/desktop-toc-toggle-island/index.d.ts +7 -0
- package/dist/desktop-toc-toggle-island/index.js +64 -0
- package/dist/doc-page-renderer/index.d.ts +12 -1
- package/dist/doc-page-renderer/index.js +10 -3
- package/dist/doc-page-shell/index.d.ts +13 -0
- package/dist/doc-page-shell/index.js +37 -3
- package/dist/doclayout/doc-layout.d.ts +14 -0
- package/dist/doclayout/doc-layout.js +4 -2
- package/dist/features.css +82 -10
- package/dist/head-with-defaults/index.js +1 -0
- package/dist/header/header.d.ts +1 -1
- package/dist/header/header.js +2 -2
- package/dist/header/types.d.ts +7 -0
- package/dist/header-with-defaults/index.d.ts +2 -0
- package/dist/header-with-defaults/index.js +9 -2
- package/dist/i18n-version/version-switcher.d.ts +36 -0
- package/dist/i18n-version/version-switcher.js +43 -3
- package/dist/inline-version-switcher/index.d.ts +18 -0
- package/dist/inline-version-switcher/index.js +3 -1
- package/dist/mdx-components/index.d.ts +11 -0
- package/dist/mdx-components/index.js +4 -4
- package/dist/nav-data-prep/index.d.ts +18 -3
- package/dist/nav-data-prep/index.js +3 -3
- package/dist/plugins/internal/claude-resources/generate.d.ts +11 -0
- package/dist/plugins/internal/claude-resources/generate.js +16 -13
- package/dist/plugins/internal/claude-resources/index.js +6 -1
- package/dist/preset.d.ts +16 -7
- package/dist/preset.js +8 -6
- package/dist/routes/_context.d.ts +1 -1
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +17 -2
- package/dist/site-tree-nav/index.d.ts +21 -0
- package/dist/site-tree-nav/index.js +26 -7
- package/dist/theme-packs/academia/meta.json +1 -1
- package/dist/theme-packs/academia/pack.css +13 -3
- package/dist/theme-packs/blueprint/meta.json +1 -1
- package/dist/theme-packs/blueprint/pack.css +9 -0
- package/dist/theme-packs/broadsheet/meta.json +1 -1
- package/dist/theme-packs/broadsheet/pack.css +9 -0
- package/dist/theme-packs/drift/meta.json +1 -1
- package/dist/theme-packs/drift/pack.css +9 -0
- package/dist/theme-packs/fjord/meta.json +1 -1
- package/dist/theme-packs/fjord/pack.css +9 -0
- package/dist/theme-packs/hearth/meta.json +1 -1
- package/dist/theme-packs/hearth/pack.css +9 -0
- package/dist/theme-packs/hollow/meta.json +1 -1
- package/dist/theme-packs/hollow/pack.css +9 -0
- package/dist/theme-packs/matcha/meta.json +1 -1
- package/dist/theme-packs/matcha/pack.css +9 -0
- package/dist/theme-packs/nocturne/meta.json +1 -1
- package/dist/theme-packs/nocturne/pack.css +9 -0
- package/dist/theme-packs/observatory/meta.json +1 -1
- package/dist/theme-packs/observatory/pack.css +18 -0
- package/dist/theme-packs/onyx/meta.json +1 -1
- package/dist/theme-packs/onyx/pack.css +9 -0
- package/dist/theme-packs/sakura/meta.json +1 -1
- package/dist/theme-packs/sakura/pack.css +9 -0
- package/dist/theme-packs/sumi/meta.json +1 -1
- package/dist/theme-packs/sumi/pack.css +9 -0
- package/dist/theme-packs/timberline/meta.json +1 -1
- package/dist/theme-packs/timberline/pack.css +9 -0
- package/dist/theme-packs-registry/validator.js +38 -6
- package/dist/toc-prepaint/index.d.ts +60 -0
- package/dist/toc-prepaint/index.js +44 -0
- package/dist/url-helpers/index.d.ts +1 -1
- package/dist/url-helpers/index.js +2 -2
- package/dist/version-availability/index.d.ts +75 -0
- package/dist/version-availability/index.js +56 -0
- package/dist/versions-page/index.d.ts +9 -1
- package/dist/versions-page/index.js +6 -2
- package/eject/header/header.tsx +3 -2
- package/eject/header/types.ts +7 -0
- package/package.json +17 -10
- package/tsconfig.base.json +2 -1
- package/zfb-config-shim.d.ts +22 -204
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Broadsheet",
|
|
5
5
|
"description": "Newspaper editorial — Playfair masthead, Oxford ink rules, a red drop cap, and a night-edition dark mode.",
|
|
6
6
|
"mode": "light",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.2",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Source Serif 4",
|
|
10
10
|
"mono": "Courier Prime",
|
|
@@ -187,6 +187,15 @@ html[data-theme-pack="broadsheet"] body {
|
|
|
187
187
|
background-attachment: fixed;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
191
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
192
|
+
convention from issue #3070. */
|
|
193
|
+
@media (pointer: coarse) {
|
|
194
|
+
html[data-theme-pack="broadsheet"] body {
|
|
195
|
+
background-attachment: scroll;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
190
199
|
/* masthead: Playfair black wordmark over a thick-thin Oxford rule */
|
|
191
200
|
html[data-theme-pack="broadsheet"] header[data-header] {
|
|
192
201
|
border-bottom: 3px solid var(--zd-fg);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Drift",
|
|
5
5
|
"description": "Floaty slate-blue comfort dark for long reading — soft glows in place of borders, gentle elevation, relaxed Plex type.",
|
|
6
6
|
"mode": "dark",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.2",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "IBM Plex Sans",
|
|
10
10
|
"mono": "IBM Plex Mono",
|
|
@@ -210,6 +210,15 @@ html[data-theme-pack="drift"] body {
|
|
|
210
210
|
);
|
|
211
211
|
background-attachment: fixed;
|
|
212
212
|
}
|
|
213
|
+
|
|
214
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
215
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
216
|
+
convention from issue #3070. */
|
|
217
|
+
@media (pointer: coarse) {
|
|
218
|
+
html[data-theme-pack="drift"] body {
|
|
219
|
+
background-attachment: scroll;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
213
222
|
/* the base stylesheet sets `.zd-content { line-height: var(--leading-relaxed) }`
|
|
214
223
|
(1.625), which beats the inherited body value — restate the relaxed
|
|
215
224
|
1.75 rhythm on the prose container itself */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Fjord",
|
|
5
5
|
"description": "Polar-night blue under a faint aurora — frost-cyan accents, icy borders, snow-white text. Cold nordic calm.",
|
|
6
6
|
"mode": "dark",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.2",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Inter",
|
|
10
10
|
"mono": "JetBrains Mono",
|
|
@@ -170,6 +170,15 @@ html[data-theme-pack="fjord"] body {
|
|
|
170
170
|
background-attachment: fixed;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
174
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
175
|
+
convention from issue #3070. */
|
|
176
|
+
@media (pointer: coarse) {
|
|
177
|
+
html[data-theme-pack="fjord"] body {
|
|
178
|
+
background-attachment: scroll;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
173
182
|
html[data-theme-pack="fjord"] {
|
|
174
183
|
scrollbar-color: color-mix(in oklch, var(--zd-muted) 45%, transparent) transparent;
|
|
175
184
|
}
|
|
@@ -172,6 +172,15 @@ html[data-theme-pack="hearth"] body {
|
|
|
172
172
|
background-attachment: fixed;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
176
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
177
|
+
convention from issue #3070. */
|
|
178
|
+
@media (pointer: coarse) {
|
|
179
|
+
html[data-theme-pack="hearth"] body {
|
|
180
|
+
background-attachment: scroll;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
175
184
|
/* header: warm mantelpiece — soft gradient, warm hairline, brown
|
|
176
185
|
shadow */
|
|
177
186
|
html[data-theme-pack="hearth"] header[data-header] {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Hollow",
|
|
5
5
|
"description": "Dark violet space — neon pink headings, violet links, a quiet starfield, and razor-square midnight chrome.",
|
|
6
6
|
"mode": "dark",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.2",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Space Grotesk",
|
|
10
10
|
"mono": "Space Mono",
|
|
@@ -209,6 +209,15 @@ html[data-theme-pack="hollow"] body {
|
|
|
209
209
|
background-attachment: fixed;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
213
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
214
|
+
convention from issue #3070. */
|
|
215
|
+
@media (pointer: coarse) {
|
|
216
|
+
html[data-theme-pack="hollow"] body {
|
|
217
|
+
background-attachment: scroll;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
212
221
|
/* sidebar floats transparently over the starfield */
|
|
213
222
|
html[data-theme-pack="hollow"] #desktop-sidebar {
|
|
214
223
|
background-color: transparent;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Matcha",
|
|
5
5
|
"description": "Green tea ceremony — deep matcha on warm cream, mincho headings, zen whitespace, tea-foam surfaces in both modes.",
|
|
6
6
|
"mode": "light",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.2",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Zen Kaku Gothic New",
|
|
10
10
|
"mono": "M PLUS 1 Code",
|
|
@@ -183,6 +183,15 @@ html[data-theme-pack="matcha"] body {
|
|
|
183
183
|
background-attachment: fixed;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
187
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
188
|
+
convention from issue #3070. */
|
|
189
|
+
@media (pointer: coarse) {
|
|
190
|
+
html[data-theme-pack="matcha"] body {
|
|
191
|
+
background-attachment: scroll;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
186
195
|
/* zen prose: let the reading column breathe. The package flow-space
|
|
187
196
|
rhythm (vsp-2xl h2 / vsp-xl h3) already sits within 0.1rem of the
|
|
188
197
|
prototype's spacing, so only the line-height lever is ported. */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Nocturne",
|
|
5
5
|
"description": "Purple midnight — velvet aubergine depths, lavender links, and muted gold hairlines. Elegant, never neon.",
|
|
6
6
|
"mode": "dark",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.2",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Manrope",
|
|
10
10
|
"mono": "IBM Plex Mono",
|
|
@@ -216,6 +216,15 @@ html[data-theme-pack="nocturne"] body {
|
|
|
216
216
|
background-attachment: fixed;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
220
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
221
|
+
convention from issue #3070. */
|
|
222
|
+
@media (pointer: coarse) {
|
|
223
|
+
html[data-theme-pack="nocturne"] body {
|
|
224
|
+
background-attachment: scroll;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
219
228
|
/* header: velvet band under a gold hairline */
|
|
220
229
|
html[data-theme-pack="nocturne"] header[data-header] {
|
|
221
230
|
border-bottom-color: light-dark(oklch(0.53 0.105 85 / 0.45), oklch(0.78 0.105 87 / 0.45));
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Observatory",
|
|
5
5
|
"description": "Night-sky atlas: star-field depth, constellation-line rules, nebula violet and comet gold over astronomer's navy.",
|
|
6
6
|
"mode": "dark",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.3",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Jost",
|
|
10
10
|
"mono": "Space Mono",
|
|
@@ -258,6 +258,15 @@ html[data-theme-pack="observatory"] body {
|
|
|
258
258
|
letter-spacing: 0.005em;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
262
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
263
|
+
convention from issue #3070. */
|
|
264
|
+
@media (pointer: coarse) {
|
|
265
|
+
html[data-theme-pack="observatory"] body {
|
|
266
|
+
background-attachment: scroll;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
261
270
|
/* header — observatory signage over a gold→violet ecliptic rule */
|
|
262
271
|
html[data-theme-pack="observatory"] header[data-header] {
|
|
263
272
|
border-image: linear-gradient(
|
|
@@ -319,6 +328,15 @@ html[data-theme-pack="observatory"] #desktop-sidebar {
|
|
|
319
328
|
320px 320px;
|
|
320
329
|
background-attachment: fixed;
|
|
321
330
|
}
|
|
331
|
+
|
|
332
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
333
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
334
|
+
convention from issue #3070. */
|
|
335
|
+
@media (pointer: coarse) {
|
|
336
|
+
html[data-theme-pack="observatory"] #desktop-sidebar {
|
|
337
|
+
background-attachment: scroll;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
322
340
|
html[data-theme-pack="observatory"] #desktop-sidebar a {
|
|
323
341
|
border-radius: 0;
|
|
324
342
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Onyx",
|
|
5
5
|
"description": "Luxury noir — jet black, champagne serif headings, and a single gold hairline accent. Watch-brand restraint.",
|
|
6
6
|
"mode": "dark",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.3",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Jost",
|
|
10
10
|
"mono": "IBM Plex Mono",
|
|
@@ -215,6 +215,15 @@ html[data-theme-pack="onyx"] body {
|
|
|
215
215
|
letter-spacing: 0.005em;
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
219
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
220
|
+
convention from issue #3070. */
|
|
221
|
+
@media (pointer: coarse) {
|
|
222
|
+
html[data-theme-pack="onyx"] body {
|
|
223
|
+
background-attachment: scroll;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
218
227
|
/* header: engraved nameplate over a gold hairline */
|
|
219
228
|
html[data-theme-pack="onyx"] header[data-header] {
|
|
220
229
|
border-bottom: 1px solid color-mix(in oklch, var(--zd-accent) 38%, transparent);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Sakura",
|
|
5
5
|
"description": "Cherry-blossom pastels — blush-white paper, plum ink, and rose accents on petal-soft corners; dark mode is yozakura, night blossoms under lantern-pink light.",
|
|
6
6
|
"mode": "light",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.1",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Nunito",
|
|
10
10
|
"mono": "M PLUS 1 Code",
|
|
@@ -194,6 +194,15 @@ html[data-theme-pack="sakura"] body {
|
|
|
194
194
|
background-attachment: fixed;
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
198
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
199
|
+
convention from issue #3070. */
|
|
200
|
+
@media (pointer: coarse) {
|
|
201
|
+
html[data-theme-pack="sakura"] body {
|
|
202
|
+
background-attachment: scroll;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
197
206
|
/* header — a blush veil fading toward the right, petal hairline */
|
|
198
207
|
html[data-theme-pack="sakura"] header[data-header] {
|
|
199
208
|
background-image: linear-gradient(
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Sumi",
|
|
5
5
|
"description": "Sumi-e ink on washi — bold mincho brush headings, deep black strokes, one vermillion hanko seal accent.",
|
|
6
6
|
"mode": "light",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.3",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Zen Kaku Gothic New",
|
|
10
10
|
"mono": "IBM Plex Mono",
|
|
@@ -239,6 +239,15 @@ html[data-theme-pack="sumi"] body {
|
|
|
239
239
|
background-attachment: fixed;
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
243
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
244
|
+
convention from issue #3070. */
|
|
245
|
+
@media (pointer: coarse) {
|
|
246
|
+
html[data-theme-pack="sumi"] body {
|
|
247
|
+
background-attachment: scroll;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
242
251
|
/* header: one decisive ink rule; mincho logo signed with a seal */
|
|
243
252
|
html[data-theme-pack="sumi"] header[data-header] {
|
|
244
253
|
border-bottom: 3px solid var(--zd-fg);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Timberline",
|
|
5
5
|
"description": "Forest cabin after dark — pine & umber planks, cream prose, and matte lantern-amber accents; light mode is the same lodge at morning.",
|
|
6
6
|
"mode": "dark",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.1",
|
|
8
8
|
"fonts": {
|
|
9
9
|
"sans": "Source Sans 3",
|
|
10
10
|
"mono": "JetBrains Mono",
|
|
@@ -191,6 +191,15 @@ html[data-theme-pack="timberline"] body {
|
|
|
191
191
|
background-attachment: fixed;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
/* Touch devices: background-attachment:fixed is unsupported (iOS Safari) or
|
|
195
|
+
repaint-heavy on scroll — fall back to scroll attachment. Catalog-wide
|
|
196
|
+
convention from issue #3070. */
|
|
197
|
+
@media (pointer: coarse) {
|
|
198
|
+
html[data-theme-pack="timberline"] body {
|
|
199
|
+
background-attachment: scroll;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
194
203
|
/* header: the lintel beam — umber board over a plank seam (dark
|
|
195
204
|
groove hairline + chamfer highlight catching on the board below) */
|
|
196
205
|
html[data-theme-pack="timberline"] header[data-header] {
|
|
@@ -11,15 +11,28 @@ import {
|
|
|
11
11
|
function stripComments(css) {
|
|
12
12
|
return css.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
13
13
|
}
|
|
14
|
-
function parseTopLevelRules(css) {
|
|
14
|
+
function parseTopLevelRules(css, onBareStatement) {
|
|
15
15
|
const text = stripComments(css);
|
|
16
16
|
const rules = [];
|
|
17
17
|
const n = text.length;
|
|
18
18
|
let i = 0;
|
|
19
|
+
const reportBareStatements = (segment) => {
|
|
20
|
+
if (!onBareStatement) return;
|
|
21
|
+
const re = /@[a-zA-Z-]+[^{;]*;/g;
|
|
22
|
+
let m;
|
|
23
|
+
while ((m = re.exec(segment)) !== null) {
|
|
24
|
+
onBareStatement(m[0].trim());
|
|
25
|
+
}
|
|
26
|
+
};
|
|
19
27
|
while (i < n) {
|
|
20
28
|
const braceIdx = text.indexOf("{", i);
|
|
21
|
-
if (braceIdx === -1)
|
|
22
|
-
|
|
29
|
+
if (braceIdx === -1) {
|
|
30
|
+
reportBareStatements(text.slice(i));
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
const preludeSegment = text.slice(i, braceIdx);
|
|
34
|
+
reportBareStatements(preludeSegment);
|
|
35
|
+
const preludeRaw = preludeSegment.replace(/@[a-zA-Z-]+[^{;]*;/g, "");
|
|
23
36
|
const prelude = preludeRaw.trim();
|
|
24
37
|
let depth = 1;
|
|
25
38
|
let j = braceIdx + 1;
|
|
@@ -38,6 +51,9 @@ function parseTopLevelRules(css) {
|
|
|
38
51
|
function isFontFaceRule(rule) {
|
|
39
52
|
return /^@font-face\b/i.test(rule.prelude);
|
|
40
53
|
}
|
|
54
|
+
function isMediaRule(rule) {
|
|
55
|
+
return /^@media\b/i.test(rule.prelude);
|
|
56
|
+
}
|
|
41
57
|
function extractFontFaceFamilies(cssContent) {
|
|
42
58
|
const families = [];
|
|
43
59
|
for (const rule of parseTopLevelRules(cssContent)) {
|
|
@@ -86,9 +102,8 @@ function checkCssPresence(dirName, cssContent, issues) {
|
|
|
86
102
|
}
|
|
87
103
|
function checkScoping(slug, cssContent, issues) {
|
|
88
104
|
const prefix = `html[data-theme-pack="${slug}"]`;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
for (const rawBranch of rule.prelude.split(",")) {
|
|
105
|
+
const checkPrelude = (prelude) => {
|
|
106
|
+
for (const rawBranch of prelude.split(",")) {
|
|
92
107
|
const branch = rawBranch.trim();
|
|
93
108
|
if (branch.length === 0) continue;
|
|
94
109
|
if (!branch.startsWith(prefix)) {
|
|
@@ -99,6 +114,23 @@ function checkScoping(slug, cssContent, issues) {
|
|
|
99
114
|
});
|
|
100
115
|
}
|
|
101
116
|
}
|
|
117
|
+
};
|
|
118
|
+
for (const rule of parseTopLevelRules(cssContent)) {
|
|
119
|
+
if (isFontFaceRule(rule)) continue;
|
|
120
|
+
if (isMediaRule(rule)) {
|
|
121
|
+
const innerRules = parseTopLevelRules(rule.body, (statement) => {
|
|
122
|
+
issues.push({
|
|
123
|
+
rule: "scoping",
|
|
124
|
+
severity: "error",
|
|
125
|
+
message: `at-rule statement "${statement}" inside @media is not a pack-scoped rule and is not allowed`
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
for (const innerRule of innerRules) {
|
|
129
|
+
checkPrelude(innerRule.prelude);
|
|
130
|
+
}
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
checkPrelude(rule.prelude);
|
|
102
134
|
}
|
|
103
135
|
}
|
|
104
136
|
function checkKnownTokenNames(cssContent, issues) {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
import type { JSX } from "preact";
|
|
4
|
+
export interface TocPrepaintProps {
|
|
5
|
+
/**
|
|
6
|
+
* Whether the page actually renders the package's own default TOC (i.e.
|
|
7
|
+
* `shouldRenderToc && !customTocIsPresent`, computed by the shell). When
|
|
8
|
+
* false there is no default TOC for the toggle to collapse — the shell
|
|
9
|
+
* either has no TOC at all or renders a custom `hostBindings.Toc` override.
|
|
10
|
+
*/
|
|
11
|
+
shouldRenderDefaultToc?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Settings subset read by the toc-prepaint factories. */
|
|
14
|
+
export interface TocPrepaintSettings {
|
|
15
|
+
tocToggle?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Shared gate for BOTH toc-prepaint factories: the head pre-paint `<script>`
|
|
19
|
+
* and the `afterSidebar` toggle Island must appear on exactly the same pages,
|
|
20
|
+
* so they read the same predicate here rather than each inlining
|
|
21
|
+
* `settings.tocToggle && shouldRenderDefaultToc` (a one-sided edit could
|
|
22
|
+
* otherwise let the script and the button desync — the #2571 pattern).
|
|
23
|
+
*
|
|
24
|
+
* The predicate cannot know whether a custom Toc exists on its own — the
|
|
25
|
+
* shell computes `shouldRenderDefaultToc` and passes it in.
|
|
26
|
+
*/
|
|
27
|
+
export declare function tocPrepaintActive(settings: TocPrepaintSettings, shouldRenderDefaultToc?: boolean): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Pre-paint inline script body: restore persisted TOC visibility to
|
|
30
|
+
* `<html data-toc-hidden>` before first paint to avoid a hard-reload flash.
|
|
31
|
+
*
|
|
32
|
+
* A tiny synchronous IIFE that reads `localStorage[TOC_STORAGE_KEY]` and
|
|
33
|
+
* sets `data-toc-hidden` only when the stored value is exactly "false"
|
|
34
|
+
* (the collapsed preference) — the default (visible) needs no attribute and
|
|
35
|
+
* causes no layout shift. Silently no-ops in privacy / disabled-storage modes.
|
|
36
|
+
*
|
|
37
|
+
* The storage key is interpolated from `TOC_STORAGE_KEY` so it stays in
|
|
38
|
+
* sync with the island's reader; the `data-toc-hidden` attribute name is a
|
|
39
|
+
* literal here (the island's `setDataAttribute` hardcodes the same literal —
|
|
40
|
+
* keep the two in sync). Intended for `<head>` placement so it executes before
|
|
41
|
+
* the `.zd-toc-col` TOC column is painted.
|
|
42
|
+
*/
|
|
43
|
+
export declare const TOC_VISIBILITY_PREPAINT_SCRIPT: string;
|
|
44
|
+
/**
|
|
45
|
+
* Create a `TocVisibilityPrepaint` component bound to the host's settings.
|
|
46
|
+
*
|
|
47
|
+
* Returns the pre-paint `<script>` (for the page `<head>`) when
|
|
48
|
+
* `settings.tocToggle` is enabled AND the page actually renders the default
|
|
49
|
+
* TOC; returns `undefined` otherwise — the SAME gating as
|
|
50
|
+
* {@link createTocPrepaint}, so the head script and the afterSidebar toggle
|
|
51
|
+
* button always appear together.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createTocVisibilityPrepaint(settings: TocPrepaintSettings): (props: TocPrepaintProps) => JSX.Element | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Create a `TocPrepaint` component bound to the host's settings.
|
|
56
|
+
*
|
|
57
|
+
* The host stub calls this once with `{ tocToggle: settings.tocToggle }`
|
|
58
|
+
* and re-exports the result.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createTocPrepaint(settings: TocPrepaintSettings): (props: TocPrepaintProps) => JSX.Element | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Fragment, jsx } from "preact/jsx-runtime";
|
|
2
|
+
import { Island } from "@takazudo/zfb";
|
|
3
|
+
import {
|
|
4
|
+
DesktopTocToggle,
|
|
5
|
+
TOC_STORAGE_KEY
|
|
6
|
+
} from "../desktop-toc-toggle-island/index.js";
|
|
7
|
+
function tocPrepaintActive(settings, shouldRenderDefaultToc) {
|
|
8
|
+
return Boolean(settings.tocToggle) && Boolean(shouldRenderDefaultToc);
|
|
9
|
+
}
|
|
10
|
+
const TOC_VISIBILITY_PREPAINT_SCRIPT = `(function(){try{if(localStorage.getItem(${JSON.stringify(
|
|
11
|
+
TOC_STORAGE_KEY
|
|
12
|
+
)})==='false'){document.documentElement.setAttribute('data-toc-hidden','');}}catch(e){}})();`;
|
|
13
|
+
function createTocVisibilityPrepaint(settings) {
|
|
14
|
+
function TocVisibilityPrepaint({
|
|
15
|
+
shouldRenderDefaultToc
|
|
16
|
+
}) {
|
|
17
|
+
if (!tocPrepaintActive(settings, shouldRenderDefaultToc)) return void 0;
|
|
18
|
+
return /* @__PURE__ */ jsx(
|
|
19
|
+
"script",
|
|
20
|
+
{
|
|
21
|
+
dangerouslySetInnerHTML: { __html: TOC_VISIBILITY_PREPAINT_SCRIPT }
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return TocVisibilityPrepaint;
|
|
26
|
+
}
|
|
27
|
+
function createTocPrepaint(settings) {
|
|
28
|
+
function TocPrepaint({
|
|
29
|
+
shouldRenderDefaultToc
|
|
30
|
+
}) {
|
|
31
|
+
if (!tocPrepaintActive(settings, shouldRenderDefaultToc)) return void 0;
|
|
32
|
+
return /* @__PURE__ */ jsx(Fragment, { children: Island({
|
|
33
|
+
when: "load",
|
|
34
|
+
children: /* @__PURE__ */ jsx(DesktopTocToggle, {})
|
|
35
|
+
}) });
|
|
36
|
+
}
|
|
37
|
+
return TocPrepaint;
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
TOC_VISIBILITY_PREPAINT_SCRIPT,
|
|
41
|
+
createTocPrepaint,
|
|
42
|
+
createTocVisibilityPrepaint,
|
|
43
|
+
tocPrepaintActive
|
|
44
|
+
};
|
|
@@ -20,7 +20,7 @@ export interface UrlHelpers {
|
|
|
20
20
|
docsUrl(slug: string, lang?: string): string;
|
|
21
21
|
isExternal(href: string): boolean;
|
|
22
22
|
resolveHref(href: string): string;
|
|
23
|
-
navHref(path: string, lang: string | undefined, currentVersion: string | undefined): string;
|
|
23
|
+
navHref(path: string, lang: string | undefined, currentVersion: string | undefined, versioned?: boolean): string;
|
|
24
24
|
getPathForLocale(path: string, currentLang: string, targetLang: string): string;
|
|
25
25
|
buildLocaleLinks(currentPath: string, currentLang: string): LocaleLink[];
|
|
26
26
|
isDefaultLocaleOnlyPath(path: string): boolean;
|
|
@@ -35,9 +35,9 @@ function makeUrlHelpers(settings, i18n) {
|
|
|
35
35
|
function resolveHref(href) {
|
|
36
36
|
return isExternal(href) ? href : withBase(href);
|
|
37
37
|
}
|
|
38
|
-
function navHref(path, lang, currentVersion) {
|
|
38
|
+
function navHref(path, lang, currentVersion, versioned = true) {
|
|
39
39
|
const isNonDefaultLocale = lang != null && lang !== defaultLocale && !isDefaultLocaleOnlyPath(path);
|
|
40
|
-
const versionPrefix = currentVersion ? `/v/${currentVersion}` : "";
|
|
40
|
+
const versionPrefix = versioned && currentVersion ? `/v/${currentVersion}` : "";
|
|
41
41
|
return withBase(
|
|
42
42
|
isNonDefaultLocale ? `${versionPrefix}/${lang}${path}` : `${versionPrefix}${path}`
|
|
43
43
|
);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { DocPageEntry, DocNavNode } from "../doc-page-props/index.js";
|
|
2
|
+
import type { CategoryMeta } from "../sidebar-tree/index.js";
|
|
3
|
+
/** Structural subset of `NavSourceDocs` this module reads. */
|
|
4
|
+
export interface VersionAvailabilityNavSource {
|
|
5
|
+
docs: DocPageEntry[];
|
|
6
|
+
navDocs: DocPageEntry[];
|
|
7
|
+
categoryMeta: Map<string, CategoryMeta>;
|
|
8
|
+
}
|
|
9
|
+
/** Injected dependencies for {@link createGetUnavailableVersions}. */
|
|
10
|
+
export interface VersionAvailabilityDeps {
|
|
11
|
+
/** Configured versions to check availability for (`false` / empty ⇒ no-op). */
|
|
12
|
+
versions: Array<{
|
|
13
|
+
slug: string;
|
|
14
|
+
}> | false;
|
|
15
|
+
/**
|
|
16
|
+
* Identity-stable nav-source resolver (`resolveNavSource` from
|
|
17
|
+
* `nav-source-docs`) — already memoized per (locale, version, options), so
|
|
18
|
+
* a cache miss in {@link createGetUnavailableVersions} is cheap.
|
|
19
|
+
*/
|
|
20
|
+
resolveNavSource: (locale: string, versionSlug: string, options?: {
|
|
21
|
+
applyDefaultLocaleOnlyFilter?: boolean;
|
|
22
|
+
keepUnlisted?: boolean;
|
|
23
|
+
}) => VersionAvailabilityNavSource;
|
|
24
|
+
/** Canonical route slug for a zfb content slug — injected, not ambient. */
|
|
25
|
+
toRouteSlug: (entrySlug: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Nav-tree builder, already bound to a href builder by the caller (hrefs
|
|
28
|
+
* are irrelevant here — the tree is only walked to discover auto-index
|
|
29
|
+
* nodes via {@link VersionAvailabilityDeps.collectAutoIndexNodes}).
|
|
30
|
+
*/
|
|
31
|
+
buildNavTree: (docs: DocPageEntry[], locale: string, categoryMeta: Map<string, CategoryMeta>) => DocNavNode[];
|
|
32
|
+
/** Category nodes with children but no page of their own — real routes
|
|
33
|
+
* with no corresponding docs entry (see module header). */
|
|
34
|
+
collectAutoIndexNodes: (tree: DocNavNode[]) => DocNavNode[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build `getUnavailableVersions(slug, locale)`, bound to the injected deps.
|
|
38
|
+
*
|
|
39
|
+
* Returns `undefined` when there is no current slug to test (e.g. a
|
|
40
|
+
* no-current-slug header render on the home page) or when versioning is not
|
|
41
|
+
* configured — NEVER mark every archive unavailable just because there is no
|
|
42
|
+
* page to test against.
|
|
43
|
+
*
|
|
44
|
+
* Each version's available-slug Set is cached here keyed by BOTH locale and
|
|
45
|
+
* version (`${locale}\n${versionSlug}`) — a version-slug-only key would be
|
|
46
|
+
* wrong, because a versioned locale merge differs per language.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createGetUnavailableVersions(deps: VersionAvailabilityDeps): (slug: string | undefined, locale: string) => ReadonlySet<string> | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* `data-*` attribute name the client payload rides on — see the module
|
|
51
|
+
* header's "Client payload contract" section for the full spelling/format
|
|
52
|
+
* contract. Exported so a future consumer (#3244) reads the same literal
|
|
53
|
+
* instead of hand-copying the string.
|
|
54
|
+
*/
|
|
55
|
+
export declare const UNAVAILABLE_VERSIONS_ATTR = "data-doc-unavailable-versions";
|
|
56
|
+
/**
|
|
57
|
+
* Serialize a `getUnavailableVersions()` result into the `data-*` attribute
|
|
58
|
+
* bag `<DocPageShell>` spreads onto `<article>`. Returns `{}` (no key at
|
|
59
|
+
* all) for `undefined` input so the attribute is genuinely ABSENT from the
|
|
60
|
+
* rendered element, preserving the three-state contract documented above —
|
|
61
|
+
* an empty object here must not be confused with `{ [ATTR]: "" }`.
|
|
62
|
+
*/
|
|
63
|
+
export declare function serializeUnavailableVersions(unavailableVersions: ReadonlySet<string> | undefined): Record<string, string>;
|
|
64
|
+
/**
|
|
65
|
+
* Enforce the comma-free version-slug constraint the module header's
|
|
66
|
+
* "Client payload contract" section documents. Shared by BOTH `zudoDoc()`
|
|
67
|
+
* (`../config.ts`) and `zudoDocPreset()` (`../preset.ts`) — the preset is
|
|
68
|
+
* itself part of the frozen exported API and documented as directly
|
|
69
|
+
* spreadable into `defineConfig`, so a consumer calling it straight (bypassing
|
|
70
|
+
* `zudoDoc()`) must hit the same guard (#3244 codex review finding 2 follow-up).
|
|
71
|
+
* Throws a `TypeError` naming the offending slug; no-op for `false`/`undefined`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function assertNoCommaInVersionSlugs(versions: ReadonlyArray<{
|
|
74
|
+
slug: string;
|
|
75
|
+
}> | false | undefined): void;
|