hono-decks 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.d.ts +603 -46
- package/dist/advanced.js +2011 -1907
- package/dist/bin.d.ts +1 -1
- package/dist/bin.js +1763 -1910
- package/dist/cli.d.ts +16 -15
- package/dist/cli.js +1766 -1915
- package/dist/client.d.ts +14 -8
- package/dist/client.js +13 -16
- package/dist/mod.d.ts +512 -27
- package/dist/mod.js +797 -759
- package/dist/node.d.ts +670 -111
- package/dist/node.js +3756 -3937
- package/dist/vite.d.ts +8 -8
- package/dist/vite.js +1646 -1805
- package/package.json +3 -3
- package/dist/define-decks-U4NxIs66.d.ts +0 -587
- package/dist/jsx-renderer-BO-N4tMZ.d.ts +0 -20
package/dist/mod.js
CHANGED
|
@@ -1,437 +1,444 @@
|
|
|
1
|
-
|
|
2
|
-
import { Hono } from "hono";
|
|
3
|
-
import { raw as raw2 } from "hono/html";
|
|
4
|
-
|
|
5
|
-
// src/deck/model.ts
|
|
6
|
-
var SLIDE_TRANSITIONS = [
|
|
7
|
-
"none",
|
|
8
|
-
"fade",
|
|
9
|
-
"fade-out",
|
|
10
|
-
"slide-left",
|
|
11
|
-
"slide-right",
|
|
12
|
-
"slide-up",
|
|
13
|
-
"slide-down",
|
|
14
|
-
"view-transition"
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
// src/renderer/jsx-renderer.ts
|
|
1
|
+
import { raw } from "hono/html";
|
|
18
2
|
import { jsx } from "hono/jsx/jsx-runtime";
|
|
19
3
|
import { HtmlEscapedCallbackPhase, resolveCallback } from "hono/utils/html";
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
4
|
+
//#region src/deck/model.ts
|
|
5
|
+
const SLIDE_TRANSITIONS = [
|
|
6
|
+
"none",
|
|
7
|
+
"fade",
|
|
8
|
+
"fade-out",
|
|
9
|
+
"slide-left",
|
|
10
|
+
"slide-right",
|
|
11
|
+
"slide-up",
|
|
12
|
+
"slide-down",
|
|
13
|
+
"view-transition"
|
|
14
|
+
];
|
|
15
|
+
defineSlideComponents({
|
|
16
|
+
Fire: (props) => {
|
|
17
|
+
if (props.order !== void 0) throw new Error("The Fire \"order\" prop is not supported. Fires reveal in source order.");
|
|
18
|
+
const effect = stringProp(props.effect);
|
|
19
|
+
const at = fireAtProp(props.at);
|
|
20
|
+
return jsx("div", {
|
|
21
|
+
"data-hono-decks-fire": true,
|
|
22
|
+
...at ? { "data-fire-at": at } : {},
|
|
23
|
+
...effect ? { "data-fire-effect": safeToken(effect).toLowerCase() } : {},
|
|
24
|
+
children: props.children
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
Hero: (props) => jsx("section", {
|
|
28
|
+
class: `mdx-hero${props.featured === true ? " is-featured" : ""}${props.image || props.src ? " has-image" : ""}`,
|
|
29
|
+
"data-component": "Hero",
|
|
30
|
+
children: [heroImage(props), jsx("div", {
|
|
31
|
+
class: "mdx-hero-copy",
|
|
32
|
+
children: [
|
|
33
|
+
typeof props.eyebrow === "string" && props.eyebrow ? jsx("p", {
|
|
34
|
+
class: "mdx-hero-eyebrow",
|
|
35
|
+
children: props.eyebrow
|
|
36
|
+
}) : "",
|
|
37
|
+
typeof props.title === "string" && props.title ? jsx("h1", { children: props.title }) : "",
|
|
38
|
+
typeof props.subtitle === "string" && props.subtitle ? jsx("p", {
|
|
39
|
+
class: "mdx-hero-subtitle",
|
|
40
|
+
children: props.subtitle
|
|
41
|
+
}) : typeof props.description === "string" && props.description ? jsx("p", {
|
|
42
|
+
class: "mdx-hero-subtitle",
|
|
43
|
+
children: props.description
|
|
44
|
+
}) : ""
|
|
45
|
+
]
|
|
46
|
+
})]
|
|
47
|
+
}),
|
|
48
|
+
CodeBlock: (props) => {
|
|
49
|
+
const lang = stringProp(props.lang);
|
|
50
|
+
const filename = stringProp(props.filename ?? props.title);
|
|
51
|
+
const highlight = stringProp(props.highlight);
|
|
52
|
+
const code = codeBlockText(props.children);
|
|
53
|
+
const highlightedHtml = typeof props.highlightedHtml === "string" ? props.highlightedHtml : void 0;
|
|
54
|
+
return jsx("figure", {
|
|
55
|
+
class: "hono-decks-code-block",
|
|
56
|
+
...lang ? { "data-lang": lang } : {},
|
|
57
|
+
...filename ? { "data-filename": filename } : {},
|
|
58
|
+
...highlight ? { "data-highlight": highlight } : {},
|
|
59
|
+
children: [filename ? jsx("figcaption", {
|
|
60
|
+
class: "hono-decks-code-caption",
|
|
61
|
+
children: filename
|
|
62
|
+
}) : "", highlightedHtml ? jsx("div", {
|
|
63
|
+
class: "hono-decks-code-highlight",
|
|
64
|
+
dangerouslySetInnerHTML: { __html: highlightedHtml }
|
|
65
|
+
}) : jsx("pre", { children: jsx("code", {
|
|
66
|
+
...lang ? {
|
|
67
|
+
class: `language-${safeToken(lang)}`,
|
|
68
|
+
"data-lang": lang
|
|
69
|
+
} : {},
|
|
70
|
+
children: code
|
|
71
|
+
}) })]
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
EmbedFrame: (props) => {
|
|
75
|
+
const src = stringProp(props.src);
|
|
76
|
+
const provider = stringProp(props.provider)?.trim().toLowerCase();
|
|
77
|
+
const title = stringProp(props.title) ?? "Embedded content";
|
|
78
|
+
const aspectRatio = stringProp(props.aspectRatio) ?? "16 / 9";
|
|
79
|
+
const loading = stringProp(props.loading) ?? "lazy";
|
|
80
|
+
const allow = stringProp(props.allow) ?? "fullscreen; picture-in-picture";
|
|
81
|
+
const sandbox = props.sandbox === false ? void 0 : stringProp(props.sandbox) ?? "allow-scripts allow-same-origin allow-presentation allow-popups";
|
|
82
|
+
const referrerPolicy = stringProp(props.referrerPolicy ?? props.referrerpolicy) ?? "strict-origin-when-cross-origin";
|
|
83
|
+
const fallbackHref = stringProp(props.fallbackHref ?? props.fallbackUrl ?? props.href) ?? src;
|
|
84
|
+
const fallback = codeBlockText(props.children) || "Open embed";
|
|
85
|
+
const printPoster = provider === "youtube" ? youtubePrintPoster(src) : void 0;
|
|
86
|
+
return jsx("figure", {
|
|
87
|
+
class: "hono-decks-embed-frame",
|
|
88
|
+
"data-component": "EmbedFrame",
|
|
89
|
+
...provider ? { "data-provider": safeToken(provider).toLowerCase() } : {},
|
|
90
|
+
children: [jsx("div", {
|
|
91
|
+
class: "hono-decks-embed-viewport",
|
|
92
|
+
style: `aspect-ratio:${safeAspectRatio(aspectRatio)}`,
|
|
93
|
+
children: [src ? jsx("iframe", {
|
|
94
|
+
src,
|
|
95
|
+
title,
|
|
96
|
+
loading,
|
|
97
|
+
referrerpolicy: referrerPolicy,
|
|
98
|
+
...sandbox ? { sandbox } : {},
|
|
99
|
+
...allow ? { allow } : {},
|
|
100
|
+
allowfullscreen: true
|
|
101
|
+
}) : "", fallbackHref ? jsx("a", {
|
|
102
|
+
class: "hono-decks-embed-print-fallback",
|
|
103
|
+
href: fallbackHref,
|
|
104
|
+
children: [printPoster ? jsx("img", {
|
|
105
|
+
class: "hono-decks-embed-print-poster",
|
|
106
|
+
src: printPoster,
|
|
107
|
+
alt: `${title} thumbnail`
|
|
108
|
+
}) : "", jsx("span", { children: fallback })]
|
|
109
|
+
}) : ""]
|
|
110
|
+
}), src ? jsx("figcaption", {
|
|
111
|
+
class: "hono-decks-embed-fallback",
|
|
112
|
+
children: jsx("a", {
|
|
113
|
+
href: fallbackHref,
|
|
114
|
+
target: "_blank",
|
|
115
|
+
rel: "noreferrer",
|
|
116
|
+
children: fallback
|
|
117
|
+
})
|
|
118
|
+
}) : ""]
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
SocialEmbed: (props) => {
|
|
122
|
+
const href = stringProp(props.href ?? props.url);
|
|
123
|
+
const provider = stringProp(props.provider ?? props.service);
|
|
124
|
+
const author = stringProp(props.author);
|
|
125
|
+
const label = stringProp(props.label) ?? (provider ? `Open on ${provider}` : "Open social post");
|
|
126
|
+
const quote = codeBlockText(props.children);
|
|
127
|
+
return jsx("figure", {
|
|
128
|
+
class: "hono-decks-social-embed",
|
|
129
|
+
"data-component": "SocialEmbed",
|
|
130
|
+
...provider ? { "data-provider": safeToken(provider).toLowerCase() } : {},
|
|
131
|
+
children: jsx("blockquote", {
|
|
132
|
+
class: "hono-decks-social-card",
|
|
133
|
+
...href ? { cite: href } : {},
|
|
134
|
+
children: [quote ? jsx("p", { children: quote }) : "", jsx("footer", { children: [author ? jsx("span", {
|
|
135
|
+
class: "hono-decks-social-author",
|
|
136
|
+
children: author
|
|
137
|
+
}) : "", href ? jsx("a", {
|
|
138
|
+
href,
|
|
139
|
+
target: "_blank",
|
|
140
|
+
rel: "noreferrer",
|
|
141
|
+
children: label
|
|
142
|
+
}) : ""] })]
|
|
143
|
+
})
|
|
144
|
+
});
|
|
145
|
+
},
|
|
146
|
+
TweetEmbed: (props) => {
|
|
147
|
+
const href = stringProp(props.href ?? props.url);
|
|
148
|
+
const label = stringProp(props.label) ?? "Open post on X";
|
|
149
|
+
return jsx("figure", {
|
|
150
|
+
class: "hono-decks-tweet-embed",
|
|
151
|
+
"data-component": "TweetEmbed",
|
|
152
|
+
children: [
|
|
153
|
+
jsx("blockquote", {
|
|
154
|
+
class: "twitter-tweet",
|
|
155
|
+
"data-dnt": "true",
|
|
156
|
+
children: href ? jsx("a", {
|
|
157
|
+
href,
|
|
158
|
+
target: "_blank",
|
|
159
|
+
rel: "noreferrer",
|
|
160
|
+
children: label
|
|
161
|
+
}) : label
|
|
162
|
+
}),
|
|
163
|
+
href ? jsx("script", {
|
|
164
|
+
async: true,
|
|
165
|
+
src: "https://platform.twitter.com/widgets.js",
|
|
166
|
+
charset: "utf-8"
|
|
167
|
+
}) : "",
|
|
168
|
+
href ? jsx("a", {
|
|
169
|
+
class: "hono-decks-tweet-print-fallback",
|
|
170
|
+
href,
|
|
171
|
+
children: label
|
|
172
|
+
}) : ""
|
|
173
|
+
]
|
|
174
|
+
});
|
|
175
|
+
},
|
|
176
|
+
LinkCard: (props) => {
|
|
177
|
+
const href = stringProp(props.href ?? props.url);
|
|
178
|
+
const title = stringProp(props.title) ?? href ?? "Link";
|
|
179
|
+
const description = stringProp(props.description);
|
|
180
|
+
const image = stringProp(props.image ?? props.imageUrl);
|
|
181
|
+
const siteName = stringProp(props.siteName ?? props.site);
|
|
182
|
+
const label = codeBlockText(props.children) || "Open link";
|
|
183
|
+
return jsx("figure", {
|
|
184
|
+
class: "hono-decks-link-card",
|
|
185
|
+
"data-component": "LinkCard",
|
|
186
|
+
children: href ? jsx("a", {
|
|
187
|
+
class: "hono-decks-link-card-anchor",
|
|
188
|
+
href,
|
|
189
|
+
target: "_blank",
|
|
190
|
+
rel: "noreferrer",
|
|
191
|
+
children: [image ? jsx("img", {
|
|
192
|
+
class: "hono-decks-link-card-image",
|
|
193
|
+
src: image,
|
|
194
|
+
alt: title
|
|
195
|
+
}) : "", jsx("span", {
|
|
196
|
+
class: "hono-decks-link-card-body",
|
|
197
|
+
children: [
|
|
198
|
+
siteName ? jsx("span", {
|
|
199
|
+
class: "hono-decks-link-card-site",
|
|
200
|
+
children: siteName
|
|
201
|
+
}) : "",
|
|
202
|
+
jsx("span", {
|
|
203
|
+
class: "hono-decks-link-card-title",
|
|
204
|
+
children: title
|
|
205
|
+
}),
|
|
206
|
+
description ? jsx("span", {
|
|
207
|
+
class: "hono-decks-link-card-description",
|
|
208
|
+
children: description
|
|
209
|
+
}) : "",
|
|
210
|
+
jsx("span", {
|
|
211
|
+
class: "hono-decks-link-card-label",
|
|
212
|
+
children: label
|
|
213
|
+
})
|
|
214
|
+
]
|
|
215
|
+
})]
|
|
216
|
+
}) : [
|
|
217
|
+
image ? jsx("img", {
|
|
218
|
+
class: "hono-decks-link-card-image",
|
|
219
|
+
src: image,
|
|
220
|
+
alt: title
|
|
221
|
+
}) : "",
|
|
222
|
+
siteName ? jsx("span", {
|
|
223
|
+
class: "hono-decks-link-card-site",
|
|
224
|
+
children: siteName
|
|
225
|
+
}) : "",
|
|
226
|
+
jsx("span", {
|
|
227
|
+
class: "hono-decks-link-card-title",
|
|
228
|
+
children: title
|
|
229
|
+
}),
|
|
230
|
+
description ? jsx("span", {
|
|
231
|
+
class: "hono-decks-link-card-description",
|
|
232
|
+
children: description
|
|
233
|
+
}) : ""
|
|
234
|
+
]
|
|
235
|
+
});
|
|
236
|
+
}
|
|
220
237
|
});
|
|
221
238
|
function defineSlideComponents(input) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
return registry;
|
|
239
|
+
const registry = {};
|
|
240
|
+
for (const [name, value] of Object.entries(input)) registry[name] = typeof value === "function" ? { component: value } : value;
|
|
241
|
+
return registry;
|
|
227
242
|
}
|
|
228
243
|
function heroImage(props) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
244
|
+
const image = typeof props.image === "string" ? props.image : typeof props.src === "string" ? props.src : void 0;
|
|
245
|
+
if (!image) return "";
|
|
246
|
+
return jsx("img", {
|
|
247
|
+
class: "mdx-hero-image",
|
|
248
|
+
src: image,
|
|
249
|
+
alt: typeof props.alt === "string" && props.alt ? props.alt : typeof props.title === "string" ? props.title : "Hero image"
|
|
250
|
+
});
|
|
233
251
|
}
|
|
234
252
|
function stringProp(value) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return void 0;
|
|
253
|
+
if (typeof value === "string") return value;
|
|
254
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
238
255
|
}
|
|
239
256
|
function fireAtProp(value) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
257
|
+
if (value === void 0 || value === null) return void 0;
|
|
258
|
+
if (typeof value === "number") {
|
|
259
|
+
if (Number.isInteger(value) && value >= 0) return String(value);
|
|
260
|
+
throw new Error("The Fire \"at\" prop accepts a non-negative integer or a relative string such as \"+1\".");
|
|
261
|
+
}
|
|
262
|
+
if (typeof value === "string") {
|
|
263
|
+
const at = value.trim();
|
|
264
|
+
if (/^(?:\d+|[+-]\d+)$/.test(at)) return at;
|
|
265
|
+
}
|
|
266
|
+
throw new Error("The Fire \"at\" prop accepts a non-negative integer or a relative string such as \"+1\".");
|
|
250
267
|
}
|
|
251
268
|
function safeToken(value) {
|
|
252
|
-
|
|
269
|
+
return value.trim().replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "text";
|
|
253
270
|
}
|
|
254
271
|
function safeAspectRatio(value) {
|
|
255
|
-
|
|
272
|
+
return /^\s*\d+(\.\d+)?\s*(\/|:)\s*\d+(\.\d+)?\s*$/.test(value) ? value.replace(":", " / ") : "16 / 9";
|
|
256
273
|
}
|
|
257
274
|
function youtubePrintPoster(src) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
275
|
+
if (!src) return void 0;
|
|
276
|
+
try {
|
|
277
|
+
const url = new URL(src);
|
|
278
|
+
if (![
|
|
279
|
+
"youtube.com",
|
|
280
|
+
"www.youtube.com",
|
|
281
|
+
"youtube-nocookie.com",
|
|
282
|
+
"www.youtube-nocookie.com"
|
|
283
|
+
].includes(url.hostname)) return;
|
|
284
|
+
const match = url.pathname.match(/^\/embed\/([A-Za-z0-9_-]+)$/);
|
|
285
|
+
return match ? `https://i.ytimg.com/vi/${match[1]}/hqdefault.jpg` : void 0;
|
|
286
|
+
} catch {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
269
289
|
}
|
|
270
290
|
function codeBlockText(value) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
291
|
+
if (Array.isArray(value)) return value.map(codeBlockText).join("");
|
|
292
|
+
if (value === null || value === void 0 || typeof value === "boolean") return "";
|
|
293
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
294
|
+
if (isJsxValue(value)) return codeBlockText(value.props?.children);
|
|
295
|
+
return String(value);
|
|
276
296
|
}
|
|
277
297
|
async function renderJsxValue(value) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
298
|
+
const resolved = value instanceof Promise ? await value : value;
|
|
299
|
+
if (typeof resolved === "string") return resolved;
|
|
300
|
+
if (resolved === null || resolved === void 0 || typeof resolved === "boolean") return "";
|
|
301
|
+
if (typeof resolved === "number") return String(resolved);
|
|
302
|
+
return await resolveCallback(resolved, HtmlEscapedCallbackPhase.Stringify, false, {});
|
|
283
303
|
}
|
|
284
304
|
function isJsxValue(value) {
|
|
285
|
-
|
|
305
|
+
return typeof value === "object" && value !== null && "tag" in value && "props" in value && "type" in value;
|
|
286
306
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
import { jsx as jsx2 } from "hono/jsx/jsx-runtime";
|
|
307
|
+
//#endregion
|
|
308
|
+
//#region src/renderer/control-icons.ts
|
|
290
309
|
function renderControlIcon(name, className = "hono-decks-control-icon") {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
310
|
+
return jsx("svg", {
|
|
311
|
+
class: className,
|
|
312
|
+
"data-hono-decks-control-icon": true,
|
|
313
|
+
viewBox: "0 0 24 24",
|
|
314
|
+
"aria-hidden": "true",
|
|
315
|
+
focusable: "false",
|
|
316
|
+
fill: "none",
|
|
317
|
+
"stroke-width": "2",
|
|
318
|
+
"stroke-linecap": "round",
|
|
319
|
+
"stroke-linejoin": "round",
|
|
320
|
+
children: controlIconPaths(name)
|
|
321
|
+
});
|
|
303
322
|
}
|
|
304
323
|
function controlIconLabel(name) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return "Next slide";
|
|
320
|
-
case "fullscreen":
|
|
321
|
-
return "Toggle fullscreen";
|
|
322
|
-
case "print":
|
|
323
|
-
return "Print view";
|
|
324
|
-
case "details":
|
|
325
|
-
return "Details";
|
|
326
|
-
case "export-pdf":
|
|
327
|
-
return "Export PDF";
|
|
328
|
-
case "export-png":
|
|
329
|
-
return "Export PNG";
|
|
330
|
-
}
|
|
324
|
+
switch (name) {
|
|
325
|
+
case "deck-list": return "Deck list";
|
|
326
|
+
case "home": return "Home";
|
|
327
|
+
case "viewer": return "Viewer";
|
|
328
|
+
case "projection": return "Projection";
|
|
329
|
+
case "presenter": return "Presenter";
|
|
330
|
+
case "previous": return "Previous slide";
|
|
331
|
+
case "next": return "Next slide";
|
|
332
|
+
case "fullscreen": return "Toggle fullscreen";
|
|
333
|
+
case "print": return "Print view";
|
|
334
|
+
case "details": return "Details";
|
|
335
|
+
case "export-pdf": return "Export PDF";
|
|
336
|
+
case "export-png": return "Export PNG";
|
|
337
|
+
}
|
|
331
338
|
}
|
|
332
339
|
function controlIconPaths(name) {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
340
|
+
switch (name) {
|
|
341
|
+
case "deck-list": return [
|
|
342
|
+
jsx("path", { d: "M4 5h16" }),
|
|
343
|
+
jsx("path", { d: "M4 12h16" }),
|
|
344
|
+
jsx("path", { d: "M4 19h16" })
|
|
345
|
+
];
|
|
346
|
+
case "home": return [
|
|
347
|
+
jsx("path", { d: "M3 11l9-8 9 8" }),
|
|
348
|
+
jsx("path", { d: "M5 10v10h14V10" }),
|
|
349
|
+
jsx("path", { d: "M9 20v-6h6v6" })
|
|
350
|
+
];
|
|
351
|
+
case "viewer": return [jsx("path", { d: "M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z" }), jsx("circle", {
|
|
352
|
+
cx: "12",
|
|
353
|
+
cy: "12",
|
|
354
|
+
r: "3"
|
|
355
|
+
})];
|
|
356
|
+
case "projection": return [
|
|
357
|
+
jsx("path", { d: "M4 5h16v10H4z" }),
|
|
358
|
+
jsx("path", { d: "M8 19h8" }),
|
|
359
|
+
jsx("path", { d: "M12 15v4" })
|
|
360
|
+
];
|
|
361
|
+
case "presenter": return [
|
|
362
|
+
jsx("path", { d: "M4 5h16v10H4z" }),
|
|
363
|
+
jsx("path", { d: "M8 21l4-6 4 6" }),
|
|
364
|
+
jsx("path", { d: "M9 9h6" })
|
|
365
|
+
];
|
|
366
|
+
case "previous": return [jsx("path", { d: "M15 6l-6 6 6 6" })];
|
|
367
|
+
case "next": return [jsx("path", { d: "M9 6l6 6-6 6" })];
|
|
368
|
+
case "fullscreen": return [
|
|
369
|
+
jsx("path", { d: "M8 3H5a2 2 0 0 0-2 2v3" }),
|
|
370
|
+
jsx("path", { d: "M16 3h3a2 2 0 0 1 2 2v3" }),
|
|
371
|
+
jsx("path", { d: "M8 21H5a2 2 0 0 1-2-2v-3" }),
|
|
372
|
+
jsx("path", { d: "M16 21h3a2 2 0 0 0 2-2v-3" })
|
|
373
|
+
];
|
|
374
|
+
case "print": return [
|
|
375
|
+
jsx("path", { d: "M6 9V3h12v6" }),
|
|
376
|
+
jsx("path", { d: "M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2" }),
|
|
377
|
+
jsx("path", { d: "M6 14h12v7H6z" })
|
|
378
|
+
];
|
|
379
|
+
case "details": return [
|
|
380
|
+
jsx("circle", {
|
|
381
|
+
cx: "12",
|
|
382
|
+
cy: "12",
|
|
383
|
+
r: "9"
|
|
384
|
+
}),
|
|
385
|
+
jsx("path", { d: "M12 11v5" }),
|
|
386
|
+
jsx("path", { d: "M12 8h.01" })
|
|
387
|
+
];
|
|
388
|
+
case "export-pdf": return [
|
|
389
|
+
jsx("path", { d: "M14 3v4a2 2 0 0 0 2 2h4" }),
|
|
390
|
+
jsx("path", { d: "M5 3h9l6 6v12H5z" }),
|
|
391
|
+
jsx("path", { d: "M8 15h8" }),
|
|
392
|
+
jsx("path", { d: "M8 18h5" })
|
|
393
|
+
];
|
|
394
|
+
case "export-png": return [
|
|
395
|
+
jsx("rect", {
|
|
396
|
+
x: "4",
|
|
397
|
+
y: "5",
|
|
398
|
+
width: "16",
|
|
399
|
+
height: "14",
|
|
400
|
+
rx: "2"
|
|
401
|
+
}),
|
|
402
|
+
jsx("path", { d: "M8 14l2.5-2.5L14 15l2-2 2 2" }),
|
|
403
|
+
jsx("circle", {
|
|
404
|
+
cx: "9",
|
|
405
|
+
cy: "9",
|
|
406
|
+
r: "1"
|
|
407
|
+
})
|
|
408
|
+
];
|
|
409
|
+
}
|
|
400
410
|
}
|
|
401
|
-
|
|
402
|
-
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region src/server/paths.ts
|
|
413
|
+
/** Creates the canonical route map used by routers, controls, and app code. */
|
|
403
414
|
function createDeckPaths(mountPath, slug) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
415
|
+
const mount = normalizeMountPath(mountPath);
|
|
416
|
+
const viewer = `${mount === "/" ? "" : mount}/${encodeURIComponent(slug)}`;
|
|
417
|
+
return {
|
|
418
|
+
viewer,
|
|
419
|
+
render: `${viewer}/render`,
|
|
420
|
+
print: `${viewer}/print`,
|
|
421
|
+
presentation: `${viewer}/presentation`,
|
|
422
|
+
presenter: `${viewer}/presenter`,
|
|
423
|
+
embed: `${viewer}/embed`,
|
|
424
|
+
exportPdf: `${viewer}/export.pdf`,
|
|
425
|
+
exportPng: `${viewer}/export.png`,
|
|
426
|
+
ogImage: `${viewer}/og.png`,
|
|
427
|
+
assets: `${viewer}/assets`
|
|
428
|
+
};
|
|
418
429
|
}
|
|
430
|
+
/** Normalizes a configured mount path to one leading slash and no trailing slash. */
|
|
419
431
|
function normalizeMountPath(value) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
432
|
+
const trimmed = value.trim();
|
|
433
|
+
if (!trimmed || trimmed === "/") return "/";
|
|
434
|
+
return `/${trimmed.replace(/^\/+|\/+$/g, "")}`;
|
|
423
435
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
// src/server/viewer-script.ts
|
|
430
|
-
var VIEWER_STATE_MESSAGE_TYPE = "hono-decks:state";
|
|
431
|
-
var VIEWER_COMMAND_MESSAGE_TYPE = "hono-decks:command";
|
|
436
|
+
//#endregion
|
|
437
|
+
//#region src/server/viewer-script.ts
|
|
438
|
+
const VIEWER_STATE_MESSAGE_TYPE = "hono-decks:state";
|
|
439
|
+
const VIEWER_COMMAND_MESSAGE_TYPE = "hono-decks:command";
|
|
432
440
|
function renderViewerScript(nonce) {
|
|
433
|
-
|
|
434
|
-
return `<script data-hono-decks-viewer-runtime${nonceAttribute}>
|
|
441
|
+
return `<script data-hono-decks-viewer-runtime${nonce ? ` nonce="${escapeHtml$1(nonce)}"` : ""}>
|
|
435
442
|
(() => {
|
|
436
443
|
const roots = Array.from(document.querySelectorAll("[data-hono-decks-viewer]"));
|
|
437
444
|
const runtime = window.__honoDecksViewerRuntime ??= { controllers: new Map(), globalInitialized: false };
|
|
@@ -618,17 +625,17 @@ function renderViewerScript(nonce) {
|
|
|
618
625
|
});
|
|
619
626
|
}
|
|
620
627
|
})();
|
|
621
|
-
|
|
628
|
+
<\/script>`;
|
|
622
629
|
}
|
|
623
|
-
function escapeHtml(value) {
|
|
624
|
-
|
|
630
|
+
function escapeHtml$1(value) {
|
|
631
|
+
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
625
632
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
633
|
+
//#endregion
|
|
634
|
+
//#region src/server/viewer-style.ts
|
|
635
|
+
const VIEWER_ASPECT_RATIO = "16/9";
|
|
629
636
|
function embeddedViewerStyle() {
|
|
630
|
-
|
|
631
|
-
|
|
637
|
+
const root = "[data-hono-decks-viewer][data-hono-decks-embed]";
|
|
638
|
+
return `${root}{color-scheme:dark;background:#050816;color:#eef2ff;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;display:grid;gap:12px;width:100%;min-width:0;box-sizing:border-box}
|
|
632
639
|
${root} *:focus-visible{outline:none}
|
|
633
640
|
${root} .hono-decks-viewer-shell{display:grid;grid-template-rows:minmax(0,1fr) auto;place-items:center;width:100%;min-width:0;min-height:0;box-sizing:border-box}
|
|
634
641
|
${root} .hono-decks-viewer-stage{display:grid;place-items:center;width:100%;min-width:0;min-height:0;container-type:inline-size}
|
|
@@ -649,423 +656,454 @@ ${root} .hono-decks-control-icon{width:16px;height:16px;flex:0 0 auto;stroke:cur
|
|
|
649
656
|
${root} .hono-decks-viewer-toc button{font:inherit}
|
|
650
657
|
@media (prefers-reduced-motion: reduce){${root},${root} *{scroll-behavior:auto!important;animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}}`;
|
|
651
658
|
}
|
|
652
|
-
|
|
653
|
-
|
|
659
|
+
//#endregion
|
|
660
|
+
//#region src/server/viewer.ts
|
|
654
661
|
async function createDeckViewerParts(input) {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
662
|
+
const slug = input.deck.slug;
|
|
663
|
+
const title = input.deck.meta.title ?? slug;
|
|
664
|
+
const basePath = input.mountPath.replace(/\/$/, "");
|
|
665
|
+
const paths = createDeckPaths(basePath, slug);
|
|
666
|
+
const imagePath = await resolveOpenGraphImagePath(input.openGraph, {
|
|
667
|
+
deck: input.deck,
|
|
668
|
+
paths
|
|
669
|
+
});
|
|
670
|
+
const renderUrl = `${paths.render}${input.viewerStateQuery ?? ""}`;
|
|
671
|
+
const slides = createDeckToc(input.deck);
|
|
672
|
+
const meta = {
|
|
673
|
+
title,
|
|
674
|
+
description: input.deck.meta.description,
|
|
675
|
+
paths,
|
|
676
|
+
availablePages: { print: input.availablePages?.print !== false },
|
|
677
|
+
availableExports: input.exportPaths ?? {},
|
|
678
|
+
...imagePath ? { imagePath } : {}
|
|
679
|
+
};
|
|
680
|
+
const controlsInput = input.controls === false ? false : input.controls ?? {};
|
|
681
|
+
const controls = controlsInput === false ? null : renderViewerControls(controlsInput, {
|
|
682
|
+
slug,
|
|
683
|
+
title,
|
|
684
|
+
mountPath: basePath,
|
|
685
|
+
meta,
|
|
686
|
+
slides
|
|
687
|
+
});
|
|
688
|
+
return {
|
|
689
|
+
slug,
|
|
690
|
+
title,
|
|
691
|
+
renderUrl,
|
|
692
|
+
frame: {
|
|
693
|
+
content: renderViewerFrame({
|
|
694
|
+
title,
|
|
695
|
+
renderUrl
|
|
696
|
+
}),
|
|
697
|
+
html: renderViewerFrameHtml({
|
|
698
|
+
title,
|
|
699
|
+
renderUrl
|
|
700
|
+
})
|
|
701
|
+
},
|
|
702
|
+
controls: controls ? {
|
|
703
|
+
content: controls,
|
|
704
|
+
html: await renderJsxValue(controls)
|
|
705
|
+
} : null,
|
|
706
|
+
toc: {
|
|
707
|
+
content: renderViewerToc(slides),
|
|
708
|
+
html: renderViewerTocHtml(slides)
|
|
709
|
+
},
|
|
710
|
+
slides,
|
|
711
|
+
meta
|
|
712
|
+
};
|
|
686
713
|
}
|
|
687
714
|
async function createDeckViewerEmbed(input) {
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
return {
|
|
708
|
-
...parts,
|
|
709
|
-
embed: raw(embedHtml),
|
|
710
|
-
embedHtml
|
|
711
|
-
};
|
|
715
|
+
const parts = await createDeckViewerParts(input);
|
|
716
|
+
const rootHtml = await renderJsxValue(jsx("section", {
|
|
717
|
+
class: ["hono-decks-embedded-viewer", input.className].filter(Boolean).join(" "),
|
|
718
|
+
"data-hono-decks-viewer": true,
|
|
719
|
+
"data-hono-decks-embed": true,
|
|
720
|
+
"data-deck-slug": parts.slug,
|
|
721
|
+
...parts.meta.availablePages.print ? { "data-hono-decks-print-path": parts.meta.paths.print } : {},
|
|
722
|
+
"aria-label": parts.title,
|
|
723
|
+
children: [jsx("div", {
|
|
724
|
+
class: "hono-decks-viewer-shell",
|
|
725
|
+
children: [parts.frame.content, parts.controls?.content]
|
|
726
|
+
}), input.toc ? parts.toc.content : null]
|
|
727
|
+
}));
|
|
728
|
+
const embedHtml = `<style data-hono-decks-embed-style${input.nonce ? ` nonce="${escapeHtml(input.nonce)}"` : ""}>${embeddedViewerStyle()}${input.style ?? ""}</style>${rootHtml}${renderViewerScript(input.nonce)}`;
|
|
729
|
+
return {
|
|
730
|
+
...parts,
|
|
731
|
+
embed: raw(embedHtml),
|
|
732
|
+
embedHtml
|
|
733
|
+
};
|
|
712
734
|
}
|
|
713
735
|
async function resolveOpenGraphImagePath(options, input) {
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
736
|
+
if (!options) return void 0;
|
|
737
|
+
if (options === true) return input.paths.ogImage;
|
|
738
|
+
if (typeof options.imagePath === "function") return options.imagePath(input);
|
|
739
|
+
return options.imagePath ?? input.paths.ogImage;
|
|
718
740
|
}
|
|
719
741
|
function createDeckToc(deck) {
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
742
|
+
return deck.slides.map((slide) => ({
|
|
743
|
+
index: slide.index,
|
|
744
|
+
title: slide.meta.title,
|
|
745
|
+
label: slide.meta.title ?? `Slide ${slide.index + 1}`
|
|
746
|
+
}));
|
|
725
747
|
}
|
|
726
748
|
function renderViewerFrame(input) {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
749
|
+
return jsx("div", {
|
|
750
|
+
class: "hono-decks-viewer-stage",
|
|
751
|
+
"data-hono-decks-frame": true,
|
|
752
|
+
children: jsx("div", {
|
|
753
|
+
class: "hono-decks-viewport",
|
|
754
|
+
"data-viewer-viewport": true,
|
|
755
|
+
tabindex: "0",
|
|
756
|
+
children: [
|
|
757
|
+
jsx("div", {
|
|
758
|
+
class: "hono-decks-frame-stage",
|
|
759
|
+
"data-viewer-stage": true,
|
|
760
|
+
children: jsx("iframe", {
|
|
761
|
+
title: input.title,
|
|
762
|
+
src: input.renderUrl
|
|
763
|
+
})
|
|
764
|
+
}),
|
|
765
|
+
jsx("button", {
|
|
766
|
+
class: "hono-decks-viewer-navigation-layer hono-decks-viewer-navigation-previous",
|
|
767
|
+
type: "button",
|
|
768
|
+
"data-viewer-navigation": "previous",
|
|
769
|
+
"aria-label": "Previous slide"
|
|
770
|
+
}),
|
|
771
|
+
jsx("button", {
|
|
772
|
+
class: "hono-decks-viewer-navigation-layer hono-decks-viewer-navigation-next",
|
|
773
|
+
type: "button",
|
|
774
|
+
"data-viewer-navigation": "next",
|
|
775
|
+
"aria-label": "Next slide"
|
|
776
|
+
})
|
|
777
|
+
]
|
|
778
|
+
})
|
|
779
|
+
});
|
|
758
780
|
}
|
|
759
781
|
function renderViewerFrameHtml(input) {
|
|
760
|
-
|
|
782
|
+
return `<div class="hono-decks-viewer-stage" data-hono-decks-frame><div class="hono-decks-viewport" data-viewer-viewport tabindex="0"><div class="hono-decks-frame-stage" data-viewer-stage><iframe title="${escapeHtml(input.title)}" src="${escapeHtml(input.renderUrl)}"></iframe></div><button class="hono-decks-viewer-navigation-layer hono-decks-viewer-navigation-previous" type="button" data-viewer-navigation="previous" aria-label="Previous slide"></button><button class="hono-decks-viewer-navigation-layer hono-decks-viewer-navigation-next" type="button" data-viewer-navigation="next" aria-label="Next slide"></button></div></div>`;
|
|
761
783
|
}
|
|
762
784
|
function renderViewerControls(options, context) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
785
|
+
return jsx("nav", {
|
|
786
|
+
...controlAttributes(options.attributes),
|
|
787
|
+
class: controlsClassName(options),
|
|
788
|
+
"data-hono-decks-viewer-controls": true,
|
|
789
|
+
"aria-label": options.ariaLabel ?? "Viewer controls",
|
|
790
|
+
children: resolveViewerControlItems(options, context).map((item) => renderViewerControlItem(item, options, context))
|
|
791
|
+
});
|
|
770
792
|
}
|
|
771
793
|
function renderViewerToc(slides) {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
children: slide.label
|
|
784
|
-
})
|
|
785
|
-
})
|
|
786
|
-
)
|
|
787
|
-
})
|
|
788
|
-
});
|
|
794
|
+
return jsx("nav", {
|
|
795
|
+
class: "hono-decks-viewer-toc",
|
|
796
|
+
"data-hono-decks-toc": true,
|
|
797
|
+
"aria-label": "Slide navigation",
|
|
798
|
+
children: jsx("ol", { children: slides.map((slide) => jsx("li", { children: jsx("button", {
|
|
799
|
+
type: "button",
|
|
800
|
+
"data-action": "goTo",
|
|
801
|
+
"data-slide-index": String(slide.index),
|
|
802
|
+
children: slide.label
|
|
803
|
+
}) })) })
|
|
804
|
+
});
|
|
789
805
|
}
|
|
790
806
|
function renderViewerTocHtml(slides) {
|
|
791
|
-
|
|
792
|
-
(slide) => `<li><button type="button" data-action="goTo" data-slide-index="${slide.index}">${escapeHtml2(slide.label)}</button></li>`
|
|
793
|
-
).join("");
|
|
794
|
-
return `<nav class="hono-decks-viewer-toc" data-hono-decks-toc aria-label="Slide navigation"><ol>${items}</ol></nav>`;
|
|
807
|
+
return `<nav class="hono-decks-viewer-toc" data-hono-decks-toc aria-label="Slide navigation"><ol>${slides.map((slide) => `<li><button type="button" data-action="goTo" data-slide-index="${slide.index}">${escapeHtml(slide.label)}</button></li>`).join("")}</ol></nav>`;
|
|
795
808
|
}
|
|
796
|
-
function
|
|
797
|
-
|
|
809
|
+
function escapeHtml(value) {
|
|
810
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """);
|
|
798
811
|
}
|
|
799
812
|
function safeFilename(value) {
|
|
800
|
-
|
|
801
|
-
return normalized || "deck";
|
|
813
|
+
return value.trim().replaceAll(/[^a-zA-Z0-9._-]+/g, "-").replaceAll(/^-+|-+$/g, "") || "deck";
|
|
802
814
|
}
|
|
803
815
|
function buildViewerControlDefaults(context) {
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
816
|
+
return {
|
|
817
|
+
back: {
|
|
818
|
+
type: "default",
|
|
819
|
+
key: "back"
|
|
820
|
+
},
|
|
821
|
+
previous: {
|
|
822
|
+
type: "default",
|
|
823
|
+
key: "previous"
|
|
824
|
+
},
|
|
825
|
+
position: {
|
|
826
|
+
type: "default",
|
|
827
|
+
key: "position"
|
|
828
|
+
},
|
|
829
|
+
next: {
|
|
830
|
+
type: "default",
|
|
831
|
+
key: "next"
|
|
832
|
+
},
|
|
833
|
+
fullscreen: {
|
|
834
|
+
type: "default",
|
|
835
|
+
key: "fullscreen"
|
|
836
|
+
},
|
|
837
|
+
print: context.meta.availablePages.print ? {
|
|
838
|
+
type: "default",
|
|
839
|
+
key: "print"
|
|
840
|
+
} : null,
|
|
841
|
+
exportPdf: context.meta.availableExports.pdf ? {
|
|
842
|
+
type: "default",
|
|
843
|
+
key: "exportPdf"
|
|
844
|
+
} : null,
|
|
845
|
+
exportPng: context.meta.availableExports.png ? {
|
|
846
|
+
type: "default",
|
|
847
|
+
key: "exportPng"
|
|
848
|
+
} : null
|
|
849
|
+
};
|
|
814
850
|
}
|
|
815
851
|
function resolveViewerControlItems(options, context) {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
return items.filter((item) => Boolean(item)).map((item) => applyViewerControlLabels(item, options.labels));
|
|
852
|
+
const defaults = buildViewerControlDefaults(context);
|
|
853
|
+
const baseItems = [
|
|
854
|
+
defaults.back,
|
|
855
|
+
defaults.previous,
|
|
856
|
+
defaults.position,
|
|
857
|
+
defaults.next,
|
|
858
|
+
defaults.fullscreen,
|
|
859
|
+
defaults.print,
|
|
860
|
+
defaults.exportPdf,
|
|
861
|
+
defaults.exportPng
|
|
862
|
+
];
|
|
863
|
+
return (typeof options.items === "function" ? options.items(defaults, context) : options.items ?? [
|
|
864
|
+
...resolveViewerControlSlotItems(options.before, context),
|
|
865
|
+
...filterHiddenDefaultItems(baseItems, options.hidden),
|
|
866
|
+
...resolveViewerControlSlotItems(options.after, context)
|
|
867
|
+
]).filter((item) => Boolean(item)).map((item) => applyViewerControlLabels(item, options.labels));
|
|
833
868
|
}
|
|
834
869
|
function renderViewerControlItem(item, options, context) {
|
|
835
|
-
|
|
836
|
-
|
|
870
|
+
const renderDefault = () => renderBaseViewerControlItem(item, options, context);
|
|
871
|
+
return options.renderItem?.(item, context, renderDefault) ?? renderDefault();
|
|
837
872
|
}
|
|
838
873
|
function renderBaseViewerControlItem(item, options, context) {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
874
|
+
if (item.type === "link") {
|
|
875
|
+
const ariaLabel = item.icon ? String(item.attributes?.["aria-label"] ?? item.label) : void 0;
|
|
876
|
+
return jsx("a", {
|
|
877
|
+
...linkAttributes(item.attributes),
|
|
878
|
+
...safeHref(item.href) ? { href: safeHref(item.href) } : {},
|
|
879
|
+
...item.download ? { download: item.download } : {},
|
|
880
|
+
...classAttribute(options.itemClassName, item.className),
|
|
881
|
+
...item.icon ? {
|
|
882
|
+
"aria-label": ariaLabel,
|
|
883
|
+
title: ariaLabel
|
|
884
|
+
} : {},
|
|
885
|
+
children: item.icon ? renderControlIcon(item.icon) : item.label
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
if (item.type === "render") return item.render({ context });
|
|
889
|
+
return renderDefaultViewerControlItem(item, options, context);
|
|
854
890
|
}
|
|
855
891
|
function renderDefaultViewerControlItem(item, options, context) {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
892
|
+
const itemProps = {
|
|
893
|
+
...linkAttributes(item.attributes),
|
|
894
|
+
...classAttribute(options.itemClassName, item.className)
|
|
895
|
+
};
|
|
896
|
+
switch (item.key) {
|
|
897
|
+
case "back": return jsx("a", {
|
|
898
|
+
...itemProps,
|
|
899
|
+
href: context.mountPath,
|
|
900
|
+
"data-hono-decks-back-link": true,
|
|
901
|
+
...item.label === void 0 ? {
|
|
902
|
+
"aria-label": controlIconLabel("deck-list"),
|
|
903
|
+
title: controlIconLabel("deck-list")
|
|
904
|
+
} : {},
|
|
905
|
+
children: item.label ?? renderControlIcon("deck-list")
|
|
906
|
+
});
|
|
907
|
+
case "previous": return renderIconButton("previous", item, itemProps);
|
|
908
|
+
case "position": return jsx("span", {
|
|
909
|
+
...itemProps,
|
|
910
|
+
"data-slide-position": true,
|
|
911
|
+
"data-hono-decks-position": true,
|
|
912
|
+
children: item.label ?? "1 / ?"
|
|
913
|
+
});
|
|
914
|
+
case "next": return renderIconButton("next", item, itemProps);
|
|
915
|
+
case "fullscreen": return renderIconButton("fullscreen", item, itemProps);
|
|
916
|
+
case "print": return jsx("a", {
|
|
917
|
+
...itemProps,
|
|
918
|
+
href: context.meta.paths.print,
|
|
919
|
+
"data-hono-decks-print": true,
|
|
920
|
+
...item.label === void 0 ? {
|
|
921
|
+
"aria-label": controlIconLabel("print"),
|
|
922
|
+
title: controlIconLabel("print")
|
|
923
|
+
} : {},
|
|
924
|
+
children: item.label ?? renderControlIcon("print")
|
|
925
|
+
});
|
|
926
|
+
case "exportPdf": return jsx("a", {
|
|
927
|
+
...itemProps,
|
|
928
|
+
href: context.meta.paths.exportPdf,
|
|
929
|
+
download: `${safeFilename(context.meta.title)}.pdf`,
|
|
930
|
+
"data-hono-decks-export": "pdf",
|
|
931
|
+
...item.label === void 0 ? {
|
|
932
|
+
"aria-label": controlIconLabel("export-pdf"),
|
|
933
|
+
title: controlIconLabel("export-pdf")
|
|
934
|
+
} : {},
|
|
935
|
+
children: item.label ?? renderControlIcon("export-pdf")
|
|
936
|
+
});
|
|
937
|
+
case "exportPng": return jsx("a", {
|
|
938
|
+
...itemProps,
|
|
939
|
+
href: context.meta.paths.exportPng,
|
|
940
|
+
download: `${safeFilename(context.meta.title)}.png`,
|
|
941
|
+
"data-hono-decks-export": "png",
|
|
942
|
+
...item.label === void 0 ? {
|
|
943
|
+
"aria-label": controlIconLabel("export-png"),
|
|
944
|
+
title: controlIconLabel("export-png")
|
|
945
|
+
} : {},
|
|
946
|
+
children: item.label ?? renderControlIcon("export-png")
|
|
947
|
+
});
|
|
948
|
+
}
|
|
909
949
|
}
|
|
910
950
|
function renderIconButton(action, item, itemProps) {
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
951
|
+
const iconName = controlIconNameForKey(action);
|
|
952
|
+
const label = controlIconLabel(iconName);
|
|
953
|
+
return jsx("button", {
|
|
954
|
+
...itemProps,
|
|
955
|
+
type: "button",
|
|
956
|
+
"data-action": action,
|
|
957
|
+
"data-hono-decks-navigation-control": action,
|
|
958
|
+
...item.label === void 0 ? {
|
|
959
|
+
"aria-label": label,
|
|
960
|
+
title: label
|
|
961
|
+
} : {},
|
|
962
|
+
children: item.label ?? renderControlIcon(iconName)
|
|
963
|
+
});
|
|
921
964
|
}
|
|
922
965
|
function controlIconNameForKey(key) {
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
return "print";
|
|
934
|
-
case "exportPdf":
|
|
935
|
-
return "export-pdf";
|
|
936
|
-
case "exportPng":
|
|
937
|
-
return "export-png";
|
|
938
|
-
case "position":
|
|
939
|
-
return "viewer";
|
|
940
|
-
}
|
|
966
|
+
switch (key) {
|
|
967
|
+
case "back": return "deck-list";
|
|
968
|
+
case "previous": return "previous";
|
|
969
|
+
case "next": return "next";
|
|
970
|
+
case "fullscreen": return "fullscreen";
|
|
971
|
+
case "print": return "print";
|
|
972
|
+
case "exportPdf": return "export-pdf";
|
|
973
|
+
case "exportPng": return "export-png";
|
|
974
|
+
case "position": return "viewer";
|
|
975
|
+
}
|
|
941
976
|
}
|
|
942
977
|
function controlsClassName(options) {
|
|
943
|
-
|
|
978
|
+
return ["hono-decks-viewer-controls", options.className].filter(Boolean).join(" ");
|
|
944
979
|
}
|
|
945
980
|
function resolveViewerControlSlotItems(items, context) {
|
|
946
|
-
|
|
981
|
+
return typeof items === "function" ? items(context) : items ?? [];
|
|
947
982
|
}
|
|
948
983
|
function filterHiddenDefaultItems(items, hidden) {
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
984
|
+
if (!hidden?.length) return items;
|
|
985
|
+
const hiddenKeys = new Set(hidden);
|
|
986
|
+
return items.filter((item) => !item || item.type !== "default" || !hiddenKeys.has(item.key));
|
|
952
987
|
}
|
|
953
988
|
function applyViewerControlLabels(item, labels) {
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
989
|
+
if (item.type !== "default" || item.label !== void 0) return item;
|
|
990
|
+
const label = labels?.[item.key];
|
|
991
|
+
return label === void 0 ? item : {
|
|
992
|
+
...item,
|
|
993
|
+
label
|
|
994
|
+
};
|
|
957
995
|
}
|
|
958
996
|
function linkAttributes(attributes) {
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
997
|
+
const props = {};
|
|
998
|
+
for (const [name, value] of Object.entries(attributes ?? {})) {
|
|
999
|
+
if (!isSafeAttributeName(name) || value === false || value === void 0) continue;
|
|
1000
|
+
props[name] = value;
|
|
1001
|
+
}
|
|
1002
|
+
return props;
|
|
965
1003
|
}
|
|
966
1004
|
function controlAttributes(attributes) {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1005
|
+
const props = linkAttributes(attributes);
|
|
1006
|
+
delete props.class;
|
|
1007
|
+
delete props["aria-label"];
|
|
1008
|
+
delete props["data-hono-decks-viewer-controls"];
|
|
1009
|
+
return props;
|
|
972
1010
|
}
|
|
973
1011
|
function classAttribute(...classNames) {
|
|
974
|
-
|
|
975
|
-
|
|
1012
|
+
const className = classNames.filter(Boolean).join(" ");
|
|
1013
|
+
return className ? { class: className } : {};
|
|
976
1014
|
}
|
|
977
1015
|
function isSafeAttributeName(value) {
|
|
978
|
-
|
|
1016
|
+
return /^[A-Za-z_:][A-Za-z0-9:_.-]*$/.test(value) && !/^on/i.test(value);
|
|
979
1017
|
}
|
|
980
1018
|
function safeHref(value) {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1019
|
+
const trimmed = value.trim();
|
|
1020
|
+
if (trimmed.length === 0) return void 0;
|
|
1021
|
+
if (/^(https?:|mailto:|tel:)/i.test(trimmed)) return value;
|
|
1022
|
+
if (/^(javascript:|data:|vbscript:)/i.test(trimmed)) return void 0;
|
|
1023
|
+
if (/^[^/?#.]+:/i.test(trimmed)) return void 0;
|
|
1024
|
+
return value;
|
|
987
1025
|
}
|
|
988
|
-
|
|
989
|
-
|
|
1026
|
+
//#endregion
|
|
1027
|
+
//#region src/server/define-decks.ts
|
|
1028
|
+
/** Defines the single configuration consumed by the CLI and runtime. */
|
|
990
1029
|
function defineDecksConfig(config) {
|
|
991
|
-
|
|
1030
|
+
return config;
|
|
992
1031
|
}
|
|
993
|
-
|
|
994
|
-
|
|
1032
|
+
//#endregion
|
|
1033
|
+
//#region src/source/r2-assets.ts
|
|
995
1034
|
function withR2Assets(source, options) {
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1035
|
+
return {
|
|
1036
|
+
async listDecks(c) {
|
|
1037
|
+
return source.listDecks(c);
|
|
1038
|
+
},
|
|
1039
|
+
async getCompiledDeck(c, slug) {
|
|
1040
|
+
return source.getCompiledDeck(c, slug);
|
|
1041
|
+
},
|
|
1042
|
+
async getAsset(c, slug, assetPath) {
|
|
1043
|
+
const deck = await source.getCompiledDeck(c, slug);
|
|
1044
|
+
const asset = deck ? findRoutableAsset(deck.assets, slug, assetPath) : void 0;
|
|
1045
|
+
const bucket = asset ? await resolveBucket(options.bucket, c) : void 0;
|
|
1046
|
+
if (deck && asset && bucket) {
|
|
1047
|
+
const object = await bucket.get(resolveR2Key({
|
|
1048
|
+
deck,
|
|
1049
|
+
asset,
|
|
1050
|
+
slug,
|
|
1051
|
+
assetPath
|
|
1052
|
+
}, options));
|
|
1053
|
+
if (object) {
|
|
1054
|
+
const response = await responseFromR2Object(object, {
|
|
1055
|
+
deck,
|
|
1056
|
+
asset,
|
|
1057
|
+
slug,
|
|
1058
|
+
assetPath
|
|
1059
|
+
}, options);
|
|
1060
|
+
if (response) return response;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
return source.getAsset?.(c, slug, assetPath) ?? null;
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1017
1066
|
}
|
|
1018
1067
|
async function resolveBucket(bucket, c) {
|
|
1019
|
-
|
|
1068
|
+
return typeof bucket === "function" ? bucket(c) : bucket;
|
|
1020
1069
|
}
|
|
1021
1070
|
function findRoutableAsset(assets, slug, assetPath) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1071
|
+
const normalized = assetPath.replace(/^\/+/, "");
|
|
1072
|
+
return assets.find((asset) => {
|
|
1073
|
+
if (asset.type !== "local" && asset.type !== "r2") return false;
|
|
1074
|
+
const suffix = `/${slug}/assets/${normalized}`;
|
|
1075
|
+
return asset.publicPath.endsWith(suffix);
|
|
1076
|
+
});
|
|
1028
1077
|
}
|
|
1029
1078
|
function resolveR2Key(input, options) {
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1079
|
+
if (options.key) return options.key(input);
|
|
1080
|
+
if (input.asset.r2Key) return input.asset.r2Key;
|
|
1081
|
+
const key = input.asset.sourcePath || `${input.slug}/assets/${input.assetPath}`;
|
|
1082
|
+
const prefix = options.keyPrefix?.replace(/\/+$/, "");
|
|
1083
|
+
return prefix ? `${prefix}/${key.replace(/^\/+/, "")}` : key.replace(/^\/+/, "");
|
|
1035
1084
|
}
|
|
1036
1085
|
async function responseFromR2Object(object, input, options) {
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
headers.set("cache-control", input.asset.cacheControl);
|
|
1048
|
-
}
|
|
1049
|
-
return new Response(body, { headers });
|
|
1086
|
+
const body = object.body ?? (object.arrayBuffer ? await object.arrayBuffer() : void 0);
|
|
1087
|
+
if (body == null) return null;
|
|
1088
|
+
const headers = new Headers();
|
|
1089
|
+
object.writeHttpMetadata?.(headers);
|
|
1090
|
+
applyHttpMetadata(headers, object.httpMetadata);
|
|
1091
|
+
if (!headers.has("content-type") && input.asset.contentType) headers.set("content-type", input.asset.contentType);
|
|
1092
|
+
const cacheControl = resolveCacheControl(input, options);
|
|
1093
|
+
if (cacheControl) headers.set("cache-control", cacheControl);
|
|
1094
|
+
else if (cacheControl !== false && input.asset.cacheControl && !headers.has("cache-control")) headers.set("cache-control", input.asset.cacheControl);
|
|
1095
|
+
return new Response(body, { headers });
|
|
1050
1096
|
}
|
|
1051
1097
|
function applyHttpMetadata(headers, metadata) {
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
if (metadata.contentEncoding && !headers.has("content-encoding")) headers.set("content-encoding", metadata.contentEncoding);
|
|
1059
|
-
if (metadata.contentLanguage && !headers.has("content-language")) headers.set("content-language", metadata.contentLanguage);
|
|
1098
|
+
if (!metadata) return;
|
|
1099
|
+
if (metadata.contentType && !headers.has("content-type")) headers.set("content-type", metadata.contentType);
|
|
1100
|
+
if (metadata.cacheControl && !headers.has("cache-control")) headers.set("cache-control", metadata.cacheControl);
|
|
1101
|
+
if (metadata.contentDisposition && !headers.has("content-disposition")) headers.set("content-disposition", metadata.contentDisposition);
|
|
1102
|
+
if (metadata.contentEncoding && !headers.has("content-encoding")) headers.set("content-encoding", metadata.contentEncoding);
|
|
1103
|
+
if (metadata.contentLanguage && !headers.has("content-language")) headers.set("content-language", metadata.contentLanguage);
|
|
1060
1104
|
}
|
|
1061
1105
|
function resolveCacheControl(input, options) {
|
|
1062
|
-
|
|
1106
|
+
return typeof options.cacheControl === "function" ? options.cacheControl(input) : options.cacheControl;
|
|
1063
1107
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
createDeckPaths,
|
|
1067
|
-
createDeckViewerEmbed,
|
|
1068
|
-
defineDecksConfig,
|
|
1069
|
-
defineSlideComponents,
|
|
1070
|
-
withR2Assets
|
|
1071
|
-
};
|
|
1108
|
+
//#endregion
|
|
1109
|
+
export { SLIDE_TRANSITIONS, createDeckPaths, createDeckViewerEmbed, defineDecksConfig, defineSlideComponents, withR2Assets };
|