@takazudo/zudo-doc 5.13.0 → 5.14.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 +27 -0
- package/bin/run-parallel.mjs +272 -0
- package/bin/tags-suggest-runner.ts +7 -3
- package/dist/asset-components/asset-card.d.ts +10 -0
- package/dist/asset-components/asset-card.js +91 -0
- package/dist/asset-components/asset-code.d.ts +10 -0
- package/dist/asset-components/asset-code.js +93 -0
- package/dist/asset-components/index.d.ts +3 -0
- package/dist/asset-components/index.js +12 -0
- package/dist/asset-components/shared.d.ts +25 -0
- package/dist/asset-components/shared.js +89 -0
- package/dist/asset-index-page/index.d.ts +21 -0
- package/dist/asset-index-page/index.js +175 -0
- package/dist/asset-index-page/script.d.ts +2 -0
- package/dist/asset-index-page/script.js +4 -0
- package/dist/asset-page/index.d.ts +67 -0
- package/dist/asset-page/index.js +244 -0
- package/dist/asset-page/script.d.ts +2 -0
- package/dist/asset-page/script.js +4 -0
- package/dist/asset-path/index.d.ts +53 -0
- package/dist/asset-path/index.js +149 -0
- package/dist/chrome/derive.js +45 -9
- package/dist/chrome/index.d.ts +2 -0
- package/dist/chrome/index.js +7 -1
- package/dist/chrome-bindings.d.ts +4 -0
- package/dist/client-router/raw-link-attrs.d.ts +8 -0
- package/dist/client-router/raw-link-attrs.js +6 -0
- package/dist/compiled.css +135 -0
- package/dist/config.d.ts +13 -2
- package/dist/config.js +36 -1
- package/dist/content/content-link.d.ts +12 -0
- package/dist/content/content-link.js +43 -2
- package/dist/content/index.d.ts +1 -1
- package/dist/content/index.js +5 -1
- package/dist/doc-body-end-islands/index.d.ts +2 -0
- package/dist/doc-body-end-islands/index.js +3 -2
- package/dist/doclayout/doc-layout-with-defaults.d.ts +1 -1
- package/dist/doclayout/doc-layout-with-defaults.js +1 -1
- package/dist/eject/index.js +8 -0
- package/dist/factory-context/index.d.ts +3 -1
- package/dist/features.css +124 -3
- package/dist/frontmatter/index.d.ts +56 -0
- package/dist/frontmatter/index.js +61 -0
- package/dist/header/header.js +11 -1
- package/dist/header/nav-class-tokens.d.ts +2 -0
- package/dist/header/nav-class-tokens.js +8 -0
- package/dist/header/nav-overflow-generated-script.js +47 -2
- package/dist/header-with-defaults/index.d.ts +2 -0
- package/dist/header-with-defaults/index.js +3 -2
- package/dist/i18n-defaults/index.d.ts +3 -2
- package/dist/i18n-defaults/index.js +44 -0
- package/dist/icons/index.d.ts +9 -0
- package/dist/icons/index.js +246 -0
- package/dist/md-utils/index.js +1 -1
- package/dist/mdx-components/index.d.ts +4 -1
- package/dist/mdx-components/index.js +80 -7
- package/dist/plugins/internal/asset-viewer/build.d.ts +25 -0
- package/dist/plugins/internal/asset-viewer/build.js +118 -0
- package/dist/plugins/internal/asset-viewer/git-meta.d.ts +7 -0
- package/dist/plugins/internal/asset-viewer/git-meta.js +40 -0
- package/dist/plugins/internal/asset-viewer/highlight.d.ts +34 -0
- package/dist/plugins/internal/asset-viewer/highlight.js +181 -0
- package/dist/plugins/internal/asset-viewer/link-graph.d.ts +34 -0
- package/dist/plugins/internal/asset-viewer/link-graph.js +193 -0
- package/dist/plugins/internal/asset-viewer/probe.d.ts +13 -0
- package/dist/plugins/internal/asset-viewer/probe.js +322 -0
- package/dist/plugins/internal/asset-viewer/scan.d.ts +2 -0
- package/dist/plugins/internal/asset-viewer/scan.js +77 -0
- package/dist/plugins/internal/asset-viewer/sidecar.d.ts +6 -0
- package/dist/plugins/internal/asset-viewer/sidecar.js +34 -0
- package/dist/plugins/internal/asset-viewer/types.d.ts +22 -0
- package/dist/plugins/internal/asset-viewer/types.js +0 -0
- package/dist/plugins/internal/codex-resources/skills.js +1 -1
- package/dist/plugins/internal/llms-txt/load.d.ts +1 -1
- package/dist/plugins/internal/resource-docs-shared/mdx.d.ts +1 -2
- package/dist/plugins/internal/resource-docs-shared/mdx.js +1 -1
- package/dist/plugins/routes.js +146 -11
- package/dist/preset.d.ts +10 -0
- package/dist/preset.js +20 -3
- package/dist/route-context/index.js +18 -2
- package/dist/route-context-payload/index.d.ts +6 -2
- package/dist/route-context-payload/index.js +2 -1
- package/dist/route-context-payload/types.d.ts +37 -0
- package/dist/routes/_chrome.d.ts +1 -1
- package/dist/routes/_chrome.js +5 -1
- package/dist/routes/_context.d.ts +2 -0
- package/dist/routes/_context.js +2 -0
- package/dist/routes/files-path.d.ts +22 -0
- package/dist/routes/files-path.js +31 -0
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +10 -0
- package/dist/sidebar-tree-island/index.js +2 -2
- package/dist/site-tree-nav-island/index.js +3 -3
- package/dist/tags-audit.js +1 -1
- package/eject/asset-components/asset-card.tsx +106 -0
- package/eject/asset-components/asset-code.tsx +127 -0
- package/eject/asset-components/index.ts +7 -0
- package/eject/asset-components/shared.tsx +113 -0
- package/eject/header/gen-nav-overflow-script.mjs +53 -4
- package/eject/header/header.tsx +11 -1
- package/eject/header/nav-class-tokens.ts +12 -0
- package/eject/header/nav-overflow-generated-script.ts +1 -1
- package/eject/sidebar-tree-island/index.tsx +3 -3
- package/eject/site-tree-nav-island/index.tsx +4 -4
- package/package.json +34 -14
- package/routes-src/_chrome.tsx +2 -0
- package/routes-src/_context.ts +2 -0
- package/routes-src/_virtual.d.ts +6 -0
- package/routes-src/files-path.tsx +43 -0
- package/virtual-modules.d.ts +6 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
import type { JSX } from "preact";
|
|
4
|
+
import type { ChromeContext } from "../factory-context/index.js";
|
|
5
|
+
import type { AssetIndexEntry } from "../route-context-payload/types.js";
|
|
6
|
+
import type { Settings } from "../settings.js";
|
|
7
|
+
export { ASSET_INDEX_PAGE_SCRIPT } from "./script.js";
|
|
8
|
+
export interface AssetTreeNode {
|
|
9
|
+
name: string;
|
|
10
|
+
dirs: AssetTreeNode[];
|
|
11
|
+
files: AssetIndexEntry[];
|
|
12
|
+
fileCount: number;
|
|
13
|
+
bytes: number;
|
|
14
|
+
}
|
|
15
|
+
export interface AssetIndexPageViewProps {
|
|
16
|
+
entries: AssetIndexEntry[];
|
|
17
|
+
}
|
|
18
|
+
/** Build a sorted directory tree and aggregate every directory's subtree totals. */
|
|
19
|
+
export declare function buildAssetTree(entries: AssetIndexEntry[]): AssetTreeNode;
|
|
20
|
+
/** Build the package-owned wide asset index from a chrome context. */
|
|
21
|
+
export declare function createAssetIndexPageView<S extends Settings = Settings>(ctx: ChromeContext<S>): (props: AssetIndexPageViewProps) => JSX.Element;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { assetViewerHref } from "../asset-path/index.js";
|
|
3
|
+
import { formatAssetBytes } from "../asset-components/index.js";
|
|
4
|
+
import { assertChromeContext } from "../chrome/assert-chrome-context.js";
|
|
5
|
+
import { deriveBodyEndIslands, deriveComposeMetaTitle } from "../chrome/derive.js";
|
|
6
|
+
import { derivePrimaryChromeSlots } from "../chrome/primary-slots.js";
|
|
7
|
+
import { DocLayoutWithDefaults } from "../doclayout/index.js";
|
|
8
|
+
import { createHeadWithDefaults } from "../head-with-defaults/index.js";
|
|
9
|
+
import {
|
|
10
|
+
ChevronRight,
|
|
11
|
+
FileArchive,
|
|
12
|
+
FileCode,
|
|
13
|
+
FileGeneric,
|
|
14
|
+
FileImage,
|
|
15
|
+
FilePdf,
|
|
16
|
+
FileText,
|
|
17
|
+
FileVideo,
|
|
18
|
+
Folder,
|
|
19
|
+
FolderOpen
|
|
20
|
+
} from "../icons/index.js";
|
|
21
|
+
import { resolveThemePackSsrSlug } from "../theme/theme-pack-provider.js";
|
|
22
|
+
import { ASSET_INDEX_PAGE_SCRIPT } from "./script.js";
|
|
23
|
+
import { ASSET_INDEX_PAGE_SCRIPT as ASSET_INDEX_PAGE_SCRIPT2 } from "./script.js";
|
|
24
|
+
const ARCHIVE_EXTENSIONS = /* @__PURE__ */ new Set(["zip", "tar", "gz", "tgz", "7z", "rar"]);
|
|
25
|
+
function basename(path) {
|
|
26
|
+
return path.split("/").at(-1) ?? path;
|
|
27
|
+
}
|
|
28
|
+
function freezeTree(node) {
|
|
29
|
+
const dirs = [...node.dirs.values()].sort((a, b) => a.name.localeCompare(b.name)).map(freezeTree);
|
|
30
|
+
const files = [...node.files].sort((a, b) => basename(a.path).localeCompare(basename(b.path)));
|
|
31
|
+
return {
|
|
32
|
+
name: node.name,
|
|
33
|
+
dirs,
|
|
34
|
+
files,
|
|
35
|
+
fileCount: files.length + dirs.reduce((total, dir) => total + dir.fileCount, 0),
|
|
36
|
+
bytes: files.reduce((total, file) => total + file.bytes, 0) + dirs.reduce((total, dir) => total + dir.bytes, 0)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function buildAssetTree(entries) {
|
|
40
|
+
const root = { name: "", dirs: /* @__PURE__ */ new Map(), files: [] };
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
let node = root;
|
|
43
|
+
for (const segment of entry.dir.split("/").filter(Boolean)) {
|
|
44
|
+
let child = node.dirs.get(segment);
|
|
45
|
+
if (!child) {
|
|
46
|
+
child = { name: segment, dirs: /* @__PURE__ */ new Map(), files: [] };
|
|
47
|
+
node.dirs.set(segment, child);
|
|
48
|
+
}
|
|
49
|
+
node = child;
|
|
50
|
+
}
|
|
51
|
+
node.files.push(entry);
|
|
52
|
+
}
|
|
53
|
+
return freezeTree(root);
|
|
54
|
+
}
|
|
55
|
+
function folderCount(node) {
|
|
56
|
+
return node.dirs.reduce((total, dir) => total + 1 + folderCount(dir), 0);
|
|
57
|
+
}
|
|
58
|
+
function formatDuration(seconds) {
|
|
59
|
+
const rounded = Math.round(seconds);
|
|
60
|
+
return `${Math.floor(rounded / 60)}:${String(rounded % 60).padStart(2, "0")}`;
|
|
61
|
+
}
|
|
62
|
+
function kindLabel(asset) {
|
|
63
|
+
if (asset.language) return asset.language;
|
|
64
|
+
return asset.mime.split("/").at(-1)?.toUpperCase() ?? asset.kind.toUpperCase();
|
|
65
|
+
}
|
|
66
|
+
function facetLabel(asset, linesLabel) {
|
|
67
|
+
if (asset.lines !== void 0) return linesLabel.replace("{count}", String(asset.lines));
|
|
68
|
+
if (asset.kind === "video" && asset.durationSec !== void 0) return formatDuration(asset.durationSec);
|
|
69
|
+
if (asset.width !== void 0 && asset.height !== void 0) return `${asset.width} \xD7 ${asset.height}`;
|
|
70
|
+
if (asset.durationSec !== void 0) return formatDuration(asset.durationSec);
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
function iconFor(asset) {
|
|
74
|
+
const extension = basename(asset.path).split(".").at(-1)?.toLowerCase();
|
|
75
|
+
if (asset.kind === "other" && extension && ARCHIVE_EXTENSIONS.has(extension)) return FileArchive;
|
|
76
|
+
const icons = {
|
|
77
|
+
code: FileCode,
|
|
78
|
+
text: FileText,
|
|
79
|
+
image: FileImage,
|
|
80
|
+
video: FileVideo,
|
|
81
|
+
pdf: FilePdf,
|
|
82
|
+
other: FileGeneric
|
|
83
|
+
};
|
|
84
|
+
return icons[asset.kind];
|
|
85
|
+
}
|
|
86
|
+
function countLabel(count, plural, single) {
|
|
87
|
+
return (count === 1 ? single : plural).replace("{count}", String(count));
|
|
88
|
+
}
|
|
89
|
+
function AssetTree({ node, base, routePrefix, fileCountLabel, fileCountSingleLabel, linesLabel, root = false }) {
|
|
90
|
+
return /* @__PURE__ */ jsxs("ul", { "data-zd-asset-tree": root ? true : void 0, children: [
|
|
91
|
+
node.dirs.map((dir) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("details", { open: true, children: [
|
|
92
|
+
/* @__PURE__ */ jsxs("summary", { class: "flex cursor-pointer items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small hover:bg-accent/10 focus-visible:bg-accent/10", children: [
|
|
93
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "h-icon-xs w-icon-xs shrink-0 text-muted transition-transform" }),
|
|
94
|
+
/* @__PURE__ */ jsx(Folder, { className: "h-icon-sm w-icon-sm shrink-0 text-muted" }),
|
|
95
|
+
/* @__PURE__ */ jsx(FolderOpen, { className: "h-icon-sm w-icon-sm shrink-0 text-muted" }),
|
|
96
|
+
/* @__PURE__ */ jsxs("span", { class: "min-w-0 truncate font-mono text-fg", children: [
|
|
97
|
+
dir.name,
|
|
98
|
+
"/"
|
|
99
|
+
] }),
|
|
100
|
+
/* @__PURE__ */ jsxs("span", { class: "ml-auto hidden whitespace-nowrap pl-hsp-lg text-caption text-muted sm:block", children: [
|
|
101
|
+
countLabel(dir.fileCount, fileCountLabel, fileCountSingleLabel),
|
|
102
|
+
" \xB7 ",
|
|
103
|
+
formatAssetBytes(dir.bytes)
|
|
104
|
+
] })
|
|
105
|
+
] }),
|
|
106
|
+
/* @__PURE__ */ jsx(AssetTree, { node: dir, base, routePrefix, fileCountLabel, fileCountSingleLabel, linesLabel })
|
|
107
|
+
] }) })),
|
|
108
|
+
node.files.map((asset) => {
|
|
109
|
+
const Icon = iconFor(asset);
|
|
110
|
+
const facet = facetLabel(asset, linesLabel);
|
|
111
|
+
const meta = [kindLabel(asset), facet, formatAssetBytes(asset.bytes)].filter(Boolean).join(" \xB7 ");
|
|
112
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("a", { href: assetViewerHref({ base, routePrefix, path: asset.path }), title: asset.name, class: "flex min-w-0 items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small text-fg hover:bg-accent/10 hover:text-accent hover:underline focus-visible:bg-accent/10 focus-visible:text-accent focus-visible:underline", children: [
|
|
113
|
+
/* @__PURE__ */ jsx(Icon, { className: "h-icon-sm w-icon-sm shrink-0 text-muted" }),
|
|
114
|
+
/* @__PURE__ */ jsx("span", { class: "min-w-0 truncate font-mono", children: basename(asset.path) }),
|
|
115
|
+
/* @__PURE__ */ jsx("span", { class: "ml-auto hidden whitespace-nowrap pl-hsp-lg text-caption text-muted sm:block", children: meta })
|
|
116
|
+
] }) });
|
|
117
|
+
})
|
|
118
|
+
] });
|
|
119
|
+
}
|
|
120
|
+
function createAssetIndexPageView(ctx) {
|
|
121
|
+
assertChromeContext(ctx, "createAssetIndexPageView");
|
|
122
|
+
const settings = ctx.settings;
|
|
123
|
+
const locale = ctx.defaultLocale;
|
|
124
|
+
const t = ctx.t;
|
|
125
|
+
const composeMetaTitle = deriveComposeMetaTitle(ctx);
|
|
126
|
+
const HeadWithDefaults = createHeadWithDefaults(ctx);
|
|
127
|
+
const { Header: HeaderWithDefaults, Footer: FooterWithDefaults, Breadcrumb: BreadcrumbWithDefaults } = derivePrimaryChromeSlots(ctx);
|
|
128
|
+
const BodyEndIslands = deriveBodyEndIslands(ctx);
|
|
129
|
+
const dataThemePack = resolveThemePackSsrSlug(ctx.themePackRegistry, settings);
|
|
130
|
+
return function AssetIndexPageView({ entries }) {
|
|
131
|
+
const routePrefix = ctx.assetManifest?.routePrefix ?? settings.assetViewerRoutePrefix;
|
|
132
|
+
const dir = ctx.assetManifest?.dir ?? settings.assetViewerDir;
|
|
133
|
+
const indexUrl = ctx.withBase(`/${routePrefix}/`);
|
|
134
|
+
const tree = buildAssetTree(entries);
|
|
135
|
+
const folders = folderCount(tree);
|
|
136
|
+
const fileCountLabel = t("asset.fileCount", locale);
|
|
137
|
+
const fileCountSingleLabel = t("asset.fileCountSingle", locale);
|
|
138
|
+
const folderCountLabel = t("asset.folderCount", locale);
|
|
139
|
+
const folderCountSingleLabel = t("asset.folderCountSingle", locale);
|
|
140
|
+
const title = t("asset.crumb", locale);
|
|
141
|
+
return /* @__PURE__ */ jsx(DocLayoutWithDefaults, { title: composeMetaTitle(title), head: /* @__PURE__ */ jsx(HeadWithDefaults, { title, description: t("asset.indexDescription", locale), canonical: ctx.absoluteUrl(indexUrl) }), lang: locale, dataThemePack, noindex: settings.noindex, hideSidebar: true, hideToc: true, sidebarOverride: false, contentWide: true, breadcrumbOverride: /* @__PURE__ */ jsx(BreadcrumbWithDefaults, { items: [{ label: "", href: ctx.withBase("/") }, { label: title }] }), headerOverride: /* @__PURE__ */ jsx(HeaderWithDefaults, { lang: locale, currentPath: indexUrl, hideSidebarToggle: true }), footerOverride: /* @__PURE__ */ jsx(FooterWithDefaults, { lang: locale }), bodyEndComponents: /* @__PURE__ */ jsx(BodyEndIslands, { basePath: settings.base ?? "/" }), enableClientRouter: settings.dynamicPageTransition, children: /* @__PURE__ */ jsxs("div", { "data-zd-asset-index-page": true, children: [
|
|
142
|
+
/* @__PURE__ */ jsxs("header", { children: [
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { class: "mb-vsp-xs flex flex-wrap items-center gap-hsp-xs text-micro tracking-wide uppercase", children: [
|
|
144
|
+
/* @__PURE__ */ jsx("span", { class: "rounded-full border border-muted px-hsp-sm py-vsp-3xs text-fg", children: title }),
|
|
145
|
+
/* @__PURE__ */ jsx("span", { class: "rounded-full border border-muted px-hsp-sm py-vsp-3xs text-muted", children: t("asset.indexBadge", locale) })
|
|
146
|
+
] }),
|
|
147
|
+
/* @__PURE__ */ jsx("h1", { class: "mb-vsp-xs border-b border-fg pb-vsp-xs font-mono text-heading font-bold leading-tight", children: title }),
|
|
148
|
+
/* @__PURE__ */ jsxs("div", { "data-doc-metainfo": true, class: "mb-vsp-md flex flex-wrap items-center gap-x-hsp-md gap-y-vsp-2xs text-caption text-fg", children: [
|
|
149
|
+
/* @__PURE__ */ jsx("span", { children: countLabel(tree.fileCount, fileCountLabel, fileCountSingleLabel) }),
|
|
150
|
+
/* @__PURE__ */ jsx("span", { children: countLabel(folders, folderCountLabel, folderCountSingleLabel) }),
|
|
151
|
+
/* @__PURE__ */ jsx("span", { children: formatAssetBytes(tree.bytes) })
|
|
152
|
+
] }),
|
|
153
|
+
/* @__PURE__ */ jsx("p", { class: "mb-vsp-lg text-title text-muted", children: t("asset.indexDescription", locale) })
|
|
154
|
+
] }),
|
|
155
|
+
/* @__PURE__ */ jsxs("div", { class: "mb-vsp-sm flex flex-wrap items-center justify-between gap-hsp-sm text-caption", children: [
|
|
156
|
+
/* @__PURE__ */ jsxs("span", { class: "font-mono text-muted", children: [
|
|
157
|
+
"public/",
|
|
158
|
+
dir,
|
|
159
|
+
"/"
|
|
160
|
+
] }),
|
|
161
|
+
/* @__PURE__ */ jsxs("span", { class: "flex gap-hsp-sm", children: [
|
|
162
|
+
/* @__PURE__ */ jsx("button", { type: "button", disabled: true, "data-zd-asset-index-action": "expand", class: "text-fg hover:text-accent focus-visible:text-accent", children: t("asset.expandAll", locale) }),
|
|
163
|
+
/* @__PURE__ */ jsx("button", { type: "button", disabled: true, "data-zd-asset-index-action": "collapse", class: "text-fg hover:text-accent focus-visible:text-accent", children: t("asset.collapseAll", locale) })
|
|
164
|
+
] })
|
|
165
|
+
] }),
|
|
166
|
+
entries.length > 0 ? /* @__PURE__ */ jsx(AssetTree, { root: true, node: tree, base: settings.base, routePrefix, fileCountLabel, fileCountSingleLabel, linesLabel: t("asset.lines", locale) }) : /* @__PURE__ */ jsx("p", { class: "text-small text-muted", "data-zd-asset-index-empty": true, children: t("asset.indexEmpty", locale) }),
|
|
167
|
+
/* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: ASSET_INDEX_PAGE_SCRIPT } })
|
|
168
|
+
] }) });
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
export {
|
|
172
|
+
ASSET_INDEX_PAGE_SCRIPT2 as ASSET_INDEX_PAGE_SCRIPT,
|
|
173
|
+
buildAssetTree,
|
|
174
|
+
createAssetIndexPageView
|
|
175
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const ASSET_INDEX_PAGE_SCRIPT = String.raw`(()=>{const init=()=>{document.querySelectorAll('[data-zd-asset-index-page]').forEach(page=>{if(page.hasAttribute('data-zd-asset-index-ready'))return;page.setAttribute('data-zd-asset-index-ready','true');page.querySelectorAll('[data-zd-asset-index-action]').forEach(button=>{button.removeAttribute('disabled');button.addEventListener('click',()=>{const open=button.getAttribute('data-zd-asset-index-action')==='expand';page.querySelectorAll('[data-zd-asset-tree] details').forEach(details=>{details.open=open})})})})};if(!document.__zdAssetIndexPageInit){document.__zdAssetIndexPageInit=init;document.addEventListener('zfb:after-swap',init)}document.__zdAssetIndexPageInit()})();`;
|
|
2
|
+
export {
|
|
3
|
+
ASSET_INDEX_PAGE_SCRIPT
|
|
4
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** @jsxRuntime automatic */
|
|
2
|
+
/** @jsxImportSource preact */
|
|
3
|
+
import type { ComponentChildren, JSX, VNode } from "preact";
|
|
4
|
+
import type { ChromeContext } from "../factory-context/index.js";
|
|
5
|
+
import type { AssetRecord } from "../plugins/internal/asset-viewer/types.js";
|
|
6
|
+
import type { Settings } from "../settings.js";
|
|
7
|
+
export { ASSET_PAGE_SCRIPT } from "./script.js";
|
|
8
|
+
export type { AssetRecord } from "../plugins/internal/asset-viewer/types.js";
|
|
9
|
+
export interface AssetPageViewProps {
|
|
10
|
+
entry: AssetRecord;
|
|
11
|
+
}
|
|
12
|
+
export declare function AssetEyebrow({ asset, badge }: {
|
|
13
|
+
asset: AssetRecord;
|
|
14
|
+
badge: string;
|
|
15
|
+
}): VNode;
|
|
16
|
+
export declare function AssetHeader({ asset, locale, badge, updatedLabel, linesLabel }: {
|
|
17
|
+
asset: AssetRecord;
|
|
18
|
+
locale: string;
|
|
19
|
+
badge: string;
|
|
20
|
+
updatedLabel: string;
|
|
21
|
+
linesLabel?: string;
|
|
22
|
+
}): VNode;
|
|
23
|
+
export declare function AssetActions({ rawUrl, downloadLabel, openRawLabel, copyLabel, wrapLabel, code, bottom }: {
|
|
24
|
+
rawUrl: string;
|
|
25
|
+
downloadLabel: string;
|
|
26
|
+
openRawLabel: string;
|
|
27
|
+
copyLabel: string;
|
|
28
|
+
wrapLabel: string;
|
|
29
|
+
code?: boolean;
|
|
30
|
+
bottom?: boolean;
|
|
31
|
+
}): VNode;
|
|
32
|
+
export declare function AssetCodeBody({ asset, copyLabel, wrapLabel, truncatedLabel, linesLabel }: {
|
|
33
|
+
asset: AssetRecord;
|
|
34
|
+
copyLabel: string;
|
|
35
|
+
wrapLabel: string;
|
|
36
|
+
truncatedLabel: string;
|
|
37
|
+
linesLabel?: string;
|
|
38
|
+
}): VNode;
|
|
39
|
+
export declare function AssetImageStage({ asset, rawUrl }: {
|
|
40
|
+
asset: AssetRecord;
|
|
41
|
+
rawUrl: string;
|
|
42
|
+
}): VNode;
|
|
43
|
+
export declare function AssetVideoStage({ asset, rawUrl }: {
|
|
44
|
+
asset: AssetRecord;
|
|
45
|
+
rawUrl: string;
|
|
46
|
+
}): VNode;
|
|
47
|
+
export declare function AssetPdfStage({ asset, rawUrl, children }: {
|
|
48
|
+
asset: AssetRecord;
|
|
49
|
+
rawUrl: string;
|
|
50
|
+
children: ComponentChildren;
|
|
51
|
+
}): VNode;
|
|
52
|
+
export declare function AssetDownloadPanel({ asset, rawUrl, noPreview, downloadLabel, copyLabel }: {
|
|
53
|
+
asset: AssetRecord;
|
|
54
|
+
rawUrl: string;
|
|
55
|
+
noPreview: string;
|
|
56
|
+
downloadLabel: string;
|
|
57
|
+
copyLabel: string;
|
|
58
|
+
}): VNode;
|
|
59
|
+
export declare function AssetLinkedFrom({ asset, label }: {
|
|
60
|
+
asset: AssetRecord;
|
|
61
|
+
label: string;
|
|
62
|
+
}): VNode | null;
|
|
63
|
+
export declare function AssetDetails({ asset }: {
|
|
64
|
+
asset: AssetRecord;
|
|
65
|
+
}): VNode;
|
|
66
|
+
/** Build the package-owned wide asset viewer page from a chrome context. */
|
|
67
|
+
export declare function createAssetPageView<S extends Settings = Settings>(ctx: ChromeContext<S>): (props: AssetPageViewProps) => JSX.Element;
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { BodyFootUtilArea } from "../body-foot-util/index.js";
|
|
3
|
+
import { deriveBodyEndIslands } from "../chrome/derive.js";
|
|
4
|
+
import { deriveComposeMetaTitle } from "../chrome/derive.js";
|
|
5
|
+
import { derivePrimaryChromeSlots } from "../chrome/primary-slots.js";
|
|
6
|
+
import { assertChromeContext } from "../chrome/assert-chrome-context.js";
|
|
7
|
+
import { DocLayoutWithDefaults } from "../doclayout/index.js";
|
|
8
|
+
import { formatDate } from "../format-date/index.js";
|
|
9
|
+
import { buildGitHubSourceUrl } from "../github-helpers/index.js";
|
|
10
|
+
import { createHeadWithDefaults } from "../head-with-defaults/index.js";
|
|
11
|
+
import { assetRawHref, assetViewerHref } from "../asset-path/index.js";
|
|
12
|
+
import { formatAssetBytes } from "../asset-components/index.js";
|
|
13
|
+
import { resolveThemePackSsrSlug } from "../theme/theme-pack-provider.js";
|
|
14
|
+
import { ASSET_PAGE_SCRIPT } from "./script.js";
|
|
15
|
+
import { ASSET_PAGE_SCRIPT as ASSET_PAGE_SCRIPT2 } from "./script.js";
|
|
16
|
+
function formatDuration(seconds) {
|
|
17
|
+
const rounded = Math.round(seconds);
|
|
18
|
+
const minutes = Math.floor(rounded / 60);
|
|
19
|
+
const remainder = (rounded % 60).toString().padStart(2, "0");
|
|
20
|
+
return `${minutes}:${remainder}`;
|
|
21
|
+
}
|
|
22
|
+
function kindLabel(asset) {
|
|
23
|
+
if (asset.language) return asset.language;
|
|
24
|
+
return asset.mime.split("/").at(-1)?.toUpperCase() ?? asset.kind.toUpperCase();
|
|
25
|
+
}
|
|
26
|
+
function facetLabel(asset, linesLabel) {
|
|
27
|
+
if (asset.lines !== void 0) return linesLabel ?? `${asset.lines} lines`;
|
|
28
|
+
if (asset.kind === "video" && asset.durationSec !== void 0) {
|
|
29
|
+
return formatDuration(asset.durationSec);
|
|
30
|
+
}
|
|
31
|
+
if (asset.width !== void 0 && asset.height !== void 0) return `${asset.width} \xD7 ${asset.height}`;
|
|
32
|
+
if (asset.durationSec !== void 0) return formatDuration(asset.durationSec);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
function AssetEyebrow({ asset, badge }) {
|
|
36
|
+
return /* @__PURE__ */ jsxs("div", { class: "mb-vsp-xs flex flex-wrap items-center gap-hsp-xs text-micro tracking-wide uppercase", children: [
|
|
37
|
+
/* @__PURE__ */ jsx("span", { class: "rounded-full border border-muted px-hsp-sm py-vsp-3xs text-fg", children: badge }),
|
|
38
|
+
/* @__PURE__ */ jsx("span", { class: "rounded-full border border-muted px-hsp-sm py-vsp-3xs text-muted", children: kindLabel(asset) })
|
|
39
|
+
] });
|
|
40
|
+
}
|
|
41
|
+
function AssetHeader({ asset, locale, badge, updatedLabel, linesLabel }) {
|
|
42
|
+
const facet = facetLabel(asset, linesLabel);
|
|
43
|
+
return /* @__PURE__ */ jsxs("header", { children: [
|
|
44
|
+
/* @__PURE__ */ jsx(AssetEyebrow, { asset, badge }),
|
|
45
|
+
/* @__PURE__ */ jsx("h1", { class: "mb-vsp-xs border-b border-fg pb-vsp-xs font-mono text-heading font-bold leading-tight", children: asset.name }),
|
|
46
|
+
/* @__PURE__ */ jsxs("div", { "data-doc-metainfo": true, class: "mb-vsp-md flex flex-wrap items-center gap-x-hsp-md gap-y-vsp-2xs text-caption text-fg", children: [
|
|
47
|
+
asset.dir && /* @__PURE__ */ jsx("span", { children: asset.dir }),
|
|
48
|
+
facet && /* @__PURE__ */ jsx("span", { children: facet }),
|
|
49
|
+
/* @__PURE__ */ jsx("span", { children: formatAssetBytes(asset.bytes) }),
|
|
50
|
+
asset.updatedDate && /* @__PURE__ */ jsxs("span", { children: [
|
|
51
|
+
updatedLabel,
|
|
52
|
+
" ",
|
|
53
|
+
formatDate(asset.updatedDate, locale)
|
|
54
|
+
] }),
|
|
55
|
+
asset.author && /* @__PURE__ */ jsx("span", { children: asset.author })
|
|
56
|
+
] }),
|
|
57
|
+
asset.description && /* @__PURE__ */ jsx("p", { class: "mb-vsp-lg text-title text-muted", "data-doc-description": true, children: asset.description })
|
|
58
|
+
] });
|
|
59
|
+
}
|
|
60
|
+
function actionClass(primary = false) {
|
|
61
|
+
return `${primary ? "border-accent bg-accent text-bg" : "border-muted bg-surface text-fg"} inline-flex items-center justify-center rounded border px-hsp-md py-vsp-2xs text-caption font-medium hover:border-accent focus-visible:border-accent`;
|
|
62
|
+
}
|
|
63
|
+
function AssetActions({ rawUrl, downloadLabel, openRawLabel, copyLabel, wrapLabel, code = false, bottom = false }) {
|
|
64
|
+
return /* @__PURE__ */ jsxs("div", { class: `${bottom ? "mt-vsp-lg border-t border-muted pt-vsp-md" : "mb-vsp-md"} flex flex-wrap gap-hsp-sm`, "data-zd-asset-actions": true, children: [
|
|
65
|
+
/* @__PURE__ */ jsx("a", { download: true, href: rawUrl, class: `${actionClass(true)} hover:underline focus-visible:underline`, children: downloadLabel }),
|
|
66
|
+
/* @__PURE__ */ jsx("a", { href: rawUrl, "data-zfb-reload": true, target: "_blank", rel: "noopener", class: `${actionClass()} hover:underline focus-visible:underline`, children: openRawLabel }),
|
|
67
|
+
code && /* @__PURE__ */ jsx("button", { type: "button", disabled: true, "data-zd-asset-action": "copy", class: actionClass(), children: copyLabel }),
|
|
68
|
+
code && /* @__PURE__ */ jsx("button", { type: "button", disabled: true, "data-zd-asset-action": "wrap", class: actionClass(), children: wrapLabel })
|
|
69
|
+
] });
|
|
70
|
+
}
|
|
71
|
+
function AssetCodeBody({ asset, copyLabel, wrapLabel, truncatedLabel, linesLabel }) {
|
|
72
|
+
const highlightedCode = asset.html?.match(/^<pre\b[^>]*>\s*(<code\b[\s\S]*<\/code>)\s*<\/pre>$/)?.[1] ?? "";
|
|
73
|
+
return /* @__PURE__ */ jsxs("section", { children: [
|
|
74
|
+
/* @__PURE__ */ jsxs("div", { class: "zd-asset-filebar flex flex-wrap items-center justify-between gap-hsp-sm border border-muted bg-surface px-hsp-md py-vsp-2xs text-caption", children: [
|
|
75
|
+
/* @__PURE__ */ jsxs("span", { class: "font-mono", children: [
|
|
76
|
+
asset.name,
|
|
77
|
+
" \xB7 ",
|
|
78
|
+
linesLabel ?? `${asset.lines ?? 0} lines`,
|
|
79
|
+
" \xB7 ",
|
|
80
|
+
formatAssetBytes(asset.bytes),
|
|
81
|
+
" \xB7 ",
|
|
82
|
+
kindLabel(asset)
|
|
83
|
+
] }),
|
|
84
|
+
/* @__PURE__ */ jsxs("span", { class: "flex gap-hsp-sm", children: [
|
|
85
|
+
/* @__PURE__ */ jsx("button", { type: "button", disabled: true, "data-zd-asset-action": "copy", class: "text-fg hover:text-accent focus-visible:text-accent", children: copyLabel }),
|
|
86
|
+
/* @__PURE__ */ jsx("button", { type: "button", disabled: true, "data-zd-asset-action": "wrap", class: "text-fg hover:text-accent focus-visible:text-accent", children: wrapLabel })
|
|
87
|
+
] })
|
|
88
|
+
] }),
|
|
89
|
+
/* @__PURE__ */ jsx("pre", { class: "hi-root zd-asset-code", "data-lang": asset.language ?? "text", dangerouslySetInnerHTML: { __html: highlightedCode } }),
|
|
90
|
+
asset.truncated && /* @__PURE__ */ jsx("p", { class: "mt-vsp-xs text-caption text-muted", children: truncatedLabel })
|
|
91
|
+
] });
|
|
92
|
+
}
|
|
93
|
+
function EnlargeIcon() {
|
|
94
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fill: "none", stroke: "currentColor", "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M8 3H3v5m13-5h5v5M8 21H3v-5m13 5h5v-5M3 8l6-6m12 6-6-6M3 16l6 6m12-6-6 6" }) });
|
|
95
|
+
}
|
|
96
|
+
function AssetImageStage({ asset, rawUrl }) {
|
|
97
|
+
return /* @__PURE__ */ jsxs("section", { children: [
|
|
98
|
+
/* @__PURE__ */ jsxs("div", { class: "mb-vsp-xs flex flex-wrap gap-hsp-sm text-caption", children: [
|
|
99
|
+
/* @__PURE__ */ jsxs("div", { class: "flex rounded border border-muted", children: [
|
|
100
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "true", "data-zd-asset-action": "fit", class: "px-hsp-sm py-vsp-3xs", children: "Fit" }),
|
|
101
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "false", "data-zd-asset-action": "1to1", class: "border-l border-muted px-hsp-sm py-vsp-3xs", children: "1:1" })
|
|
102
|
+
] }),
|
|
103
|
+
/* @__PURE__ */ jsxs("div", { class: "flex rounded border border-muted", children: [
|
|
104
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "true", "data-zd-asset-action": "checker", class: "px-hsp-sm py-vsp-3xs", children: "Checker" }),
|
|
105
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": "false", "data-zd-asset-action": "dark", class: "border-l border-muted px-hsp-sm py-vsp-3xs", children: "Dark" })
|
|
106
|
+
] })
|
|
107
|
+
] }),
|
|
108
|
+
/* @__PURE__ */ jsxs("figure", { class: "zd-enlargeable zd-asset-stage is-checker flex min-h-[20rem] items-center justify-center overflow-auto rounded border border-muted bg-surface p-hsp-lg", children: [
|
|
109
|
+
/* @__PURE__ */ jsx("img", { src: rawUrl, alt: asset.description ?? asset.name, width: asset.width, height: asset.height }),
|
|
110
|
+
/* @__PURE__ */ jsx("button", { type: "button", class: "zd-enlarge-btn", hidden: true, "aria-label": "Enlarge image", children: /* @__PURE__ */ jsx(EnlargeIcon, {}) })
|
|
111
|
+
] })
|
|
112
|
+
] });
|
|
113
|
+
}
|
|
114
|
+
function AssetVideoStage({ asset, rawUrl }) {
|
|
115
|
+
return /* @__PURE__ */ jsx("div", { class: "zd-asset-stage flex items-center justify-center rounded border border-muted bg-surface p-hsp-lg", children: /* @__PURE__ */ jsx("video", { controls: true, preload: "metadata", src: rawUrl, width: asset.width, height: asset.height, class: "max-w-full" }) });
|
|
116
|
+
}
|
|
117
|
+
function AssetPdfStage({ asset, rawUrl, children }) {
|
|
118
|
+
return /* @__PURE__ */ jsxs("section", { children: [
|
|
119
|
+
/* @__PURE__ */ jsx("iframe", { title: asset.name, src: `${rawUrl}#view=FitH`, class: "zd-asset-pdf h-[70vh] w-full rounded border border-muted" }),
|
|
120
|
+
/* @__PURE__ */ jsx("div", { class: "mt-vsp-sm", children })
|
|
121
|
+
] });
|
|
122
|
+
}
|
|
123
|
+
function AssetDownloadPanel({ asset, rawUrl, noPreview, downloadLabel, copyLabel }) {
|
|
124
|
+
return /* @__PURE__ */ jsxs("section", { class: "rounded border border-dashed border-muted p-hsp-xl text-center", children: [
|
|
125
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": "true", class: "mb-vsp-xs text-heading", children: "\u2193" }),
|
|
126
|
+
/* @__PURE__ */ jsx("h2", { class: "font-mono text-title font-bold", children: asset.name }),
|
|
127
|
+
/* @__PURE__ */ jsxs("p", { class: "mb-vsp-sm text-caption text-muted", children: [
|
|
128
|
+
kindLabel(asset),
|
|
129
|
+
" \xB7 ",
|
|
130
|
+
formatAssetBytes(asset.bytes)
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsx("p", { class: "mb-vsp-md text-small text-muted", children: noPreview }),
|
|
133
|
+
/* @__PURE__ */ jsxs("div", { class: "flex flex-wrap justify-center gap-hsp-sm", children: [
|
|
134
|
+
/* @__PURE__ */ jsx("a", { download: true, href: rawUrl, class: `${actionClass(true)} hover:underline focus-visible:underline`, children: downloadLabel }),
|
|
135
|
+
/* @__PURE__ */ jsx("button", { type: "button", "data-zd-asset-action": "copy-url", "data-zd-copy-url": rawUrl, class: actionClass(), children: copyLabel })
|
|
136
|
+
] })
|
|
137
|
+
] });
|
|
138
|
+
}
|
|
139
|
+
function AssetLinkedFrom({ asset, label }) {
|
|
140
|
+
if (asset.linkedFrom.length === 0) return null;
|
|
141
|
+
return /* @__PURE__ */ jsxs("section", { class: "mt-vsp-lg", children: [
|
|
142
|
+
/* @__PURE__ */ jsx("h2", { class: "mb-vsp-xs text-title font-bold", children: label }),
|
|
143
|
+
/* @__PURE__ */ jsx("ul", { class: "space-y-vsp-sm", children: asset.linkedFrom.map((link) => /* @__PURE__ */ jsxs("li", { class: "border-l border-muted pl-hsp-md", children: [
|
|
144
|
+
/* @__PURE__ */ jsx("p", { class: "text-caption text-muted", children: link.crumb }),
|
|
145
|
+
/* @__PURE__ */ jsx("a", { href: link.href, class: "text-accent hover:underline focus-visible:underline", children: link.title }),
|
|
146
|
+
/* @__PURE__ */ jsx("p", { class: "text-caption italic text-muted", children: link.context })
|
|
147
|
+
] })) })
|
|
148
|
+
] });
|
|
149
|
+
}
|
|
150
|
+
function AssetDetails({ asset }) {
|
|
151
|
+
const rows = [["Type", asset.mime], ["Size", formatAssetBytes(asset.bytes)], ["Path", asset.path]];
|
|
152
|
+
if (asset.width !== void 0 && asset.height !== void 0) rows.splice(1, 0, ["Dimensions", `${asset.width} \xD7 ${asset.height}`]);
|
|
153
|
+
if (asset.updatedDate) rows.push(["Updated", asset.updatedDate]);
|
|
154
|
+
return /* @__PURE__ */ jsxs("section", { children: [
|
|
155
|
+
/* @__PURE__ */ jsx("h2", { class: "mb-vsp-xs text-title font-bold", children: "Details" }),
|
|
156
|
+
/* @__PURE__ */ jsx("dl", { class: "grid grid-cols-[auto_1fr] gap-x-hsp-md gap-y-vsp-2xs text-caption", children: rows.map(([term, value]) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
157
|
+
/* @__PURE__ */ jsx("dt", { class: "font-medium text-muted", children: term }),
|
|
158
|
+
/* @__PURE__ */ jsx("dd", { class: "min-w-0 break-words text-fg", children: value })
|
|
159
|
+
] })) })
|
|
160
|
+
] });
|
|
161
|
+
}
|
|
162
|
+
function MediaLayout({ stage, details, linked }) {
|
|
163
|
+
return /* @__PURE__ */ jsxs("div", { class: "zd-asset-media-grid", children: [
|
|
164
|
+
/* @__PURE__ */ jsx("div", { class: "min-w-0", children: stage }),
|
|
165
|
+
/* @__PURE__ */ jsxs("div", { class: "zd-asset-media-rail", children: [
|
|
166
|
+
/* @__PURE__ */ jsx("div", { class: "rounded border border-muted p-hsp-lg", children: details }),
|
|
167
|
+
linked
|
|
168
|
+
] })
|
|
169
|
+
] });
|
|
170
|
+
}
|
|
171
|
+
function createAssetPageView(ctx) {
|
|
172
|
+
assertChromeContext(ctx, "createAssetPageView");
|
|
173
|
+
const settings = ctx.settings;
|
|
174
|
+
const locale = ctx.defaultLocale;
|
|
175
|
+
const t = ctx.t;
|
|
176
|
+
const composeMetaTitle = deriveComposeMetaTitle(ctx);
|
|
177
|
+
const HeadWithDefaults = createHeadWithDefaults(ctx);
|
|
178
|
+
const { Header: HeaderWithDefaults, Footer: FooterWithDefaults, Breadcrumb: BreadcrumbWithDefaults } = derivePrimaryChromeSlots(ctx);
|
|
179
|
+
const BodyEndIslands = deriveBodyEndIslands(ctx);
|
|
180
|
+
const dataThemePack = resolveThemePackSsrSlug(ctx.themePackRegistry, settings);
|
|
181
|
+
return function AssetPageView({ entry: asset }) {
|
|
182
|
+
const routePrefix = ctx.assetManifest?.routePrefix ?? settings.assetViewerRoutePrefix;
|
|
183
|
+
const dir = ctx.assetManifest?.dir ?? settings.assetViewerDir;
|
|
184
|
+
const viewerUrl = assetViewerHref({ base: settings.base, routePrefix, path: asset.path });
|
|
185
|
+
const rawUrl = assetRawHref({ base: settings.base, dir, path: asset.path });
|
|
186
|
+
const linesLabel = t("asset.lines", locale).replace(
|
|
187
|
+
"{count}",
|
|
188
|
+
String(asset.lines ?? 0)
|
|
189
|
+
);
|
|
190
|
+
const dirSegments = asset.dir.split("/").filter(Boolean);
|
|
191
|
+
const indexUrl = ctx.withBase(`/${routePrefix}/`);
|
|
192
|
+
const breadcrumbItems = [
|
|
193
|
+
{ label: "", href: ctx.withBase("/") },
|
|
194
|
+
{ label: t("asset.crumb", locale), ...settings.assetViewerIndex ? { href: indexUrl } : {} },
|
|
195
|
+
...dirSegments.map((label) => ({ label })),
|
|
196
|
+
{ label: asset.name }
|
|
197
|
+
];
|
|
198
|
+
const linked = /* @__PURE__ */ jsx(AssetLinkedFrom, { asset, label: t("asset.linkedFrom", locale) });
|
|
199
|
+
const details = /* @__PURE__ */ jsx(AssetDetails, { asset });
|
|
200
|
+
const downloadPanel = /* @__PURE__ */ jsx(AssetDownloadPanel, { asset, rawUrl, noPreview: t("asset.noPreview", locale), downloadLabel: t("asset.download", locale), copyLabel: t("asset.copy", locale) });
|
|
201
|
+
let body;
|
|
202
|
+
const isMedia = asset.previewable && asset.sniffOk && ["image", "video", "pdf"].includes(asset.kind);
|
|
203
|
+
if (!asset.previewable || !asset.sniffOk) body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
204
|
+
downloadPanel,
|
|
205
|
+
/* @__PURE__ */ jsx(AssetDetails, { asset }),
|
|
206
|
+
linked
|
|
207
|
+
] });
|
|
208
|
+
else if (asset.kind === "image") body = /* @__PURE__ */ jsx(MediaLayout, { stage: /* @__PURE__ */ jsx(AssetImageStage, { asset, rawUrl }), details, linked });
|
|
209
|
+
else if (asset.kind === "video") body = /* @__PURE__ */ jsx(MediaLayout, { stage: /* @__PURE__ */ jsx(AssetVideoStage, { asset, rawUrl }), details, linked });
|
|
210
|
+
else if (asset.kind === "pdf") body = /* @__PURE__ */ jsx(MediaLayout, { stage: /* @__PURE__ */ jsx(AssetPdfStage, { asset, rawUrl, children: downloadPanel }), details, linked });
|
|
211
|
+
else body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
212
|
+
/* @__PURE__ */ jsx(AssetCodeBody, { asset, copyLabel: t("asset.copy", locale), wrapLabel: t("asset.wrap", locale), truncatedLabel: t("asset.truncated", locale), linesLabel }),
|
|
213
|
+
/* @__PURE__ */ jsx(AssetDetails, { asset }),
|
|
214
|
+
linked
|
|
215
|
+
] });
|
|
216
|
+
const showSource = settings.bodyFootUtilArea !== false && settings.bodyFootUtilArea.viewSourceLink !== false;
|
|
217
|
+
return /* @__PURE__ */ jsx(DocLayoutWithDefaults, { title: composeMetaTitle(asset.name), head: /* @__PURE__ */ jsx(HeadWithDefaults, { title: asset.name, description: asset.description, canonical: ctx.absoluteUrl(viewerUrl) }), lang: locale, dataThemePack, noindex: settings.noindex, hideSidebar: true, hideToc: true, sidebarOverride: false, contentWide: true, breadcrumbOverride: /* @__PURE__ */ jsx(BreadcrumbWithDefaults, { items: breadcrumbItems }), headerOverride: /* @__PURE__ */ jsx(HeaderWithDefaults, { lang: locale, currentPath: viewerUrl, hideSidebarToggle: true }), footerOverride: /* @__PURE__ */ jsx(FooterWithDefaults, { lang: locale }), bodyEndComponents: /* @__PURE__ */ jsx(BodyEndIslands, { basePath: settings.base ?? "/", forceImageEnlarge: asset.kind === "image" && asset.previewable && asset.sniffOk }), enableClientRouter: settings.dynamicPageTransition, children: /* @__PURE__ */ jsxs("div", { class: "zd-asset-page", "data-zd-asset-page": true, children: [
|
|
218
|
+
asset.linkedFrom[0] && /* @__PURE__ */ jsx("p", { class: "mb-vsp-xs text-caption", children: /* @__PURE__ */ jsxs("a", { href: asset.linkedFrom[0].href, class: "text-muted hover:text-accent focus-visible:text-accent hover:underline focus-visible:underline", children: [
|
|
219
|
+
"\u2190 Back to ",
|
|
220
|
+
asset.linkedFrom[0].title
|
|
221
|
+
] }) }),
|
|
222
|
+
/* @__PURE__ */ jsx(AssetHeader, { asset, locale, badge: t("asset.badge", locale), updatedLabel: t("doc.updated", locale), linesLabel }),
|
|
223
|
+
/* @__PURE__ */ jsx(AssetActions, { rawUrl, downloadLabel: t("asset.download", locale), openRawLabel: t("asset.openRaw", locale), copyLabel: t("asset.copy", locale), wrapLabel: t("asset.wrap", locale), code: !isMedia && asset.previewable && asset.sniffOk }),
|
|
224
|
+
body,
|
|
225
|
+
/* @__PURE__ */ jsx(AssetActions, { rawUrl, downloadLabel: t("asset.download", locale), openRawLabel: t("asset.openRaw", locale), copyLabel: t("asset.copy", locale), wrapLabel: t("asset.wrap", locale), bottom: true }),
|
|
226
|
+
showSource && /* @__PURE__ */ jsx(BodyFootUtilArea, { sourceUrl: buildGitHubSourceUrl(settings.githubUrl, `public/${dir}`, asset.path), viewSourceLabel: t("doc.viewSource", locale), docHistoryIsland: null }),
|
|
227
|
+
/* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: ASSET_PAGE_SCRIPT } })
|
|
228
|
+
] }) });
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
export {
|
|
232
|
+
ASSET_PAGE_SCRIPT2 as ASSET_PAGE_SCRIPT,
|
|
233
|
+
AssetActions,
|
|
234
|
+
AssetCodeBody,
|
|
235
|
+
AssetDetails,
|
|
236
|
+
AssetDownloadPanel,
|
|
237
|
+
AssetEyebrow,
|
|
238
|
+
AssetHeader,
|
|
239
|
+
AssetImageStage,
|
|
240
|
+
AssetLinkedFrom,
|
|
241
|
+
AssetPdfStage,
|
|
242
|
+
AssetVideoStage,
|
|
243
|
+
createAssetPageView
|
|
244
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const ASSET_PAGE_SCRIPT = String.raw`(()=>{const init=()=>{document.querySelectorAll('[data-zd-asset-page]').forEach(page=>{if(page.hasAttribute('data-zd-asset-ready'))return;page.setAttribute('data-zd-asset-ready','true');const pre=page.querySelector('.zd-asset-code');page.addEventListener('click',event=>{const target=event.target;if(!(target instanceof Element))return;const button=target.closest('button');const action=target.closest('[data-zd-asset-action]')?.getAttribute('data-zd-asset-action');if(action==='copy'||action==='wrap'){const proxy=pre?.closest('.code-block-wrapper')?.querySelector('.code-btn-'+action);if(proxy instanceof HTMLElement)proxy.click();return}if(action==='copy-url'&&button){navigator.clipboard.writeText(button.dataset.zdCopyUrl||location.href);return}const section=target.closest('section');const stage=section?.querySelector('.zd-asset-stage');if(action==='fit'||action==='1to1'){stage?.classList.toggle('is-1to1',action==='1to1');section?.querySelectorAll('[data-zd-asset-action="fit"],[data-zd-asset-action="1to1"]').forEach(item=>item.setAttribute('aria-pressed',String(item===button)));return}if((action==='checker'||action==='dark')&&button){stage?.classList.toggle('is-checker',action==='checker');stage?.classList.toggle('is-dark',action==='dark');section?.querySelectorAll('[data-zd-asset-action="checker"],[data-zd-asset-action="dark"]').forEach(item=>item.setAttribute('aria-pressed',String(item===button)));return}const line=target.closest('.zd-asset-code .line');const lineOffset=line?event.clientX-line.getBoundingClientRect().left:Infinity;const gutterWidth=line?parseFloat(getComputedStyle(line,'::before').width):0;if(line&&lineOffset<gutterWidth){location.hash=line.id}});if(pre){const wait=()=>{const wrapper=pre.closest('.code-block-wrapper');if(!wrapper){requestAnimationFrame(wait);return}page.querySelectorAll('[data-zd-asset-action="copy"],[data-zd-asset-action="wrap"]').forEach(button=>button.removeAttribute('disabled'))};requestAnimationFrame(wait)}})};if(!document.__zdAssetPageInit){document.__zdAssetPageInit=init;document.addEventListener('zfb:after-swap',init)}document.__zdAssetPageInit()})();`;
|
|
2
|
+
export {
|
|
3
|
+
ASSET_PAGE_SCRIPT
|
|
4
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Browser-safe canonical path and URL helpers for the asset viewer. */
|
|
2
|
+
export interface DecodedAssetHref {
|
|
3
|
+
/** Normalized path relative to the configured public asset directory. */
|
|
4
|
+
path: string;
|
|
5
|
+
/** The authored fragment, including its leading `#`, when present. */
|
|
6
|
+
fragment?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface AssetViewerHrefOptions {
|
|
9
|
+
base: string;
|
|
10
|
+
routePrefix: string;
|
|
11
|
+
path: string;
|
|
12
|
+
/** A fragment with or without its leading `#`. */
|
|
13
|
+
fragment?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface AssetRawHrefOptions {
|
|
16
|
+
base: string;
|
|
17
|
+
dir: string;
|
|
18
|
+
path: string;
|
|
19
|
+
}
|
|
20
|
+
export interface AssetViewerPathSettings {
|
|
21
|
+
dir: string;
|
|
22
|
+
routePrefix: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Normalize a public asset path to NFC POSIX form.
|
|
26
|
+
*
|
|
27
|
+
* Paths are relative file paths, never URLs: empty segments, leading slashes,
|
|
28
|
+
* dot segments, backslashes and control characters are rejected.
|
|
29
|
+
*/
|
|
30
|
+
export declare function normalizeAssetPath(path: string): string;
|
|
31
|
+
/** Encode each path segment independently, retaining POSIX `/` separators. */
|
|
32
|
+
export declare function encodeAssetPathForUrl(path: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Decode a root-relative authored href that points inside `/<dir>/`.
|
|
35
|
+
*
|
|
36
|
+
* Decoding happens exactly once. A literal query makes the href ineligible;
|
|
37
|
+
* `%3F` remains a valid filename character. Fragments are preserved verbatim.
|
|
38
|
+
*/
|
|
39
|
+
export declare function decodeAuthoredHref(href: string, options: {
|
|
40
|
+
base: string;
|
|
41
|
+
dir: string;
|
|
42
|
+
}): DecodedAssetHref | null;
|
|
43
|
+
/** Build the base-prefixed, trailing-slashed asset viewer route exactly once. */
|
|
44
|
+
export declare function assetViewerHref(options: AssetViewerHrefOptions): string;
|
|
45
|
+
/** Build the base-prefixed URL for the raw public asset. */
|
|
46
|
+
export declare function assetRawHref(options: AssetRawHrefOptions): string;
|
|
47
|
+
/** Validate the two relative URL/disk namespaces used by the asset viewer. */
|
|
48
|
+
export declare function validateAssetViewerSettings(settings: AssetViewerPathSettings): void;
|
|
49
|
+
/**
|
|
50
|
+
* Match a normalized asset path against small, whole-path glob patterns.
|
|
51
|
+
* `*` and `?` do not cross `/`; `**` does; `{a,b}` selects literal alternatives.
|
|
52
|
+
*/
|
|
53
|
+
export declare function matchExclude(path: string, globs: readonly string[]): boolean;
|