@stream-mdx/react 0.5.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +371 -0
- package/README.md +79 -4
- package/dist/blocks-renderer-DAOBFBfi.d.ts +29 -0
- package/dist/blocks-renderer-DQEL1kJW.d.cts +29 -0
- package/dist/components/bottom-stick-scroll-area.cjs +117 -193
- package/dist/components/bottom-stick-scroll-area.mjs +112 -183
- package/dist/components/diff-renderer.cjs +86 -0
- package/dist/components/diff-renderer.d.cts +11 -0
- package/dist/components/diff-renderer.d.ts +11 -0
- package/dist/components/diff-renderer.mjs +66 -0
- package/dist/components/index.cjs +2761 -1508
- package/dist/components/index.d.cts +7 -2
- package/dist/components/index.d.ts +7 -2
- package/dist/components/index.mjs +2730 -1493
- package/dist/components/katex-math.cjs +220 -0
- package/dist/components/katex-math.d.cts +10 -0
- package/dist/components/katex-math.d.ts +10 -0
- package/dist/components/katex-math.mjs +188 -0
- package/dist/contexts/math-tracker.cjs +240 -521
- package/dist/contexts/math-tracker.mjs +235 -513
- package/dist/index-Cmne1yUK.d.cts +723 -0
- package/dist/index-D7dyyu3q.d.ts +723 -0
- package/dist/index.cjs +13029 -6475
- package/dist/index.d.cts +69 -39
- package/dist/index.d.ts +69 -39
- package/dist/index.mjs +13007 -6442
- package/dist/math/display-wrapper.cjs +7 -15
- package/dist/math/display-wrapper.d.cts +2 -2
- package/dist/math/display-wrapper.d.ts +2 -2
- package/dist/math/display-wrapper.mjs +2 -6
- package/dist/node-views-Bpc6Gkgl.d.cts +13 -0
- package/dist/node-views-DpnYdaAS.d.ts +13 -0
- package/dist/renderer/hooks.cjs +35 -20
- package/dist/renderer/hooks.d.cts +22 -1
- package/dist/renderer/hooks.d.ts +22 -1
- package/dist/renderer/hooks.mjs +27 -12
- package/dist/renderer/patch-batching.cjs +5 -8
- package/dist/renderer/patch-coalescing.cjs +5 -8
- package/dist/renderer/patch-commit-scheduler.cjs +138 -356
- package/dist/renderer/patch-commit-scheduler.d.cts +13 -1
- package/dist/renderer/patch-commit-scheduler.d.ts +13 -1
- package/dist/renderer/patch-commit-scheduler.mjs +133 -348
- package/dist/renderer/store.cjs +3775 -1373
- package/dist/renderer/store.d.cts +108 -3
- package/dist/renderer/store.d.ts +108 -3
- package/dist/renderer/store.mjs +3778 -1362
- package/dist/renderer/virtualized-code.cjs +415 -71
- package/dist/renderer/virtualized-code.d.cts +24 -23
- package/dist/renderer/virtualized-code.d.ts +24 -23
- package/dist/renderer/virtualized-code.mjs +409 -62
- package/dist/renderer.cjs +10655 -4334
- package/dist/renderer.d.cts +98 -29
- package/dist/renderer.d.ts +98 -29
- package/dist/renderer.mjs +10582 -4212
- package/dist/server-regions-CPLHGli0.d.cts +32 -0
- package/dist/server-regions-mUhyoKi7.d.ts +32 -0
- package/dist/server.cjs +10195 -3872
- package/dist/server.d.cts +17 -252
- package/dist/server.d.ts +17 -252
- package/dist/server.mjs +9997 -3649
- package/dist/{streaming-markdown-CEI9eDZm.d.ts → streaming-markdown-yELbJxyH.d.ts} +49 -55
- package/dist/{streaming-markdown-DRisClXb.d.cts → streaming-markdown-zVwFuaJG.d.cts} +49 -55
- package/dist/streaming-markdown.cjs +11660 -5378
- package/dist/streaming-markdown.d.cts +7 -2
- package/dist/streaming-markdown.d.ts +7 -2
- package/dist/streaming-markdown.mjs +11679 -5347
- package/dist/trusted-mdx/index.cjs +833 -0
- package/dist/trusted-mdx/index.d.cts +11 -0
- package/dist/trusted-mdx/index.d.ts +11 -0
- package/dist/trusted-mdx/index.mjs +807 -0
- package/dist/trusted-mdx/native-children-slot.cjs +45 -0
- package/dist/trusted-mdx/native-children-slot.d.cts +11 -0
- package/dist/trusted-mdx/native-children-slot.d.ts +11 -0
- package/dist/trusted-mdx/native-children-slot.mjs +24 -0
- package/dist/trusted-mdx/server.cjs +752 -0
- package/dist/trusted-mdx/server.d.cts +24 -0
- package/dist/trusted-mdx/server.d.ts +24 -0
- package/dist/trusted-mdx/server.mjs +724 -0
- package/dist/trusted-mdx-contract-ElKpkDI5.d.cts +113 -0
- package/dist/trusted-mdx-contract-ElKpkDI5.d.ts +113 -0
- package/dist/utils/inline-html.cjs +246 -147
- package/dist/utils/inline-html.d.cts +37 -6
- package/dist/utils/inline-html.d.ts +37 -6
- package/dist/utils/inline-html.mjs +237 -134
- package/package.json +41 -18
- package/dist/index-BVhp_pcF.d.ts +0 -251
- package/dist/index-EaeouYp2.d.cts +0 -251
- package/dist/mdx-client.cjs +0 -408
- package/dist/mdx-client.d.cts +0 -113
- package/dist/mdx-client.d.ts +0 -113
- package/dist/mdx-client.mjs +0 -369
- package/dist/mdx-coordinator.cjs +0 -584
- package/dist/mdx-coordinator.d.cts +0 -21
- package/dist/mdx-coordinator.d.ts +0 -21
- package/dist/mdx-coordinator.mjs +0 -550
- package/dist/renderer/node-views.cjs +0 -1887
- package/dist/renderer/node-views.d.cts +0 -14
- package/dist/renderer/node-views.d.ts +0 -14
- package/dist/renderer/node-views.mjs +0 -1861
|
@@ -1,403 +1,22 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __esm = (fn, res) => function __init() {
|
|
5
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
-
};
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
2
|
|
|
12
|
-
// src/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
22
|
-
import React2 from "react";
|
|
23
|
-
import * as ReactJsxRuntime from "react/jsx-runtime";
|
|
24
|
-
function assignMdxChildKey(child, index) {
|
|
25
|
-
if (child == null) return child;
|
|
26
|
-
if (Array.isArray(child)) {
|
|
27
|
-
return child.map((entry, subIndex) => assignMdxChildKey(entry, `${index}-${subIndex}`));
|
|
28
|
-
}
|
|
29
|
-
if (React2.isValidElement(child)) {
|
|
30
|
-
if (child.key !== null && child.key !== void 0) {
|
|
31
|
-
return child;
|
|
32
|
-
}
|
|
33
|
-
return React2.cloneElement(child, { key: index });
|
|
34
|
-
}
|
|
35
|
-
return child;
|
|
36
|
-
}
|
|
37
|
-
function getMDXClient(compileEndpoint) {
|
|
38
|
-
if (!globalMDXClient) {
|
|
39
|
-
globalMDXClient = new MDXClient(compileEndpoint);
|
|
40
|
-
}
|
|
41
|
-
return globalMDXClient;
|
|
3
|
+
// src/code-fence-streaming.ts
|
|
4
|
+
function trimProvisionalFenceTail(raw) {
|
|
5
|
+
if (raw.endsWith(`
|
|
6
|
+
`)) return raw;
|
|
7
|
+
let opening = raw.match(/^ {0,3}(`{3,}|~{3,})[^\n]*\n/);
|
|
8
|
+
if (!opening) return raw;
|
|
9
|
+
let lastNewline = raw.lastIndexOf(`
|
|
10
|
+
`), tail = raw.slice(lastNewline + 1).match(/^ {0,3}(`+|~+)[\t ]*$/);
|
|
11
|
+
return tail && tail[1][0] === opening[1][0] && tail[1].length < opening[1].length ? raw.slice(0, lastNewline) : raw;
|
|
42
12
|
}
|
|
43
|
-
function getMDXComponentFactory(compileEndpoint) {
|
|
44
|
-
if (!globalComponentFactory) {
|
|
45
|
-
const client = getMDXClient(compileEndpoint);
|
|
46
|
-
globalComponentFactory = new MDXComponentFactory(client);
|
|
47
|
-
}
|
|
48
|
-
return globalComponentFactory;
|
|
49
|
-
}
|
|
50
|
-
function registerMDXComponents(components, options) {
|
|
51
|
-
const factory = getMDXComponentFactory();
|
|
52
|
-
factory.registerComponents(components, options);
|
|
53
|
-
}
|
|
54
|
-
function registerInlineMdxModule(compiled) {
|
|
55
|
-
const factory = getMDXComponentFactory();
|
|
56
|
-
factory.registerInlineModule({
|
|
57
|
-
id: compiled.id,
|
|
58
|
-
code: compiled.code,
|
|
59
|
-
dependencies: compiled.dependencies ?? []
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
var withClassName, MDXClient, MDXComponentFactory, globalMDXClient, globalComponentFactory;
|
|
63
|
-
var init_mdx_client = __esm({
|
|
64
|
-
"src/mdx-client.ts"() {
|
|
65
|
-
"use strict";
|
|
66
|
-
withClassName = (tag, className) => {
|
|
67
|
-
return (props) => React2.createElement(tag, { className, ...props });
|
|
68
|
-
};
|
|
69
|
-
MDXClient = class {
|
|
70
|
-
constructor(compileEndpoint = "/api/mdx-compile-v2") {
|
|
71
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
72
|
-
this.inlineModules = /* @__PURE__ */ new Map();
|
|
73
|
-
this.compiledCache = /* @__PURE__ */ new Map();
|
|
74
|
-
this.compiledInflight = /* @__PURE__ */ new Map();
|
|
75
|
-
this.compileEndpoint = compileEndpoint;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Compile MDX block on server
|
|
79
|
-
*/
|
|
80
|
-
async compile(block) {
|
|
81
|
-
if (block.type !== "mdx") {
|
|
82
|
-
throw new Error("Block is not MDX type");
|
|
83
|
-
}
|
|
84
|
-
const cacheKey = `${block.id}\0${block.payload.raw ?? ""}`;
|
|
85
|
-
const cachedPromise = this.cache.get(cacheKey);
|
|
86
|
-
if (cachedPromise) {
|
|
87
|
-
return cachedPromise;
|
|
88
|
-
}
|
|
89
|
-
const compilationPromise = this.doCompile(block);
|
|
90
|
-
this.cache.set(cacheKey, compilationPromise);
|
|
91
|
-
try {
|
|
92
|
-
const result = await compilationPromise;
|
|
93
|
-
return result;
|
|
94
|
-
} catch (error) {
|
|
95
|
-
this.cache.delete(cacheKey);
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
async getCompiledInternal(ref) {
|
|
100
|
-
const inline = this.inlineModules.get(ref.id);
|
|
101
|
-
if (inline) {
|
|
102
|
-
return this.cloneCompiled(inline);
|
|
103
|
-
}
|
|
104
|
-
const cached = this.compiledCache.get(ref.id);
|
|
105
|
-
if (cached) {
|
|
106
|
-
return this.cloneCompiled(cached);
|
|
107
|
-
}
|
|
108
|
-
const inflight = this.compiledInflight.get(ref.id);
|
|
109
|
-
if (inflight) {
|
|
110
|
-
const resolved = await inflight;
|
|
111
|
-
return this.cloneCompiled(resolved);
|
|
112
|
-
}
|
|
113
|
-
const fetchPromise = this.fetchCompiled(ref);
|
|
114
|
-
this.compiledInflight.set(ref.id, fetchPromise);
|
|
115
|
-
try {
|
|
116
|
-
const data = await fetchPromise;
|
|
117
|
-
this.compiledCache.set(ref.id, data);
|
|
118
|
-
return this.cloneCompiled(data);
|
|
119
|
-
} finally {
|
|
120
|
-
this.compiledInflight.delete(ref.id);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
async getCompiled(ref, options) {
|
|
124
|
-
if (options?.signal) {
|
|
125
|
-
const inline = this.inlineModules.get(ref.id);
|
|
126
|
-
if (inline) {
|
|
127
|
-
return this.cloneCompiled(inline);
|
|
128
|
-
}
|
|
129
|
-
const cached = this.compiledCache.get(ref.id);
|
|
130
|
-
if (cached) {
|
|
131
|
-
return this.cloneCompiled(cached);
|
|
132
|
-
}
|
|
133
|
-
const data = await this.fetchCompiled(ref, options);
|
|
134
|
-
this.compiledCache.set(ref.id, data);
|
|
135
|
-
return this.cloneCompiled(data);
|
|
136
|
-
}
|
|
137
|
-
return this.getCompiledInternal(ref);
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Clear compilation cache
|
|
141
|
-
*/
|
|
142
|
-
clearCache() {
|
|
143
|
-
this.cache.clear();
|
|
144
|
-
this.compiledCache.clear();
|
|
145
|
-
this.compiledInflight.clear();
|
|
146
|
-
}
|
|
147
|
-
registerInlineModule(compiled) {
|
|
148
|
-
this.inlineModules.set(compiled.id, {
|
|
149
|
-
...compiled,
|
|
150
|
-
dependencies: Array.isArray(compiled.dependencies) ? [...compiled.dependencies] : []
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
clearInlineModules() {
|
|
154
|
-
this.inlineModules.clear();
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Actual compilation implementation
|
|
158
|
-
*/
|
|
159
|
-
async doCompile(block) {
|
|
160
|
-
const response = await fetch(this.compileEndpoint, {
|
|
161
|
-
method: "POST",
|
|
162
|
-
headers: {
|
|
163
|
-
"Content-Type": "application/json"
|
|
164
|
-
},
|
|
165
|
-
body: JSON.stringify({
|
|
166
|
-
content: block.payload.raw,
|
|
167
|
-
blockId: block.id
|
|
168
|
-
})
|
|
169
|
-
});
|
|
170
|
-
if (!response.ok) {
|
|
171
|
-
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
172
|
-
throw new Error(`MDX compilation failed: ${error.error || response.statusText}`);
|
|
173
|
-
}
|
|
174
|
-
const data = await response.json();
|
|
175
|
-
return {
|
|
176
|
-
id: data.id,
|
|
177
|
-
code: data.code,
|
|
178
|
-
dependencies: data.dependencies || [],
|
|
179
|
-
cached: data.cached || false
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
async fetchCompiled(ref, options) {
|
|
183
|
-
const response = await fetch(`${this.compileEndpoint}?id=${ref.id}`, {
|
|
184
|
-
signal: options?.signal
|
|
185
|
-
});
|
|
186
|
-
if (!response.ok) {
|
|
187
|
-
throw new Error(`Failed to get compiled MDX: ${response.statusText}`);
|
|
188
|
-
}
|
|
189
|
-
const data = await response.json();
|
|
190
|
-
return {
|
|
191
|
-
id: data.id,
|
|
192
|
-
code: data.code,
|
|
193
|
-
dependencies: data.dependencies || [],
|
|
194
|
-
timestamp: data.timestamp
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
cloneCompiled(compiled) {
|
|
198
|
-
return {
|
|
199
|
-
...compiled,
|
|
200
|
-
dependencies: Array.isArray(compiled.dependencies) ? [...compiled.dependencies] : []
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
MDXComponentFactory = class {
|
|
205
|
-
constructor(mdxClient) {
|
|
206
|
-
this.components = /* @__PURE__ */ new Map();
|
|
207
|
-
this.customComponents = /* @__PURE__ */ new Map();
|
|
208
|
-
this.mdxClient = mdxClient;
|
|
209
|
-
this.baseComponents = this.createBaseComponents();
|
|
210
|
-
}
|
|
211
|
-
registerInlineModule(module) {
|
|
212
|
-
this.mdxClient.registerInlineModule(module);
|
|
213
|
-
this.components.delete(module.id);
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Create React component from compiled MDX
|
|
217
|
-
*/
|
|
218
|
-
async createComponent(ref) {
|
|
219
|
-
const cached = this.components.get(ref.id);
|
|
220
|
-
if (cached) {
|
|
221
|
-
return cached;
|
|
222
|
-
}
|
|
223
|
-
const compiled = await this.mdxClient.getCompiled(ref);
|
|
224
|
-
const component = this.evaluateCompiledMDX(compiled);
|
|
225
|
-
this.components.set(ref.id, component);
|
|
226
|
-
return component;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Safely evaluate compiled MDX code
|
|
230
|
-
*/
|
|
231
|
-
evaluateCompiledMDX(compiled) {
|
|
232
|
-
try {
|
|
233
|
-
const context = this.createEvaluationContext();
|
|
234
|
-
const argNames = Object.keys(context);
|
|
235
|
-
const argValues = Object.values(context);
|
|
236
|
-
const moduleExports = new Function(...argNames, compiled.code)(...argValues);
|
|
237
|
-
const MDXComponent = this.resolveEvaluatedModule(moduleExports);
|
|
238
|
-
return (props) => {
|
|
239
|
-
const registryComponents = this.getComponents();
|
|
240
|
-
const incomingComponents = props?.components;
|
|
241
|
-
const mergedComponents = incomingComponents ? { ...registryComponents, ...incomingComponents } : registryComponents;
|
|
242
|
-
return React2.createElement(MDXComponent, {
|
|
243
|
-
...props,
|
|
244
|
-
components: mergedComponents
|
|
245
|
-
});
|
|
246
|
-
};
|
|
247
|
-
} catch (error) {
|
|
248
|
-
console.error("Failed to evaluate MDX:", error);
|
|
249
|
-
return () => React2.createElement(
|
|
250
|
-
"div",
|
|
251
|
-
{
|
|
252
|
-
className: "mdx-error"
|
|
253
|
-
},
|
|
254
|
-
`MDX Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Create safe evaluation context for MDX
|
|
260
|
-
*/
|
|
261
|
-
createEvaluationContext() {
|
|
262
|
-
const runtime = ReactJsxRuntime;
|
|
263
|
-
const createElementWithChildren = (type, props, key) => {
|
|
264
|
-
const baseProps = props ?? {};
|
|
265
|
-
const finalProps = key === void 0 || key === null ? baseProps : { ...baseProps, key };
|
|
266
|
-
if (Array.isArray(finalProps.children)) {
|
|
267
|
-
finalProps.children = finalProps.children.map((child, index) => assignMdxChildKey(child, index));
|
|
268
|
-
}
|
|
269
|
-
return React2.createElement(type, finalProps);
|
|
270
|
-
};
|
|
271
|
-
const runtimeJsx = typeof runtime.jsx === "function" ? runtime.jsx.bind(runtime) : createElementWithChildren;
|
|
272
|
-
const runtimeJsxs = typeof runtime.jsxs === "function" ? runtime.jsxs.bind(runtime) : createElementWithChildren;
|
|
273
|
-
const runtimeJsxDEV = typeof runtime.jsxDEV === "function" ? runtime.jsxDEV.bind(runtime) : (type, props, key, ..._rest) => createElementWithChildren(type, props, key);
|
|
274
|
-
const jsxRuntime = {
|
|
275
|
-
jsx: runtimeJsx,
|
|
276
|
-
jsxs: runtimeJsxs,
|
|
277
|
-
jsxDEV: runtimeJsxDEV,
|
|
278
|
-
Fragment: runtime.Fragment ?? React2.Fragment
|
|
279
|
-
};
|
|
280
|
-
return {
|
|
281
|
-
__mdx_runtime: jsxRuntime,
|
|
282
|
-
React: React2,
|
|
283
|
-
Fragment: React2.Fragment,
|
|
284
|
-
useState: React2.useState,
|
|
285
|
-
useEffect: React2.useEffect,
|
|
286
|
-
useMemo: React2.useMemo,
|
|
287
|
-
useCallback: React2.useCallback,
|
|
288
|
-
useRef: React2.useRef,
|
|
289
|
-
useContext: React2.useContext,
|
|
290
|
-
useReducer: React2.useReducer,
|
|
291
|
-
useLayoutEffect: React2.useLayoutEffect,
|
|
292
|
-
console: {
|
|
293
|
-
log: console.log,
|
|
294
|
-
warn: console.warn,
|
|
295
|
-
error: console.error
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
resolveEvaluatedModule(output) {
|
|
300
|
-
if (!output) {
|
|
301
|
-
throw new Error("Compiled MDX module returned no exports");
|
|
302
|
-
}
|
|
303
|
-
if (typeof output === "function") {
|
|
304
|
-
return output;
|
|
305
|
-
}
|
|
306
|
-
if (typeof output.default === "function") {
|
|
307
|
-
return output.default;
|
|
308
|
-
}
|
|
309
|
-
if (typeof output.MDXContent === "function") {
|
|
310
|
-
return output.MDXContent;
|
|
311
|
-
}
|
|
312
|
-
throw new Error("Compiled MDX module did not export a component");
|
|
313
|
-
}
|
|
314
|
-
getComponents() {
|
|
315
|
-
if (this.customComponents.size === 0) {
|
|
316
|
-
return { ...this.baseComponents };
|
|
317
|
-
}
|
|
318
|
-
const merged = { ...this.baseComponents };
|
|
319
|
-
for (const [key, component] of this.customComponents) {
|
|
320
|
-
merged[key] = component;
|
|
321
|
-
}
|
|
322
|
-
return merged;
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Register or replace custom MDX components
|
|
326
|
-
*/
|
|
327
|
-
registerComponents(components, options) {
|
|
328
|
-
if (options?.replace) {
|
|
329
|
-
this.customComponents.clear();
|
|
330
|
-
}
|
|
331
|
-
for (const [key, component] of Object.entries(components)) {
|
|
332
|
-
if (!component) continue;
|
|
333
|
-
this.customComponents.set(key, component);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Get base MDX components
|
|
338
|
-
*/
|
|
339
|
-
createBaseComponents() {
|
|
340
|
-
return {
|
|
341
|
-
// Standard HTML elements
|
|
342
|
-
h1: withClassName("h1", "mdx-h1"),
|
|
343
|
-
h2: withClassName("h2", "mdx-h2"),
|
|
344
|
-
h3: withClassName("h3", "mdx-h3"),
|
|
345
|
-
h4: withClassName("h4", "mdx-h4"),
|
|
346
|
-
h5: withClassName("h5", "mdx-h5"),
|
|
347
|
-
h6: withClassName("h6", "mdx-h6"),
|
|
348
|
-
p: withClassName("p", "mdx-p"),
|
|
349
|
-
strong: withClassName("strong", "mdx-strong"),
|
|
350
|
-
em: withClassName("em", "mdx-em"),
|
|
351
|
-
code: withClassName("code", "mdx-code"),
|
|
352
|
-
pre: withClassName("pre", "mdx-pre"),
|
|
353
|
-
ul: withClassName("ul", "mdx-ul"),
|
|
354
|
-
ol: withClassName("ol", "mdx-ol"),
|
|
355
|
-
li: withClassName("li", "mdx-li"),
|
|
356
|
-
blockquote: withClassName("blockquote", "mdx-blockquote"),
|
|
357
|
-
a: (props) => React2.createElement("a", {
|
|
358
|
-
className: "mdx-link",
|
|
359
|
-
target: props.href?.startsWith("http") ? "_blank" : void 0,
|
|
360
|
-
rel: props.href?.startsWith("http") ? "noopener noreferrer" : void 0,
|
|
361
|
-
...props
|
|
362
|
-
}),
|
|
363
|
-
img: (props) => React2.createElement("img", { className: "mdx-img", ...props }),
|
|
364
|
-
table: withClassName("table", "mdx-table"),
|
|
365
|
-
thead: withClassName("thead", "mdx-thead"),
|
|
366
|
-
tbody: withClassName("tbody", "mdx-tbody"),
|
|
367
|
-
tr: withClassName("tr", "mdx-tr"),
|
|
368
|
-
th: withClassName("th", "mdx-th"),
|
|
369
|
-
td: withClassName("td", "mdx-td")
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Clear component cache
|
|
374
|
-
*/
|
|
375
|
-
clearCache() {
|
|
376
|
-
this.components.clear();
|
|
377
|
-
}
|
|
378
|
-
clearCustomComponents() {
|
|
379
|
-
this.customComponents.clear();
|
|
380
|
-
}
|
|
381
|
-
};
|
|
382
|
-
globalMDXClient = null;
|
|
383
|
-
globalComponentFactory = null;
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
13
|
|
|
387
14
|
// src/components/bottom-stick-scroll-area.tsx
|
|
388
15
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
389
16
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
390
|
-
var EPS_BOTTOM_PX = 2;
|
|
391
|
-
var EPS_OVERFLOW_PX = 1;
|
|
392
|
-
var DETACH_SCROLL_DELTA_PX = 1;
|
|
393
|
-
var RETURN_MIN_MS = 180;
|
|
394
|
-
var RETURN_MAX_MS = 520;
|
|
395
|
-
var RETURN_PX_PER_MS = 2.2;
|
|
396
|
-
var RETURN_SETTLE_FRAMES = 2;
|
|
17
|
+
var EPS_BOTTOM_PX = 2, EPS_OVERFLOW_PX = 1, DETACH_SCROLL_DELTA_PX = 1, RETURN_MIN_MS = 180, RETURN_MAX_MS = 520, RETURN_PX_PER_MS = 2.2, RETURN_SETTLE_FRAMES = 2;
|
|
397
18
|
function clamp01(value) {
|
|
398
|
-
|
|
399
|
-
if (value > 1) return 1;
|
|
400
|
-
return value;
|
|
19
|
+
return value < 0 ? 0 : value > 1 ? 1 : value;
|
|
401
20
|
}
|
|
402
21
|
function easeOutCubic(value) {
|
|
403
22
|
return 1 - (1 - value) ** 3;
|
|
@@ -406,14 +25,34 @@ function joinClasses(...parts) {
|
|
|
406
25
|
return parts.filter(Boolean).join(" ");
|
|
407
26
|
}
|
|
408
27
|
function measure(viewport) {
|
|
409
|
-
|
|
410
|
-
const scrollHeight = viewport.scrollHeight;
|
|
411
|
-
const clientHeight = viewport.clientHeight;
|
|
412
|
-
const maxScrollTop = Math.max(0, scrollHeight - clientHeight);
|
|
413
|
-
const distanceToBottom = Math.max(0, maxScrollTop - scrollTop);
|
|
414
|
-
const isOverflowing = scrollHeight > clientHeight + EPS_OVERFLOW_PX;
|
|
28
|
+
let scrollTop = viewport.scrollTop, scrollHeight = viewport.scrollHeight, clientHeight = viewport.clientHeight, maxScrollTop = Math.max(0, scrollHeight - clientHeight), distanceToBottom = Math.max(0, maxScrollTop - scrollTop), isOverflowing = scrollHeight > clientHeight + EPS_OVERFLOW_PX;
|
|
415
29
|
return { scrollTop, scrollHeight, clientHeight, maxScrollTop, distanceToBottom, isOverflowing };
|
|
416
30
|
}
|
|
31
|
+
function isEditableTarget(target) {
|
|
32
|
+
if (!(target instanceof Element)) return !1;
|
|
33
|
+
if (target.closest("input, textarea, select, [role='textbox']")) return !0;
|
|
34
|
+
let contentEditable = target.closest("[contenteditable]");
|
|
35
|
+
return contentEditable !== null && contentEditable.getAttribute("contenteditable")?.toLowerCase() !== "false";
|
|
36
|
+
}
|
|
37
|
+
function isScrollKeyIntent(event) {
|
|
38
|
+
if (event.defaultPrevented || isEditableTarget(event.target)) return !1;
|
|
39
|
+
switch (event.key) {
|
|
40
|
+
case "ArrowDown":
|
|
41
|
+
case "ArrowUp":
|
|
42
|
+
case "PageDown":
|
|
43
|
+
case "PageUp":
|
|
44
|
+
case "Home":
|
|
45
|
+
case "End":
|
|
46
|
+
return !0;
|
|
47
|
+
case " ":
|
|
48
|
+
case "Spacebar":
|
|
49
|
+
return event.target instanceof Element ? event.target.closest(
|
|
50
|
+
"button, input, summary, [role='button'], [role='checkbox'], [role='switch'], [role='radio'], [role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio']"
|
|
51
|
+
) === null : !0;
|
|
52
|
+
default:
|
|
53
|
+
return !1;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
417
56
|
function DefaultJumpButton({ canJump, jumpToBottom }) {
|
|
418
57
|
return /* @__PURE__ */ jsx(
|
|
419
58
|
"button",
|
|
@@ -434,7 +73,7 @@ function DefaultJumpButton({ canJump, jumpToBottom }) {
|
|
|
434
73
|
color: "var(--foreground, #111)",
|
|
435
74
|
cursor: canJump ? "pointer" : "default"
|
|
436
75
|
},
|
|
437
|
-
children: /* @__PURE__ */ jsx("span", { "aria-hidden":
|
|
76
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": !0, children: "\u2193" })
|
|
438
77
|
}
|
|
439
78
|
);
|
|
440
79
|
}
|
|
@@ -443,45 +82,23 @@ function BottomStickScrollArea({
|
|
|
443
82
|
className,
|
|
444
83
|
viewportClassName,
|
|
445
84
|
contentClassName,
|
|
446
|
-
showJumpToBottom =
|
|
85
|
+
showJumpToBottom = !0,
|
|
447
86
|
onDebugStateChange,
|
|
448
87
|
onModeChange,
|
|
449
|
-
debugDomAttributes =
|
|
88
|
+
debugDomAttributes = !1,
|
|
450
89
|
renderJumpToBottom,
|
|
451
90
|
jumpContainerClassName
|
|
452
91
|
}) {
|
|
453
|
-
|
|
454
|
-
const contentRef = useRef(null);
|
|
455
|
-
const modeRef = useRef("STICKY_INSTANT");
|
|
456
|
-
const [mode, setMode] = useState("STICKY_INSTANT");
|
|
457
|
-
const [isOverflowing, setIsOverflowing] = useState(false);
|
|
458
|
-
const [distanceToBottom, setDistanceToBottom] = useState(0);
|
|
459
|
-
const prevScrollTopRef = useRef(0);
|
|
460
|
-
const lastProgrammaticWriteRef = useRef(null);
|
|
461
|
-
const programmaticWriteCountRef = useRef(0);
|
|
462
|
-
const pendingStickRafRef = useRef(null);
|
|
463
|
-
const stickRequestedRef = useRef(false);
|
|
464
|
-
const returnRafRef = useRef(null);
|
|
465
|
-
const returnAnimRef = useRef(null);
|
|
466
|
-
const setModeBoth = useCallback(
|
|
92
|
+
let viewportRef = useRef(null), contentRef = useRef(null), modeRef = useRef("STICKY_INSTANT"), [mode, setMode] = useState("STICKY_INSTANT"), [isOverflowing, setIsOverflowing] = useState(!1), [distanceToBottom, setDistanceToBottom] = useState(0), [prefersReducedMotion, setPrefersReducedMotion] = useState(!1), prefersReducedMotionRef = useRef(!1), prevScrollTopRef = useRef(0), lastProgrammaticWriteRef = useRef(null), programmaticWriteCountRef = useRef(0), pendingStickRafRef = useRef(null), stickRequestedRef = useRef(!1), returnRafRef = useRef(null), returnAnimRef = useRef(null), setModeBoth = useCallback(
|
|
467
93
|
(next) => {
|
|
468
|
-
modeRef.current = next;
|
|
469
|
-
setMode(next);
|
|
470
|
-
onModeChange?.(next);
|
|
94
|
+
modeRef.current = next, setMode(next), onModeChange?.(next);
|
|
471
95
|
},
|
|
472
96
|
[onModeChange]
|
|
473
|
-
)
|
|
474
|
-
|
|
475
|
-
const viewport = viewportRef.current;
|
|
97
|
+
), updateDebug = useCallback(() => {
|
|
98
|
+
let viewport = viewportRef.current;
|
|
476
99
|
if (!viewport) return;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
viewport.dataset.stickyMode = modeRef.current;
|
|
480
|
-
viewport.dataset.distanceToBottom = String(m.distanceToBottom);
|
|
481
|
-
viewport.dataset.isOverflowing = m.isOverflowing ? "1" : "0";
|
|
482
|
-
viewport.dataset.programmaticWrites = String(programmaticWriteCountRef.current);
|
|
483
|
-
}
|
|
484
|
-
onDebugStateChange?.({
|
|
100
|
+
let m = measure(viewport);
|
|
101
|
+
debugDomAttributes && (viewport.dataset.stickyMode = modeRef.current, viewport.dataset.distanceToBottom = String(m.distanceToBottom), viewport.dataset.isOverflowing = m.isOverflowing ? "1" : "0", viewport.dataset.programmaticWrites = String(programmaticWriteCountRef.current)), onDebugStateChange?.({
|
|
485
102
|
mode: modeRef.current,
|
|
486
103
|
isOverflowing: m.isOverflowing,
|
|
487
104
|
distanceToBottom: m.distanceToBottom,
|
|
@@ -490,60 +107,54 @@ function BottomStickScrollArea({
|
|
|
490
107
|
scrollHeight: m.scrollHeight,
|
|
491
108
|
clientHeight: m.clientHeight,
|
|
492
109
|
programmaticWrites: programmaticWriteCountRef.current
|
|
493
|
-
})
|
|
494
|
-
setDistanceToBottom(
|
|
110
|
+
}), setDistanceToBottom(
|
|
495
111
|
(previous) => Math.abs(previous - m.distanceToBottom) <= 0.1 ? previous : m.distanceToBottom
|
|
496
112
|
);
|
|
497
|
-
}, [debugDomAttributes, onDebugStateChange])
|
|
498
|
-
|
|
499
|
-
|
|
113
|
+
}, [debugDomAttributes, onDebugStateChange]), writeScrollTop = useCallback((nextTop) => {
|
|
114
|
+
let viewport = viewportRef.current;
|
|
115
|
+
viewport && (viewport.scrollTop = nextTop, programmaticWriteCountRef.current += 1, lastProgrammaticWriteRef.current = { at: performance.now(), top: nextTop });
|
|
116
|
+
}, []), cancelPendingStick = useCallback(() => {
|
|
117
|
+
pendingStickRafRef.current !== null && (cancelAnimationFrame(pendingStickRafRef.current), pendingStickRafRef.current = null), stickRequestedRef.current = !1;
|
|
118
|
+
}, []), cancelReturn = useCallback(() => {
|
|
119
|
+
returnRafRef.current !== null && (cancelAnimationFrame(returnRafRef.current), returnRafRef.current = null), returnAnimRef.current = null;
|
|
120
|
+
}, []), handleReducedMotionChange = useCallback(
|
|
121
|
+
(matches) => {
|
|
122
|
+
if (prefersReducedMotionRef.current !== matches && (prefersReducedMotionRef.current = matches, setPrefersReducedMotion(matches)), !matches || modeRef.current !== "RETURNING_SMOOTH") return;
|
|
123
|
+
cancelPendingStick(), cancelReturn(), setModeBoth("STICKY_INSTANT");
|
|
124
|
+
let viewport = viewportRef.current;
|
|
125
|
+
viewport && (writeScrollTop(measure(viewport).maxScrollTop), prevScrollTopRef.current = viewport.scrollTop), updateDebug();
|
|
126
|
+
},
|
|
127
|
+
[cancelPendingStick, cancelReturn, setModeBoth, updateDebug, writeScrollTop]
|
|
128
|
+
), reducedMotionChangeHandlerRef = useRef(handleReducedMotionChange);
|
|
129
|
+
reducedMotionChangeHandlerRef.current = handleReducedMotionChange;
|
|
130
|
+
let interruptReturnForUserIntent = useCallback(() => {
|
|
131
|
+
modeRef.current === "RETURNING_SMOOTH" && (cancelPendingStick(), cancelReturn(), setModeBoth("DETACHED"), updateDebug());
|
|
132
|
+
}, [cancelPendingStick, cancelReturn, setModeBoth, updateDebug]), onViewportKeyDown = useCallback(
|
|
133
|
+
(event) => {
|
|
134
|
+
isScrollKeyIntent(event) && interruptReturnForUserIntent();
|
|
135
|
+
},
|
|
136
|
+
[interruptReturnForUserIntent]
|
|
137
|
+
), stickToBottomInstant = useCallback(() => {
|
|
138
|
+
let viewport = viewportRef.current;
|
|
139
|
+
viewport && (stickRequestedRef.current = !0, pendingStickRafRef.current === null && (pendingStickRafRef.current = requestAnimationFrame(() => {
|
|
140
|
+
if (pendingStickRafRef.current = null, !stickRequestedRef.current || (stickRequestedRef.current = !1, modeRef.current !== "STICKY_INSTANT")) return;
|
|
141
|
+
let m = measure(viewport);
|
|
142
|
+
writeScrollTop(m.maxScrollTop), updateDebug();
|
|
143
|
+
})));
|
|
144
|
+
}, [updateDebug, writeScrollTop]), startReturnToBottomSmooth = useCallback(() => {
|
|
145
|
+
let viewport = viewportRef.current;
|
|
500
146
|
if (!viewport) return;
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
}, []);
|
|
505
|
-
const cancelPendingStick = useCallback(() => {
|
|
506
|
-
if (pendingStickRafRef.current !== null) {
|
|
507
|
-
cancelAnimationFrame(pendingStickRafRef.current);
|
|
508
|
-
pendingStickRafRef.current = null;
|
|
509
|
-
}
|
|
510
|
-
stickRequestedRef.current = false;
|
|
511
|
-
}, []);
|
|
512
|
-
const cancelReturn = useCallback(() => {
|
|
513
|
-
if (returnRafRef.current !== null) {
|
|
514
|
-
cancelAnimationFrame(returnRafRef.current);
|
|
515
|
-
returnRafRef.current = null;
|
|
147
|
+
if (prefersReducedMotionRef.current) {
|
|
148
|
+
cancelPendingStick(), cancelReturn(), setModeBoth("STICKY_INSTANT"), writeScrollTop(measure(viewport).maxScrollTop), prevScrollTopRef.current = viewport.scrollTop, updateDebug();
|
|
149
|
+
return;
|
|
516
150
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
const stickToBottomInstant = useCallback(() => {
|
|
520
|
-
const viewport = viewportRef.current;
|
|
521
|
-
if (!viewport) return;
|
|
522
|
-
stickRequestedRef.current = true;
|
|
523
|
-
if (pendingStickRafRef.current !== null) return;
|
|
524
|
-
pendingStickRafRef.current = requestAnimationFrame(() => {
|
|
525
|
-
pendingStickRafRef.current = null;
|
|
526
|
-
if (!stickRequestedRef.current) return;
|
|
527
|
-
stickRequestedRef.current = false;
|
|
528
|
-
if (modeRef.current !== "STICKY_INSTANT") return;
|
|
529
|
-
const m = measure(viewport);
|
|
530
|
-
writeScrollTop(m.maxScrollTop);
|
|
531
|
-
updateDebug();
|
|
532
|
-
});
|
|
533
|
-
}, [updateDebug, writeScrollTop]);
|
|
534
|
-
const startReturnToBottomSmooth = useCallback(() => {
|
|
535
|
-
const viewport = viewportRef.current;
|
|
536
|
-
if (!viewport) return;
|
|
537
|
-
cancelPendingStick();
|
|
538
|
-
cancelReturn();
|
|
539
|
-
const initial = measure(viewport);
|
|
151
|
+
cancelPendingStick(), cancelReturn();
|
|
152
|
+
let initial = measure(viewport);
|
|
540
153
|
if (initial.distanceToBottom <= EPS_BOTTOM_PX) {
|
|
541
|
-
setModeBoth("STICKY_INSTANT");
|
|
542
|
-
stickToBottomInstant();
|
|
543
|
-
updateDebug();
|
|
154
|
+
setModeBoth("STICKY_INSTANT"), stickToBottomInstant(), updateDebug();
|
|
544
155
|
return;
|
|
545
156
|
}
|
|
546
|
-
|
|
157
|
+
let durationMs = Math.max(
|
|
547
158
|
RETURN_MIN_MS,
|
|
548
159
|
Math.min(RETURN_MAX_MS, initial.distanceToBottom / RETURN_PX_PER_MS)
|
|
549
160
|
);
|
|
@@ -552,118 +163,60 @@ function BottomStickScrollArea({
|
|
|
552
163
|
startTop: initial.scrollTop,
|
|
553
164
|
durationMs,
|
|
554
165
|
settleFrames: 0
|
|
555
|
-
};
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
const viewportCurrent = viewportRef.current;
|
|
559
|
-
const anim = returnAnimRef.current;
|
|
166
|
+
}, setModeBoth("RETURNING_SMOOTH");
|
|
167
|
+
let tick = (now) => {
|
|
168
|
+
let viewportCurrent = viewportRef.current, anim = returnAnimRef.current;
|
|
560
169
|
if (!viewportCurrent || !anim || modeRef.current !== "RETURNING_SMOOTH") {
|
|
561
170
|
cancelReturn();
|
|
562
171
|
return;
|
|
563
172
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
const targetBottom = before.maxScrollTop;
|
|
568
|
-
let nextTop = anim.startTop + (targetBottom - anim.startTop) * eased;
|
|
569
|
-
if (nextTop < before.scrollTop) {
|
|
570
|
-
nextTop = before.scrollTop;
|
|
571
|
-
}
|
|
572
|
-
writeScrollTop(nextTop);
|
|
573
|
-
const after = measure(viewportCurrent);
|
|
574
|
-
if (after.distanceToBottom <= EPS_BOTTOM_PX) {
|
|
575
|
-
anim.settleFrames += 1;
|
|
576
|
-
} else {
|
|
577
|
-
anim.settleFrames = 0;
|
|
578
|
-
}
|
|
579
|
-
const doneByTime = progress >= 1;
|
|
580
|
-
const doneBySettle = anim.settleFrames >= RETURN_SETTLE_FRAMES && progress >= 0.6;
|
|
173
|
+
let before = measure(viewportCurrent), progress = clamp01((now - anim.startTime) / anim.durationMs), eased = easeOutCubic(progress), targetBottom = before.maxScrollTop, nextTop = anim.startTop + (targetBottom - anim.startTop) * eased;
|
|
174
|
+
nextTop < before.scrollTop && (nextTop = before.scrollTop), writeScrollTop(nextTop), measure(viewportCurrent).distanceToBottom <= EPS_BOTTOM_PX ? anim.settleFrames += 1 : anim.settleFrames = 0;
|
|
175
|
+
let doneByTime = progress >= 1, doneBySettle = anim.settleFrames >= RETURN_SETTLE_FRAMES && progress >= 0.6;
|
|
581
176
|
if (doneByTime && doneBySettle) {
|
|
582
|
-
cancelReturn();
|
|
583
|
-
setModeBoth("STICKY_INSTANT");
|
|
584
|
-
stickToBottomInstant();
|
|
585
|
-
updateDebug();
|
|
177
|
+
cancelReturn(), setModeBoth("STICKY_INSTANT"), stickToBottomInstant(), updateDebug();
|
|
586
178
|
return;
|
|
587
179
|
}
|
|
588
|
-
updateDebug();
|
|
589
|
-
returnRafRef.current = requestAnimationFrame(tick);
|
|
180
|
+
updateDebug(), returnRafRef.current = requestAnimationFrame(tick);
|
|
590
181
|
};
|
|
591
182
|
returnRafRef.current = requestAnimationFrame(tick);
|
|
592
|
-
}, [cancelPendingStick, cancelReturn, setModeBoth, stickToBottomInstant, updateDebug, writeScrollTop])
|
|
593
|
-
const onViewportScroll = useCallback(
|
|
183
|
+
}, [cancelPendingStick, cancelReturn, setModeBoth, stickToBottomInstant, updateDebug, writeScrollTop]), onViewportScroll = useCallback(
|
|
594
184
|
(event) => {
|
|
595
|
-
|
|
596
|
-
const m = measure(viewport);
|
|
185
|
+
let viewport = event.currentTarget, m = measure(viewport);
|
|
597
186
|
setIsOverflowing((previous) => previous === m.isOverflowing ? previous : m.isOverflowing);
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
const lastWrite = lastProgrammaticWriteRef.current;
|
|
601
|
-
const wroteRecently = lastWrite !== null && performance.now() - lastWrite.at < 60;
|
|
602
|
-
const isLikelyOwnWrite = wroteRecently && lastWrite !== null && Math.abs(m.scrollTop - lastWrite.top) <= 2;
|
|
603
|
-
if (modeRef.current === "RETURNING_SMOOTH") {
|
|
604
|
-
if (!isLikelyOwnWrite && delta < -DETACH_SCROLL_DELTA_PX) {
|
|
605
|
-
cancelReturn();
|
|
606
|
-
setModeBoth("DETACHED");
|
|
607
|
-
}
|
|
608
|
-
} else if (modeRef.current === "STICKY_INSTANT") {
|
|
609
|
-
if (!isLikelyOwnWrite && delta < -DETACH_SCROLL_DELTA_PX && m.isOverflowing) {
|
|
610
|
-
cancelPendingStick();
|
|
611
|
-
setModeBoth("DETACHED");
|
|
612
|
-
}
|
|
613
|
-
} else if (modeRef.current === "DETACHED") {
|
|
614
|
-
if (m.distanceToBottom <= EPS_BOTTOM_PX) {
|
|
615
|
-
setModeBoth("STICKY_INSTANT");
|
|
616
|
-
stickToBottomInstant();
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
prevScrollTopRef.current = m.scrollTop;
|
|
620
|
-
updateDebug();
|
|
187
|
+
let previousTop = prevScrollTopRef.current, delta = m.scrollTop - previousTop, lastWrite = lastProgrammaticWriteRef.current, isLikelyOwnWrite = lastWrite !== null && performance.now() - lastWrite.at < 60 && lastWrite !== null && Math.abs(m.scrollTop - lastWrite.top) <= 2;
|
|
188
|
+
modeRef.current === "RETURNING_SMOOTH" ? !isLikelyOwnWrite && delta < -DETACH_SCROLL_DELTA_PX && (cancelReturn(), setModeBoth("DETACHED")) : modeRef.current === "STICKY_INSTANT" ? !isLikelyOwnWrite && delta < -DETACH_SCROLL_DELTA_PX && m.isOverflowing && (cancelPendingStick(), setModeBoth("DETACHED")) : modeRef.current === "DETACHED" && m.distanceToBottom <= EPS_BOTTOM_PX && (setModeBoth("STICKY_INSTANT"), stickToBottomInstant()), prevScrollTopRef.current = m.scrollTop, updateDebug();
|
|
621
189
|
},
|
|
622
190
|
[cancelPendingStick, cancelReturn, setModeBoth, stickToBottomInstant, updateDebug]
|
|
623
191
|
);
|
|
624
192
|
useEffect(() => {
|
|
625
|
-
|
|
626
|
-
const content = contentRef.current;
|
|
193
|
+
let viewport = viewportRef.current, content = contentRef.current;
|
|
627
194
|
if (!viewport || !content) return;
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
setIsOverflowing((previous) => previous === m.isOverflowing ? previous : m.isOverflowing);
|
|
631
|
-
if (modeRef.current === "STICKY_INSTANT") {
|
|
632
|
-
stickToBottomInstant();
|
|
633
|
-
}
|
|
634
|
-
updateDebug();
|
|
195
|
+
let observer = new ResizeObserver(() => {
|
|
196
|
+
let m = measure(viewport);
|
|
197
|
+
setIsOverflowing((previous) => previous === m.isOverflowing ? previous : m.isOverflowing), modeRef.current === "STICKY_INSTANT" && stickToBottomInstant(), updateDebug();
|
|
635
198
|
});
|
|
636
|
-
observer.observe(content);
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
}, [stickToBottomInstant, updateDebug]);
|
|
640
|
-
useLayoutEffect(() => {
|
|
641
|
-
const viewport = viewportRef.current;
|
|
199
|
+
return observer.observe(content), observer.observe(viewport), () => observer.disconnect();
|
|
200
|
+
}, [stickToBottomInstant, updateDebug]), useLayoutEffect(() => {
|
|
201
|
+
let viewport = viewportRef.current;
|
|
642
202
|
if (!viewport) return;
|
|
643
203
|
setModeBoth("STICKY_INSTANT");
|
|
644
|
-
|
|
645
|
-
writeScrollTop(initial.maxScrollTop);
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
}, [
|
|
651
|
-
|
|
652
|
-
return () => {
|
|
653
|
-
cancelPendingStick();
|
|
654
|
-
cancelReturn();
|
|
655
|
-
};
|
|
204
|
+
let initial = measure(viewport);
|
|
205
|
+
writeScrollTop(initial.maxScrollTop), prevScrollTopRef.current = viewport.scrollTop, setIsOverflowing(initial.isOverflowing), setDistanceToBottom(initial.distanceToBottom), updateDebug();
|
|
206
|
+
}, [setModeBoth, updateDebug, writeScrollTop]), useLayoutEffect(() => {
|
|
207
|
+
if (typeof window > "u" || typeof window.matchMedia != "function") return;
|
|
208
|
+
let mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)"), onChange = () => reducedMotionChangeHandlerRef.current(mediaQuery.matches);
|
|
209
|
+
return onChange(), typeof mediaQuery.addEventListener == "function" ? (mediaQuery.addEventListener("change", onChange), () => mediaQuery.removeEventListener("change", onChange)) : (mediaQuery.addListener(onChange), () => mediaQuery.removeListener(onChange));
|
|
210
|
+
}, []), useEffect(() => () => {
|
|
211
|
+
cancelPendingStick(), cancelReturn();
|
|
656
212
|
}, [cancelPendingStick, cancelReturn]);
|
|
657
|
-
|
|
658
|
-
const jumpButton = renderJumpToBottom?.({
|
|
213
|
+
let canJump = isOverflowing && mode === "DETACHED", jumpButton = renderJumpToBottom?.({
|
|
659
214
|
mode,
|
|
660
215
|
canJump,
|
|
661
216
|
isOverflowing,
|
|
662
217
|
distanceToBottom,
|
|
663
218
|
jumpToBottom: startReturnToBottomSmooth
|
|
664
|
-
}) ?? /* @__PURE__ */ jsx(DefaultJumpButton, { canJump, jumpToBottom: startReturnToBottomSmooth })
|
|
665
|
-
const jumpContainerClassNameBase = "pointer-events-none absolute z-20";
|
|
666
|
-
const jumpContainerStyle = {
|
|
219
|
+
}) ?? /* @__PURE__ */ jsx(DefaultJumpButton, { canJump, jumpToBottom: startReturnToBottomSmooth }), jumpContainerClassNameBase = "pointer-events-none absolute z-20", jumpContainerStyle = {
|
|
667
220
|
position: "absolute",
|
|
668
221
|
zIndex: 20,
|
|
669
222
|
left: 0,
|
|
@@ -672,8 +225,8 @@ function BottomStickScrollArea({
|
|
|
672
225
|
display: "flex",
|
|
673
226
|
justifyContent: "center",
|
|
674
227
|
opacity: canJump ? 1 : 0,
|
|
675
|
-
transform: canJump ? "translateY(0px)" : "translateY(4px)",
|
|
676
|
-
transition: "opacity 150ms ease, transform 150ms ease",
|
|
228
|
+
transform: prefersReducedMotion ? "none" : canJump ? "translateY(0px)" : "translateY(4px)",
|
|
229
|
+
transition: prefersReducedMotion ? "none" : "opacity 150ms ease, transform 150ms ease",
|
|
677
230
|
pointerEvents: "none"
|
|
678
231
|
};
|
|
679
232
|
return /* @__PURE__ */ jsxs("div", { className: joinClasses("relative h-full w-full overflow-hidden", className), children: [
|
|
@@ -683,6 +236,9 @@ function BottomStickScrollArea({
|
|
|
683
236
|
ref: viewportRef,
|
|
684
237
|
className: joinClasses("h-full w-full overflow-auto", viewportClassName),
|
|
685
238
|
onScroll: onViewportScroll,
|
|
239
|
+
onWheel: interruptReturnForUserIntent,
|
|
240
|
+
onTouchStart: interruptReturnForUserIntent,
|
|
241
|
+
onKeyDown: onViewportKeyDown,
|
|
686
242
|
"data-testid": "sticky-scroll-viewport",
|
|
687
243
|
children: /* @__PURE__ */ jsx("div", { ref: contentRef, className: joinClasses("flex min-h-full w-full flex-col", contentClassName), children })
|
|
688
244
|
}
|
|
@@ -699,200 +255,1102 @@ function BottomStickScrollArea({
|
|
|
699
255
|
] });
|
|
700
256
|
}
|
|
701
257
|
|
|
702
|
-
// src/components/
|
|
703
|
-
import {
|
|
258
|
+
// src/components/diff-renderer.tsx
|
|
259
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
260
|
+
var DefaultDiffRenderer = ({
|
|
261
|
+
meta,
|
|
262
|
+
renderCode,
|
|
263
|
+
className = "",
|
|
264
|
+
style
|
|
265
|
+
}) => {
|
|
266
|
+
let diffBlocks = Array.isArray(meta?.diffBlocks) ? meta.diffBlocks : null;
|
|
267
|
+
return !diffBlocks || diffBlocks.length === 0 ? /* @__PURE__ */ jsx2(Fragment, { children: renderCode }) : /* @__PURE__ */ jsx2(
|
|
268
|
+
"div",
|
|
269
|
+
{
|
|
270
|
+
className: `stream-mdx-diff-container my-4 rounded-md border border-border bg-muted/20 font-mono text-sm overflow-hidden ${className}`.trim(),
|
|
271
|
+
style,
|
|
272
|
+
children: diffBlocks.map((diffBlock, bIdx) => /* @__PURE__ */ jsxs2("div", { className: "stream-mdx-diff-block", children: [
|
|
273
|
+
(diffBlock.filePath || diffBlock.additions != null || diffBlock.deletions != null) && /* @__PURE__ */ jsxs2("div", { className: "stream-mdx-diff-header flex items-center justify-between border-b border-border bg-muted/40 px-4 py-2 text-xs font-semibold text-muted-foreground", children: [
|
|
274
|
+
/* @__PURE__ */ jsx2("span", { className: "stream-mdx-diff-filepath", children: diffBlock.filePath ?? "diff" }),
|
|
275
|
+
/* @__PURE__ */ jsxs2("span", { className: "stream-mdx-diff-stats flex gap-2", children: [
|
|
276
|
+
diffBlock.additions != null && /* @__PURE__ */ jsxs2("span", { className: "stream-mdx-diff-stat-add text-green-600 dark:text-green-400", children: [
|
|
277
|
+
"+",
|
|
278
|
+
diffBlock.additions
|
|
279
|
+
] }),
|
|
280
|
+
diffBlock.deletions != null && /* @__PURE__ */ jsxs2("span", { className: "stream-mdx-diff-stat-del text-red-600 dark:text-red-400", children: [
|
|
281
|
+
"-",
|
|
282
|
+
diffBlock.deletions
|
|
283
|
+
] })
|
|
284
|
+
] })
|
|
285
|
+
] }),
|
|
286
|
+
/* @__PURE__ */ jsx2("div", { className: "stream-mdx-diff-lines overflow-x-auto", children: /* @__PURE__ */ jsx2("table", { className: "w-full border-collapse font-mono text-xs", children: /* @__PURE__ */ jsx2("tbody", { children: diffBlock.lines.map((line, lIdx) => {
|
|
287
|
+
let kindClass = `diff-line-${line.kind} ${line.kind === "add" ? "bg-green-500/10 text-green-900 dark:text-green-200" : line.kind === "del" ? "bg-red-500/10 text-red-900 dark:text-red-200" : line.kind === "hunk" ? "bg-blue-500/10 text-blue-800 dark:text-blue-300 font-semibold" : line.kind === "meta" ? "bg-muted/50 text-muted-foreground italic" : "text-foreground"}`;
|
|
288
|
+
return /* @__PURE__ */ jsxs2(
|
|
289
|
+
"tr",
|
|
290
|
+
{
|
|
291
|
+
className: `stream-mdx-diff-row ${kindClass}`,
|
|
292
|
+
"data-diff-kind": line.kind,
|
|
293
|
+
children: [
|
|
294
|
+
/* @__PURE__ */ jsx2("td", { className: "stream-mdx-diff-old-no select-none px-2 py-0.5 text-right opacity-50 w-10", children: line.oldNo != null ? line.oldNo : "" }),
|
|
295
|
+
/* @__PURE__ */ jsx2("td", { className: "stream-mdx-diff-new-no select-none px-2 py-0.5 text-right opacity-50 w-10", children: line.newNo != null ? line.newNo : "" }),
|
|
296
|
+
/* @__PURE__ */ jsx2("td", { className: "stream-mdx-diff-prefix select-none px-1 py-0.5 text-center w-4 font-bold", children: line.kind === "add" ? "+" : line.kind === "del" ? "-" : line.kind === "hunk" ? "@" : " " }),
|
|
297
|
+
/* @__PURE__ */ jsx2("td", { className: "stream-mdx-diff-content px-2 py-0.5 whitespace-pre", children: line.tokens && line.tokens.length > 0 ? line.tokens.map((token, tIdx) => /* @__PURE__ */ jsx2(
|
|
298
|
+
"span",
|
|
299
|
+
{
|
|
300
|
+
style: {
|
|
301
|
+
color: token.color ?? void 0,
|
|
302
|
+
fontStyle: token.fontStyle === 1 || token.fontStyle === 3 ? "italic" : void 0,
|
|
303
|
+
fontWeight: token.fontStyle === 2 || token.fontStyle === 3 ? "bold" : void 0
|
|
304
|
+
},
|
|
305
|
+
children: token.content
|
|
306
|
+
},
|
|
307
|
+
tIdx
|
|
308
|
+
)) : /* @__PURE__ */ jsx2("span", { children: line.raw.replace(/^[+\- ]/, "") }) })
|
|
309
|
+
]
|
|
310
|
+
},
|
|
311
|
+
lIdx
|
|
312
|
+
);
|
|
313
|
+
}) }) }) })
|
|
314
|
+
] }, bIdx))
|
|
315
|
+
}
|
|
316
|
+
);
|
|
317
|
+
};
|
|
318
|
+
DefaultDiffRenderer.displayName = "DefaultDiffRenderer";
|
|
704
319
|
|
|
705
|
-
// src/
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
}
|
|
712
|
-
return Date.now();
|
|
713
|
-
}
|
|
714
|
-
function markMdxHydrationStart(id) {
|
|
715
|
-
if (!id) return;
|
|
716
|
-
const entry = entries.get(id) ?? { status: "compiled" };
|
|
717
|
-
if (entry.startedAt === void 0) {
|
|
718
|
-
entry.startedAt = now();
|
|
719
|
-
}
|
|
720
|
-
entry.status = "compiled";
|
|
721
|
-
entries.set(id, entry);
|
|
722
|
-
}
|
|
723
|
-
function markMdxHydrated(id) {
|
|
724
|
-
if (!id) return;
|
|
725
|
-
const entry = entries.get(id) ?? { status: "hydrated" };
|
|
726
|
-
if (entry.startedAt === void 0) {
|
|
727
|
-
entry.startedAt = now();
|
|
728
|
-
}
|
|
729
|
-
entry.hydratedAt = now();
|
|
730
|
-
entry.status = "hydrated";
|
|
731
|
-
entries.set(id, entry);
|
|
732
|
-
lastHydrationMs = entry.startedAt ? entry.hydratedAt - entry.startedAt : null;
|
|
733
|
-
}
|
|
734
|
-
function markMdxHydrationError(id) {
|
|
735
|
-
if (!id) return;
|
|
736
|
-
const entry = entries.get(id) ?? { status: "error" };
|
|
737
|
-
entry.status = "error";
|
|
738
|
-
entries.set(id, entry);
|
|
320
|
+
// src/components/katex-math.tsx
|
|
321
|
+
import { createContext, useContext, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
322
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
323
|
+
var katexPromise = null;
|
|
324
|
+
async function loadKaTeX() {
|
|
325
|
+
return katexPromise || (katexPromise = import("katex").then((mod) => mod && typeof mod == "object" && "default" in mod && mod.default ? mod.default : mod)), katexPromise;
|
|
739
326
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
mdxRuntimePromise = Promise.resolve().then(() => (init_mdx_client(), mdx_client_exports));
|
|
327
|
+
var DOCUMENT_POSITION_PRECEDING = 2, DOCUMENT_POSITION_FOLLOWING = 4, DocumentMathMacroScope = class {
|
|
328
|
+
constructor() {
|
|
329
|
+
this.entries = /* @__PURE__ */ new Set();
|
|
330
|
+
this.orderedEntries = [];
|
|
331
|
+
this.macroSnapshots = [];
|
|
332
|
+
this.katex = null;
|
|
333
|
+
this.loadError = null;
|
|
334
|
+
this.loading = !1;
|
|
335
|
+
this.disposed = !1;
|
|
750
336
|
}
|
|
751
|
-
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
337
|
+
register(element, tex, displayMode, complete, publish) {
|
|
338
|
+
let entry = { element, tex, displayMode, complete, publish };
|
|
339
|
+
return this.entries.add(entry), this.refresh(), () => {
|
|
340
|
+
this.entries.delete(entry) && this.refresh();
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
dispose() {
|
|
344
|
+
this.disposed = !0, this.entries.clear(), this.orderedEntries = [], this.macroSnapshots = [];
|
|
345
|
+
}
|
|
346
|
+
refresh() {
|
|
347
|
+
if (!this.disposed) {
|
|
348
|
+
if (this.loadError) {
|
|
349
|
+
for (let entry of this.entries)
|
|
350
|
+
entry.publish({ tex: entry.tex, displayMode: entry.displayMode, scope: this, error: this.loadError });
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (this.katex) {
|
|
354
|
+
this.recompute(this.katex);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
this.loading || (this.loading = !0, loadKaTeX().then((katex) => {
|
|
358
|
+
this.disposed || (this.katex = katex, this.refresh());
|
|
359
|
+
}).catch((reason) => {
|
|
360
|
+
if (!this.disposed) {
|
|
361
|
+
this.loadError = reason instanceof Error ? reason : new Error(String(reason));
|
|
362
|
+
for (let entry of this.entries)
|
|
363
|
+
entry.publish({ tex: entry.tex, displayMode: entry.displayMode, scope: this, error: this.loadError });
|
|
364
|
+
}
|
|
365
|
+
}).finally(() => {
|
|
366
|
+
this.loading = !1;
|
|
367
|
+
}));
|
|
763
368
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
369
|
+
}
|
|
370
|
+
recompute(katex) {
|
|
371
|
+
let nextEntries = [...this.entries].sort((left, right) => {
|
|
372
|
+
let position = left.element.compareDocumentPosition(right.element);
|
|
373
|
+
return position & DOCUMENT_POSITION_FOLLOWING ? -1 : position & DOCUMENT_POSITION_PRECEDING ? 1 : 0;
|
|
374
|
+
}), unchangedPrefix = 0;
|
|
375
|
+
for (; unchangedPrefix < this.orderedEntries.length && unchangedPrefix < nextEntries.length && this.orderedEntries[unchangedPrefix] === nextEntries[unchangedPrefix]; )
|
|
376
|
+
unchangedPrefix += 1;
|
|
377
|
+
let macros = unchangedPrefix > 0 ? { ...this.macroSnapshots[unchangedPrefix - 1] } : {};
|
|
378
|
+
this.orderedEntries = nextEntries, this.macroSnapshots.length = unchangedPrefix;
|
|
379
|
+
for (let index = unchangedPrefix; index < nextEntries.length; index += 1) {
|
|
380
|
+
let entry = nextEntries[index], preparation = null;
|
|
381
|
+
if (entry.complete) {
|
|
382
|
+
let nextMacros = { ...macros };
|
|
383
|
+
try {
|
|
384
|
+
let html = katex.renderToString(entry.tex, {
|
|
385
|
+
displayMode: entry.displayMode,
|
|
386
|
+
throwOnError: !1,
|
|
387
|
+
trust: !1,
|
|
388
|
+
maxExpand: 1e3,
|
|
389
|
+
macros: nextMacros
|
|
390
|
+
});
|
|
391
|
+
macros = nextMacros, preparation = { tex: entry.tex, displayMode: entry.displayMode, scope: this, html };
|
|
392
|
+
} catch (reason) {
|
|
393
|
+
preparation = {
|
|
394
|
+
tex: entry.tex,
|
|
395
|
+
displayMode: entry.displayMode,
|
|
396
|
+
scope: this,
|
|
397
|
+
error: reason instanceof Error ? reason : new Error(String(reason))
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
this.macroSnapshots[index] = { ...macros }, entry.publish(preparation);
|
|
767
402
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
403
|
+
}
|
|
404
|
+
}, DocumentMathMacroScopeContext = createContext(null), MathExpressionCompletenessContext = createContext(!0), MathEngineOutputView = ({ engine, tex, displayMode }) => {
|
|
405
|
+
let output = useMemo(
|
|
406
|
+
() => engine.render(tex, { displayMode }),
|
|
407
|
+
[engine, engine.id, tex, displayMode]
|
|
408
|
+
);
|
|
409
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: output });
|
|
410
|
+
};
|
|
411
|
+
function useMathPreparation(tex, displayMode, elementRef, enabled) {
|
|
412
|
+
let scope = useContext(DocumentMathMacroScopeContext), complete = useContext(MathExpressionCompletenessContext), [preparation, setPreparation] = useState2(null);
|
|
413
|
+
return useEffect2(() => {
|
|
414
|
+
if (!enabled) return;
|
|
415
|
+
let active = !0;
|
|
416
|
+
if (scope) {
|
|
417
|
+
let element = elementRef.current;
|
|
418
|
+
return element ? scope.register(element, tex, displayMode, complete, (result) => {
|
|
419
|
+
active && setPreparation(result);
|
|
420
|
+
}) : () => {
|
|
421
|
+
active = !1;
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
return (async () => {
|
|
425
|
+
try {
|
|
426
|
+
let html = (await loadKaTeX()).renderToString(tex, {
|
|
427
|
+
displayMode,
|
|
428
|
+
throwOnError: !1,
|
|
429
|
+
trust: !1,
|
|
430
|
+
maxExpand: 1e3
|
|
431
|
+
});
|
|
432
|
+
active && setPreparation({ tex, displayMode, scope: null, html });
|
|
433
|
+
} catch (reason) {
|
|
434
|
+
active && setPreparation({
|
|
435
|
+
tex,
|
|
436
|
+
displayMode,
|
|
437
|
+
scope: null,
|
|
438
|
+
error: reason instanceof Error ? reason : new Error(String(reason))
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
})(), () => {
|
|
442
|
+
active = !1;
|
|
774
443
|
};
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
444
|
+
}, [tex, displayMode, scope, complete, elementRef, enabled]), scope && !complete ? null : preparation?.tex === tex && preparation.displayMode === displayMode && preparation.scope === scope ? preparation : null;
|
|
445
|
+
}
|
|
446
|
+
var KaTeXInlineMath = ({ tex, className = "", fallback, engine }) => {
|
|
447
|
+
let elementRef = useRef2(null), preparation = useMathPreparation(tex, !1, elementRef, !engine);
|
|
448
|
+
return engine ? /* @__PURE__ */ jsx3("span", { className: `math-inline ${className}`.trim(), "data-tex": tex, children: /* @__PURE__ */ jsx3(MathEngineOutputView, { engine, tex, displayMode: !1 }) }) : preparation && "error" in preparation && fallback ? /* @__PURE__ */ jsx3(Fragment2, { children: fallback(tex, preparation.error) }) : preparation && "html" in preparation ? /* @__PURE__ */ jsx3(
|
|
449
|
+
"span",
|
|
450
|
+
{
|
|
451
|
+
ref: elementRef,
|
|
452
|
+
className: `math-inline katex-inline ${className}`.trim(),
|
|
453
|
+
"data-tex": tex,
|
|
454
|
+
dangerouslySetInnerHTML: { __html: preparation.html }
|
|
455
|
+
}
|
|
456
|
+
) : /* @__PURE__ */ jsxs3("span", { ref: elementRef, className: `math-inline ${className}`.trim(), "data-tex": tex, children: [
|
|
457
|
+
"$",
|
|
458
|
+
tex,
|
|
459
|
+
"$"
|
|
460
|
+
] });
|
|
461
|
+
};
|
|
462
|
+
KaTeXInlineMath.displayName = "KaTeXInlineMath";
|
|
463
|
+
var KaTeXBlockMath = ({ tex, className = "", fallback, engine }) => {
|
|
464
|
+
let elementRef = useRef2(null), preparation = useMathPreparation(tex, !0, elementRef, !engine);
|
|
465
|
+
return engine ? /* @__PURE__ */ jsx3(
|
|
466
|
+
"div",
|
|
467
|
+
{
|
|
468
|
+
className: `math-display markdown-math-display ${className}`.trim(),
|
|
469
|
+
"data-tex": tex,
|
|
470
|
+
style: { overflowX: "auto" },
|
|
471
|
+
children: /* @__PURE__ */ jsx3(MathEngineOutputView, { engine, tex, displayMode: !0 })
|
|
472
|
+
}
|
|
473
|
+
) : preparation && "error" in preparation && fallback ? /* @__PURE__ */ jsx3(Fragment2, { children: fallback(tex, preparation.error) }) : preparation && "html" in preparation ? /* @__PURE__ */ jsx3(
|
|
474
|
+
"div",
|
|
475
|
+
{
|
|
476
|
+
ref: elementRef,
|
|
477
|
+
className: `math-display katex-block markdown-math-display ${className}`.trim(),
|
|
478
|
+
"data-tex": tex,
|
|
479
|
+
style: { overflowX: "auto" },
|
|
480
|
+
dangerouslySetInnerHTML: { __html: preparation.html }
|
|
481
|
+
}
|
|
482
|
+
) : /* @__PURE__ */ jsx3(
|
|
483
|
+
"div",
|
|
484
|
+
{
|
|
485
|
+
ref: elementRef,
|
|
486
|
+
className: `math-display markdown-math-display ${className}`.trim(),
|
|
487
|
+
"data-tex": tex,
|
|
488
|
+
style: { overflowX: "auto" },
|
|
489
|
+
children: /* @__PURE__ */ jsxs3("span", { className: "math-display-content", children: [
|
|
490
|
+
"$$",
|
|
491
|
+
tex,
|
|
492
|
+
"$$"
|
|
493
|
+
] })
|
|
494
|
+
}
|
|
495
|
+
);
|
|
496
|
+
};
|
|
497
|
+
KaTeXBlockMath.displayName = "KaTeXBlockMath";
|
|
498
|
+
|
|
499
|
+
// src/components/controls.tsx
|
|
500
|
+
import React2, { useCallback as useCallback2, useState as useState3 } from "react";
|
|
501
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
502
|
+
var DEFAULT_CONTROLS_LABELS = {
|
|
503
|
+
copy: "Copy code",
|
|
504
|
+
copied: "Copied!",
|
|
505
|
+
copyError: "Failed to copy",
|
|
506
|
+
download: "Download snippet",
|
|
507
|
+
downloadCsv: "Download CSV",
|
|
508
|
+
downloadTsv: "Download TSV",
|
|
509
|
+
downloadMarkdown: "Download Markdown",
|
|
510
|
+
copyTsv: "Copy TSV",
|
|
511
|
+
copyMarkdown: "Copy Markdown",
|
|
512
|
+
copyTable: "Copy table",
|
|
513
|
+
fullscreen: "Enter fullscreen",
|
|
514
|
+
exitFullscreen: "Exit fullscreen"
|
|
515
|
+
}, LANGUAGE_EXTENSION_MAP = {
|
|
516
|
+
javascript: "js",
|
|
517
|
+
js: "js",
|
|
518
|
+
mjs: "mjs",
|
|
519
|
+
cjs: "cjs",
|
|
520
|
+
typescript: "ts",
|
|
521
|
+
ts: "ts",
|
|
522
|
+
mts: "mts",
|
|
523
|
+
cts: "cts",
|
|
524
|
+
jsx: "jsx",
|
|
525
|
+
tsx: "tsx",
|
|
526
|
+
python: "py",
|
|
527
|
+
py: "py",
|
|
528
|
+
rust: "rs",
|
|
529
|
+
rs: "rs",
|
|
530
|
+
ruby: "rb",
|
|
531
|
+
rb: "rb",
|
|
532
|
+
go: "go",
|
|
533
|
+
golang: "go",
|
|
534
|
+
c: "c",
|
|
535
|
+
cpp: "cpp",
|
|
536
|
+
"c++": "cpp",
|
|
537
|
+
csharp: "cs",
|
|
538
|
+
"c#": "cs",
|
|
539
|
+
cs: "cs",
|
|
540
|
+
java: "java",
|
|
541
|
+
kotlin: "kt",
|
|
542
|
+
kt: "kt",
|
|
543
|
+
swift: "swift",
|
|
544
|
+
php: "php",
|
|
545
|
+
html: "html",
|
|
546
|
+
css: "css",
|
|
547
|
+
scss: "scss",
|
|
548
|
+
sass: "sass",
|
|
549
|
+
less: "less",
|
|
550
|
+
json: "json",
|
|
551
|
+
jsonc: "jsonc",
|
|
552
|
+
yaml: "yaml",
|
|
553
|
+
yml: "yaml",
|
|
554
|
+
toml: "toml",
|
|
555
|
+
xml: "xml",
|
|
556
|
+
svg: "svg",
|
|
557
|
+
markdown: "md",
|
|
558
|
+
md: "md",
|
|
559
|
+
mdx: "mdx",
|
|
560
|
+
sh: "sh",
|
|
561
|
+
bash: "sh",
|
|
562
|
+
shell: "sh",
|
|
563
|
+
zsh: "sh",
|
|
564
|
+
sql: "sql",
|
|
565
|
+
diff: "diff",
|
|
566
|
+
dockerfile: "dockerfile",
|
|
567
|
+
makefile: "makefile",
|
|
568
|
+
graphql: "graphql",
|
|
569
|
+
gql: "graphql",
|
|
570
|
+
lua: "lua",
|
|
571
|
+
r: "r",
|
|
572
|
+
scala: "scala",
|
|
573
|
+
perl: "pl",
|
|
574
|
+
pl: "pl",
|
|
575
|
+
mermaid: "mmd",
|
|
576
|
+
latex: "tex",
|
|
577
|
+
tex: "tex",
|
|
578
|
+
ini: "ini",
|
|
579
|
+
env: "env",
|
|
580
|
+
text: "txt",
|
|
581
|
+
txt: "txt"
|
|
582
|
+
};
|
|
583
|
+
function getExtensionForLanguage(lang) {
|
|
584
|
+
if (!lang) return "txt";
|
|
585
|
+
let clean = lang.trim().toLowerCase().split(/\s+/)[0] ?? "";
|
|
586
|
+
return clean ? LANGUAGE_EXTENSION_MAP[clean] ? LANGUAGE_EXTENSION_MAP[clean] : /^[a-z0-9]+$/.test(clean) ? clean : "txt" : "txt";
|
|
587
|
+
}
|
|
588
|
+
function getCodeSnippetFilename(lang) {
|
|
589
|
+
return `snippet.${getExtensionForLanguage(lang)}`;
|
|
590
|
+
}
|
|
591
|
+
async function copyToClipboard(text) {
|
|
592
|
+
if (typeof navigator > "u" || !navigator.clipboard?.writeText)
|
|
593
|
+
return !1;
|
|
594
|
+
try {
|
|
595
|
+
return await navigator.clipboard.writeText(text), !0;
|
|
596
|
+
} catch {
|
|
597
|
+
return !1;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
function downloadFile(content, filename, mimeType = "text/plain;charset=utf-8") {
|
|
601
|
+
if (!(typeof window > "u" || typeof document > "u"))
|
|
602
|
+
try {
|
|
603
|
+
let blob = new Blob([content], { type: mimeType }), url = URL.createObjectURL(blob), a = document.createElement("a");
|
|
604
|
+
a.href = url, a.download = filename, a.style.display = "none", document.body.appendChild(a);
|
|
605
|
+
try {
|
|
606
|
+
a.click();
|
|
607
|
+
} finally {
|
|
608
|
+
document.body.removeChild(a), setTimeout(() => {
|
|
609
|
+
try {
|
|
610
|
+
URL.revokeObjectURL(url);
|
|
611
|
+
} catch {
|
|
612
|
+
}
|
|
613
|
+
}, 100);
|
|
780
614
|
}
|
|
615
|
+
} catch {
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
function escapeCsvCell(cell) {
|
|
619
|
+
return /[",\r\n]/.test(cell) ? `"${cell.replace(/"/g, '""')}"` : cell;
|
|
620
|
+
}
|
|
621
|
+
function escapeTsvCell(cell) {
|
|
622
|
+
return cell.replace(/\t/g, " ").replace(/\r?\n/g, " ");
|
|
623
|
+
}
|
|
624
|
+
function tableToCsv(headers, rows) {
|
|
625
|
+
let lines = [];
|
|
626
|
+
headers.length > 0 && lines.push(headers.map(escapeCsvCell).join(","));
|
|
627
|
+
for (let row of rows)
|
|
628
|
+
lines.push(row.map(escapeCsvCell).join(","));
|
|
629
|
+
return lines.join(`
|
|
630
|
+
`);
|
|
631
|
+
}
|
|
632
|
+
function tableToTsv(headers, rows) {
|
|
633
|
+
let lines = [];
|
|
634
|
+
headers.length > 0 && lines.push(headers.map(escapeTsvCell).join(" "));
|
|
635
|
+
for (let row of rows)
|
|
636
|
+
lines.push(row.map(escapeTsvCell).join(" "));
|
|
637
|
+
return lines.join(`
|
|
638
|
+
`);
|
|
639
|
+
}
|
|
640
|
+
function tableToMarkdown(headers, rows, align) {
|
|
641
|
+
if (headers.length === 0 && rows.length === 0) return "";
|
|
642
|
+
let columnCount = Math.max(headers.length, ...rows.map((r) => r.length));
|
|
643
|
+
if (columnCount === 0) return "";
|
|
644
|
+
let padRow = (row) => {
|
|
645
|
+
let padded = [...row];
|
|
646
|
+
for (; padded.length < columnCount; ) padded.push("");
|
|
647
|
+
return padded.map((cell) => cell.replace(/\r?\n/g, " ").replace(/\|/g, "\\|"));
|
|
648
|
+
}, headerLine = `| ${padRow(headers.length > 0 ? headers : Array(columnCount).fill("")).join(" | ")} |`, separatorLine = `| ${Array.from({ length: columnCount }, (_, i) => {
|
|
649
|
+
let a = align?.[i];
|
|
650
|
+
return a === "center" ? ":---:" : a === "right" ? "---:" : a === "left" ? ":---" : "---";
|
|
651
|
+
}).join(" | ")} |`, dataLines = rows.map((row) => `| ${padRow(row).join(" | ")} |`);
|
|
652
|
+
return [headerLine, separatorLine, ...dataLines].join(`
|
|
653
|
+
`);
|
|
654
|
+
}
|
|
655
|
+
function inlineToPlainText(nodes) {
|
|
656
|
+
if (!Array.isArray(nodes) || nodes.length === 0) return "";
|
|
657
|
+
let out = "";
|
|
658
|
+
for (let node of nodes)
|
|
659
|
+
if (node)
|
|
660
|
+
switch (node.kind) {
|
|
661
|
+
case "text":
|
|
662
|
+
case "code":
|
|
663
|
+
out += node.text ?? "";
|
|
664
|
+
break;
|
|
665
|
+
case "strong":
|
|
666
|
+
case "em":
|
|
667
|
+
case "strike":
|
|
668
|
+
out += inlineToPlainText(node.children);
|
|
669
|
+
break;
|
|
670
|
+
case "link":
|
|
671
|
+
out += inlineToPlainText(node.children) || node.title || node.href || "";
|
|
672
|
+
break;
|
|
673
|
+
case "image":
|
|
674
|
+
out += node.alt || node.title || "";
|
|
675
|
+
break;
|
|
676
|
+
case "br":
|
|
677
|
+
out += `
|
|
678
|
+
`;
|
|
679
|
+
break;
|
|
680
|
+
case "html":
|
|
681
|
+
Array.isArray(node.children) && node.children.length > 0 ? out += inlineToPlainText(node.children) : node.raw && (/<br\s*\/?>/i.test(node.raw) ? out += `
|
|
682
|
+
` : out += node.raw.replace(/<[^>]*>/g, ""));
|
|
683
|
+
break;
|
|
684
|
+
case "math-inline":
|
|
685
|
+
case "math-display":
|
|
686
|
+
out += node.tex ?? "";
|
|
687
|
+
break;
|
|
688
|
+
case "mention":
|
|
689
|
+
out += `@${node.handle ?? ""}`;
|
|
690
|
+
break;
|
|
691
|
+
case "citation":
|
|
692
|
+
out += `[${node.id ?? ""}]`;
|
|
693
|
+
break;
|
|
694
|
+
case "footnote-ref":
|
|
695
|
+
out += `[${node.label ?? ""}]`;
|
|
696
|
+
break;
|
|
697
|
+
case "plugin":
|
|
698
|
+
Array.isArray(node.children) ? out += inlineToPlainText(node.children) : out += node.raw ?? "";
|
|
699
|
+
break;
|
|
700
|
+
default: {
|
|
701
|
+
let generic = node;
|
|
702
|
+
generic && typeof generic == "object" && ("text" in generic && typeof generic.text == "string" ? out += generic.text : "children" in generic && Array.isArray(generic.children) && (out += inlineToPlainText(generic.children)));
|
|
703
|
+
break;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return out;
|
|
707
|
+
}
|
|
708
|
+
function resolveCodeControls(config) {
|
|
709
|
+
if (!config)
|
|
710
|
+
return { enabled: !1, copy: !1, download: !1, labels: DEFAULT_CONTROLS_LABELS };
|
|
711
|
+
let labels = {
|
|
712
|
+
...DEFAULT_CONTROLS_LABELS,
|
|
713
|
+
...typeof config == "object" ? config.labels : void 0
|
|
714
|
+
};
|
|
715
|
+
if (config === !0)
|
|
716
|
+
return { enabled: !0, copy: !0, download: !0, labels };
|
|
717
|
+
let codeOpt = config.code;
|
|
718
|
+
if (!codeOpt)
|
|
719
|
+
return { enabled: !1, copy: !1, download: !1, labels };
|
|
720
|
+
if (codeOpt === !0)
|
|
721
|
+
return { enabled: !0, copy: !0, download: !0, labels };
|
|
722
|
+
let copy = !!codeOpt.copy, download = !!codeOpt.download;
|
|
723
|
+
return { enabled: copy || download, copy, download, labels };
|
|
724
|
+
}
|
|
725
|
+
function resolveTableControls(config) {
|
|
726
|
+
if (!config)
|
|
727
|
+
return {
|
|
728
|
+
enabled: !1,
|
|
729
|
+
copy: !1,
|
|
730
|
+
copyFormats: [],
|
|
731
|
+
download: !1,
|
|
732
|
+
downloadFormats: [],
|
|
733
|
+
labels: DEFAULT_CONTROLS_LABELS
|
|
734
|
+
};
|
|
735
|
+
let labels = {
|
|
736
|
+
...DEFAULT_CONTROLS_LABELS,
|
|
737
|
+
...typeof config == "object" ? config.labels : void 0
|
|
738
|
+
};
|
|
739
|
+
if (config === !0)
|
|
740
|
+
return {
|
|
741
|
+
enabled: !0,
|
|
742
|
+
copy: !0,
|
|
743
|
+
copyFormats: ["tsv", "markdown"],
|
|
744
|
+
download: !0,
|
|
745
|
+
downloadFormats: ["csv"],
|
|
746
|
+
labels
|
|
747
|
+
};
|
|
748
|
+
let tableOpt = config.table;
|
|
749
|
+
if (!tableOpt)
|
|
750
|
+
return {
|
|
751
|
+
enabled: !1,
|
|
752
|
+
copy: !1,
|
|
753
|
+
copyFormats: [],
|
|
754
|
+
download: !1,
|
|
755
|
+
downloadFormats: [],
|
|
756
|
+
labels: DEFAULT_CONTROLS_LABELS
|
|
781
757
|
};
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
758
|
+
if (tableOpt === !0)
|
|
759
|
+
return {
|
|
760
|
+
enabled: !0,
|
|
761
|
+
copy: !0,
|
|
762
|
+
copyFormats: ["tsv", "markdown"],
|
|
763
|
+
download: !0,
|
|
764
|
+
downloadFormats: ["csv"],
|
|
765
|
+
labels
|
|
766
|
+
};
|
|
767
|
+
let copyVal = tableOpt.copy, copy = !!copyVal, copyFormats = Array.isArray(copyVal) ? copyVal : copyVal ? ["tsv", "markdown"] : [], downloadVal = tableOpt.download, download = !!downloadVal, downloadFormats = Array.isArray(downloadVal) ? downloadVal : downloadVal ? ["csv"] : [];
|
|
768
|
+
return {
|
|
769
|
+
enabled: copy || download,
|
|
770
|
+
copy,
|
|
771
|
+
copyFormats,
|
|
772
|
+
download,
|
|
773
|
+
downloadFormats,
|
|
774
|
+
labels
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
function resolveMermaidControls(config) {
|
|
778
|
+
if (!config)
|
|
779
|
+
return { enabled: !1, copy: !1, fullscreen: !1, labels: DEFAULT_CONTROLS_LABELS };
|
|
780
|
+
let labels = {
|
|
781
|
+
...DEFAULT_CONTROLS_LABELS,
|
|
782
|
+
...typeof config == "object" ? config.labels : void 0
|
|
783
|
+
};
|
|
784
|
+
if (config === !0)
|
|
785
|
+
return { enabled: !0, copy: !0, fullscreen: !1, labels };
|
|
786
|
+
let mermaidOpt = config.mermaid;
|
|
787
|
+
if (!mermaidOpt)
|
|
788
|
+
return { enabled: !1, copy: !1, fullscreen: !1, labels };
|
|
789
|
+
if (mermaidOpt === !0)
|
|
790
|
+
return { enabled: !0, copy: !0, fullscreen: !1, labels };
|
|
791
|
+
let copy = !!mermaidOpt.copy, fullscreen = !!mermaidOpt.fullscreen;
|
|
792
|
+
return { enabled: copy || fullscreen, copy, fullscreen, labels };
|
|
793
|
+
}
|
|
794
|
+
function resolveControlsConfig(config) {
|
|
795
|
+
return {
|
|
796
|
+
code: resolveCodeControls(config),
|
|
797
|
+
table: resolveTableControls(config),
|
|
798
|
+
mermaid: resolveMermaidControls(config)
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
var CodeControlsBar = ({ code, language, config, className }) => {
|
|
802
|
+
let [copied, setCopied] = useState3(!1), { labels } = config, handleCopy = useCallback2(async () => {
|
|
803
|
+
await copyToClipboard(code) && (setCopied(!0), setTimeout(() => setCopied(!1), 2e3));
|
|
804
|
+
}, [code]), handleDownload = useCallback2(() => {
|
|
805
|
+
let filename = getCodeSnippetFilename(language);
|
|
806
|
+
downloadFile(code, filename);
|
|
807
|
+
}, [code, language]);
|
|
808
|
+
return /* @__PURE__ */ jsxs4(
|
|
809
|
+
"div",
|
|
810
|
+
{
|
|
811
|
+
className: `stream-mdx-controls stream-mdx-code-controls flex items-center justify-end gap-1 px-2 py-1 text-xs select-none ${className ?? ""}`.trim(),
|
|
812
|
+
"data-stream-mdx-controls": "code",
|
|
813
|
+
children: [
|
|
814
|
+
language ? /* @__PURE__ */ jsx4("span", { className: "stream-mdx-code-language mr-auto text-muted-foreground opacity-60 text-[11px] font-mono", children: language }) : null,
|
|
815
|
+
config.copy ? /* @__PURE__ */ jsx4(
|
|
816
|
+
"button",
|
|
817
|
+
{
|
|
818
|
+
type: "button",
|
|
819
|
+
className: "stream-mdx-control stream-mdx-control-copy stream-mdx-control-code-copy inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs hover:bg-muted focus:outline-none",
|
|
820
|
+
"data-stream-mdx-control": "copy",
|
|
821
|
+
"data-stream-mdx-target": "code",
|
|
822
|
+
"data-stream-mdx-action": "copy",
|
|
823
|
+
"aria-label": copied ? labels.copied ?? "Copied!" : labels.copy ?? "Copy code",
|
|
824
|
+
onClick: handleCopy,
|
|
825
|
+
children: copied ? labels.copied ?? "Copied!" : labels.copy ?? "Copy"
|
|
826
|
+
}
|
|
827
|
+
) : null,
|
|
828
|
+
config.download ? /* @__PURE__ */ jsx4(
|
|
829
|
+
"button",
|
|
830
|
+
{
|
|
831
|
+
type: "button",
|
|
832
|
+
className: "stream-mdx-control stream-mdx-control-download stream-mdx-control-code-download inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs hover:bg-muted focus:outline-none",
|
|
833
|
+
"data-stream-mdx-control": "download",
|
|
834
|
+
"data-stream-mdx-target": "code",
|
|
835
|
+
"data-stream-mdx-action": "download",
|
|
836
|
+
"aria-label": labels.download ?? "Download snippet",
|
|
837
|
+
onClick: handleDownload,
|
|
838
|
+
children: labels.download ?? "Download"
|
|
790
839
|
}
|
|
840
|
+
) : null
|
|
841
|
+
]
|
|
842
|
+
}
|
|
843
|
+
);
|
|
844
|
+
}, TableControlsBar = ({
|
|
845
|
+
headers,
|
|
846
|
+
rows,
|
|
847
|
+
align,
|
|
848
|
+
getTableData,
|
|
849
|
+
getMarkdownSource,
|
|
850
|
+
isFinalized,
|
|
851
|
+
config,
|
|
852
|
+
className
|
|
853
|
+
}) => {
|
|
854
|
+
let [copiedFormat, setCopiedFormat] = useState3(null), copiedFeedbackTimeout = React2.useRef(void 0), mounted = React2.useRef(!0), { labels } = config;
|
|
855
|
+
React2.useEffect(() => (mounted.current = !0, () => {
|
|
856
|
+
mounted.current = !1, window.clearTimeout(copiedFeedbackTimeout.current);
|
|
857
|
+
}), []);
|
|
858
|
+
let handleCopy = useCallback2(
|
|
859
|
+
async (format) => {
|
|
860
|
+
if (!isFinalized) return;
|
|
861
|
+
let text;
|
|
862
|
+
if (format === "markdown") {
|
|
863
|
+
let source = getMarkdownSource?.();
|
|
864
|
+
if (source !== void 0)
|
|
865
|
+
text = source;
|
|
866
|
+
else {
|
|
867
|
+
let data = getTableData?.() ?? { headers, rows, align };
|
|
868
|
+
text = tableToMarkdown(data.headers, data.rows, data.align);
|
|
791
869
|
}
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
observer.observe(target);
|
|
796
|
-
return () => {
|
|
797
|
-
cancelled = true;
|
|
798
|
-
observer.disconnect();
|
|
799
|
-
if (idleId !== null && typeof globalThis.cancelIdleCallback === "function") {
|
|
800
|
-
globalThis.cancelIdleCallback(idleId);
|
|
870
|
+
} else {
|
|
871
|
+
let data = getTableData?.() ?? { headers, rows, align };
|
|
872
|
+
text = tableToTsv(data.headers, data.rows);
|
|
801
873
|
}
|
|
802
|
-
if (
|
|
803
|
-
|
|
874
|
+
if (await copyToClipboard(text)) {
|
|
875
|
+
if (!mounted.current) return;
|
|
876
|
+
setCopiedFormat(format), window.clearTimeout(copiedFeedbackTimeout.current), copiedFeedbackTimeout.current = window.setTimeout(() => {
|
|
877
|
+
copiedFeedbackTimeout.current = void 0, setCopiedFormat(null);
|
|
878
|
+
}, 2e3);
|
|
804
879
|
}
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
|
|
880
|
+
},
|
|
881
|
+
[headers, rows, align, getTableData, getMarkdownSource, isFinalized]
|
|
882
|
+
), handleDownload = useCallback2(
|
|
883
|
+
(format) => {
|
|
884
|
+
if (!isFinalized) return;
|
|
885
|
+
let text = "", filename = "table.csv", mimeType = "text/csv;charset=utf-8";
|
|
886
|
+
if (format === "markdown") {
|
|
887
|
+
let source = getMarkdownSource?.();
|
|
888
|
+
if (source !== void 0)
|
|
889
|
+
text = source;
|
|
890
|
+
else {
|
|
891
|
+
let data = getTableData?.() ?? { headers, rows, align };
|
|
892
|
+
text = tableToMarkdown(data.headers, data.rows, data.align);
|
|
893
|
+
}
|
|
894
|
+
filename = "table.md", mimeType = "text/markdown;charset=utf-8";
|
|
895
|
+
} else if (format === "tsv") {
|
|
896
|
+
let data = getTableData?.() ?? { headers, rows, align };
|
|
897
|
+
text = tableToTsv(data.headers, data.rows), filename = "table.tsv", mimeType = "text/tab-separated-values;charset=utf-8";
|
|
898
|
+
} else {
|
|
899
|
+
let data = getTableData?.() ?? { headers, rows, align };
|
|
900
|
+
text = tableToCsv(data.headers, data.rows);
|
|
901
|
+
}
|
|
902
|
+
downloadFile(text, filename, mimeType);
|
|
903
|
+
},
|
|
904
|
+
[headers, rows, align, getTableData, getMarkdownSource, isFinalized]
|
|
905
|
+
);
|
|
906
|
+
return /* @__PURE__ */ jsxs4(
|
|
907
|
+
"div",
|
|
908
|
+
{
|
|
909
|
+
className: `stream-mdx-controls stream-mdx-table-controls flex items-center justify-end gap-1 px-2 py-1 text-xs select-none ${className ?? ""}`.trim(),
|
|
910
|
+
"data-stream-mdx-controls": "table",
|
|
911
|
+
children: [
|
|
912
|
+
config.copyFormats.map((format) => {
|
|
913
|
+
let isCopied = copiedFormat === format, defaultLabel = format === "markdown" ? "Copy Markdown" : "Copy TSV", labelText = format === "markdown" ? labels.copyMarkdown ?? defaultLabel : labels.copyTsv ?? defaultLabel;
|
|
914
|
+
return /* @__PURE__ */ jsx4(
|
|
915
|
+
"button",
|
|
916
|
+
{
|
|
917
|
+
type: "button",
|
|
918
|
+
disabled: !isFinalized,
|
|
919
|
+
className: `stream-mdx-control stream-mdx-control-copy stream-mdx-control-table-copy stream-mdx-control-copy-${format} inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs hover:bg-muted focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed`,
|
|
920
|
+
"data-stream-mdx-control": "copy",
|
|
921
|
+
"data-stream-mdx-target": "table",
|
|
922
|
+
"data-stream-mdx-format": format,
|
|
923
|
+
"data-stream-mdx-action": `copy-${format}`,
|
|
924
|
+
"data-format": format,
|
|
925
|
+
"aria-label": isCopied ? labels.copied ?? "Copied!" : labelText,
|
|
926
|
+
onClick: () => handleCopy(format),
|
|
927
|
+
children: isCopied ? labels.copied ?? "Copied!" : labelText
|
|
928
|
+
},
|
|
929
|
+
`copy-${format}`
|
|
930
|
+
);
|
|
931
|
+
}),
|
|
932
|
+
config.downloadFormats.map((format) => {
|
|
933
|
+
let defaultLabel = format === "csv" ? "Download CSV" : format === "tsv" ? "Download TSV" : "Download Markdown", labelText = format === "csv" ? labels.downloadCsv ?? defaultLabel : format === "tsv" ? labels.downloadTsv ?? defaultLabel : labels.downloadMarkdown ?? defaultLabel;
|
|
934
|
+
return /* @__PURE__ */ jsx4(
|
|
935
|
+
"button",
|
|
936
|
+
{
|
|
937
|
+
type: "button",
|
|
938
|
+
disabled: !isFinalized,
|
|
939
|
+
className: `stream-mdx-control stream-mdx-control-download stream-mdx-control-table-download stream-mdx-control-download-${format} inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs hover:bg-muted focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed`,
|
|
940
|
+
"data-stream-mdx-control": "download",
|
|
941
|
+
"data-stream-mdx-target": "table",
|
|
942
|
+
"data-stream-mdx-format": format,
|
|
943
|
+
"data-stream-mdx-action": `download-${format}`,
|
|
944
|
+
"data-format": format,
|
|
945
|
+
"aria-label": labelText,
|
|
946
|
+
onClick: () => handleDownload(format),
|
|
947
|
+
children: labelText
|
|
948
|
+
},
|
|
949
|
+
`download-${format}`
|
|
950
|
+
);
|
|
951
|
+
})
|
|
952
|
+
]
|
|
953
|
+
}
|
|
954
|
+
);
|
|
955
|
+
}, CodeBlockCopyButton = ({
|
|
956
|
+
code,
|
|
957
|
+
labels,
|
|
958
|
+
className,
|
|
959
|
+
...props
|
|
960
|
+
}) => {
|
|
961
|
+
let [copied, setCopied] = useState3(!1), copyLabel = labels?.copy ?? DEFAULT_CONTROLS_LABELS.copy ?? "Copy code", copiedLabel = labels?.copied ?? DEFAULT_CONTROLS_LABELS.copied ?? "Copied!", handleCopy = useCallback2(
|
|
962
|
+
async (e) => {
|
|
963
|
+
if (props.onClick?.(e), e.defaultPrevented) return;
|
|
964
|
+
await copyToClipboard(code) && (setCopied(!0), setTimeout(() => setCopied(!1), 2e3));
|
|
965
|
+
},
|
|
966
|
+
[code, props.onClick]
|
|
967
|
+
);
|
|
968
|
+
return /* @__PURE__ */ jsx4(
|
|
969
|
+
"button",
|
|
970
|
+
{
|
|
971
|
+
type: "button",
|
|
972
|
+
className: `stream-mdx-control stream-mdx-control-copy stream-mdx-control-code-copy ${className ?? ""}`.trim(),
|
|
973
|
+
"data-stream-mdx-control": "copy",
|
|
974
|
+
"data-stream-mdx-target": "code",
|
|
975
|
+
"data-stream-mdx-action": "copy",
|
|
976
|
+
"aria-label": copied ? copiedLabel : copyLabel,
|
|
977
|
+
...props,
|
|
978
|
+
onClick: handleCopy,
|
|
979
|
+
children: props.children ?? (copied ? copiedLabel : "Copy")
|
|
980
|
+
}
|
|
981
|
+
);
|
|
982
|
+
}, CodeBlockDownloadButton = ({
|
|
983
|
+
code,
|
|
984
|
+
language,
|
|
985
|
+
filename,
|
|
986
|
+
labels,
|
|
987
|
+
className,
|
|
988
|
+
...props
|
|
989
|
+
}) => {
|
|
990
|
+
let downloadLabel = labels?.download ?? DEFAULT_CONTROLS_LABELS.download ?? "Download snippet", handleDownload = useCallback2(
|
|
991
|
+
(e) => {
|
|
992
|
+
if (props.onClick?.(e), e.defaultPrevented) return;
|
|
993
|
+
let targetFilename = filename ?? getCodeSnippetFilename(language);
|
|
994
|
+
downloadFile(code, targetFilename);
|
|
995
|
+
},
|
|
996
|
+
[code, language, filename, props.onClick]
|
|
997
|
+
);
|
|
998
|
+
return /* @__PURE__ */ jsx4(
|
|
999
|
+
"button",
|
|
1000
|
+
{
|
|
1001
|
+
type: "button",
|
|
1002
|
+
className: `stream-mdx-control stream-mdx-control-download stream-mdx-control-code-download ${className ?? ""}`.trim(),
|
|
1003
|
+
"data-stream-mdx-control": "download",
|
|
1004
|
+
"data-stream-mdx-target": "code",
|
|
1005
|
+
"data-stream-mdx-action": "download",
|
|
1006
|
+
"aria-label": downloadLabel,
|
|
1007
|
+
...props,
|
|
1008
|
+
onClick: handleDownload,
|
|
1009
|
+
children: props.children ?? labels?.download ?? "Download"
|
|
1010
|
+
}
|
|
1011
|
+
);
|
|
1012
|
+
};
|
|
1013
|
+
|
|
1014
|
+
// src/animation.ts
|
|
1015
|
+
var BUILTIN_ANIMATION_NAMES = {
|
|
1016
|
+
fadeIn: "stream-mdx-fade-in",
|
|
1017
|
+
blurIn: "stream-mdx-blur-in",
|
|
1018
|
+
slideUp: "stream-mdx-slide-up"
|
|
1019
|
+
}, DEFAULT_ANIMATED_OPTIONS = {
|
|
1020
|
+
animation: "fadeIn",
|
|
1021
|
+
animationName: "stream-mdx-fade-in",
|
|
1022
|
+
duration: 150,
|
|
1023
|
+
durationStr: "150ms",
|
|
1024
|
+
easing: "ease-out",
|
|
1025
|
+
sep: "word",
|
|
1026
|
+
stagger: 20,
|
|
1027
|
+
maxBacklogMs: 320
|
|
1028
|
+
};
|
|
1029
|
+
function resolveAnimatedOptions(prop) {
|
|
1030
|
+
if (!prop) return null;
|
|
1031
|
+
if (prop === !0) return DEFAULT_ANIMATED_OPTIONS;
|
|
1032
|
+
let animation = prop.animation ?? DEFAULT_ANIMATED_OPTIONS.animation, duration = typeof prop.duration == "number" ? prop.duration : DEFAULT_ANIMATED_OPTIONS.duration;
|
|
1033
|
+
return {
|
|
1034
|
+
animation,
|
|
1035
|
+
animationName: BUILTIN_ANIMATION_NAMES[animation] ?? animation,
|
|
1036
|
+
duration,
|
|
1037
|
+
durationStr: `${duration}ms`,
|
|
1038
|
+
easing: prop.easing ?? DEFAULT_ANIMATED_OPTIONS.easing,
|
|
1039
|
+
sep: prop.sep ?? DEFAULT_ANIMATED_OPTIONS.sep,
|
|
1040
|
+
stagger: typeof prop.stagger == "number" ? prop.stagger : DEFAULT_ANIMATED_OPTIONS.stagger,
|
|
1041
|
+
maxBacklogMs: typeof prop.maxBacklogMs == "number" ? prop.maxBacklogMs : DEFAULT_ANIMATED_OPTIONS.maxBacklogMs
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
var STREAM_MDX_ANIMATION_CSS = `
|
|
1045
|
+
@keyframes stream-mdx-fade-in {
|
|
1046
|
+
from {
|
|
1047
|
+
opacity: 0;
|
|
1048
|
+
}
|
|
1049
|
+
to {
|
|
1050
|
+
opacity: 1;
|
|
1051
|
+
}
|
|
808
1052
|
}
|
|
809
1053
|
|
|
1054
|
+
@keyframes fadeIn {
|
|
1055
|
+
from {
|
|
1056
|
+
opacity: 0;
|
|
1057
|
+
}
|
|
1058
|
+
to {
|
|
1059
|
+
opacity: 1;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
@keyframes stream-mdx-blur-in {
|
|
1064
|
+
from {
|
|
1065
|
+
opacity: 0;
|
|
1066
|
+
filter: blur(4px);
|
|
1067
|
+
}
|
|
1068
|
+
to {
|
|
1069
|
+
opacity: 1;
|
|
1070
|
+
filter: blur(0px);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
@keyframes blurIn {
|
|
1075
|
+
from {
|
|
1076
|
+
opacity: 0;
|
|
1077
|
+
filter: blur(4px);
|
|
1078
|
+
}
|
|
1079
|
+
to {
|
|
1080
|
+
opacity: 1;
|
|
1081
|
+
filter: blur(0px);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
@keyframes stream-mdx-slide-up {
|
|
1086
|
+
from {
|
|
1087
|
+
opacity: 0;
|
|
1088
|
+
transform: translateY(4px);
|
|
1089
|
+
}
|
|
1090
|
+
to {
|
|
1091
|
+
opacity: 1;
|
|
1092
|
+
transform: translateY(0);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
@keyframes slideUp {
|
|
1097
|
+
from {
|
|
1098
|
+
opacity: 0;
|
|
1099
|
+
transform: translateY(4px);
|
|
1100
|
+
}
|
|
1101
|
+
to {
|
|
1102
|
+
opacity: 1;
|
|
1103
|
+
transform: translateY(0);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
.stream-mdx-anim {
|
|
1108
|
+
display: inline;
|
|
1109
|
+
animation-name: var(--sm-anim-name, stream-mdx-fade-in);
|
|
1110
|
+
animation-duration: var(--sm-anim-duration, 150ms);
|
|
1111
|
+
animation-timing-function: var(--sm-anim-easing, ease-out);
|
|
1112
|
+
animation-delay: var(--sm-anim-delay, 0ms);
|
|
1113
|
+
animation-fill-mode: both;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1117
|
+
.stream-mdx-anim {
|
|
1118
|
+
animation: none !important;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
`.trim(), WHITESPACE_REGEX = /\s/;
|
|
1122
|
+
function splitWordSegments(text) {
|
|
1123
|
+
let result = [], current = "", inWhitespace = !1;
|
|
1124
|
+
for (let char of text) {
|
|
1125
|
+
let isSpace = WHITESPACE_REGEX.test(char);
|
|
1126
|
+
if (isSpace !== inWhitespace && current) {
|
|
1127
|
+
if (isSpace) {
|
|
1128
|
+
current += char, inWhitespace = !0;
|
|
1129
|
+
continue;
|
|
1130
|
+
}
|
|
1131
|
+
result.push(current), current = "";
|
|
1132
|
+
}
|
|
1133
|
+
current += char, inWhitespace = isSpace;
|
|
1134
|
+
}
|
|
1135
|
+
return current && result.push(current), result;
|
|
1136
|
+
}
|
|
1137
|
+
function splitTextSegments(text, sep) {
|
|
1138
|
+
return sep === "char" ? Array.from(text) : splitWordSegments(text);
|
|
1139
|
+
}
|
|
1140
|
+
var AnimationTimeline = class {
|
|
1141
|
+
constructor(options) {
|
|
1142
|
+
this.committedEndTime = 0;
|
|
1143
|
+
this.cursorEndTime = 0;
|
|
1144
|
+
this.passActive = !1;
|
|
1145
|
+
this.nodeStates = /* @__PURE__ */ new Map();
|
|
1146
|
+
this.now = options?.now ?? (() => typeof performance < "u" ? performance.now() : Date.now()), this.maxBacklogMs = options?.maxBacklogMs ?? 320, this.stagger = options?.stagger ?? 20;
|
|
1147
|
+
}
|
|
1148
|
+
updateOptions(options) {
|
|
1149
|
+
typeof options.maxBacklogMs == "number" && (this.maxBacklogMs = options.maxBacklogMs), typeof options.stagger == "number" && (this.stagger = options.stagger);
|
|
1150
|
+
}
|
|
1151
|
+
beginPass(currentTime = this.now()) {
|
|
1152
|
+
this.passActive || (this.passActive = !0, this.cursorEndTime = Math.min(
|
|
1153
|
+
Math.max(this.committedEndTime, currentTime),
|
|
1154
|
+
currentTime + this.maxBacklogMs
|
|
1155
|
+
), typeof queueMicrotask == "function" ? queueMicrotask(() => this.commitPass()) : setTimeout(() => this.commitPass(), 0));
|
|
1156
|
+
}
|
|
1157
|
+
commitPass() {
|
|
1158
|
+
this.committedEndTime = this.cursorEndTime, this.passActive = !1;
|
|
1159
|
+
}
|
|
1160
|
+
schedule(count, stagger = this.stagger, currentTime = this.now()) {
|
|
1161
|
+
if (this.beginPass(currentTime), count <= 0) return [];
|
|
1162
|
+
let d = Math.max(0, stagger), maxDeadline = currentTime + this.maxBacklogMs, start = Math.min(Math.max(this.cursorEndTime, currentTime), maxDeadline), step = count > 1 ? Math.min(d, Math.max(0, maxDeadline - start) / (count - 1)) : d, baseDelay = Math.max(0, start - currentTime);
|
|
1163
|
+
this.cursorEndTime = Math.min(start + count * step, maxDeadline);
|
|
1164
|
+
let delays = [];
|
|
1165
|
+
for (let i = 0; i < count; i++)
|
|
1166
|
+
delays.push(Math.min(this.maxBacklogMs, Math.round(baseDelay + i * step)));
|
|
1167
|
+
return delays;
|
|
1168
|
+
}
|
|
1169
|
+
getNodeState(key) {
|
|
1170
|
+
let state = this.nodeStates.get(key);
|
|
1171
|
+
return state || (state = { count: 0, delays: [] }, this.nodeStates.set(key, state)), state;
|
|
1172
|
+
}
|
|
1173
|
+
reset() {
|
|
1174
|
+
this.committedEndTime = 0, this.cursorEndTime = 0, this.passActive = !1, this.nodeStates.clear();
|
|
1175
|
+
}
|
|
1176
|
+
releasePrefix(prefix) {
|
|
1177
|
+
let prefixColon = `${prefix}:`;
|
|
1178
|
+
for (let key of this.nodeStates.keys())
|
|
1179
|
+
(key === prefix || key.startsWith(prefixColon)) && this.nodeStates.delete(key);
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
|
|
810
1183
|
// src/components/index.ts
|
|
1184
|
+
import { defaultUrlTransform as defaultUrlTransform3 } from "@stream-mdx/core";
|
|
1185
|
+
import { InlineParser, createTrustedHTML, defaultUrlTransform as defaultUrlTransform4, isForbiddenAttribute as isForbiddenAttribute2, isSafeStyleDeclaration as isSafeStyleDeclaration2, sanitizeHTML, stripCodeFence } from "@stream-mdx/core";
|
|
811
1186
|
import { removeHeadingMarkers } from "@stream-mdx/core";
|
|
812
|
-
import
|
|
1187
|
+
import React8 from "react";
|
|
813
1188
|
|
|
814
1189
|
// src/utils/inline-html.ts
|
|
815
1190
|
import React3 from "react";
|
|
816
|
-
|
|
817
|
-
|
|
1191
|
+
import { defaultUrlTransform, isForbiddenAttribute, isSafeStyleDeclaration } from "@stream-mdx/core";
|
|
1192
|
+
function renderHtmlInlineNode(node, children, elements, key, textValue, urlTransform, filterElement, parentTagName, renderPresentation, renderNativeElement) {
|
|
1193
|
+
if (node.isClose || node.tagName === "script" || node.tagName === "style") return null;
|
|
1194
|
+
if (!node.tagName || node.sanitized === "")
|
|
1195
|
+
return React3.createElement(React3.Fragment, { key }, children);
|
|
1196
|
+
let tag = node.tagName.toLowerCase(), props = mapAttributesToProps(node.attributes ?? {}, urlTransform);
|
|
1197
|
+
props.key = key;
|
|
1198
|
+
let renderElement = () => {
|
|
1199
|
+
let nativeView;
|
|
1200
|
+
return renderNativeElement ? nativeView = renderNativeElement(
|
|
1201
|
+
tag,
|
|
1202
|
+
props,
|
|
1203
|
+
node.isSelfClosing ? void 0 : children,
|
|
1204
|
+
key ?? tag
|
|
1205
|
+
) : tag === "textarea" ? (props.defaultValue = textValue ?? "", nativeView = React3.createElement(elements?.[tag] ?? tag, props)) : nativeView = React3.createElement(elements?.[tag] ?? tag, props, node.isSelfClosing ? void 0 : children), renderPresentation ? renderPresentation(tag, props, nativeView, children, key ?? tag) : nativeView;
|
|
1206
|
+
};
|
|
1207
|
+
return filterElement ? filterElement(
|
|
1208
|
+
{ tagName: tag, properties: props },
|
|
1209
|
+
{ source: "html", parentTagName },
|
|
1210
|
+
renderElement,
|
|
1211
|
+
() => children
|
|
1212
|
+
) : renderElement();
|
|
1213
|
+
}
|
|
1214
|
+
function renderHtmlOwnershipTree(nodes, elements, renderBlock, renderInline, renderInlineElement, renderParagraph, urlTransform, filterElement, parentTagName, contentComponents, renderPresentation, parentPath = "html", renderComponentPresentation) {
|
|
1215
|
+
return nodes.map((node, index) => {
|
|
1216
|
+
let nodeKey = `${parentPath}:${index}`;
|
|
1217
|
+
if (node.kind === "text") return node.inline && renderInline ? renderInline(node.inline, parentTagName) : node.rawSource ?? node.text;
|
|
1218
|
+
if (node.kind === "block") return renderBlock(node.block, parentTagName);
|
|
1219
|
+
if (node.kind === "component") {
|
|
1220
|
+
let reg = contentComponents?.[node.name];
|
|
1221
|
+
if (!reg)
|
|
1222
|
+
return React3.createElement(React3.Fragment, { key: nodeKey }, node.rawSource ?? `<${node.name} />`);
|
|
1223
|
+
let result = reg.render({
|
|
1224
|
+
props: node.props,
|
|
1225
|
+
key: index,
|
|
1226
|
+
hasChildren: node.children.length > 0,
|
|
1227
|
+
renderChildren: () => renderHtmlOwnershipTree(
|
|
1228
|
+
node.children,
|
|
1229
|
+
elements,
|
|
1230
|
+
renderBlock,
|
|
1231
|
+
renderInline,
|
|
1232
|
+
renderInlineElement,
|
|
1233
|
+
renderParagraph,
|
|
1234
|
+
urlTransform,
|
|
1235
|
+
filterElement,
|
|
1236
|
+
node.name,
|
|
1237
|
+
contentComponents,
|
|
1238
|
+
renderPresentation,
|
|
1239
|
+
nodeKey,
|
|
1240
|
+
renderComponentPresentation
|
|
1241
|
+
),
|
|
1242
|
+
status: node.status,
|
|
1243
|
+
diagnostic: node.diagnostic
|
|
1244
|
+
});
|
|
1245
|
+
return result.kind === "invalid" ? React3.createElement(React3.Fragment, { key: nodeKey }, node.rawSource ?? `<${node.name} />`) : result.kind === "suppressed" ? null : renderComponentPresentation ? renderComponentPresentation(
|
|
1246
|
+
node.name,
|
|
1247
|
+
result.element,
|
|
1248
|
+
React3.isValidElement(result.element) ? result.element.props.children : void 0,
|
|
1249
|
+
nodeKey,
|
|
1250
|
+
node.status,
|
|
1251
|
+
node.rawSource
|
|
1252
|
+
) : result.element;
|
|
1253
|
+
}
|
|
1254
|
+
let tag = node.tagName.toLowerCase(), props = mapAttributesToProps(node.attributes, urlTransform);
|
|
1255
|
+
props.key = nodeKey;
|
|
1256
|
+
let children = renderHtmlOwnershipTree(node.children, elements, renderBlock, renderInline, renderInlineElement, renderParagraph, urlTransform, filterElement, tag, contentComponents, renderPresentation, nodeKey, renderComponentPresentation);
|
|
1257
|
+
if (node.paragraphRoot && renderParagraph) {
|
|
1258
|
+
let paragraph = filterElement ? filterElement(
|
|
1259
|
+
{ tagName: "p", properties: props, blockType: "paragraph" },
|
|
1260
|
+
{ source: "markdown", parentTagName },
|
|
1261
|
+
() => renderParagraph(children),
|
|
1262
|
+
() => children
|
|
1263
|
+
) : renderParagraph(children);
|
|
1264
|
+
return React3.createElement(React3.Fragment, { key: nodeKey }, paragraph);
|
|
1265
|
+
}
|
|
1266
|
+
if (node.inlineNode && renderInlineElement)
|
|
1267
|
+
return React3.createElement(React3.Fragment, { key: nodeKey }, renderInlineElement(node.inlineNode, children, parentTagName, nodeKey));
|
|
1268
|
+
let renderElement = () => {
|
|
1269
|
+
let nativeView;
|
|
1270
|
+
if (tag === "textarea")
|
|
1271
|
+
props.defaultValue = node.children.map((child) => child.kind === "text" ? child.text : "").join(""), nativeView = React3.createElement(elements[tag] ?? tag, props);
|
|
1272
|
+
else {
|
|
1273
|
+
let content = tag === "pre" && node.children.every((child) => child.kind === "text" && !child.inline) ? node.children.map((child) => child.kind === "text" ? child.text : "").join("") : children;
|
|
1274
|
+
nativeView = React3.createElement(elements[tag] ?? tag, props, node.children.length ? content : void 0);
|
|
1275
|
+
}
|
|
1276
|
+
return renderPresentation ? renderPresentation(tag, props, nativeView, children, nodeKey) : nativeView;
|
|
1277
|
+
};
|
|
1278
|
+
return filterElement ? filterElement(
|
|
1279
|
+
{ tagName: tag, properties: props },
|
|
1280
|
+
{ source: "html", parentTagName },
|
|
1281
|
+
renderElement,
|
|
1282
|
+
() => children
|
|
1283
|
+
) : renderElement();
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
var BACKTICK_CONTENT = /^`([\s\S]+)`$/, DEFAULT_INLINE_HTML_RENDERERS = {
|
|
818
1287
|
kbd: (descriptor, ctx) => {
|
|
819
|
-
|
|
820
|
-
const match = BACKTICK_CONTENT.exec(trimmed);
|
|
1288
|
+
let trimmed = descriptor.rawInner.trim(), match = BACKTICK_CONTENT.exec(trimmed);
|
|
821
1289
|
if (match) {
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
if (ctx.key !== void 0 && ctx.key !== null) {
|
|
825
|
-
props.key = ctx.key;
|
|
826
|
-
}
|
|
827
|
-
return React3.createElement("kbd", props, React3.createElement("code", { className: "inline-code" }, codeText));
|
|
1290
|
+
let codeText = decodeHtmlEntities(match[1]), props = mapAttributesToProps(descriptor.attributes);
|
|
1291
|
+
return ctx.key !== void 0 && ctx.key !== null && (props.key = ctx.key), React3.createElement("kbd", props, React3.createElement("code", { className: "inline-code" }, codeText));
|
|
828
1292
|
}
|
|
829
1293
|
return ctx.defaultRender();
|
|
830
1294
|
}
|
|
831
1295
|
};
|
|
832
1296
|
function renderInlineHtmlSegment(raw, sanitized, options = {}) {
|
|
833
|
-
|
|
834
|
-
if (!descriptor)
|
|
1297
|
+
let descriptor = parseInlineHtmlDescriptor(raw, sanitized);
|
|
1298
|
+
if (!descriptor)
|
|
835
1299
|
return null;
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
const defaultRender = () => {
|
|
840
|
-
if (!descriptor.sanitized || descriptor.sanitized.length === 0) {
|
|
841
|
-
if (!descriptor.text) {
|
|
842
|
-
return null;
|
|
843
|
-
}
|
|
844
|
-
if (options.key !== void 0 && options.key !== null) {
|
|
845
|
-
return React3.createElement(React3.Fragment, { key: options.key }, descriptor.text);
|
|
846
|
-
}
|
|
847
|
-
return React3.createElement(React3.Fragment, {}, descriptor.text);
|
|
848
|
-
}
|
|
1300
|
+
let className = options.className ?? "markdown-inline-html", hasCustomElement = !!options.htmlElements?.[descriptor.tagName], isInlineTag = INLINE_ELEMENTS.has(descriptor.tagName) || hasCustomElement, defaultRender = () => {
|
|
1301
|
+
if (!descriptor.sanitized || descriptor.sanitized.length === 0)
|
|
1302
|
+
return descriptor.text ? options.key !== void 0 && options.key !== null ? React3.createElement(React3.Fragment, { key: options.key }, descriptor.text) : React3.createElement(React3.Fragment, {}, descriptor.text) : null;
|
|
849
1303
|
if (isInlineTag) {
|
|
850
|
-
|
|
851
|
-
|
|
1304
|
+
let parsedElement = renderSanitizedHtmlTree(
|
|
1305
|
+
descriptor.sanitized,
|
|
1306
|
+
options.key,
|
|
1307
|
+
options.htmlElements,
|
|
1308
|
+
options.literalTagContent,
|
|
1309
|
+
options.parseMarkdown
|
|
1310
|
+
);
|
|
1311
|
+
if (parsedElement)
|
|
852
1312
|
return parsedElement;
|
|
853
|
-
}
|
|
854
1313
|
}
|
|
855
|
-
|
|
1314
|
+
let customElementComp = options.htmlElements?.[descriptor.tagName];
|
|
1315
|
+
if (customElementComp) {
|
|
1316
|
+
let props2 = mapAttributesToProps(descriptor.attributes, options.urlTransform);
|
|
1317
|
+
return options.key !== void 0 && options.key !== null && (props2.key = options.key), React3.createElement(customElementComp, props2, descriptor.text || descriptor.sanitizedInner || void 0);
|
|
1318
|
+
}
|
|
1319
|
+
let props = {
|
|
856
1320
|
className,
|
|
857
1321
|
dangerouslySetInnerHTML: { __html: descriptor.sanitized }
|
|
858
1322
|
};
|
|
859
|
-
|
|
860
|
-
props.key = options.key;
|
|
861
|
-
}
|
|
862
|
-
return React3.createElement("span", props);
|
|
1323
|
+
return options.key !== void 0 && options.key !== null && (props.key = options.key), React3.createElement("span", props);
|
|
863
1324
|
};
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
return React3.cloneElement(rendered, { key: options.key });
|
|
871
|
-
}
|
|
872
|
-
return rendered;
|
|
1325
|
+
if (!hasCustomElement) {
|
|
1326
|
+
let renderer = (options.renderers ? { ...DEFAULT_INLINE_HTML_RENDERERS, ...options.renderers } : DEFAULT_INLINE_HTML_RENDERERS)[descriptor.tagName];
|
|
1327
|
+
if (renderer) {
|
|
1328
|
+
let rendered = renderer(descriptor, { key: options.key, defaultRender });
|
|
1329
|
+
if (rendered)
|
|
1330
|
+
return options.key !== void 0 && options.key !== null && React3.isValidElement(rendered) && rendered.key === null ? React3.cloneElement(rendered, { key: options.key }) : rendered;
|
|
873
1331
|
}
|
|
874
1332
|
}
|
|
875
1333
|
return defaultRender();
|
|
876
1334
|
}
|
|
877
1335
|
function parseInlineHtmlDescriptor(raw, sanitized) {
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
if (!normalizedSanitized) {
|
|
881
|
-
return null;
|
|
882
|
-
}
|
|
883
|
-
const match = normalizedSanitized.match(/^<([A-Za-z][\w:-]*)(\s[^>]*)?>([\s\S]*)<\/\1>$/);
|
|
884
|
-
if (!match) {
|
|
1336
|
+
let normalizedRaw = typeof raw == "string" ? raw.trim() : "", normalizedSanitized = typeof sanitized == "string" && sanitized.length > 0 ? sanitized.trim() : normalizedRaw;
|
|
1337
|
+
if (!normalizedSanitized)
|
|
885
1338
|
return null;
|
|
1339
|
+
let pairedMatch = normalizedSanitized.match(/^<([A-Za-z][\w:-]*)((?:\s+[^>]*)?)>([\s\S]*)<\/\1>$/), tagNameRaw, attrString = "", sanitizedInner = "";
|
|
1340
|
+
if (pairedMatch)
|
|
1341
|
+
tagNameRaw = pairedMatch[1], attrString = pairedMatch[2] ?? "", sanitizedInner = pairedMatch[3] ?? "";
|
|
1342
|
+
else {
|
|
1343
|
+
let selfClosingMatch = normalizedSanitized.match(/^<([A-Za-z][\w:-]*)((?:\s+[^>]*)?)\s*(?:\/?>|>)$/) || normalizedRaw.match(/^<([A-Za-z][\w:-]*)((?:\s+[^>]*)?)\s*(?:\/?>|>)$/);
|
|
1344
|
+
if (!selfClosingMatch)
|
|
1345
|
+
return null;
|
|
1346
|
+
tagNameRaw = selfClosingMatch[1], attrString = selfClosingMatch[2] ?? "", sanitizedInner = "";
|
|
886
1347
|
}
|
|
887
|
-
|
|
888
|
-
const tagName = tagNameRaw.toLowerCase();
|
|
889
|
-
const attributes = parseAttributes(attrString);
|
|
890
|
-
let rawInner = "";
|
|
1348
|
+
let tagName = tagNameRaw.toLowerCase(), attributes = parseAttributes(attrString), rawInner = "";
|
|
891
1349
|
if (normalizedRaw) {
|
|
892
|
-
|
|
1350
|
+
let rawMatch = normalizedRaw.match(/^<([A-Za-z][\w:-]*)(\s[^>]*)?>([\s\S]*)<\/\1>$/);
|
|
893
1351
|
rawInner = rawMatch ? rawMatch[3] ?? "" : normalizedRaw;
|
|
894
1352
|
}
|
|
895
|
-
|
|
1353
|
+
let text = extractPlainText(rawInner || sanitizedInner);
|
|
896
1354
|
return {
|
|
897
1355
|
tagName,
|
|
898
1356
|
attributes,
|
|
@@ -904,52 +1362,91 @@ function parseInlineHtmlDescriptor(raw, sanitized) {
|
|
|
904
1362
|
};
|
|
905
1363
|
}
|
|
906
1364
|
function parseAttributes(input) {
|
|
907
|
-
|
|
1365
|
+
let attrs = {};
|
|
908
1366
|
if (!input) return attrs;
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
const name = match[1];
|
|
1367
|
+
let attrPattern = /([A-Za-z_:][\w:.\-]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g, match = attrPattern.exec(input);
|
|
1368
|
+
for (; match !== null; ) {
|
|
1369
|
+
let name = match[1];
|
|
913
1370
|
if (!name) continue;
|
|
914
|
-
|
|
915
|
-
attrs[name] = value;
|
|
916
|
-
match = attrPattern.exec(input);
|
|
1371
|
+
let value = match[2] ?? match[3] ?? match[4] ?? "";
|
|
1372
|
+
attrs[name] = value, match = attrPattern.exec(input);
|
|
917
1373
|
}
|
|
918
1374
|
return attrs;
|
|
919
1375
|
}
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
1376
|
+
var BOOLEAN_HTML_PROPS = {
|
|
1377
|
+
allowFullScreen: !0,
|
|
1378
|
+
async: !0,
|
|
1379
|
+
autoFocus: !0,
|
|
1380
|
+
autoPlay: !0,
|
|
1381
|
+
checked: !0,
|
|
1382
|
+
controls: !0,
|
|
1383
|
+
default: !0,
|
|
1384
|
+
defer: !0,
|
|
1385
|
+
disabled: !0,
|
|
1386
|
+
formNoValidate: !0,
|
|
1387
|
+
hidden: !0,
|
|
1388
|
+
inert: !0,
|
|
1389
|
+
loop: !0,
|
|
1390
|
+
multiple: !0,
|
|
1391
|
+
muted: !0,
|
|
1392
|
+
noModule: !0,
|
|
1393
|
+
noValidate: !0,
|
|
1394
|
+
open: !0,
|
|
1395
|
+
playsInline: !0,
|
|
1396
|
+
readOnly: !0,
|
|
1397
|
+
required: !0,
|
|
1398
|
+
reversed: !0,
|
|
1399
|
+
selected: !0,
|
|
1400
|
+
itemScope: !0
|
|
1401
|
+
};
|
|
1402
|
+
function mapAttributesToProps(attrs, urlTransform) {
|
|
1403
|
+
let props = {}, transform = urlTransform ?? defaultUrlTransform;
|
|
1404
|
+
for (let [key, value] of Object.entries(attrs)) {
|
|
1405
|
+
let lower = key.toLowerCase();
|
|
1406
|
+
if (!isForbiddenAttribute(lower))
|
|
1407
|
+
if (key === "class")
|
|
1408
|
+
props.className = value;
|
|
1409
|
+
else if (key === "style")
|
|
1410
|
+
props.style = parseStyleAttribute(value);
|
|
1411
|
+
else if (key === "tabindex" || key === "tabIndex") {
|
|
1412
|
+
let normalized = normalizeTabIndex(value);
|
|
1413
|
+
normalized !== void 0 && (props.tabIndex = normalized);
|
|
1414
|
+
} else if (lower === "href") {
|
|
1415
|
+
let safe = transform(value, "href", { source: "html" });
|
|
1416
|
+
safe != null && (props.href = safe);
|
|
1417
|
+
} else if (lower === "src") {
|
|
1418
|
+
let safe = transform(value, "src", { source: "html" });
|
|
1419
|
+
safe != null && (props.src = safe);
|
|
1420
|
+
} else if (lower === "action") {
|
|
1421
|
+
let safe = transform(value, "href", { source: "html" });
|
|
1422
|
+
safe != null && (props.action = safe);
|
|
1423
|
+
} else if (lower === "formaction") {
|
|
1424
|
+
let safe = transform(value, "href", { source: "html" });
|
|
1425
|
+
safe != null && (props.formAction = safe);
|
|
1426
|
+
} else if (lower === "xlink:href" || lower === "xlinkhref") {
|
|
1427
|
+
let safe = transform(value, "href", { source: "html" });
|
|
1428
|
+
safe != null && (props.xlinkHref = safe);
|
|
1429
|
+
} else /^(?:data|aria)[A-Z]/.test(key) ? props[key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)] = value : BOOLEAN_HTML_PROPS[key] ? props[key] = !0 : props[key] = value;
|
|
935
1430
|
}
|
|
936
1431
|
return props;
|
|
937
1432
|
}
|
|
938
1433
|
function parseStyleAttribute(value) {
|
|
939
|
-
|
|
1434
|
+
let style = {};
|
|
940
1435
|
if (!value) return style;
|
|
941
|
-
|
|
942
|
-
for (
|
|
1436
|
+
let pairs = value.split(";");
|
|
1437
|
+
for (let pair of pairs) {
|
|
943
1438
|
if (!pair.trim()) continue;
|
|
944
|
-
|
|
945
|
-
if (
|
|
946
|
-
|
|
947
|
-
|
|
1439
|
+
let separator = pair.indexOf(":");
|
|
1440
|
+
if (separator <= 0) continue;
|
|
1441
|
+
let property = pair.slice(0, separator).trim(), rawVal = pair.slice(separator + 1).trim();
|
|
1442
|
+
if (!isSafeStyleDeclaration(property, rawVal)) continue;
|
|
1443
|
+
let camelProp = property.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
1444
|
+
style[camelProp] = rawVal;
|
|
948
1445
|
}
|
|
949
1446
|
return style;
|
|
950
1447
|
}
|
|
951
1448
|
function normalizeTabIndex(value) {
|
|
952
|
-
|
|
1449
|
+
let numeric = Number(value);
|
|
953
1450
|
return Number.isNaN(numeric) ? void 0 : numeric;
|
|
954
1451
|
}
|
|
955
1452
|
function decodeHtmlEntities(value) {
|
|
@@ -957,76 +1454,50 @@ function decodeHtmlEntities(value) {
|
|
|
957
1454
|
}
|
|
958
1455
|
function extractPlainText(value) {
|
|
959
1456
|
if (!value) return "";
|
|
960
|
-
|
|
1457
|
+
let withoutTags = value.replace(/<\/?[^>]+>/g, "");
|
|
961
1458
|
return decodeHtmlEntities(withoutTags);
|
|
962
1459
|
}
|
|
963
|
-
|
|
964
|
-
|
|
1460
|
+
var DEFAULT_LITERAL_TAGS = /* @__PURE__ */ new Set(["code", "pre", "script", "style", "textarea"]);
|
|
1461
|
+
function renderSanitizedHtmlTree(html, key, htmlElements, literalTagContent, parseMarkdown) {
|
|
1462
|
+
if (typeof DOMParser > "u")
|
|
965
1463
|
return null;
|
|
966
|
-
}
|
|
967
1464
|
try {
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
const body = doc.body;
|
|
971
|
-
const nodes = Array.from(body.childNodes);
|
|
972
|
-
if (nodes.length === 0) {
|
|
1465
|
+
let body = new DOMParser().parseFromString(html, "text/html").body, nodes = Array.from(body.childNodes);
|
|
1466
|
+
if (nodes.length === 0)
|
|
973
1467
|
return null;
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
const children = nodes.map((node, index) => convertDomNode(node, `${baseKey}-${index}`)).filter((child) => child !== null && child !== void 0);
|
|
977
|
-
if (children.length === 0) {
|
|
1468
|
+
let literalTags = literalTagContent ? /* @__PURE__ */ new Set([...DEFAULT_LITERAL_TAGS, ...literalTagContent.map((t) => t.toLowerCase())]) : DEFAULT_LITERAL_TAGS, baseKey = typeof key == "string" || typeof key == "number" ? String(key) : "inline-html", children = nodes.map((node, index) => convertDomNode(node, `${baseKey}-${index}`, htmlElements, literalTags, !1, parseMarkdown)).filter((child) => child != null);
|
|
1469
|
+
if (children.length === 0)
|
|
978
1470
|
return null;
|
|
979
|
-
}
|
|
980
1471
|
if (children.length === 1) {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
if (key !== void 0 && key !== null) {
|
|
984
|
-
return React3.cloneElement(child, { key });
|
|
985
|
-
}
|
|
986
|
-
return child;
|
|
987
|
-
}
|
|
988
|
-
if (typeof child === "string" || typeof child === "number") {
|
|
989
|
-
if (key !== void 0 && key !== null) {
|
|
990
|
-
return React3.createElement(React3.Fragment, { key }, child);
|
|
991
|
-
}
|
|
992
|
-
return React3.createElement(React3.Fragment, {}, child);
|
|
993
|
-
}
|
|
994
|
-
return React3.createElement(React3.Fragment, { key }, child);
|
|
1472
|
+
let [child] = children;
|
|
1473
|
+
return React3.isValidElement(child) ? key != null ? React3.cloneElement(child, { key }) : child : typeof child == "string" || typeof child == "number" ? key != null ? React3.createElement(React3.Fragment, { key }, child) : React3.createElement(React3.Fragment, {}, child) : React3.createElement(React3.Fragment, { key }, child);
|
|
995
1474
|
}
|
|
996
1475
|
return React3.createElement(React3.Fragment, { key }, ...children);
|
|
997
1476
|
} catch {
|
|
998
1477
|
return null;
|
|
999
1478
|
}
|
|
1000
1479
|
}
|
|
1001
|
-
function convertDomNode(node, key) {
|
|
1480
|
+
function convertDomNode(node, key, htmlElements, literalTags, parentIsLiteral, parseMarkdown) {
|
|
1002
1481
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
1003
|
-
|
|
1482
|
+
let rawText = node.textContent ?? "";
|
|
1483
|
+
return parentIsLiteral || !parseMarkdown ? rawText : parseMarkdown(rawText);
|
|
1004
1484
|
}
|
|
1005
|
-
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
1485
|
+
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
1006
1486
|
return null;
|
|
1007
|
-
|
|
1008
|
-
const element = node;
|
|
1009
|
-
const tagName = element.tagName.toLowerCase();
|
|
1010
|
-
const attrs = getElementAttributes(element);
|
|
1011
|
-
const props = mapAttributesToProps(attrs);
|
|
1487
|
+
let element = node, tagName = element.tagName.toLowerCase(), attrs = getElementAttributes(element), props = mapAttributesToProps(attrs);
|
|
1012
1488
|
props.key = key;
|
|
1013
|
-
|
|
1489
|
+
let isLiteral = parentIsLiteral || (literalTags ? literalTags.has(tagName) : !1), children = [];
|
|
1014
1490
|
element.childNodes.forEach((child, index) => {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
children.push(converted);
|
|
1018
|
-
}
|
|
1491
|
+
let converted = convertDomNode(child, `${key}-${index}`, htmlElements, literalTags, isLiteral, parseMarkdown);
|
|
1492
|
+
converted != null && children.push(converted);
|
|
1019
1493
|
});
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
}
|
|
1023
|
-
return React3.createElement(tagName, props, ...children);
|
|
1494
|
+
let customComponent = htmlElements?.[tagName];
|
|
1495
|
+
return customComponent ? children.length === 0 ? React3.createElement(customComponent, props) : React3.createElement(customComponent, props, ...children) : children.length === 0 ? React3.createElement(tagName, props) : React3.createElement(tagName, props, ...children);
|
|
1024
1496
|
}
|
|
1025
1497
|
function getElementAttributes(element) {
|
|
1026
|
-
|
|
1027
|
-
for (
|
|
1498
|
+
let attrs = {};
|
|
1499
|
+
for (let attr of Array.from(element.attributes))
|
|
1028
1500
|
attrs[attr.name] = attr.value;
|
|
1029
|
-
}
|
|
1030
1501
|
return attrs;
|
|
1031
1502
|
}
|
|
1032
1503
|
var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
|
|
@@ -1036,6 +1507,11 @@ var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
1036
1507
|
"bdi",
|
|
1037
1508
|
"bdo",
|
|
1038
1509
|
"br",
|
|
1510
|
+
"img",
|
|
1511
|
+
"input",
|
|
1512
|
+
"picture",
|
|
1513
|
+
"del",
|
|
1514
|
+
"ins",
|
|
1039
1515
|
"cite",
|
|
1040
1516
|
"code",
|
|
1041
1517
|
"data",
|
|
@@ -1080,67 +1556,404 @@ var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
1080
1556
|
"mtd"
|
|
1081
1557
|
]);
|
|
1082
1558
|
|
|
1083
|
-
// src/components/
|
|
1084
|
-
import
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1559
|
+
// src/components/owned-html.tsx
|
|
1560
|
+
import React4 from "react";
|
|
1561
|
+
import { defaultUrlTransform as defaultUrlTransform2 } from "@stream-mdx/core";
|
|
1562
|
+
function renderOwnedHtmlTree(tree, context) {
|
|
1563
|
+
return renderHtmlOwnershipTree(
|
|
1564
|
+
tree,
|
|
1565
|
+
context.elements,
|
|
1566
|
+
context.renderBlock,
|
|
1567
|
+
context.renderInline,
|
|
1568
|
+
(node, children, parentTagName, key) => {
|
|
1569
|
+
if (node.kind === "strong" || node.kind === "em" || node.kind === "strike" || node.kind === "link") {
|
|
1570
|
+
let component = context.inlineComponents[node.kind], renderElement = () => {
|
|
1571
|
+
let direct;
|
|
1572
|
+
if (node.kind === "link") {
|
|
1573
|
+
if (node.autolink && context.isAutolinkProtocolDisabled(node.href)) return children;
|
|
1574
|
+
let { href, ...linkProps } = node, safeHref = (context.urlTransform ?? defaultUrlTransform2)(href ?? "", "href", { source: "markdown" });
|
|
1575
|
+
direct = component ? React4.createElement(component, {
|
|
1576
|
+
...linkProps,
|
|
1577
|
+
key,
|
|
1578
|
+
...safeHref != null ? { href: safeHref } : {},
|
|
1579
|
+
children
|
|
1580
|
+
}) : React4.createElement("a", { key, href: safeHref ?? void 0 }, children);
|
|
1581
|
+
} else {
|
|
1582
|
+
let tag2 = node.kind === "strike" ? "del" : node.kind;
|
|
1583
|
+
direct = component ? React4.createElement(component, { ...node, key, children }) : React4.createElement(tag2, { key }, children);
|
|
1584
|
+
}
|
|
1585
|
+
return context.renderInlinePresentation ? context.renderInlinePresentation(node, direct, key) : direct;
|
|
1586
|
+
};
|
|
1587
|
+
if (!context.filterElement) return renderElement();
|
|
1588
|
+
let tag = node.kind === "strike" ? "del" : node.kind === "link" ? "a" : node.kind, properties = node.kind === "link" ? { href: context.urlTransform?.(node.href ?? "", "href", { source: "markdown" }) ?? node.href, title: node.title } : {};
|
|
1589
|
+
return context.filterElement(
|
|
1590
|
+
{ tagName: tag, properties },
|
|
1591
|
+
{ source: "markdown", parentTagName },
|
|
1592
|
+
renderElement,
|
|
1593
|
+
() => children
|
|
1594
|
+
);
|
|
1595
|
+
}
|
|
1596
|
+
if (node.kind === "plugin") {
|
|
1597
|
+
let component = context.inlineComponents[node.name] ?? context.inlineComponents.plugin, direct = component ? React4.createElement(component, { ...node.attrs, key, name: node.name, attrs: node.attrs, raw: node.raw, children }) : node.raw;
|
|
1598
|
+
return context.renderInlinePresentation ? context.renderInlinePresentation(node, direct, key, children) : direct;
|
|
1599
|
+
}
|
|
1600
|
+
return context.renderInline([node], parentTagName);
|
|
1601
|
+
},
|
|
1602
|
+
context.renderParagraph,
|
|
1603
|
+
context.urlTransform,
|
|
1604
|
+
context.filterElement,
|
|
1605
|
+
context.parentTagName,
|
|
1606
|
+
context.contentComponents,
|
|
1607
|
+
context.renderHtmlPresentation,
|
|
1608
|
+
void 0,
|
|
1609
|
+
context.renderComponentPresentation
|
|
1610
|
+
);
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
// src/trusted-mdx/native-inline.tsx
|
|
1614
|
+
import React6, { useContext as useContext2 } from "react";
|
|
1615
|
+
import { TrustedMdxNativeChildrenContext } from "@stream-mdx/react/_internal/trusted-mdx-native-children";
|
|
1616
|
+
|
|
1617
|
+
// src/trusted-mdx-boundary.tsx
|
|
1618
|
+
import React5, { createContext as createContext2, useCallback as useCallback3, useEffect as useEffect3, useRef as useRef3, useState as useState4, useSyncExternalStore } from "react";
|
|
1619
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1620
|
+
var EMPTY_PROJECTIONS = Object.freeze({}), EMPTY_COMPONENTS = Object.freeze({}), EMPTY_DOCUMENT_SNAPSHOT = Object.freeze({
|
|
1621
|
+
requestedRevision: 0,
|
|
1622
|
+
projectionRevision: null,
|
|
1623
|
+
renderedRevision: null,
|
|
1624
|
+
status: "idle",
|
|
1625
|
+
error: null,
|
|
1626
|
+
components: EMPTY_COMPONENTS,
|
|
1627
|
+
layout: null,
|
|
1628
|
+
projections: EMPTY_PROJECTIONS
|
|
1629
|
+
}), EMPTY_FEED_SNAPSHOT = Object.freeze({
|
|
1630
|
+
generation: 0,
|
|
1631
|
+
version: 0,
|
|
1632
|
+
generationCause: "initial",
|
|
1633
|
+
pendingSource: null,
|
|
1634
|
+
revision: null
|
|
1635
|
+
});
|
|
1636
|
+
var TrustedMdxProjectionContext = createContext2(null);
|
|
1637
|
+
var TrustedMdxProjectionErrorBoundary = class extends React5.Component {
|
|
1638
|
+
constructor() {
|
|
1639
|
+
super(...arguments);
|
|
1640
|
+
this.state = { error: null };
|
|
1088
1641
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1642
|
+
static getDerivedStateFromError(error) {
|
|
1643
|
+
return { error: error instanceof Error ? error : new Error(String(error)) };
|
|
1644
|
+
}
|
|
1645
|
+
componentDidCatch(error) {
|
|
1646
|
+
this.props.revision !== null && this.props.document.reportRenderError(this.props.revision, error);
|
|
1647
|
+
}
|
|
1648
|
+
render() {
|
|
1649
|
+
return this.state.error ? /* @__PURE__ */ jsx5(TrustedMdxProjectionContext.Provider, { value: null, children: this.props.fallback }) : this.props.children;
|
|
1650
|
+
}
|
|
1651
|
+
}, CapturedNativeFrameErrorBoundary = class extends React5.Component {
|
|
1652
|
+
constructor() {
|
|
1653
|
+
super(...arguments);
|
|
1654
|
+
this.state = { error: null };
|
|
1655
|
+
}
|
|
1656
|
+
static getDerivedStateFromError(error) {
|
|
1657
|
+
return { error: error instanceof Error ? error : new Error(String(error)) };
|
|
1658
|
+
}
|
|
1659
|
+
render() {
|
|
1660
|
+
return this.state.error ? /* @__PURE__ */ jsxs5("section", { role: "alert", "data-trusted-mdx-retained-frame-error": "true", children: [
|
|
1661
|
+
/* @__PURE__ */ jsxs5("p", { children: [
|
|
1662
|
+
"Previously committed trusted MDX source generation ",
|
|
1663
|
+
this.props.sourceGeneration,
|
|
1664
|
+
", document revision ",
|
|
1665
|
+
this.props.documentRevision,
|
|
1666
|
+
"failed to render: ",
|
|
1667
|
+
this.state.error.message
|
|
1668
|
+
] }),
|
|
1669
|
+
/* @__PURE__ */ jsxs5("details", { children: [
|
|
1670
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
1671
|
+
"Escaped source for generation ",
|
|
1672
|
+
this.props.sourceGeneration,
|
|
1673
|
+
", document revision ",
|
|
1674
|
+
this.props.documentRevision
|
|
1675
|
+
] }),
|
|
1676
|
+
/* @__PURE__ */ jsx5("pre", { children: this.props.source })
|
|
1677
|
+
] })
|
|
1678
|
+
] }) : this.props.children;
|
|
1679
|
+
}
|
|
1680
|
+
};
|
|
1681
|
+
|
|
1682
|
+
// src/trusted-mdx-contract.ts
|
|
1683
|
+
function assertTrustedMdxNativeChildContinuations(owners, flowChildren) {
|
|
1684
|
+
if (owners.length !== flowChildren.length)
|
|
1685
|
+
throw new Error("A trusted MDX native child continuation has misaligned owner and source spans.");
|
|
1686
|
+
let continuationOwnerIndex;
|
|
1687
|
+
for (let index = 0; index < owners.length; index++) {
|
|
1688
|
+
let owner = owners[index];
|
|
1689
|
+
if (owner?.kind !== "continuation") {
|
|
1690
|
+
continuationOwnerIndex = void 0;
|
|
1691
|
+
continue;
|
|
1132
1692
|
}
|
|
1133
|
-
|
|
1693
|
+
let ownerIndex = owner.ownerIndex, ownerForRun = owners[ownerIndex], previousChild = flowChildren[index - 1], child = flowChildren[index];
|
|
1694
|
+
if (!Number.isSafeInteger(ownerIndex) || ownerIndex < 0 || ownerIndex >= index || (continuationOwnerIndex === void 0 ? ownerIndex !== index - 1 : ownerIndex !== continuationOwnerIndex) || ownerForRun === null || ownerForRun === void 0 || ownerForRun.kind === "continuation" || previousChild?.kind !== "inline" || child?.kind !== "inline" || previousChild.to <= previousChild.from || child.to <= child.from || previousChild.to !== child.from)
|
|
1695
|
+
throw new Error("A trusted MDX native child continuation does not cover one exact contiguous inline run.");
|
|
1696
|
+
continuationOwnerIndex = ownerIndex;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
// src/trusted-mdx/native-inline.tsx
|
|
1701
|
+
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1702
|
+
function renderTrustedMdxOwner(ownerId, snapshot, source, inline, nativeChildren) {
|
|
1703
|
+
let projection = snapshot.projections[ownerId];
|
|
1704
|
+
if (projection?.kind === "native-child") return;
|
|
1705
|
+
if (projection?.kind === "module") return null;
|
|
1706
|
+
if (projection?.kind === "server-content") {
|
|
1707
|
+
if (!projection.nativeChildren) return projection.content;
|
|
1708
|
+
if (nativeChildren === void 0)
|
|
1709
|
+
throw new Error(`Trusted MDX owner "${ownerId}" has no prepared native children.`);
|
|
1710
|
+
return /* @__PURE__ */ jsx6(TrustedMdxNativeChildrenContext.Provider, { value: nativeChildren, children: projection.content });
|
|
1711
|
+
}
|
|
1712
|
+
if (projection?.kind === "render" && projection.nativeChildren && nativeChildren === void 0)
|
|
1713
|
+
throw new Error(`Trusted MDX owner "${ownerId}" has no prepared native children.`);
|
|
1714
|
+
if (projection?.kind === "render") {
|
|
1715
|
+
let nativeChildrenFactory = projection.rootElementName === void 0 || nativeChildren === void 0 ? void 0 : (fallback) => {
|
|
1716
|
+
let owners = projection.nativeChildOwners, flowChildren = projection.flowChildren;
|
|
1717
|
+
if (!owners || !flowChildren || owners.length !== flowChildren.length || !Array.isArray(nativeChildren) || nativeChildren.length !== owners.length)
|
|
1718
|
+
throw new Error(`Trusted MDX owner "${ownerId}" has misaligned native child owners.`);
|
|
1719
|
+
return assertTrustedMdxNativeChildContinuations(owners, flowChildren), owners.map((owner, index) => {
|
|
1720
|
+
if (owner === null) return fallback(index);
|
|
1721
|
+
if (owner.kind === "continuation") return;
|
|
1722
|
+
let child = nativeChildren[index];
|
|
1723
|
+
if (child === void 0)
|
|
1724
|
+
throw new Error(`Trusted MDX owner "${ownerId}" has no rendered native child "${owner.blockId}".`);
|
|
1725
|
+
return child;
|
|
1726
|
+
});
|
|
1727
|
+
};
|
|
1728
|
+
return /* @__PURE__ */ jsx6(Fragment4, { children: projection.regions.map((Region, index) => {
|
|
1729
|
+
let regionProps = {
|
|
1730
|
+
components: snapshot.components,
|
|
1731
|
+
...nativeChildrenFactory === void 0 ? {} : { children: nativeChildrenFactory }
|
|
1732
|
+
};
|
|
1733
|
+
return React6.createElement(
|
|
1734
|
+
React6.Fragment,
|
|
1735
|
+
{ key: `${ownerId}:${index}` },
|
|
1736
|
+
Region(regionProps)
|
|
1737
|
+
);
|
|
1738
|
+
}) });
|
|
1739
|
+
}
|
|
1740
|
+
let diagnostic = projection?.kind === "unmapped" ? projection.diagnostic : snapshot.error ?? `MDX owner "${ownerId}" has no exact trusted source projection.`, status = projection?.kind === "unmapped" ? "unmapped" : snapshot.status === "error" ? "error" : "pending";
|
|
1741
|
+
return (projection?.kind === "unmapped" && projection.placement !== void 0 ? projection.placement === "inline" : inline) ? /* @__PURE__ */ jsxs6("span", { className: "markdown-mdx-inline", "data-mdx-status": status, "data-mdx-diagnostic": diagnostic, children: [
|
|
1742
|
+
source,
|
|
1743
|
+
/* @__PURE__ */ jsx6("span", { className: "markdown-mdx-diagnostic", role: "note", children: diagnostic })
|
|
1744
|
+
] }) : /* @__PURE__ */ jsxs6("div", { className: "markdown-mdx-inert", "data-mdx-status": status, "data-mdx-diagnostic": diagnostic, children: [
|
|
1745
|
+
/* @__PURE__ */ jsx6("pre", { children: /* @__PURE__ */ jsx6("code", { children: source }) }),
|
|
1746
|
+
/* @__PURE__ */ jsx6("span", { className: "markdown-mdx-diagnostic", role: "note", children: diagnostic })
|
|
1747
|
+
] });
|
|
1748
|
+
}
|
|
1749
|
+
function TrustedMdxInlineOwner({ ownerId, source }) {
|
|
1750
|
+
let snapshot = useContext2(TrustedMdxProjectionContext);
|
|
1751
|
+
return snapshot ? /* @__PURE__ */ jsx6(Fragment4, { children: renderTrustedMdxOwner(ownerId, snapshot, source, !0) }) : /* @__PURE__ */ jsx6("span", { className: "markdown-mdx-inline", children: source });
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
// src/renderer/node-presentations.ts
|
|
1755
|
+
import React7 from "react";
|
|
1756
|
+
function renderPresentedNode(presentation, nativeView, context, applyPresentationPropsToCustomElements = !1) {
|
|
1757
|
+
if (!presentation) return nativeView;
|
|
1758
|
+
let prepared = nativeView;
|
|
1759
|
+
return presentation.props && React7.isValidElement(prepared) && (typeof prepared.type == "string" || applyPresentationPropsToCustomElements) && (prepared = React7.cloneElement(
|
|
1760
|
+
prepared,
|
|
1761
|
+
mergeNodePresentationProps(prepared.props, presentation.props)
|
|
1762
|
+
)), "view" in presentation && presentation.view ? React7.createElement(presentation.view, {
|
|
1763
|
+
...context.viewProps,
|
|
1764
|
+
key: context.key
|
|
1765
|
+
}) : "wrapper" in presentation && presentation.wrapper ? React7.createElement(presentation.wrapper, {
|
|
1766
|
+
key: context.key,
|
|
1767
|
+
children: prepared,
|
|
1768
|
+
metadata: context.metadata,
|
|
1769
|
+
actions: context.actions
|
|
1770
|
+
}) : prepared;
|
|
1771
|
+
}
|
|
1772
|
+
var PRESENTATION_KEY_PATTERNS = [
|
|
1773
|
+
/^[a-z][a-z0-9-]*$/,
|
|
1774
|
+
/^inline:[a-z][a-z0-9-]*$/,
|
|
1775
|
+
/^html:[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/,
|
|
1776
|
+
/^component:[A-Za-z][A-Za-z0-9_.-]*$/,
|
|
1777
|
+
/^extension:[A-Za-z][A-Za-z0-9_.-]*$/
|
|
1778
|
+
], RESERVED_PRESENTATION_PROPS = {
|
|
1779
|
+
className: !0,
|
|
1780
|
+
style: !0,
|
|
1781
|
+
title: !0
|
|
1134
1782
|
};
|
|
1135
|
-
|
|
1783
|
+
function resolveNodePresentation(presentations, key) {
|
|
1784
|
+
if (!isNodePresentationKey(key))
|
|
1785
|
+
throw new TypeError(`invalid node presentation key: ${key}`);
|
|
1786
|
+
if (!presentations || !Object.prototype.hasOwnProperty.call(presentations, key)) return;
|
|
1787
|
+
let candidate = presentations[key];
|
|
1788
|
+
return validateNodePresentation(key, candidate), candidate;
|
|
1789
|
+
}
|
|
1790
|
+
function mergeNodePresentationProps(nativeProps, decoration) {
|
|
1791
|
+
if (!decoration) return nativeProps;
|
|
1792
|
+
let merged = {};
|
|
1793
|
+
for (let [property, value] of Object.entries(decoration))
|
|
1794
|
+
if (property === "className") {
|
|
1795
|
+
let nativeClass = nativeProps.className;
|
|
1796
|
+
merged.className = typeof nativeClass == "string" && value ? `${nativeClass} ${value}` : value ?? nativeClass;
|
|
1797
|
+
} else property === "style" ? merged.style = { ...nativeProps.style, ...value } : Object.prototype.hasOwnProperty.call(nativeProps, property) || (merged[property] = value);
|
|
1798
|
+
return merged;
|
|
1799
|
+
}
|
|
1800
|
+
function validateNodePresentations(presentations) {
|
|
1801
|
+
if (presentations !== void 0) {
|
|
1802
|
+
if (presentations === null || typeof presentations != "object" || Array.isArray(presentations))
|
|
1803
|
+
throw new TypeError("node presentations must be an object");
|
|
1804
|
+
for (let key of Object.keys(presentations)) {
|
|
1805
|
+
if (!isNodePresentationKey(key))
|
|
1806
|
+
throw new TypeError(`invalid node presentation key: ${key}`);
|
|
1807
|
+
validateNodePresentation(key, presentations[key]);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
function isNodePresentationKey(key) {
|
|
1812
|
+
return PRESENTATION_KEY_PATTERNS.some((pattern) => pattern.test(key));
|
|
1813
|
+
}
|
|
1814
|
+
function validateNodePresentation(key, candidate) {
|
|
1815
|
+
if (candidate === null || typeof candidate != "object" || Array.isArray(candidate))
|
|
1816
|
+
throw new TypeError(`node presentation for ${key} must be an object`);
|
|
1817
|
+
let presentation = candidate;
|
|
1818
|
+
if ((key === "table-row" || key === "table-cell") && presentation.view !== void 0)
|
|
1819
|
+
throw new TypeError(
|
|
1820
|
+
`node presentation for ${key}: headless table-part views are not supported; use components.table.view with useTableRows`
|
|
1821
|
+
);
|
|
1822
|
+
if ((key === "table-row" || key === "table-cell") && presentation.slots !== void 0)
|
|
1823
|
+
throw new TypeError(`node presentation for ${key} only supports wrapper and props`);
|
|
1824
|
+
if (key.startsWith("component:") && presentation.view !== void 0)
|
|
1825
|
+
throw new TypeError(`node presentation for ${key}: headless views are not supported for restricted content components`);
|
|
1826
|
+
if (presentation.wrapper !== void 0 && presentation.view !== void 0)
|
|
1827
|
+
throw new TypeError(`node presentation for ${key}: wrapper and view are mutually exclusive`);
|
|
1828
|
+
if (presentation.wrapper !== void 0 && !isComponentType(presentation.wrapper))
|
|
1829
|
+
throw new TypeError(`node presentation for ${key} has an invalid wrapper`);
|
|
1830
|
+
if (presentation.view !== void 0 && !isComponentType(presentation.view))
|
|
1831
|
+
throw new TypeError(`node presentation for ${key} has an invalid view`);
|
|
1832
|
+
presentation.props !== void 0 && validatePresentationProps(key, presentation.props), presentation.slots !== void 0 && validatePresentationSlots(key, presentation.slots);
|
|
1833
|
+
for (let property of Object.keys(presentation))
|
|
1834
|
+
if (property !== "props" && property !== "wrapper" && property !== "view" && property !== "slots")
|
|
1835
|
+
throw new TypeError(`node presentation for ${key} has an unknown field: ${property}`);
|
|
1836
|
+
}
|
|
1837
|
+
function isComponentType(value) {
|
|
1838
|
+
return typeof value == "function" || typeof value == "object" && value !== null;
|
|
1839
|
+
}
|
|
1840
|
+
function validatePresentationProps(key, candidate) {
|
|
1841
|
+
if (candidate === null || typeof candidate != "object" || Array.isArray(candidate))
|
|
1842
|
+
throw new TypeError(`node presentation props for ${key} must be an object`);
|
|
1843
|
+
let props = candidate;
|
|
1844
|
+
for (let [property, value] of Object.entries(props)) {
|
|
1845
|
+
let isDataOrAria = /^(data|aria)-[a-z][a-z0-9_.:-]*$/.test(property);
|
|
1846
|
+
if (RESERVED_PRESENTATION_PROPS[property] !== !0 && !isDataOrAria)
|
|
1847
|
+
throw new TypeError(`presentation prop is not allowed: ${property}`);
|
|
1848
|
+
if (property === "style" && (value === null || typeof value != "object" || Array.isArray(value)))
|
|
1849
|
+
throw new TypeError(`presentation style for ${key} must be an object`);
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
function validatePresentationSlots(key, candidate) {
|
|
1853
|
+
if (candidate === null || typeof candidate != "object" || Array.isArray(candidate))
|
|
1854
|
+
throw new TypeError(`node presentation slots for ${key} must be an object`);
|
|
1855
|
+
for (let slot of Object.keys(candidate))
|
|
1856
|
+
if (key !== "code" && key !== "table" || slot !== "actions")
|
|
1857
|
+
throw new TypeError(`presentation slot is not supported for ${key}: ${slot}`);
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
// src/renderer/virtualized-table.ts
|
|
1861
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState5 } from "react";
|
|
1862
|
+
import { flushSync } from "react-dom";
|
|
1863
|
+
var DEFAULT_TABLE_VIRTUALIZATION_CONFIG = Object.freeze({
|
|
1864
|
+
enabled: !1,
|
|
1865
|
+
minRows: 40,
|
|
1866
|
+
virtualizeThreshold: 40,
|
|
1867
|
+
estimatedRowHeight: 40,
|
|
1868
|
+
overscan: 8,
|
|
1869
|
+
maxHeight: "600px"
|
|
1870
|
+
});
|
|
1871
|
+
function resolveTableVirtualizationConfig(options) {
|
|
1872
|
+
if (options === !0) return { ...DEFAULT_TABLE_VIRTUALIZATION_CONFIG, enabled: !0 };
|
|
1873
|
+
if (!options) return DEFAULT_TABLE_VIRTUALIZATION_CONFIG;
|
|
1874
|
+
let threshold = options.minRows ?? options.virtualizeThreshold ?? 40, minRows = Number.isFinite(threshold) ? Math.max(1, Math.floor(threshold)) : 40, buffer = options.overscan ?? 8, overscan = Number.isFinite(buffer) ? Math.min(50, Math.max(1, Math.floor(buffer))) : 8, estimate = options.estimatedRowHeight ?? 40;
|
|
1875
|
+
return {
|
|
1876
|
+
enabled: options.enabled ?? !0,
|
|
1877
|
+
minRows,
|
|
1878
|
+
virtualizeThreshold: minRows,
|
|
1879
|
+
estimatedRowHeight: Number.isFinite(estimate) && estimate > 0 ? estimate : 40,
|
|
1880
|
+
overscan,
|
|
1881
|
+
maxHeight: options.maxHeight ?? "600px"
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
// src/renderer/virtualized-code.tsx
|
|
1886
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef5, useState as useState6 } from "react";
|
|
1887
|
+
import { flushSync as flushSync2 } from "react-dom";
|
|
1888
|
+
var DEFAULT_VIRTUALIZED_CODE_CONFIG = {
|
|
1889
|
+
enabled: !0,
|
|
1890
|
+
windowSize: 100,
|
|
1891
|
+
bufferSize: 50,
|
|
1892
|
+
virtualizeThreshold: 200,
|
|
1893
|
+
followTail: !1
|
|
1894
|
+
};
|
|
1895
|
+
function resolveVirtualizedCodeConfig(options) {
|
|
1896
|
+
return {
|
|
1897
|
+
...DEFAULT_VIRTUALIZED_CODE_CONFIG,
|
|
1898
|
+
...options,
|
|
1899
|
+
followTail: options?.followTail ?? DEFAULT_VIRTUALIZED_CODE_CONFIG.followTail
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
// src/components/link-safety-modal.tsx
|
|
1904
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1905
|
+
var DefaultLinkSafetyModal = ({ url, isOpen, isChecking, onClose, onConfirm, onCopy }) => isOpen ? /* @__PURE__ */ jsx7(
|
|
1906
|
+
"div",
|
|
1907
|
+
{
|
|
1908
|
+
className: "stream-mdx-link-modal-backdrop",
|
|
1909
|
+
role: "dialog",
|
|
1910
|
+
"aria-modal": "true",
|
|
1911
|
+
"aria-label": "Link safety confirmation",
|
|
1912
|
+
style: {
|
|
1913
|
+
position: "fixed",
|
|
1914
|
+
inset: 0,
|
|
1915
|
+
display: "flex",
|
|
1916
|
+
alignItems: "center",
|
|
1917
|
+
justifyContent: "center",
|
|
1918
|
+
background: "rgba(0, 0, 0, 0.4)",
|
|
1919
|
+
zIndex: 9999,
|
|
1920
|
+
padding: "24px"
|
|
1921
|
+
},
|
|
1922
|
+
onClick: onClose,
|
|
1923
|
+
children: /* @__PURE__ */ jsxs7(
|
|
1924
|
+
"div",
|
|
1925
|
+
{
|
|
1926
|
+
className: "stream-mdx-link-modal",
|
|
1927
|
+
style: {
|
|
1928
|
+
width: "min(520px, 100%)",
|
|
1929
|
+
borderRadius: 12,
|
|
1930
|
+
background: "var(--background, #fff)",
|
|
1931
|
+
color: "var(--foreground, #111)",
|
|
1932
|
+
border: "1px solid var(--border, rgba(0, 0, 0, 0.1))",
|
|
1933
|
+
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.25)",
|
|
1934
|
+
padding: 20
|
|
1935
|
+
},
|
|
1936
|
+
onClick: (event) => event.stopPropagation(),
|
|
1937
|
+
children: [
|
|
1938
|
+
/* @__PURE__ */ jsx7("div", { style: { fontWeight: 600, marginBottom: 8 }, children: "Open external link?" }),
|
|
1939
|
+
/* @__PURE__ */ jsx7("div", { style: { fontSize: 13, opacity: 0.8, wordBreak: "break-all", marginBottom: 16 }, children: url }),
|
|
1940
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 8, justifyContent: "flex-end" }, children: [
|
|
1941
|
+
/* @__PURE__ */ jsx7("button", { type: "button", onClick: onCopy, disabled: isChecking, style: buttonStyle, children: "Copy link" }),
|
|
1942
|
+
/* @__PURE__ */ jsx7("button", { type: "button", onClick: onConfirm, disabled: isChecking, style: primaryButtonStyle, children: "Open link" }),
|
|
1943
|
+
/* @__PURE__ */ jsx7("button", { type: "button", onClick: onClose, style: buttonStyle, children: "Cancel" })
|
|
1944
|
+
] })
|
|
1945
|
+
]
|
|
1946
|
+
}
|
|
1947
|
+
)
|
|
1948
|
+
}
|
|
1949
|
+
) : null, buttonStyle = {
|
|
1136
1950
|
borderRadius: 8,
|
|
1137
1951
|
border: "1px solid var(--border, rgba(0, 0, 0, 0.1))",
|
|
1138
1952
|
padding: "6px 12px",
|
|
1139
1953
|
background: "var(--background, #fff)",
|
|
1140
1954
|
color: "inherit",
|
|
1141
1955
|
fontSize: 13
|
|
1142
|
-
}
|
|
1143
|
-
var primaryButtonStyle = {
|
|
1956
|
+
}, primaryButtonStyle = {
|
|
1144
1957
|
...buttonStyle,
|
|
1145
1958
|
background: "var(--foreground, #111)",
|
|
1146
1959
|
color: "var(--background, #fff)",
|
|
@@ -1148,120 +1961,295 @@ var primaryButtonStyle = {
|
|
|
1148
1961
|
};
|
|
1149
1962
|
|
|
1150
1963
|
// src/components/index.ts
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
}
|
|
1156
|
-
static getDerivedStateFromError() {
|
|
1157
|
-
return { hasError: true };
|
|
1158
|
-
}
|
|
1159
|
-
componentDidCatch(error) {
|
|
1160
|
-
this.props.onError(error);
|
|
1161
|
-
}
|
|
1162
|
-
componentDidUpdate(prevProps) {
|
|
1163
|
-
if (prevProps.resetKey !== this.props.resetKey && this.state.hasError) {
|
|
1164
|
-
this.setState({ hasError: false });
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
render() {
|
|
1168
|
-
if (this.state.hasError) {
|
|
1169
|
-
return null;
|
|
1170
|
-
}
|
|
1171
|
-
return this.props.children;
|
|
1172
|
-
}
|
|
1173
|
-
};
|
|
1174
|
-
function renderInlineNodes(nodes, components) {
|
|
1964
|
+
function presentationText(node) {
|
|
1965
|
+
return typeof node == "string" || typeof node == "number" ? String(node) : Array.isArray(node) ? node.map(presentationText).join("") : React8.isValidElement(node) ? presentationText(node.props.children) : "";
|
|
1966
|
+
}
|
|
1967
|
+
function renderInlineNodes(nodes, components, urlTransform, registry, parentTagName, animationContext) {
|
|
1175
1968
|
return nodes.map((node, index) => {
|
|
1176
|
-
|
|
1969
|
+
let key = `${node.kind}-${index}`, itemChildContext = animationContext?.animated && !animationContext.isFinalized ? {
|
|
1970
|
+
...animationContext,
|
|
1971
|
+
nodeKeyPrefix: animationContext.nodeKeyPrefix ? `${animationContext.nodeKeyPrefix}:${key}` : key
|
|
1972
|
+
} : animationContext, presentInline = (nativeView, renderedChildren) => registry ? registry.renderInlinePresentation(node, nativeView, key, itemChildContext, renderedChildren) : nativeView;
|
|
1177
1973
|
switch (node.kind) {
|
|
1178
1974
|
case "text": {
|
|
1179
|
-
|
|
1180
|
-
if (textComponent && textComponent !== defaultInlineComponents.text)
|
|
1181
|
-
return
|
|
1975
|
+
let textComponent = components.text;
|
|
1976
|
+
if (textComponent && textComponent !== defaultInlineComponents.text)
|
|
1977
|
+
return presentInline(React8.createElement(textComponent, { key, text: node.text }));
|
|
1978
|
+
if (animationContext?.animated && !animationContext.isFinalized && animationContext.timeline) {
|
|
1979
|
+
let { animated, timeline, nodeKeyPrefix } = animationContext, nodeKey = nodeKeyPrefix ? `${nodeKeyPrefix}:${key}` : key, segments = splitTextSegments(node.text, animated.sep), state = timeline.getNodeState(nodeKey);
|
|
1980
|
+
if (segments.length > state.count) {
|
|
1981
|
+
let newCount = segments.length - state.count, newDelays = timeline.schedule(newCount, animated.stagger);
|
|
1982
|
+
state.delays.push(...newDelays), state.count = segments.length;
|
|
1983
|
+
} else segments.length < state.count && (state.count = segments.length, state.delays.length = segments.length);
|
|
1984
|
+
let animName = animated.animationName, durationStr = animated.durationStr, spans = segments.map((segment, segmentIndex) => {
|
|
1985
|
+
let delay = state.delays[segmentIndex] ?? 0, animStyle = {
|
|
1986
|
+
"--sm-anim-duration": durationStr,
|
|
1987
|
+
"--sm-anim-easing": animated.easing,
|
|
1988
|
+
"--sm-anim-delay": `${delay}ms`
|
|
1989
|
+
};
|
|
1990
|
+
return animName && (animStyle["--sm-anim-name"] = animName, animStyle.animationName = animName), React8.createElement(
|
|
1991
|
+
"span",
|
|
1992
|
+
{
|
|
1993
|
+
key: segmentIndex,
|
|
1994
|
+
className: "stream-mdx-anim",
|
|
1995
|
+
style: animStyle
|
|
1996
|
+
},
|
|
1997
|
+
segment
|
|
1998
|
+
);
|
|
1999
|
+
});
|
|
2000
|
+
return presentInline(React8.createElement(React8.Fragment, { key }, ...spans));
|
|
1182
2001
|
}
|
|
1183
|
-
return
|
|
2002
|
+
return presentInline(React8.createElement(React8.Fragment, { key, children: node.text }));
|
|
1184
2003
|
}
|
|
1185
|
-
case "strong":
|
|
1186
|
-
|
|
2004
|
+
case "strong": {
|
|
2005
|
+
if (!registry?.hasElementFilters())
|
|
2006
|
+
return presentInline(React8.createElement(components.strong, {
|
|
2007
|
+
key,
|
|
2008
|
+
children: renderInlineNodes(node.children, components, urlTransform, registry, "strong", itemChildContext)
|
|
2009
|
+
}));
|
|
2010
|
+
let renderChildren = () => renderInlineNodes(node.children, components, urlTransform, registry, "strong", itemChildContext), renderElement = () => presentInline(React8.createElement(components.strong, {
|
|
1187
2011
|
key,
|
|
1188
|
-
children:
|
|
1189
|
-
});
|
|
1190
|
-
|
|
1191
|
-
|
|
2012
|
+
children: renderChildren()
|
|
2013
|
+
}));
|
|
2014
|
+
return registry.filterElement(
|
|
2015
|
+
{ tagName: "strong", properties: { key }, blockType: void 0 },
|
|
2016
|
+
{ source: "markdown", parentTagName },
|
|
2017
|
+
renderElement,
|
|
2018
|
+
renderChildren
|
|
2019
|
+
);
|
|
2020
|
+
}
|
|
2021
|
+
case "em": {
|
|
2022
|
+
if (!registry?.hasElementFilters())
|
|
2023
|
+
return presentInline(React8.createElement(components.em, {
|
|
2024
|
+
key,
|
|
2025
|
+
children: renderInlineNodes(node.children, components, urlTransform, registry, "em", itemChildContext)
|
|
2026
|
+
}));
|
|
2027
|
+
let renderChildren = () => renderInlineNodes(node.children, components, urlTransform, registry, "em", itemChildContext), renderElement = () => presentInline(React8.createElement(components.em, {
|
|
1192
2028
|
key,
|
|
1193
|
-
children:
|
|
1194
|
-
});
|
|
2029
|
+
children: renderChildren()
|
|
2030
|
+
}));
|
|
2031
|
+
return registry.filterElement(
|
|
2032
|
+
{ tagName: "em", properties: { key }, blockType: void 0 },
|
|
2033
|
+
{ source: "markdown", parentTagName },
|
|
2034
|
+
renderElement,
|
|
2035
|
+
renderChildren
|
|
2036
|
+
);
|
|
2037
|
+
}
|
|
1195
2038
|
case "strike": {
|
|
1196
|
-
|
|
1197
|
-
|
|
2039
|
+
let StrikeComponent = components.strike ?? ((props) => React8.createElement("del", {}, props.children));
|
|
2040
|
+
if (!registry?.hasElementFilters())
|
|
2041
|
+
return presentInline(React8.createElement(StrikeComponent, {
|
|
2042
|
+
key,
|
|
2043
|
+
children: renderInlineNodes(node.children, components, urlTransform, registry, "del", itemChildContext)
|
|
2044
|
+
}));
|
|
2045
|
+
let renderChildren = () => renderInlineNodes(node.children, components, urlTransform, registry, "del", itemChildContext), renderElement = () => presentInline(React8.createElement(StrikeComponent, {
|
|
1198
2046
|
key,
|
|
1199
|
-
children:
|
|
1200
|
-
});
|
|
2047
|
+
children: renderChildren()
|
|
2048
|
+
}));
|
|
2049
|
+
return registry.filterElement(
|
|
2050
|
+
{ tagName: "del", properties: { key }, blockType: void 0 },
|
|
2051
|
+
{ source: "markdown", parentTagName },
|
|
2052
|
+
renderElement,
|
|
2053
|
+
renderChildren
|
|
2054
|
+
);
|
|
1201
2055
|
}
|
|
1202
|
-
case "code":
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
2056
|
+
case "code": {
|
|
2057
|
+
if (!registry?.hasElementFilters())
|
|
2058
|
+
return presentInline(React8.createElement(components.code, { key, text: node.text }));
|
|
2059
|
+
let renderChildren = () => node.text, renderElement = () => presentInline(React8.createElement(components.code, { key, text: node.text }));
|
|
2060
|
+
return registry.filterElement(
|
|
2061
|
+
{ tagName: "code", properties: { key, text: node.text }, blockType: void 0 },
|
|
2062
|
+
{ source: "markdown", parentTagName },
|
|
2063
|
+
renderElement,
|
|
2064
|
+
renderChildren
|
|
2065
|
+
);
|
|
2066
|
+
}
|
|
2067
|
+
case "link": {
|
|
2068
|
+
if (node.autolink && registry?.isAutolinkProtocolDisabled(node.href))
|
|
2069
|
+
return renderInlineNodes(node.children, components, urlTransform, registry, parentTagName, itemChildContext);
|
|
2070
|
+
let safeHref = (urlTransform ?? defaultUrlTransform4)(node.href ?? "", "href", { source: "markdown" });
|
|
2071
|
+
if (!registry?.hasElementFilters())
|
|
2072
|
+
return presentInline(React8.createElement(
|
|
2073
|
+
components.link,
|
|
2074
|
+
{
|
|
2075
|
+
key,
|
|
2076
|
+
...safeHref != null ? { href: safeHref } : {},
|
|
2077
|
+
title: node.title,
|
|
2078
|
+
children: renderInlineNodes(node.children, components, urlTransform, registry, "a", itemChildContext)
|
|
2079
|
+
}
|
|
2080
|
+
));
|
|
2081
|
+
let renderChildren = () => renderInlineNodes(node.children, components, urlTransform, registry, "a", itemChildContext), renderElement = () => presentInline(React8.createElement(
|
|
1206
2082
|
components.link,
|
|
1207
2083
|
{
|
|
1208
2084
|
key,
|
|
1209
|
-
href:
|
|
2085
|
+
...safeHref != null ? { href: safeHref } : {},
|
|
1210
2086
|
title: node.title,
|
|
1211
|
-
children:
|
|
2087
|
+
children: renderChildren()
|
|
1212
2088
|
}
|
|
2089
|
+
));
|
|
2090
|
+
return registry.filterElement(
|
|
2091
|
+
{ tagName: "a", properties: { key, href: safeHref, title: node.title }, blockType: void 0 },
|
|
2092
|
+
{ source: "markdown", parentTagName },
|
|
2093
|
+
renderElement,
|
|
2094
|
+
renderChildren
|
|
1213
2095
|
);
|
|
1214
|
-
|
|
1215
|
-
|
|
2096
|
+
}
|
|
2097
|
+
case "image": {
|
|
2098
|
+
let safeSrc = (urlTransform ?? defaultUrlTransform4)(node.src ?? "", "src", { source: "markdown" });
|
|
2099
|
+
if (!registry?.hasElementFilters())
|
|
2100
|
+
return presentInline(React8.createElement(components.image, {
|
|
2101
|
+
key,
|
|
2102
|
+
...safeSrc != null ? { src: safeSrc } : {},
|
|
2103
|
+
alt: node.alt ?? "",
|
|
2104
|
+
title: node.title
|
|
2105
|
+
}));
|
|
2106
|
+
let renderElement = () => presentInline(React8.createElement(components.image, {
|
|
1216
2107
|
key,
|
|
1217
|
-
src:
|
|
1218
|
-
alt: node.alt,
|
|
2108
|
+
...safeSrc != null ? { src: safeSrc } : {},
|
|
2109
|
+
alt: node.alt ?? "",
|
|
1219
2110
|
title: node.title
|
|
1220
|
-
});
|
|
1221
|
-
|
|
1222
|
-
|
|
2111
|
+
}));
|
|
2112
|
+
return registry.filterElement(
|
|
2113
|
+
{ tagName: "img", properties: { key, src: safeSrc, alt: node.alt ?? "", title: node.title }, blockType: void 0 },
|
|
2114
|
+
{ source: "markdown", parentTagName },
|
|
2115
|
+
renderElement,
|
|
2116
|
+
void 0
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
case "br": {
|
|
2120
|
+
if (!registry?.hasElementFilters())
|
|
2121
|
+
return presentInline(React8.createElement(
|
|
2122
|
+
React8.Fragment,
|
|
2123
|
+
{ key },
|
|
2124
|
+
React8.createElement(components.br, {}),
|
|
2125
|
+
`
|
|
2126
|
+
`
|
|
2127
|
+
));
|
|
2128
|
+
let renderElement = () => presentInline(React8.createElement(
|
|
2129
|
+
React8.Fragment,
|
|
2130
|
+
{ key },
|
|
2131
|
+
React8.createElement(components.br, {}),
|
|
2132
|
+
`
|
|
2133
|
+
`
|
|
2134
|
+
));
|
|
2135
|
+
return registry.filterElement(
|
|
2136
|
+
{ tagName: "br", properties: { key }, blockType: void 0 },
|
|
2137
|
+
{ source: "markdown", parentTagName },
|
|
2138
|
+
renderElement,
|
|
2139
|
+
void 0
|
|
2140
|
+
);
|
|
2141
|
+
}
|
|
2142
|
+
case "plugin": {
|
|
2143
|
+
let pluginComponent = components[node.name] ?? components.plugin, hasExtensionPresentation = registry?.getNodePresentation(`extension:${node.name}`) !== void 0, pluginChildren = node.children && (pluginComponent || hasExtensionPresentation) ? renderInlineNodes(node.children, components, urlTransform, registry, parentTagName, itemChildContext) : void 0;
|
|
2144
|
+
return pluginComponent ? presentInline(React8.createElement(pluginComponent, {
|
|
2145
|
+
key,
|
|
2146
|
+
...node.attrs,
|
|
2147
|
+
name: node.name,
|
|
2148
|
+
attrs: node.attrs,
|
|
2149
|
+
children: pluginChildren,
|
|
2150
|
+
raw: node.raw
|
|
2151
|
+
}), pluginChildren) : hasExtensionPresentation ? presentInline(React8.createElement(React8.Fragment, { key }, pluginChildren ?? node.raw), pluginChildren) : presentInline(React8.createElement(React8.Fragment, { key }, node.raw));
|
|
2152
|
+
}
|
|
2153
|
+
case "trusted-mdx-inline":
|
|
2154
|
+
return React8.createElement(TrustedMdxInlineOwner, { key, ownerId: node.ownerId, source: node.raw });
|
|
2155
|
+
case "html": {
|
|
2156
|
+
let children = node.children ? renderInlineNodes(node.children, components, urlTransform, registry, node.tagName?.toLowerCase(), itemChildContext) : void 0, textValue = node.children?.map((child) => child.kind === "text" ? child.text : "").join(""), htmlRenderer = components.html;
|
|
2157
|
+
return htmlRenderer && !registry?.isDefaultHtmlInlineRenderer(htmlRenderer) ? renderHtmlInlineNode(
|
|
2158
|
+
node,
|
|
2159
|
+
children,
|
|
2160
|
+
void 0,
|
|
2161
|
+
key,
|
|
2162
|
+
textValue,
|
|
2163
|
+
urlTransform,
|
|
2164
|
+
registry?.hasElementFilters() ? (el, ctx, renderElement, renderChildren) => registry.filterElement(el, ctx, renderElement, renderChildren) : void 0,
|
|
2165
|
+
parentTagName,
|
|
2166
|
+
registry ? (tagName, properties, nativeView, htmlChildren, presentationKey) => registry.renderHtmlPresentation(
|
|
2167
|
+
tagName,
|
|
2168
|
+
properties,
|
|
2169
|
+
nativeView,
|
|
2170
|
+
htmlChildren,
|
|
2171
|
+
presentationKey,
|
|
2172
|
+
animationContext?.nodeKeyPrefix,
|
|
2173
|
+
animationContext?.isFinalized,
|
|
2174
|
+
animationContext?.sourceGuard
|
|
2175
|
+
) : void 0,
|
|
2176
|
+
(tagName, properties, htmlChildren, presentationKey) => React8.createElement(htmlRenderer, {
|
|
2177
|
+
...node,
|
|
2178
|
+
key: presentationKey,
|
|
2179
|
+
children: htmlChildren,
|
|
2180
|
+
textValue,
|
|
2181
|
+
properties
|
|
2182
|
+
})
|
|
2183
|
+
) : renderHtmlInlineNode(
|
|
2184
|
+
node,
|
|
2185
|
+
children,
|
|
2186
|
+
void 0,
|
|
2187
|
+
key,
|
|
2188
|
+
textValue,
|
|
2189
|
+
urlTransform,
|
|
2190
|
+
registry?.hasElementFilters() ? (el, ctx, renderElement, renderChildren) => registry.filterElement(el, ctx, renderElement, renderChildren) : void 0,
|
|
2191
|
+
parentTagName,
|
|
2192
|
+
registry ? (tagName, properties, nativeView, htmlChildren, presentationKey) => registry.renderHtmlPresentation(
|
|
2193
|
+
tagName,
|
|
2194
|
+
properties,
|
|
2195
|
+
nativeView,
|
|
2196
|
+
htmlChildren,
|
|
2197
|
+
presentationKey,
|
|
2198
|
+
animationContext?.nodeKeyPrefix,
|
|
2199
|
+
animationContext?.isFinalized,
|
|
2200
|
+
animationContext?.sourceGuard
|
|
2201
|
+
) : void 0
|
|
2202
|
+
);
|
|
2203
|
+
}
|
|
1223
2204
|
default: {
|
|
1224
|
-
|
|
2205
|
+
let component = components[node.kind];
|
|
1225
2206
|
if (component) {
|
|
1226
|
-
|
|
2207
|
+
let engine = node.kind === "math-inline" || node.kind === "math-display" ? registry?.getMathEngine() : void 0;
|
|
2208
|
+
return presentInline(React8.createElement(component, { key, ...node, ...engine ? { engine } : {} }));
|
|
1227
2209
|
}
|
|
1228
|
-
return null;
|
|
2210
|
+
return presentInline(React8.createElement(React8.Fragment, { key }, null));
|
|
1229
2211
|
}
|
|
1230
2212
|
}
|
|
1231
2213
|
});
|
|
1232
2214
|
}
|
|
1233
2215
|
var defaultInlineComponents = {
|
|
1234
|
-
text: ({ text }) =>
|
|
1235
|
-
strong: ({ children }) =>
|
|
1236
|
-
em: ({ children }) =>
|
|
1237
|
-
strike: ({ children }) =>
|
|
1238
|
-
code: ({ text }) =>
|
|
2216
|
+
text: ({ text }) => React8.createElement(React8.Fragment, {}, text),
|
|
2217
|
+
strong: ({ children }) => React8.createElement("strong", {}, children),
|
|
2218
|
+
em: ({ children }) => React8.createElement("em", {}, children),
|
|
2219
|
+
strike: ({ children }) => React8.createElement("del", {}, children),
|
|
2220
|
+
code: ({ text }) => React8.createElement(
|
|
1239
2221
|
"code",
|
|
1240
2222
|
{
|
|
1241
2223
|
className: "inline-code"
|
|
1242
2224
|
},
|
|
1243
2225
|
text
|
|
1244
2226
|
),
|
|
1245
|
-
link: ({ href, title, children }) =>
|
|
1246
|
-
"
|
|
1247
|
-
|
|
1248
|
-
|
|
2227
|
+
link: ({ href, title, children }) => {
|
|
2228
|
+
let safeHref = href == null ? void 0 : defaultUrlTransform4(href, "href", { source: "markdown" });
|
|
2229
|
+
return React8.createElement(
|
|
2230
|
+
"a",
|
|
2231
|
+
{
|
|
2232
|
+
...safeHref != null ? { href: safeHref } : {},
|
|
2233
|
+
title,
|
|
2234
|
+
className: "markdown-link",
|
|
2235
|
+
target: safeHref?.startsWith("http") ? "_blank" : void 0,
|
|
2236
|
+
rel: safeHref?.startsWith("http") ? "noopener noreferrer" : void 0
|
|
2237
|
+
},
|
|
2238
|
+
children
|
|
2239
|
+
);
|
|
2240
|
+
},
|
|
2241
|
+
image: ({ src, alt, title }) => {
|
|
2242
|
+
let safeSrc = defaultUrlTransform4(src ?? "", "src", { source: "markdown" });
|
|
2243
|
+
return React8.createElement("img", {
|
|
2244
|
+
...safeSrc != null ? { src: safeSrc } : {},
|
|
2245
|
+
alt,
|
|
1249
2246
|
title,
|
|
1250
|
-
className: "markdown-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
children
|
|
1255
|
-
),
|
|
1256
|
-
image: ({ src, alt, title }) => React4.createElement("img", {
|
|
1257
|
-
src,
|
|
1258
|
-
alt,
|
|
1259
|
-
title,
|
|
1260
|
-
className: "markdown-image"
|
|
1261
|
-
}),
|
|
1262
|
-
br: () => React4.createElement("br"),
|
|
2247
|
+
className: "markdown-image"
|
|
2248
|
+
});
|
|
2249
|
+
},
|
|
2250
|
+
br: () => React8.createElement("br"),
|
|
1263
2251
|
// Custom extensible components
|
|
1264
|
-
mention: ({ handle }) =>
|
|
2252
|
+
mention: ({ handle }) => React8.createElement(
|
|
1265
2253
|
"span",
|
|
1266
2254
|
{
|
|
1267
2255
|
className: "mention",
|
|
@@ -1269,7 +2257,7 @@ var defaultInlineComponents = {
|
|
|
1269
2257
|
},
|
|
1270
2258
|
`@${handle}`
|
|
1271
2259
|
),
|
|
1272
|
-
citation: ({ id }) =>
|
|
2260
|
+
citation: ({ id }) => React8.createElement(
|
|
1273
2261
|
"span",
|
|
1274
2262
|
{
|
|
1275
2263
|
className: "citation",
|
|
@@ -1277,111 +2265,135 @@ var defaultInlineComponents = {
|
|
|
1277
2265
|
},
|
|
1278
2266
|
`[${id}]`
|
|
1279
2267
|
),
|
|
1280
|
-
"math-inline": ({ tex }) =>
|
|
1281
|
-
|
|
1282
|
-
{
|
|
1283
|
-
className: "math-inline",
|
|
1284
|
-
"data-tex": tex
|
|
1285
|
-
},
|
|
1286
|
-
`$${tex}$`
|
|
1287
|
-
),
|
|
1288
|
-
"math-display": ({ tex }) => React4.createElement(
|
|
1289
|
-
"div",
|
|
1290
|
-
{
|
|
1291
|
-
className: "math-display markdown-math-display",
|
|
1292
|
-
"data-tex": tex,
|
|
1293
|
-
style: { overflowX: "auto" }
|
|
1294
|
-
},
|
|
1295
|
-
React4.createElement("span", { className: "math-display-content" }, `$$${tex}$$`)
|
|
1296
|
-
),
|
|
2268
|
+
"math-inline": ({ tex, engine }) => React8.createElement(KaTeXInlineMath, { tex, engine }),
|
|
2269
|
+
"math-display": ({ tex, engine }) => React8.createElement(KaTeXBlockMath, { tex, engine }),
|
|
1297
2270
|
// Footnote inline reference (superscript anchor)
|
|
1298
|
-
"footnote-ref": ({ label, number }) => {
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
return React4.createElement(
|
|
2271
|
+
"footnote-ref": ({ label, number, occurrence, defined }) => {
|
|
2272
|
+
if (!number || defined === !1) return React8.createElement(React8.Fragment, null, `[^${label}]`);
|
|
2273
|
+
let n = number, href = `#fn:${n}`, id = `fnref:${n}${occurrence && occurrence > 1 ? `:${occurrence}` : ""}`;
|
|
2274
|
+
return React8.createElement(
|
|
1303
2275
|
"sup",
|
|
1304
2276
|
{ className: "footnote-ref" },
|
|
1305
|
-
|
|
2277
|
+
React8.createElement("a", { href, id, "data-label": label, style: { color: "var(--foreground)", textDecoration: "underline" } }, String(n))
|
|
1306
2278
|
);
|
|
1307
2279
|
}
|
|
1308
2280
|
};
|
|
2281
|
+
function blockPresentationProps(props) {
|
|
2282
|
+
let decoration = {};
|
|
2283
|
+
for (let [property, value] of Object.entries(props))
|
|
2284
|
+
(property === "className" || property === "style" || property === "title" || property.startsWith("data-") || property.startsWith("aria-")) && (decoration[property] = value);
|
|
2285
|
+
return Object.keys(decoration).length > 0 ? decoration : void 0;
|
|
2286
|
+
}
|
|
2287
|
+
function applyBlockPresentationProps(nativeView, decoration) {
|
|
2288
|
+
if (!decoration) return nativeView;
|
|
2289
|
+
if (Array.isArray(nativeView))
|
|
2290
|
+
return nativeView.map((child) => applyBlockPresentationProps(child, decoration));
|
|
2291
|
+
if (!React8.isValidElement(nativeView)) return nativeView;
|
|
2292
|
+
if (nativeView.type === React8.Fragment) {
|
|
2293
|
+
let children = React8.Children.map(
|
|
2294
|
+
nativeView.props.children,
|
|
2295
|
+
(child) => applyBlockPresentationProps(child, decoration)
|
|
2296
|
+
);
|
|
2297
|
+
return React8.cloneElement(nativeView, void 0, children);
|
|
2298
|
+
}
|
|
2299
|
+
return React8.cloneElement(
|
|
2300
|
+
nativeView,
|
|
2301
|
+
mergeNodePresentationProps(nativeView.props, decoration)
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
1309
2304
|
var defaultBlockComponents = {
|
|
1310
|
-
paragraph: (
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
{
|
|
1315
|
-
|
|
1316
|
-
},
|
|
1317
|
-
children
|
|
2305
|
+
paragraph: (props) => {
|
|
2306
|
+
let { inlines, raw, meta, children } = props, decoration = blockPresentationProps(props);
|
|
2307
|
+
if (children !== void 0)
|
|
2308
|
+
return applyBlockPresentationProps(
|
|
2309
|
+
React8.createElement("p", { className: "markdown-paragraph" }, children),
|
|
2310
|
+
decoration
|
|
1318
2311
|
);
|
|
1319
|
-
|
|
1320
|
-
const segments = Array.isArray(meta?.mixedSegments) ? meta?.mixedSegments : void 0;
|
|
2312
|
+
let segments = Array.isArray(meta?.mixedSegments) ? meta?.mixedSegments : void 0;
|
|
1321
2313
|
if (segments && segments.length > 0) {
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
2314
|
+
let structured = renderParagraphMixedSegments(segments, defaultInlineComponents, DEFAULT_INLINE_HTML_RENDERERS);
|
|
2315
|
+
return structured.length === 1 ? applyBlockPresentationProps(structured[0], decoration) : applyBlockPresentationProps(
|
|
2316
|
+
React8.createElement(React8.Fragment, {}, ...structured),
|
|
2317
|
+
decoration
|
|
2318
|
+
);
|
|
1327
2319
|
}
|
|
1328
|
-
|
|
1329
|
-
const effectiveInlines = filteredInlines.length > 0 ? filteredInlines : raw ? [
|
|
2320
|
+
let filteredInlines = inlines && raw && inlines.length > 0 ? inlines.filter((node) => !(node.kind === "text" && node.text === raw)) : inlines ?? [], effectiveInlines = filteredInlines.length > 0 ? filteredInlines : raw ? [
|
|
1330
2321
|
{
|
|
1331
2322
|
kind: "text",
|
|
1332
2323
|
text: raw
|
|
1333
2324
|
}
|
|
1334
2325
|
] : [];
|
|
1335
|
-
return
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
className: "markdown-paragraph"
|
|
1339
|
-
|
|
1340
|
-
|
|
2326
|
+
return applyBlockPresentationProps(
|
|
2327
|
+
React8.createElement(
|
|
2328
|
+
"p",
|
|
2329
|
+
{ className: "markdown-paragraph" },
|
|
2330
|
+
effectiveInlines.length > 0 ? renderInlineNodes(effectiveInlines, defaultInlineComponents) : raw ?? ""
|
|
2331
|
+
),
|
|
2332
|
+
decoration
|
|
1341
2333
|
);
|
|
1342
2334
|
},
|
|
1343
|
-
heading: (
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
2335
|
+
heading: (props) => {
|
|
2336
|
+
let { level, inlines, text, meta, children } = props, decoration = blockPresentationProps(props), tag = `h${level}`, onlyPlainText = Array.isArray(inlines) && inlines.length > 0 && inlines.every((node) => node.kind === "text"), content = children !== void 0 ? children : onlyPlainText ? inlines.map((node) => node.kind === "text" ? node.text : "").join("") : renderInlineNodes(inlines, defaultInlineComponents), headingId = typeof meta?.headingId == "string" && meta.headingId.length > 0 ? meta.headingId : void 0;
|
|
2337
|
+
return applyBlockPresentationProps(
|
|
2338
|
+
React8.createElement(
|
|
2339
|
+
tag,
|
|
2340
|
+
{
|
|
2341
|
+
className: `markdown-heading markdown-h${level}`,
|
|
2342
|
+
...text ? { "data-heading-text": text } : {},
|
|
2343
|
+
...headingId ? { id: headingId, "data-heading-id": headingId } : {}
|
|
2344
|
+
},
|
|
2345
|
+
content
|
|
2346
|
+
),
|
|
2347
|
+
decoration
|
|
1356
2348
|
);
|
|
1357
2349
|
},
|
|
1358
|
-
code: ({ html, meta, lines, lang, preAttrs, codeAttrs }) => {
|
|
1359
|
-
|
|
1360
|
-
if (
|
|
1361
|
-
|
|
1362
|
-
|
|
2350
|
+
code: ({ html, meta, lines, children, lang, preAttrs, codeAttrs }) => {
|
|
2351
|
+
let language = (typeof lang == "string" ? lang : typeof meta?.lang == "string" ? String(meta.lang) : "").trim();
|
|
2352
|
+
if (children !== void 0) {
|
|
2353
|
+
let preAttributes = attrsToProps(preAttrs), codeAttributes = attrsToProps(codeAttrs), preClassName = [preAttributes.className, "markdown-code-block", language ? `language-${language}` : ""].filter(Boolean).join(" "), codeClassName = [codeAttributes.className, language ? `language-${language}` : ""].filter(Boolean).join(" ");
|
|
2354
|
+
return React8.createElement(
|
|
2355
|
+
"div",
|
|
2356
|
+
{ className: language ? `markdown-code-block language-${language}` : "markdown-code-block" },
|
|
2357
|
+
React8.createElement(
|
|
2358
|
+
"pre",
|
|
2359
|
+
{
|
|
2360
|
+
...preAttributes,
|
|
2361
|
+
className: preClassName
|
|
2362
|
+
},
|
|
2363
|
+
React8.createElement(
|
|
2364
|
+
"code",
|
|
2365
|
+
{
|
|
2366
|
+
...codeAttributes,
|
|
2367
|
+
...codeClassName ? { className: codeClassName } : {}
|
|
2368
|
+
},
|
|
2369
|
+
children
|
|
2370
|
+
)
|
|
2371
|
+
)
|
|
2372
|
+
);
|
|
2373
|
+
}
|
|
2374
|
+
if (html)
|
|
2375
|
+
return React8.createElement("div", {
|
|
2376
|
+
className: language ? `markdown-code-block language-${language}` : "markdown-code-block",
|
|
1363
2377
|
/* biome-ignore lint/security/noDangerouslySetInnerHtml: highlighted HTML is generated by our sanitizer */
|
|
1364
2378
|
dangerouslySetInnerHTML: { __html: html }
|
|
1365
2379
|
});
|
|
1366
|
-
|
|
1367
|
-
const code = meta?.code || "";
|
|
2380
|
+
let code = meta?.code || "";
|
|
1368
2381
|
if (lines && lines.length > 0) {
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
return React4.createElement(
|
|
2382
|
+
let preAttributes = attrsToProps(preAttrs), codeAttributes = attrsToProps(codeAttrs), preClassName = [preAttributes.className, "markdown-code-block", language ? `language-${language}` : ""].filter(Boolean).join(" "), codeClassName = [codeAttributes.className, language ? `language-${language}` : ""].filter(Boolean).join(" ");
|
|
2383
|
+
return React8.createElement(
|
|
1372
2384
|
"pre",
|
|
1373
2385
|
{
|
|
1374
2386
|
...preAttributes,
|
|
1375
|
-
className:
|
|
2387
|
+
className: preClassName
|
|
1376
2388
|
},
|
|
1377
|
-
|
|
2389
|
+
React8.createElement(
|
|
1378
2390
|
"code",
|
|
1379
2391
|
{
|
|
1380
2392
|
...codeAttributes,
|
|
1381
|
-
|
|
2393
|
+
...codeClassName ? { className: codeClassName } : {}
|
|
1382
2394
|
},
|
|
1383
2395
|
lines.map(
|
|
1384
|
-
(line) =>
|
|
2396
|
+
(line) => React8.createElement("span", {
|
|
1385
2397
|
key: line.id,
|
|
1386
2398
|
className: "line",
|
|
1387
2399
|
/* biome-ignore lint/security/noDangerouslySetInnerHtml: line HTML is sanitized server-side */
|
|
@@ -1391,29 +2403,26 @@ var defaultBlockComponents = {
|
|
|
1391
2403
|
)
|
|
1392
2404
|
);
|
|
1393
2405
|
}
|
|
1394
|
-
return
|
|
1395
|
-
className: `markdown-code-block language-${language
|
|
2406
|
+
return React8.createElement("pre", {
|
|
2407
|
+
className: language ? `markdown-code-block language-${language}` : "markdown-code-block",
|
|
1396
2408
|
children: code
|
|
1397
2409
|
});
|
|
1398
2410
|
},
|
|
1399
|
-
blockquote: ({ inlines, renderedContent }) =>
|
|
2411
|
+
blockquote: ({ inlines, renderedContent }) => React8.createElement(
|
|
1400
2412
|
"blockquote",
|
|
1401
2413
|
{
|
|
1402
2414
|
className: "markdown-blockquote"
|
|
1403
2415
|
},
|
|
1404
2416
|
renderedContent ?? renderInlineNodes(inlines, defaultInlineComponents)
|
|
1405
2417
|
),
|
|
1406
|
-
hr: (props) =>
|
|
2418
|
+
hr: (props) => React8.createElement("hr", props),
|
|
1407
2419
|
list: ({ ordered, items }) => {
|
|
1408
|
-
if (items.length === 0)
|
|
2420
|
+
if (items.length === 0)
|
|
1409
2421
|
return null;
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
} : void 0;
|
|
1415
|
-
const listItems = items.map(
|
|
1416
|
-
(item, index) => React4.createElement(
|
|
2422
|
+
let tag = ordered ? "ol" : "ul", listStyle = ordered ? {
|
|
2423
|
+
"--list-indent": `calc(2.5rem + ${String(items.length).length}ch)`
|
|
2424
|
+
} : void 0, listItems = items.map(
|
|
2425
|
+
(item, index) => React8.createElement(
|
|
1417
2426
|
"li",
|
|
1418
2427
|
{
|
|
1419
2428
|
key: index,
|
|
@@ -1424,7 +2433,7 @@ var defaultBlockComponents = {
|
|
|
1424
2433
|
renderInlineNodes(item, defaultInlineComponents)
|
|
1425
2434
|
)
|
|
1426
2435
|
);
|
|
1427
|
-
return
|
|
2436
|
+
return React8.createElement(
|
|
1428
2437
|
tag,
|
|
1429
2438
|
{
|
|
1430
2439
|
className: `markdown-list ${ordered ? "ordered" : "unordered"}`,
|
|
@@ -1433,214 +2442,69 @@ var defaultBlockComponents = {
|
|
|
1433
2442
|
listItems
|
|
1434
2443
|
);
|
|
1435
2444
|
},
|
|
1436
|
-
html: ({ __trustedHtml, elements }) => {
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
2445
|
+
html: ({ __trustedHtml, elements, isSanitized, literalTagContent, children }) => {
|
|
2446
|
+
if (children !== void 0)
|
|
2447
|
+
return React8.createElement("div", { className: "markdown-html" }, children);
|
|
2448
|
+
let raw = typeof __trustedHtml == "string" ? __trustedHtml : __trustedHtml.toString(), htmlString = isSanitized || typeof window > "u" ? raw : sanitizeHTML(raw);
|
|
2449
|
+
if (typeof window < "u" && elements) {
|
|
2450
|
+
let content = mapHtmlToReact(htmlString, elements, literalTagContent);
|
|
2451
|
+
return React8.createElement("div", { className: "markdown-html" }, content);
|
|
1442
2452
|
}
|
|
1443
|
-
return
|
|
2453
|
+
return React8.createElement("div", {
|
|
1444
2454
|
className: "markdown-html",
|
|
1445
2455
|
/* biome-ignore lint/security/noDangerouslySetInnerHtml: htmlString is sanitized before injection */
|
|
1446
2456
|
dangerouslySetInnerHTML: { __html: htmlString }
|
|
1447
2457
|
});
|
|
1448
2458
|
},
|
|
1449
|
-
mdx: ({
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
const hydrationContext = React4.useContext(MdxHydrationContext);
|
|
1455
|
-
const hydrationController = hydrationContext?.controller ?? null;
|
|
1456
|
-
const hydrationOptions = hydrationContext?.options;
|
|
1457
|
-
const containerRef = React4.useRef(null);
|
|
1458
|
-
const deferHydration = hydrationOptions?.strategy === "visible";
|
|
1459
|
-
const shouldHydrate = useDeferredRender(
|
|
1460
|
-
containerRef,
|
|
1461
|
-
deferHydration ? {
|
|
1462
|
-
enabled: true,
|
|
1463
|
-
rootMargin: hydrationOptions?.rootMargin,
|
|
1464
|
-
idleTimeoutMs: hydrationOptions?.idleTimeoutMs,
|
|
1465
|
-
debounceMs: hydrationOptions?.debounceMs
|
|
1466
|
-
} : { enabled: false }
|
|
1467
|
-
);
|
|
1468
|
-
const resolvedId = compiledModule?.id ?? (compiledRef?.id && compiledRef.id !== "pending" ? compiledRef.id : void 0);
|
|
1469
|
-
const handleRetry = React4.useCallback(() => {
|
|
1470
|
-
setInternalError(null);
|
|
1471
|
-
setRenderError(null);
|
|
1472
|
-
setComp(null);
|
|
1473
|
-
setRetryKey((prev) => prev + 1);
|
|
1474
|
-
}, []);
|
|
1475
|
-
const handleRuntimeError = React4.useCallback(
|
|
1476
|
-
(error) => {
|
|
1477
|
-
const message2 = error instanceof Error ? error.message : String(error);
|
|
1478
|
-
setRenderError(message2);
|
|
1479
|
-
markMdxHydrationError(resolvedId ?? compiledRef?.id);
|
|
1480
|
-
},
|
|
1481
|
-
[resolvedId, compiledRef?.id]
|
|
1482
|
-
);
|
|
1483
|
-
const effectiveStatus = status ? status : resolvedId ? "compiled" : "pending";
|
|
1484
|
-
const failureMessage = errorMessage ?? internalError ?? renderError ?? null;
|
|
1485
|
-
const moduleDependencies = compiledModule?.dependencies;
|
|
1486
|
-
React4.useEffect(() => {
|
|
1487
|
-
if (!shouldHydrate) {
|
|
1488
|
-
return;
|
|
1489
|
-
}
|
|
1490
|
-
if (status === "error") {
|
|
1491
|
-
markMdxHydrationError(resolvedId ?? compiledRef?.id);
|
|
1492
|
-
return;
|
|
1493
|
-
}
|
|
1494
|
-
let cancelled = false;
|
|
1495
|
-
async function ensure() {
|
|
1496
|
-
let permit = null;
|
|
1497
|
-
try {
|
|
1498
|
-
if (status === "error" || !resolvedId || resolvedId === "pending") {
|
|
1499
|
-
if (!cancelled) {
|
|
1500
|
-
setComp(null);
|
|
1501
|
-
setInternalError(null);
|
|
1502
|
-
}
|
|
1503
|
-
return;
|
|
1504
|
-
}
|
|
1505
|
-
if (hydrationController) {
|
|
1506
|
-
permit = await hydrationController.acquire();
|
|
1507
|
-
if (cancelled) {
|
|
1508
|
-
permit.release();
|
|
1509
|
-
return;
|
|
1510
|
-
}
|
|
1511
|
-
}
|
|
1512
|
-
setInternalError(null);
|
|
1513
|
-
setRenderError(null);
|
|
1514
|
-
markMdxHydrationStart(resolvedId);
|
|
1515
|
-
const { getMDXComponentFactory: getMDXComponentFactory2, registerInlineMdxModule: registerInlineMdxModule2 } = await loadMdxRuntime();
|
|
1516
|
-
if (compiledModule?.code) {
|
|
1517
|
-
registerInlineMdxModule2({
|
|
1518
|
-
id: compiledModule.id,
|
|
1519
|
-
code: compiledModule.code,
|
|
1520
|
-
dependencies: moduleDependencies ?? []
|
|
1521
|
-
});
|
|
1522
|
-
}
|
|
1523
|
-
const factory = getMDXComponentFactory2();
|
|
1524
|
-
const C = await factory.createComponent({ id: resolvedId });
|
|
1525
|
-
if (!cancelled) {
|
|
1526
|
-
setComp(() => C);
|
|
1527
|
-
setInternalError(null);
|
|
1528
|
-
markMdxHydrated(resolvedId);
|
|
1529
|
-
}
|
|
1530
|
-
} catch (error) {
|
|
1531
|
-
if (!cancelled) {
|
|
1532
|
-
const message2 = error instanceof Error ? error.message : String(error);
|
|
1533
|
-
setInternalError(message2);
|
|
1534
|
-
markMdxHydrationError(resolvedId);
|
|
1535
|
-
}
|
|
1536
|
-
} finally {
|
|
1537
|
-
permit?.release();
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1540
|
-
ensure();
|
|
1541
|
-
return () => {
|
|
1542
|
-
cancelled = true;
|
|
1543
|
-
};
|
|
1544
|
-
}, [compiledModule?.id, compiledModule?.code, moduleDependencies, resolvedId, status, shouldHydrate, retryKey]);
|
|
1545
|
-
const compileMode = compiledModule?.source === "worker" || compiledRef?.id?.startsWith("worker:") ? "worker" : "server";
|
|
1546
|
-
const pendingId = resolvedId && resolvedId !== "pending" ? resolvedId : compiledRef?.id ?? "pending";
|
|
1547
|
-
const waitingForVisibility = deferHydration && !shouldHydrate && Boolean(resolvedId);
|
|
1548
|
-
const pendingLabel = waitingForVisibility ? "MDX ready (hydrate on view)\u2026" : compileMode === "worker" ? "Compiling MDX (client)\u2026" : "Compiling MDX (server)\u2026";
|
|
1549
|
-
const message = failureMessage ?? (compileMode === "worker" ? "MDX compilation failed in client mode. Try switching back to server rendering or restarting the stream." : "MDX compilation failed. Try restarting the stream.");
|
|
1550
|
-
const allowRetry = Boolean(internalError || renderError);
|
|
1551
|
-
const retryButton = allowRetry ? React4.createElement(
|
|
1552
|
-
"button",
|
|
1553
|
-
{
|
|
1554
|
-
type: "button",
|
|
1555
|
-
className: "markdown-mdx-retry",
|
|
1556
|
-
onClick: handleRetry
|
|
1557
|
-
},
|
|
1558
|
-
"Retry hydration"
|
|
1559
|
-
) : null;
|
|
1560
|
-
const errorPanel = React4.createElement(
|
|
1561
|
-
React4.Fragment,
|
|
1562
|
-
null,
|
|
1563
|
-
React4.createElement("strong", null, "MDX failed"),
|
|
1564
|
-
React4.createElement("div", null, message)
|
|
1565
|
-
);
|
|
1566
|
-
if (Comp && !failureMessage) {
|
|
1567
|
-
return React4.createElement(
|
|
1568
|
-
"div",
|
|
1569
|
-
{
|
|
1570
|
-
className: "markdown-mdx",
|
|
1571
|
-
ref: containerRef,
|
|
1572
|
-
"data-mdx-ref": resolvedId ?? compiledRef?.id ?? "compiled",
|
|
1573
|
-
"data-mdx-status": failureMessage ? "error" : "compiled",
|
|
1574
|
-
"data-mdx-mode": compileMode
|
|
1575
|
-
},
|
|
1576
|
-
React4.createElement(
|
|
1577
|
-
MdxRuntimeBoundary,
|
|
1578
|
-
{ resetKey: retryKey, onError: handleRuntimeError },
|
|
1579
|
-
React4.createElement(Comp, {})
|
|
1580
|
-
)
|
|
1581
|
-
);
|
|
1582
|
-
}
|
|
1583
|
-
if (failureMessage) {
|
|
1584
|
-
return React4.createElement(
|
|
1585
|
-
"div",
|
|
1586
|
-
{
|
|
1587
|
-
className: "markdown-mdx error",
|
|
1588
|
-
ref: containerRef,
|
|
1589
|
-
"data-mdx-ref": pendingId,
|
|
1590
|
-
"data-mdx-status": "error",
|
|
1591
|
-
"data-mdx-mode": compileMode
|
|
1592
|
-
},
|
|
1593
|
-
errorPanel,
|
|
1594
|
-
retryButton
|
|
1595
|
-
);
|
|
1596
|
-
}
|
|
1597
|
-
if (!Comp) {
|
|
1598
|
-
return React4.createElement(
|
|
1599
|
-
"div",
|
|
1600
|
-
{
|
|
1601
|
-
className: "markdown-mdx",
|
|
1602
|
-
ref: containerRef,
|
|
1603
|
-
"data-mdx-ref": pendingId,
|
|
1604
|
-
"data-mdx-status": "pending",
|
|
1605
|
-
"data-mdx-mode": compileMode
|
|
1606
|
-
},
|
|
1607
|
-
pendingLabel
|
|
1608
|
-
);
|
|
2459
|
+
mdx: ({ raw, meta }) => {
|
|
2460
|
+
let originalType = typeof meta?.originalType == "string" ? String(meta.originalType) : void 0, mixedSegments = Array.isArray(meta?.mixedSegments) ? meta.mixedSegments : void 0;
|
|
2461
|
+
if (originalType === "paragraph" && !meta?.mdxStandalone && mixedSegments && mixedSegments.length > 0) {
|
|
2462
|
+
let structured = renderParagraphMixedSegments(mixedSegments, defaultInlineComponents, DEFAULT_INLINE_HTML_RENDERERS);
|
|
2463
|
+
return structured.length === 1 ? structured[0] : React8.createElement(React8.Fragment, {}, ...structured);
|
|
1609
2464
|
}
|
|
2465
|
+
return React8.createElement(
|
|
2466
|
+
"div",
|
|
2467
|
+
{ className: "markdown-mdx-inert", "data-diagnostic": "MDX requires explicit engines.mdx in trusted-mdx mode" },
|
|
2468
|
+
React8.createElement("pre", null, React8.createElement("code", null, raw ?? ""))
|
|
2469
|
+
);
|
|
1610
2470
|
},
|
|
1611
2471
|
// Footnotes block rendered at page end
|
|
1612
2472
|
footnotes: ({ items }) => {
|
|
1613
|
-
if (!items || items.length === 0) return
|
|
1614
|
-
|
|
1615
|
-
(item) =>
|
|
2473
|
+
if (!items || items.length === 0) return React8.createElement(React8.Fragment, null);
|
|
2474
|
+
let listItems = items.map(
|
|
2475
|
+
(item) => React8.createElement(
|
|
1616
2476
|
"li",
|
|
1617
2477
|
{ key: item.number, id: `fn:${item.number}` },
|
|
1618
2478
|
renderInlineNodes(item.inlines, defaultInlineComponents),
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
2479
|
+
...Array.from({ length: item.refCount ?? 1 }, (_, index) => React8.createElement(
|
|
2480
|
+
React8.Fragment,
|
|
2481
|
+
{ key: index },
|
|
2482
|
+
" ",
|
|
2483
|
+
React8.createElement(
|
|
2484
|
+
"a",
|
|
2485
|
+
{
|
|
2486
|
+
href: `#fnref:${item.number}${index > 0 ? `:${index + 1}` : ""}`,
|
|
2487
|
+
className: "footnote-backref",
|
|
2488
|
+
"aria-label": index > 0 ? `Back to content (reference ${index + 1})` : "Back to content",
|
|
2489
|
+
style: { color: "var(--foreground)", textDecoration: "underline" }
|
|
2490
|
+
},
|
|
2491
|
+
"\u21A9",
|
|
2492
|
+
index > 0 ? React8.createElement("sup", null, String(index + 1)) : null
|
|
2493
|
+
)
|
|
2494
|
+
))
|
|
1630
2495
|
)
|
|
1631
2496
|
);
|
|
1632
|
-
return
|
|
2497
|
+
return React8.createElement("section", { className: "footnotes" }, React8.createElement("hr", {}), React8.createElement("ol", {}, listItems));
|
|
1633
2498
|
},
|
|
1634
2499
|
// Footnote definition placeholders (render nothing)
|
|
1635
|
-
"footnote-def": () =>
|
|
2500
|
+
"footnote-def": () => React8.createElement(React8.Fragment, null),
|
|
1636
2501
|
// Callouts block
|
|
1637
2502
|
callout: ({ kind, inlines = [] }) => {
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
return React4.createElement(
|
|
2503
|
+
let tone = (kind || "NOTE").toUpperCase(), title = tone.charAt(0) + tone.slice(1).toLowerCase();
|
|
2504
|
+
return React8.createElement(
|
|
1641
2505
|
"div",
|
|
1642
2506
|
{ className: `markdown-callout markdown-callout-${tone.toLowerCase()} border rounded p-3 my-3` },
|
|
1643
|
-
|
|
2507
|
+
React8.createElement("div", { className: "font-semibold mb-1" }, title),
|
|
1644
2508
|
inlines.length > 0 ? renderInlineNodes(inlines, defaultInlineComponents) : null
|
|
1645
2509
|
);
|
|
1646
2510
|
},
|
|
@@ -1651,11 +2515,9 @@ var defaultBlockComponents = {
|
|
|
1651
2515
|
align,
|
|
1652
2516
|
elements
|
|
1653
2517
|
}) => {
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
const cellStyle = columnAlign ? { textAlign: columnAlign } : void 0;
|
|
1658
|
-
return React4.createElement(
|
|
2518
|
+
let El = getDefaultTableElements(elements), renderCells = (cells, tag, rowIdx) => cells.map((cell, i) => {
|
|
2519
|
+
let columnAlign = align?.[i] ?? void 0, cellStyle = columnAlign ? { textAlign: columnAlign } : void 0;
|
|
2520
|
+
return React8.createElement(
|
|
1659
2521
|
tag === "th" ? El.Th : El.Td,
|
|
1660
2522
|
{
|
|
1661
2523
|
key: `${rowIdx}-${i}`,
|
|
@@ -1666,54 +2528,228 @@ var defaultBlockComponents = {
|
|
|
1666
2528
|
renderInlineNodes(cell, defaultInlineComponents)
|
|
1667
2529
|
);
|
|
1668
2530
|
});
|
|
1669
|
-
return
|
|
2531
|
+
return React8.createElement(
|
|
1670
2532
|
El.Table,
|
|
1671
2533
|
{ className: "markdown-table" },
|
|
1672
|
-
header && header.length > 0 ?
|
|
1673
|
-
|
|
2534
|
+
header && header.length > 0 ? React8.createElement(El.Thead, {}, React8.createElement(El.Tr, {}, renderCells(header, "th", -1))) : null,
|
|
2535
|
+
rows && rows.length > 0 ? React8.createElement(
|
|
1674
2536
|
El.Tbody,
|
|
1675
2537
|
{},
|
|
1676
|
-
rows.map((row, r) =>
|
|
1677
|
-
)
|
|
2538
|
+
rows.map((row, r) => React8.createElement(El.Tr, { key: r }, renderCells(row, "td", r)))
|
|
2539
|
+
) : null
|
|
1678
2540
|
);
|
|
1679
2541
|
}
|
|
1680
|
-
}
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
this.
|
|
2542
|
+
}, ComponentRegistry = class {
|
|
2543
|
+
constructor(options) {
|
|
2544
|
+
this.nodePresentations = {};
|
|
2545
|
+
this.tableVirtualization = DEFAULT_TABLE_VIRTUALIZATION_CONFIG;
|
|
2546
|
+
this.tableVirtualizationListeners = /* @__PURE__ */ new Set();
|
|
2547
|
+
this.codeVirtualization = DEFAULT_VIRTUALIZED_CODE_CONFIG;
|
|
2548
|
+
this.codeVirtualizationListeners = /* @__PURE__ */ new Set();
|
|
1684
2549
|
this.inlineComponentMapCache = null;
|
|
1685
|
-
this.
|
|
1686
|
-
this.
|
|
1687
|
-
this.
|
|
1688
|
-
this.
|
|
2550
|
+
this.controls = !1;
|
|
2551
|
+
this.animatedOptions = null;
|
|
2552
|
+
this.animationTimeline = null;
|
|
2553
|
+
this.hasFilterConfig = !1;
|
|
2554
|
+
this.mathEngine = options?.engines?.math, this.mermaidEngine = options?.engines?.mermaid, this.inlineComponents = { ...defaultInlineComponents }, this.htmlElements = getDefaultHtmlElements(), options?.urlTransform && (this.urlTransform = options.urlTransform), options?.contentComponents && (this.contentComponents = options.contentComponents);
|
|
2555
|
+
let defaultHtmlInlineRenderer = (node) => renderHtmlInlineNode(node, node.children, this.htmlElements, void 0, node.textValue, this.urlTransform);
|
|
2556
|
+
this.defaultHtmlInlineRenderer = defaultHtmlInlineRenderer, this.inlineComponents.html = defaultHtmlInlineRenderer, this.tableElements = getDefaultTableElements(), this.setNodePresentations(options?.components), options?.tableVirtualization !== void 0 && this.setTableVirtualization(options.tableVirtualization), options?.codeVirtualization !== void 0 && this.setCodeVirtualization(options.codeVirtualization), options?.controls !== void 0 && this.setControls(options.controls), options?.controlsComponent !== void 0 && this.setControlsComponent(options.controlsComponent), options?.animated !== void 0 && this.setAnimated(options.animated), options && this.setElementFilters(options);
|
|
1689
2557
|
}
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
this.
|
|
1695
|
-
this.blockComponentMapCache = null;
|
|
2558
|
+
setLinkSafetyRenderer(renderer) {
|
|
2559
|
+
this.inlineComponents = {
|
|
2560
|
+
...this.inlineComponents,
|
|
2561
|
+
link: renderer ?? defaultInlineComponents.link
|
|
2562
|
+
}, this.inlineComponentMapCache = null;
|
|
1696
2563
|
}
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
2564
|
+
hasElementFilters() {
|
|
2565
|
+
return this.hasFilterConfig;
|
|
2566
|
+
}
|
|
2567
|
+
/** Replaces the whole filter configuration at once so prop swaps (allowed -> disallowed) never trip the exclusivity check. */
|
|
2568
|
+
setElementFilters(options) {
|
|
2569
|
+
let { allowedElements, disallowedElements, allowElement, unwrapDisallowed, disableAutolinkProtocols } = options;
|
|
2570
|
+
if (allowedElements && disallowedElements)
|
|
2571
|
+
throw new Error("Cannot specify both allowedElements and disallowedElements; expected one or the other");
|
|
2572
|
+
let toTagSet = (tags) => tags ? new Set(tags.map((tag) => tag.trim().toLowerCase())) : void 0;
|
|
2573
|
+
this.allowedElements = toTagSet(allowedElements), this.disallowedElements = toTagSet(disallowedElements), this.allowElement = allowElement, this.unwrapDisallowed = unwrapDisallowed, this.disableAutolinkProtocols = disableAutolinkProtocols ? new Set(disableAutolinkProtocols.map((protocol) => protocol.trim().toLowerCase().replace(/:$/, ""))) : void 0, this.hasFilterConfig = !!(this.allowedElements || this.disallowedElements || this.allowElement);
|
|
2574
|
+
}
|
|
2575
|
+
isAutolinkProtocolDisabled(href) {
|
|
2576
|
+
if (!this.disableAutolinkProtocols || !href) return !1;
|
|
2577
|
+
let match = /^[a-zA-Z][a-zA-Z0-9+.-]*(?=:)/.exec(href.trim());
|
|
2578
|
+
return match ? this.disableAutolinkProtocols.has(match[0].toLowerCase()) : !1;
|
|
2579
|
+
}
|
|
2580
|
+
isElementAllowed(element, context) {
|
|
2581
|
+
let tag = element.tagName.toLowerCase();
|
|
2582
|
+
return !(this.allowedElements && !this.allowedElements.has(tag) || this.disallowedElements && this.disallowedElements.has(tag) || this.allowElement && !this.allowElement(
|
|
2583
|
+
{ tagName: tag, properties: element.properties ?? {}, blockType: element.blockType },
|
|
2584
|
+
context
|
|
2585
|
+
));
|
|
2586
|
+
}
|
|
2587
|
+
filterElement(element, context, renderElement, renderChildren) {
|
|
2588
|
+
if (!this.hasFilterConfig || this.isElementAllowed(element, context))
|
|
2589
|
+
return renderElement();
|
|
2590
|
+
if (this.unwrapDisallowed && renderChildren) {
|
|
2591
|
+
let children = renderChildren();
|
|
2592
|
+
if (children == null) return null;
|
|
2593
|
+
let key = element.properties?.key;
|
|
2594
|
+
return React8.createElement(React8.Fragment, key !== void 0 ? { key } : null, children);
|
|
2595
|
+
}
|
|
2596
|
+
return null;
|
|
2597
|
+
}
|
|
2598
|
+
setUrlTransform(transform) {
|
|
2599
|
+
this.urlTransform = transform;
|
|
1703
2600
|
}
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
2601
|
+
setAnimated(animated) {
|
|
2602
|
+
this.animated = animated, this.animatedOptions = resolveAnimatedOptions(animated), this.animatedOptions ? this.animationTimeline ? this.animationTimeline.updateOptions({
|
|
2603
|
+
maxBacklogMs: this.animatedOptions.maxBacklogMs,
|
|
2604
|
+
stagger: this.animatedOptions.stagger
|
|
2605
|
+
}) : this.animationTimeline = new AnimationTimeline({
|
|
2606
|
+
maxBacklogMs: this.animatedOptions.maxBacklogMs,
|
|
2607
|
+
stagger: this.animatedOptions.stagger
|
|
2608
|
+
}) : (this.animationTimeline && this.animationTimeline.reset(), this.animationTimeline = null);
|
|
1707
2609
|
}
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
2610
|
+
getAnimated() {
|
|
2611
|
+
return this.animated;
|
|
2612
|
+
}
|
|
2613
|
+
getAnimatedOptions() {
|
|
2614
|
+
return this.animatedOptions;
|
|
2615
|
+
}
|
|
2616
|
+
getAnimationTimeline() {
|
|
2617
|
+
return this.animationTimeline;
|
|
2618
|
+
}
|
|
2619
|
+
getRenderInlineContext(isFinalized, blockId, sourceGuard) {
|
|
2620
|
+
let context;
|
|
2621
|
+
return isFinalized ? (blockId && this.animationTimeline && this.animationTimeline.releasePrefix(blockId), context = blockId ? { isFinalized: !0, nodeKeyPrefix: blockId } : void 0) : this.animatedOptions && this.animationTimeline && (context = {
|
|
2622
|
+
isFinalized: !1,
|
|
2623
|
+
animated: this.animatedOptions,
|
|
2624
|
+
timeline: this.animationTimeline,
|
|
2625
|
+
nodeKeyPrefix: blockId
|
|
2626
|
+
}), sourceGuard ? { ...context ?? { isFinalized: isFinalized ?? !1 }, sourceGuard } : context;
|
|
2627
|
+
}
|
|
2628
|
+
resetAnimationTimeline() {
|
|
2629
|
+
this.animationTimeline?.reset();
|
|
2630
|
+
}
|
|
2631
|
+
getUrlTransform() {
|
|
2632
|
+
return this.urlTransform;
|
|
2633
|
+
}
|
|
2634
|
+
releaseFinalizedBlockAnimations(blockId) {
|
|
2635
|
+
this.animationTimeline?.releasePrefix(blockId);
|
|
2636
|
+
}
|
|
2637
|
+
setNodePresentations(presentations) {
|
|
2638
|
+
validateNodePresentations(presentations), this.nodePresentations = presentations ?? {};
|
|
2639
|
+
}
|
|
2640
|
+
getNodePresentation(key) {
|
|
2641
|
+
return resolveNodePresentation(this.nodePresentations, key);
|
|
2642
|
+
}
|
|
2643
|
+
isDefaultHtmlInlineRenderer(renderer) {
|
|
2644
|
+
return !renderer || !this.defaultHtmlInlineRenderer ? !1 : renderer === this.defaultHtmlInlineRenderer;
|
|
2645
|
+
}
|
|
2646
|
+
renderInlinePresentation(node, nativeView, key, context, renderedChildren) {
|
|
2647
|
+
let keyName = node.kind === "plugin" ? `extension:${node.name}` : node.kind === "math-inline" || node.kind === "math-display" ? "inline:math" : `inline:${node.kind}`, presentation = this.getNodePresentation(keyName);
|
|
2648
|
+
if (!presentation) return nativeView;
|
|
2649
|
+
let hasPluginComponent = node.kind === "plugin" && (this.inlineComponents[node.name] !== void 0 || this.inlineComponents.plugin !== void 0), preparedNativeView = node.kind === "plugin" && !hasPluginComponent && renderedChildren !== void 0 ? React8.createElement(React8.Fragment, { key }, renderedChildren) : nativeView, presentedNode = node;
|
|
2650
|
+
if ("view" in presentation && presentation.view) {
|
|
2651
|
+
let transform = this.urlTransform ?? defaultUrlTransform4;
|
|
2652
|
+
node.kind === "link" ? presentedNode = {
|
|
2653
|
+
...node,
|
|
2654
|
+
href: transform(node.href ?? "", "href", { source: "markdown" }) ?? void 0
|
|
2655
|
+
} : node.kind === "image" && (presentedNode = {
|
|
2656
|
+
...node,
|
|
2657
|
+
src: transform(node.src ?? "", "src", { source: "markdown" }) ?? ""
|
|
2658
|
+
});
|
|
2659
|
+
}
|
|
2660
|
+
let metadata = Object.freeze({
|
|
2661
|
+
id: `${context?.nodeKeyPrefix ?? "inline"}:${String(key)}`,
|
|
2662
|
+
type: keyName,
|
|
2663
|
+
isFinalized: context?.isFinalized ?? !1
|
|
2664
|
+
}), source = () => (context?.sourceGuard?.(), inlineToPlainText([node])), actions = Object.freeze({
|
|
2665
|
+
readSource: source,
|
|
2666
|
+
copy: () => copyToClipboard(source()),
|
|
2667
|
+
download: () => downloadFile(source(), `${node.kind}.txt`)
|
|
2668
|
+
}), children = node.kind === "math-inline" || node.kind === "math-display" ? nativeView : renderedChildren ?? (React8.isValidElement(preparedNativeView) ? preparedNativeView.props.children : void 0);
|
|
2669
|
+
return renderPresentedNode(presentation, preparedNativeView, {
|
|
2670
|
+
key,
|
|
2671
|
+
metadata,
|
|
2672
|
+
actions,
|
|
2673
|
+
viewProps: { node: presentedNode, children, metadata, actions }
|
|
2674
|
+
});
|
|
2675
|
+
}
|
|
2676
|
+
renderHtmlPresentation(tagName, properties, nativeView, children, key, ownerId, isFinalized = !1, sourceGuard) {
|
|
2677
|
+
let keyName = `html:${tagName.toLowerCase()}`, presentation = this.getNodePresentation(keyName);
|
|
2678
|
+
if (!presentation) return nativeView;
|
|
2679
|
+
let viewProperties = {};
|
|
2680
|
+
for (let [property, value] of Object.entries(properties))
|
|
2681
|
+
property !== "key" && (viewProperties[property] = value);
|
|
2682
|
+
let source = () => (sourceGuard?.(), presentationText(children)), metadata = Object.freeze({
|
|
2683
|
+
id: `${ownerId ?? "html"}:${String(key)}`,
|
|
2684
|
+
type: keyName,
|
|
2685
|
+
isFinalized
|
|
2686
|
+
}), actions = Object.freeze({
|
|
2687
|
+
readSource: source,
|
|
2688
|
+
copy: () => copyToClipboard(source()),
|
|
2689
|
+
download: () => downloadFile(source(), `${tagName.toLowerCase()}.txt`)
|
|
2690
|
+
});
|
|
2691
|
+
return renderPresentedNode(presentation, nativeView, {
|
|
2692
|
+
key,
|
|
2693
|
+
metadata,
|
|
2694
|
+
actions,
|
|
2695
|
+
viewProps: { tagName: tagName.toLowerCase(), properties: viewProperties, children, metadata, actions }
|
|
2696
|
+
});
|
|
2697
|
+
}
|
|
2698
|
+
renderComponentPresentation(name, nativeView, children, key, status, rawSource, ownerId, sourceGuard) {
|
|
2699
|
+
let keyName = `component:${name}`, presentation = this.getNodePresentation(keyName);
|
|
2700
|
+
if (!presentation) return nativeView;
|
|
2701
|
+
if ("view" in presentation && presentation.view)
|
|
2702
|
+
throw new TypeError(`node presentation for ${keyName}: headless views are not supported for restricted content components`);
|
|
2703
|
+
let preparedNativeView = presentation.props ? React8.cloneElement(
|
|
2704
|
+
nativeView,
|
|
2705
|
+
mergeNodePresentationProps(nativeView.props, presentation.props)
|
|
2706
|
+
) : nativeView;
|
|
2707
|
+
if (!("wrapper" in presentation) || !presentation.wrapper) return preparedNativeView;
|
|
2708
|
+
let source = () => (sourceGuard?.(), rawSource ?? presentationText(children)), metadata = Object.freeze({
|
|
2709
|
+
id: `${ownerId ?? "component"}:${String(key)}`,
|
|
2710
|
+
type: keyName,
|
|
2711
|
+
isFinalized: status === "closed"
|
|
2712
|
+
}), actions = Object.freeze({
|
|
2713
|
+
readSource: source,
|
|
2714
|
+
copy: () => copyToClipboard(source()),
|
|
2715
|
+
download: () => downloadFile(source(), `${name}.txt`)
|
|
2716
|
+
});
|
|
2717
|
+
return React8.createElement(presentation.wrapper, { key, children: preparedNativeView, metadata, actions });
|
|
2718
|
+
}
|
|
2719
|
+
/** Get HTML element mapping */
|
|
2720
|
+
getHtmlElements() {
|
|
2721
|
+
return this.htmlElements;
|
|
2722
|
+
}
|
|
2723
|
+
/** Update literal tag content list */
|
|
2724
|
+
setLiteralTagContent(tags) {
|
|
2725
|
+
this.literalTagContent = tags;
|
|
2726
|
+
}
|
|
2727
|
+
/** Get literal tag content list */
|
|
2728
|
+
getLiteralTagContent() {
|
|
2729
|
+
return this.literalTagContent;
|
|
2730
|
+
}
|
|
2731
|
+
setControls(controls) {
|
|
2732
|
+
this.controls = controls ?? !1;
|
|
2733
|
+
}
|
|
2734
|
+
getControls() {
|
|
2735
|
+
return this.controls;
|
|
2736
|
+
}
|
|
2737
|
+
setControlsComponent(component) {
|
|
2738
|
+
this.controlsComponent = component;
|
|
2739
|
+
}
|
|
2740
|
+
getControlsComponent() {
|
|
2741
|
+
if (this.controlsComponent)
|
|
2742
|
+
return this.controlsComponent;
|
|
1711
2743
|
}
|
|
1712
2744
|
/**
|
|
1713
2745
|
* Get block component
|
|
1714
2746
|
*/
|
|
1715
2747
|
getBlockComponent(type) {
|
|
1716
|
-
return
|
|
2748
|
+
return defaultBlockComponents[type] ?? defaultBlockComponents.paragraph;
|
|
2749
|
+
}
|
|
2750
|
+
getCodeNodeView() {
|
|
2751
|
+
let presentation = this.getNodePresentation("code");
|
|
2752
|
+
return presentation && "view" in presentation ? presentation.view : void 0;
|
|
1717
2753
|
}
|
|
1718
2754
|
/**
|
|
1719
2755
|
* Get inline components
|
|
@@ -1721,112 +2757,309 @@ var ComponentRegistry = class {
|
|
|
1721
2757
|
getInlineComponents() {
|
|
1722
2758
|
return this.inlineComponents;
|
|
1723
2759
|
}
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
this.blockComponentMapCache = { ...this.blockComponents };
|
|
1727
|
-
}
|
|
1728
|
-
return this.blockComponentMapCache;
|
|
2760
|
+
getMathEngine() {
|
|
2761
|
+
return this.mathEngine;
|
|
1729
2762
|
}
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
return this.
|
|
2763
|
+
setMermaidEngine(engine) {
|
|
2764
|
+
this.mermaidEngine = engine;
|
|
2765
|
+
}
|
|
2766
|
+
getMermaidEngine() {
|
|
2767
|
+
return this.mermaidEngine;
|
|
2768
|
+
}
|
|
2769
|
+
setContentComponents(contentComponents) {
|
|
2770
|
+
this.contentComponents = contentComponents;
|
|
2771
|
+
}
|
|
2772
|
+
getContentComponents() {
|
|
2773
|
+
return this.contentComponents;
|
|
2774
|
+
}
|
|
2775
|
+
renderHtmlTree(tree, renderBlock = (block) => this.renderBlock(block), paragraph, parentTagName, renderParagraphPresentation, sourceGuard) {
|
|
2776
|
+
return renderOwnedHtmlTree(
|
|
2777
|
+
tree,
|
|
2778
|
+
this.ownedHtmlRenderContext(renderBlock, paragraph, parentTagName, void 0, renderParagraphPresentation, sourceGuard)
|
|
2779
|
+
);
|
|
2780
|
+
}
|
|
2781
|
+
ownedHtmlRenderContext(renderBlock = (block) => this.renderBlock(block), paragraph, parentTagName, inlineContext, renderParagraphPresentation, sourceGuard) {
|
|
2782
|
+
let renderContext = inlineContext ?? (paragraph ? this.getRenderInlineContext(paragraph.isFinalized, paragraph.id, sourceGuard) : void 0);
|
|
2783
|
+
return {
|
|
2784
|
+
elements: this.htmlElements,
|
|
2785
|
+
renderBlock,
|
|
2786
|
+
renderInline: (nodes, parentTagName2) => renderInlineNodes(nodes, this.inlineComponents, this.urlTransform, this, parentTagName2, renderContext),
|
|
2787
|
+
renderInlinePresentation: (node, nativeView, key, children) => this.renderInlinePresentation(node, nativeView, key, renderContext, children),
|
|
2788
|
+
renderHtmlPresentation: (tagName, properties, nativeView, children, key) => this.renderHtmlPresentation(
|
|
2789
|
+
tagName,
|
|
2790
|
+
properties,
|
|
2791
|
+
nativeView,
|
|
2792
|
+
children,
|
|
2793
|
+
key,
|
|
2794
|
+
renderContext?.nodeKeyPrefix ?? String(paragraph?.id ?? parentTagName ?? "html"),
|
|
2795
|
+
renderContext?.isFinalized ?? paragraph?.isFinalized ?? !1,
|
|
2796
|
+
renderContext?.sourceGuard
|
|
2797
|
+
),
|
|
2798
|
+
renderComponentPresentation: (name, nativeView, children, key, status, rawSource) => this.renderComponentPresentation(
|
|
2799
|
+
name,
|
|
2800
|
+
nativeView,
|
|
2801
|
+
children,
|
|
2802
|
+
key,
|
|
2803
|
+
status,
|
|
2804
|
+
rawSource,
|
|
2805
|
+
renderContext?.nodeKeyPrefix ?? String(paragraph?.id ?? parentTagName ?? "html"),
|
|
2806
|
+
renderContext?.sourceGuard
|
|
2807
|
+
),
|
|
2808
|
+
inlineComponents: this.inlineComponents,
|
|
2809
|
+
urlTransform: this.urlTransform,
|
|
2810
|
+
isAutolinkProtocolDisabled: (href) => this.isAutolinkProtocolDisabled(href),
|
|
2811
|
+
filterElement: this.hasElementFilters() ? (element, context, renderElement, renderChildren) => this.filterElement(element, context, renderElement, renderChildren) : void 0,
|
|
2812
|
+
parentTagName,
|
|
2813
|
+
contentComponents: this.contentComponents,
|
|
2814
|
+
renderParagraph: paragraph ? (children) => {
|
|
2815
|
+
let nativeView = React8.createElement(this.getBlockComponent("paragraph"), {
|
|
2816
|
+
...this.getBlockProps(paragraph, sourceGuard),
|
|
2817
|
+
children
|
|
2818
|
+
});
|
|
2819
|
+
return renderParagraphPresentation ? renderParagraphPresentation(nativeView) : nativeView;
|
|
2820
|
+
} : void 0
|
|
2821
|
+
};
|
|
1735
2822
|
}
|
|
1736
2823
|
getTableElements() {
|
|
1737
2824
|
return this.tableElements;
|
|
1738
2825
|
}
|
|
2826
|
+
subscribeTableVirtualization(listener) {
|
|
2827
|
+
return this.tableVirtualizationListeners.add(listener), () => {
|
|
2828
|
+
this.tableVirtualizationListeners.delete(listener);
|
|
2829
|
+
};
|
|
2830
|
+
}
|
|
2831
|
+
setTableVirtualization(options) {
|
|
2832
|
+
this.tableVirtualization = resolveTableVirtualizationConfig(options);
|
|
2833
|
+
for (let listener of this.tableVirtualizationListeners)
|
|
2834
|
+
listener();
|
|
2835
|
+
}
|
|
2836
|
+
getTableVirtualization() {
|
|
2837
|
+
return this.tableVirtualization;
|
|
2838
|
+
}
|
|
2839
|
+
subscribeCodeVirtualization(listener) {
|
|
2840
|
+
return this.codeVirtualizationListeners.add(listener), () => {
|
|
2841
|
+
this.codeVirtualizationListeners.delete(listener);
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
setCodeVirtualization(options) {
|
|
2845
|
+
this.codeVirtualization = resolveVirtualizedCodeConfig(options);
|
|
2846
|
+
for (let listener of this.codeVirtualizationListeners)
|
|
2847
|
+
listener();
|
|
2848
|
+
}
|
|
2849
|
+
getCodeVirtualization() {
|
|
2850
|
+
return this.codeVirtualization;
|
|
2851
|
+
}
|
|
1739
2852
|
/**
|
|
1740
2853
|
* Render a block
|
|
1741
2854
|
*/
|
|
1742
|
-
renderBlock(block) {
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
2855
|
+
renderBlock(block, renderPresentation, sourceGuard) {
|
|
2856
|
+
let meta = block.payload.meta, sourceOwnedHtmlTree = meta?.htmlOwnership === !0 && Array.isArray(meta.htmlTree) ? meta.htmlTree : void 0;
|
|
2857
|
+
if (block.type === "paragraph" && sourceOwnedHtmlTree)
|
|
2858
|
+
return React8.createElement(
|
|
2859
|
+
React8.Fragment,
|
|
2860
|
+
{},
|
|
2861
|
+
this.renderHtmlTree(sourceOwnedHtmlTree, void 0, block, void 0, renderPresentation, sourceGuard)
|
|
2862
|
+
);
|
|
2863
|
+
if (block.type === "paragraph" && meta?.htmlParagraphTree)
|
|
2864
|
+
return React8.createElement(
|
|
2865
|
+
React8.Fragment,
|
|
2866
|
+
{},
|
|
2867
|
+
this.renderHtmlTree(meta.htmlParagraphTree, void 0, block, void 0, renderPresentation, sourceGuard)
|
|
2868
|
+
);
|
|
2869
|
+
let Component = this.getBlockComponent(block.type), props = this.getBlockProps(block, sourceGuard), paragraphGroups = block.type === "paragraph" && Array.isArray(block.payload.meta?.mixedSegments) && Array.isArray(props.children) ? props.children : void 0;
|
|
2870
|
+
paragraphGroups && (props.children = paragraphGroups.flatMap(
|
|
2871
|
+
(group) => React8.isValidElement(group) && group.type === "p" ? React8.Children.toArray(group.props.children) : [group]
|
|
2872
|
+
));
|
|
2873
|
+
let element = paragraphGroups ? React8.createElement(React8.Fragment, { key: block.id }, ...paragraphGroups.map(
|
|
2874
|
+
(group, index) => React8.isValidElement(group) && group.type === "p" ? React8.createElement(Component, { ...props, key: `${block.id}-${index}`, children: group.props.children }) : group
|
|
2875
|
+
)) : React8.createElement(Component, { key: block.id, ...props }), finalElement = (() => {
|
|
2876
|
+
if (block.type === "code") {
|
|
2877
|
+
let meta2 = block.payload.meta ?? {}, lang = typeof meta2.lang == "string" ? String(meta2.lang) : "", raw = typeof block.payload.raw == "string" ? block.payload.raw : "", metaCode = typeof meta2.code == "string" ? meta2.code : null, normalizedRaw = raw.replace(/\r\n?/g, `
|
|
2878
|
+
`), fenced = stripCodeFence(block.isFinalized ? normalizedRaw : trimProvisionalFenceTail(normalizedRaw)), codeText = metaCode !== null ? metaCode.replace(/\r\n?/g, `
|
|
2879
|
+
`) : fenced.hadFence ? fenced.code : normalizedRaw, codeControls = resolveCodeControls(this.getControls());
|
|
2880
|
+
if (Array.isArray(meta2.diffBlocks) && meta2.diffBlocks.length > 0)
|
|
2881
|
+
return React8.createElement(DefaultDiffRenderer, {
|
|
2882
|
+
key: block.id,
|
|
2883
|
+
meta: meta2,
|
|
2884
|
+
renderCode: element
|
|
2885
|
+
});
|
|
2886
|
+
if (codeControls.enabled) {
|
|
2887
|
+
let ControlsComponent = this.getControlsComponent(), controlsElement = ControlsComponent ? React8.createElement(ControlsComponent, {
|
|
2888
|
+
type: "code",
|
|
2889
|
+
blockId: block.id,
|
|
2890
|
+
code: codeText,
|
|
2891
|
+
language: lang,
|
|
2892
|
+
isFinalized: block.isFinalized,
|
|
2893
|
+
onCopy: () => copyToClipboard(codeText),
|
|
2894
|
+
onDownload: () => downloadFile(codeText, getCodeSnippetFilename(lang)),
|
|
2895
|
+
labels: codeControls.labels
|
|
2896
|
+
}) : React8.createElement(CodeControlsBar, {
|
|
2897
|
+
code: codeText,
|
|
2898
|
+
language: lang,
|
|
2899
|
+
config: codeControls
|
|
2900
|
+
});
|
|
2901
|
+
return React8.createElement("div", { className: "stream-mdx-code-wrapper relative", key: block.id }, controlsElement, element);
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
if (block.type === "table") {
|
|
2905
|
+
let tableControls = resolveTableControls(this.getControls());
|
|
2906
|
+
if (tableControls.enabled) {
|
|
2907
|
+
let meta2 = block.payload.meta ?? {}, header = Array.isArray(meta2.header) ? meta2.header.map((cell) => inlineToPlainText(cell)) : [], rows = Array.isArray(meta2.rows) ? meta2.rows.map((r) => r.map((cell) => inlineToPlainText(cell))) : [], align = Array.isArray(meta2.align) ? meta2.align : void 0, isFinalized = !!block.isFinalized, ControlsComponent = this.getControlsComponent(), controlsElement = ControlsComponent ? React8.createElement(ControlsComponent, {
|
|
2908
|
+
type: "table",
|
|
2909
|
+
blockId: block.id,
|
|
2910
|
+
headers: header,
|
|
2911
|
+
rows,
|
|
2912
|
+
align,
|
|
2913
|
+
isFinalized,
|
|
2914
|
+
onCopy: (format) => {
|
|
2915
|
+
if (!isFinalized) return;
|
|
2916
|
+
let text = format === "markdown" ? tableToMarkdown(header, rows, align) : tableToTsv(header, rows);
|
|
2917
|
+
return copyToClipboard(text);
|
|
2918
|
+
},
|
|
2919
|
+
onDownload: (format) => {
|
|
2920
|
+
isFinalized && (format === "tsv" ? downloadFile(tableToTsv(header, rows), "table.tsv", "text/tab-separated-values;charset=utf-8") : format === "markdown" ? downloadFile(tableToMarkdown(header, rows, align), "table.md", "text/markdown;charset=utf-8") : downloadFile(tableToCsv(header, rows), "table.csv", "text/csv;charset=utf-8"));
|
|
2921
|
+
},
|
|
2922
|
+
labels: tableControls.labels
|
|
2923
|
+
}) : React8.createElement(TableControlsBar, {
|
|
2924
|
+
headers: header,
|
|
2925
|
+
rows,
|
|
2926
|
+
align,
|
|
2927
|
+
isFinalized,
|
|
2928
|
+
config: tableControls
|
|
2929
|
+
});
|
|
2930
|
+
return React8.createElement("div", { className: "stream-mdx-table-wrapper relative", key: block.id }, controlsElement, element);
|
|
2931
|
+
}
|
|
2932
|
+
}
|
|
2933
|
+
return element;
|
|
2934
|
+
})();
|
|
2935
|
+
if (this.hasFilterConfig) {
|
|
2936
|
+
let blockTagName = "";
|
|
2937
|
+
switch (block.type) {
|
|
2938
|
+
case "paragraph":
|
|
2939
|
+
blockTagName = "p";
|
|
2940
|
+
break;
|
|
2941
|
+
case "heading": {
|
|
2942
|
+
let meta2 = block.payload.meta ?? {}, levelFromMeta = typeof meta2.headingLevel == "number" ? meta2.headingLevel : void 0, normalizedLevel = Number.isFinite(levelFromMeta) ? Math.min(Math.max(levelFromMeta, 1), 6) : void 0, rawHeading = typeof block.payload.raw == "string" ? block.payload.raw : "";
|
|
2943
|
+
blockTagName = `h${normalizedLevel ?? this.extractHeadingLevel(rawHeading)}`;
|
|
2944
|
+
break;
|
|
2945
|
+
}
|
|
2946
|
+
case "code":
|
|
2947
|
+
blockTagName = "pre";
|
|
2948
|
+
break;
|
|
2949
|
+
case "blockquote":
|
|
2950
|
+
blockTagName = "blockquote";
|
|
2951
|
+
break;
|
|
2952
|
+
case "hr":
|
|
2953
|
+
blockTagName = "hr";
|
|
2954
|
+
break;
|
|
2955
|
+
case "list":
|
|
2956
|
+
blockTagName = block.payload.meta?.ordered ? "ol" : "ul";
|
|
2957
|
+
break;
|
|
2958
|
+
case "table":
|
|
2959
|
+
blockTagName = "table";
|
|
2960
|
+
break;
|
|
2961
|
+
}
|
|
2962
|
+
if (blockTagName) {
|
|
2963
|
+
let renderChildren = () => {
|
|
2964
|
+
if (block.type === "paragraph" || block.type === "heading")
|
|
2965
|
+
return "children" in props ? props.children : void 0;
|
|
2966
|
+
if (block.type === "blockquote")
|
|
2967
|
+
return "renderedContent" in props ? props.renderedContent : void 0;
|
|
2968
|
+
if (block.type === "code") {
|
|
2969
|
+
let meta2 = block.payload.meta;
|
|
2970
|
+
return (meta2 && typeof meta2 == "object" && "code" in meta2 && typeof meta2.code == "string" ? meta2.code : void 0) || block.payload.raw || "";
|
|
2971
|
+
}
|
|
2972
|
+
}, filtered = this.filterElement(
|
|
2973
|
+
{ tagName: blockTagName, properties: props, blockType: block.type },
|
|
2974
|
+
{ source: "markdown" },
|
|
2975
|
+
() => renderPresentation ? renderPresentation(finalElement) : finalElement,
|
|
2976
|
+
renderChildren
|
|
2977
|
+
);
|
|
2978
|
+
return filtered == null ? React8.createElement(React8.Fragment, { key: block.id }) : React8.isValidElement(filtered) ? filtered : React8.createElement(React8.Fragment, { key: block.id }, filtered);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
let presented = renderPresentation ? renderPresentation(finalElement) : finalElement;
|
|
2982
|
+
return React8.isValidElement(presented) ? presented : React8.createElement(React8.Fragment, { key: block.id }, presented);
|
|
1749
2983
|
}
|
|
1750
2984
|
/**
|
|
1751
2985
|
* Get props for a block based on its type
|
|
1752
2986
|
*/
|
|
1753
|
-
getBlockProps(block) {
|
|
2987
|
+
getBlockProps(block, sourceGuard) {
|
|
2988
|
+
let animCtx = this.getRenderInlineContext(block.isFinalized, block.id, sourceGuard);
|
|
1754
2989
|
switch (block.type) {
|
|
1755
2990
|
case "heading": {
|
|
1756
|
-
|
|
1757
|
-
const inlineNodes = Array.isArray(block.payload.inline) ? block.payload.inline : [];
|
|
1758
|
-
const levelFromMeta = typeof meta.headingLevel === "number" ? meta.headingLevel : void 0;
|
|
1759
|
-
const normalizedLevel = Number.isFinite(levelFromMeta) ? Math.min(Math.max(levelFromMeta, 1), 6) : void 0;
|
|
1760
|
-
const rawHeading = typeof block.payload.raw === "string" ? block.payload.raw : "";
|
|
1761
|
-
const headingText = typeof meta.headingText === "string" && meta.headingText.trim().length > 0 ? meta.headingText : removeHeadingMarkers(rawHeading).trim();
|
|
1762
|
-
const level = normalizedLevel ?? this.extractHeadingLevel(rawHeading);
|
|
2991
|
+
let meta = block.payload.meta ?? {}, inlineNodes = Array.isArray(block.payload.inline) ? block.payload.inline : [], levelFromMeta = typeof meta.headingLevel == "number" ? meta.headingLevel : void 0, normalizedLevel = Number.isFinite(levelFromMeta) ? Math.min(Math.max(levelFromMeta, 1), 6) : void 0, rawHeading = typeof block.payload.raw == "string" ? block.payload.raw : "", headingText = typeof meta.headingText == "string" && meta.headingText.trim().length > 0 ? meta.headingText : removeHeadingMarkers(rawHeading).trim(), level = normalizedLevel ?? this.extractHeadingLevel(rawHeading), ownedTree = block.payload.meta?.htmlOwnership === !0 ? block.payload.meta.htmlTree : void 0, ownedRoot = ownedTree?.length === 1 ? ownedTree[0] : void 0, ownedChildren = ownedRoot?.kind === "element" && ownedRoot.tagName === `h${level}` ? ownedRoot.children : void 0, renderedChildren = ownedChildren ? renderOwnedHtmlTree(ownedChildren, this.ownedHtmlRenderContext(void 0, void 0, `h${level}`, animCtx)) : renderInlineNodes(inlineNodes, this.inlineComponents, this.urlTransform, this, `h${level}`, animCtx);
|
|
1763
2992
|
return {
|
|
1764
2993
|
level,
|
|
1765
2994
|
inlines: inlineNodes,
|
|
1766
2995
|
text: headingText,
|
|
1767
|
-
meta
|
|
2996
|
+
meta,
|
|
2997
|
+
children: renderedChildren
|
|
1768
2998
|
};
|
|
1769
2999
|
}
|
|
1770
|
-
case "paragraph":
|
|
3000
|
+
case "paragraph": {
|
|
3001
|
+
let segments = block.payload.meta?.mixedSegments;
|
|
1771
3002
|
return {
|
|
1772
3003
|
inlines: block.payload.inline || [],
|
|
1773
3004
|
raw: block.payload.raw,
|
|
1774
|
-
meta: block.payload.meta
|
|
3005
|
+
meta: block.payload.meta,
|
|
3006
|
+
children: Array.isArray(segments) && segments.length > 0 ? renderMixedParagraphSegments(
|
|
3007
|
+
segments,
|
|
3008
|
+
this.inlineComponents,
|
|
3009
|
+
DEFAULT_INLINE_HTML_RENDERERS,
|
|
3010
|
+
this.htmlElements,
|
|
3011
|
+
this.literalTagContent,
|
|
3012
|
+
this.urlTransform,
|
|
3013
|
+
this,
|
|
3014
|
+
animCtx,
|
|
3015
|
+
block.payload.meta?.mixedHtmlTrees,
|
|
3016
|
+
(tree) => renderOwnedHtmlTree(tree, this.ownedHtmlRenderContext(void 0, void 0, "p", animCtx))
|
|
3017
|
+
) : renderInlineNodes(block.payload.inline ?? [], this.inlineComponents, this.urlTransform, this, "p", animCtx)
|
|
1775
3018
|
};
|
|
3019
|
+
}
|
|
1776
3020
|
case "blockquote":
|
|
1777
3021
|
return {
|
|
1778
|
-
inlines: block.payload.inline || []
|
|
3022
|
+
inlines: block.payload.inline || [],
|
|
3023
|
+
renderedContent: renderInlineNodes(block.payload.inline || [], this.inlineComponents, this.urlTransform, this, "blockquote", animCtx)
|
|
1779
3024
|
};
|
|
1780
3025
|
case "hr": {
|
|
1781
|
-
|
|
3026
|
+
let range = block.payload.range;
|
|
1782
3027
|
return {
|
|
1783
3028
|
className: "markdown-hr",
|
|
1784
|
-
"data-start": typeof range?.from
|
|
1785
|
-
"data-end": typeof range?.to
|
|
3029
|
+
"data-start": typeof range?.from == "number" ? range.from : void 0,
|
|
3030
|
+
"data-end": typeof range?.to == "number" ? range.to : void 0
|
|
1786
3031
|
};
|
|
1787
3032
|
}
|
|
1788
3033
|
case "code":
|
|
1789
3034
|
return {
|
|
1790
3035
|
html: block.payload.highlightedHtml,
|
|
1791
3036
|
meta: block.payload.meta,
|
|
1792
|
-
lang: typeof block.payload.meta?.lang
|
|
3037
|
+
lang: typeof block.payload.meta?.lang == "string" ? String(block.payload.meta?.lang) : void 0
|
|
1793
3038
|
};
|
|
1794
3039
|
case "list": {
|
|
1795
|
-
|
|
3040
|
+
let items = Array.isArray(block.payload.meta?.items) ? block.payload.meta?.items : [];
|
|
1796
3041
|
return {
|
|
1797
|
-
ordered:
|
|
3042
|
+
ordered: !!block.payload.meta?.ordered,
|
|
1798
3043
|
items
|
|
1799
3044
|
};
|
|
1800
3045
|
}
|
|
1801
3046
|
case "html": {
|
|
1802
|
-
|
|
3047
|
+
let isWorkerSanitized = !!(block.payload.sanitizedHtml || block.payload.meta?.sanitized), content = block.payload.sanitizedHtml ?? block.payload.raw ?? "", htmlTree = block.payload.meta?.htmlTree;
|
|
1803
3048
|
return {
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
3049
|
+
__trustedHtml: isWorkerSanitized || typeof window > "u" ? String(content) : createTrustedHTML(String(content)),
|
|
3050
|
+
elements: this.htmlElements,
|
|
3051
|
+
isSanitized: isWorkerSanitized,
|
|
3052
|
+
literalTagContent: this.literalTagContent,
|
|
3053
|
+
children: htmlTree ? this.renderHtmlTree(htmlTree, void 0, block) : void 0
|
|
1808
3054
|
};
|
|
1809
3055
|
}
|
|
1810
3056
|
case "mdx":
|
|
1811
|
-
return
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
const errorMessage = typeof meta?.mdxError === "string" ? String(meta.mdxError) : void 0;
|
|
1816
|
-
const compiledModule = block.payload.compiledMdxModule ?? null;
|
|
1817
|
-
const compiledRef = block.payload.compiledMdxRef ?? (compiledModule ? { id: compiledModule.id } : void 0);
|
|
1818
|
-
return {
|
|
1819
|
-
compiledRef: compiledRef ?? { id: "pending" },
|
|
1820
|
-
compiledModule,
|
|
1821
|
-
status,
|
|
1822
|
-
errorMessage,
|
|
1823
|
-
raw: typeof block.payload.raw === "string" ? block.payload.raw : void 0
|
|
1824
|
-
};
|
|
1825
|
-
})();
|
|
3057
|
+
return {
|
|
3058
|
+
raw: typeof block.payload.raw == "string" ? block.payload.raw : void 0,
|
|
3059
|
+
meta: block.payload.meta
|
|
3060
|
+
};
|
|
1826
3061
|
case "table": {
|
|
1827
|
-
|
|
1828
|
-
const rows = Array.isArray(block.payload.meta?.rows) ? block.payload.meta?.rows : [];
|
|
1829
|
-
const align = Array.isArray(block.payload.meta?.align) ? block.payload.meta?.align : void 0;
|
|
3062
|
+
let header = Array.isArray(block.payload.meta?.header) ? block.payload.meta?.header : void 0, rows = Array.isArray(block.payload.meta?.rows) ? block.payload.meta?.rows : [], align = Array.isArray(block.payload.meta?.align) ? block.payload.meta?.align : void 0;
|
|
1830
3063
|
return {
|
|
1831
3064
|
header,
|
|
1832
3065
|
rows,
|
|
@@ -1834,17 +3067,14 @@ var ComponentRegistry = class {
|
|
|
1834
3067
|
elements: this.tableElements
|
|
1835
3068
|
};
|
|
1836
3069
|
}
|
|
1837
|
-
case "footnotes":
|
|
1838
|
-
const items = Array.isArray(block.payload.meta?.items) ? block.payload.meta?.items : [];
|
|
3070
|
+
case "footnotes":
|
|
1839
3071
|
return {
|
|
1840
|
-
items
|
|
3072
|
+
items: Array.isArray(block.payload.meta?.items) ? block.payload.meta?.items : []
|
|
1841
3073
|
};
|
|
1842
|
-
}
|
|
1843
3074
|
case "footnote-def":
|
|
1844
3075
|
return {};
|
|
1845
3076
|
case "callout": {
|
|
1846
|
-
|
|
1847
|
-
const inlineNodes = Array.isArray(block.payload.inline) ? block.payload.inline : [];
|
|
3077
|
+
let kind = typeof block.payload.meta?.kind == "string" ? String(block.payload.meta.kind) : void 0, inlineNodes = Array.isArray(block.payload.inline) ? block.payload.inline : [];
|
|
1848
3078
|
return {
|
|
1849
3079
|
kind,
|
|
1850
3080
|
inlines: inlineNodes
|
|
@@ -1861,112 +3091,117 @@ var ComponentRegistry = class {
|
|
|
1861
3091
|
* Extract heading level from raw markdown
|
|
1862
3092
|
*/
|
|
1863
3093
|
extractHeadingLevel(raw) {
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
return Math.min(match[1].length, 6);
|
|
1867
|
-
}
|
|
1868
|
-
return 1;
|
|
3094
|
+
let match = raw.match(/^(#{1,6})\s/);
|
|
3095
|
+
return match ? Math.min(match[1].length, 6) : 1;
|
|
1869
3096
|
}
|
|
1870
3097
|
};
|
|
1871
3098
|
function getDefaultHtmlElements() {
|
|
1872
3099
|
return {
|
|
1873
3100
|
// Text semantics
|
|
1874
|
-
p: (props) =>
|
|
1875
|
-
strong: (props) =>
|
|
1876
|
-
em: (props) =>
|
|
1877
|
-
code: (props) =>
|
|
1878
|
-
pre: (props) =>
|
|
1879
|
-
span: (props) =>
|
|
1880
|
-
br: (props) =>
|
|
1881
|
-
hr: (props) =>
|
|
3101
|
+
p: (props) => React8.createElement("p", props),
|
|
3102
|
+
strong: (props) => React8.createElement("strong", props),
|
|
3103
|
+
em: (props) => React8.createElement("em", props),
|
|
3104
|
+
code: (props) => React8.createElement("code", props),
|
|
3105
|
+
pre: (props) => React8.createElement("pre", props),
|
|
3106
|
+
span: (props) => React8.createElement("span", props),
|
|
3107
|
+
br: (props) => React8.createElement("br", props),
|
|
3108
|
+
hr: (props) => React8.createElement("hr", props),
|
|
1882
3109
|
// Lists
|
|
1883
|
-
ul: (props) =>
|
|
1884
|
-
ol: (props) =>
|
|
1885
|
-
li: (props) =>
|
|
3110
|
+
ul: (props) => React8.createElement("ul", props),
|
|
3111
|
+
ol: (props) => React8.createElement("ol", props),
|
|
3112
|
+
li: (props) => React8.createElement("li", props),
|
|
1886
3113
|
// Links & media
|
|
1887
|
-
a: (props) =>
|
|
1888
|
-
img: (props) =>
|
|
3114
|
+
a: (props) => React8.createElement("a", props),
|
|
3115
|
+
img: (props) => React8.createElement("img", props),
|
|
1889
3116
|
// Blockquotes
|
|
1890
|
-
blockquote: (props) =>
|
|
3117
|
+
blockquote: (props) => React8.createElement("blockquote", props),
|
|
1891
3118
|
// Tables
|
|
1892
|
-
table: (props) =>
|
|
1893
|
-
thead: (props) =>
|
|
1894
|
-
tbody: (props) =>
|
|
1895
|
-
tr: (props) =>
|
|
1896
|
-
th: (props) =>
|
|
1897
|
-
td: (props) =>
|
|
3119
|
+
table: (props) => React8.createElement("table", props),
|
|
3120
|
+
thead: (props) => React8.createElement("thead", props),
|
|
3121
|
+
tbody: (props) => React8.createElement("tbody", props),
|
|
3122
|
+
tr: (props) => React8.createElement("tr", props),
|
|
3123
|
+
th: (props) => React8.createElement("th", props),
|
|
3124
|
+
td: (props) => React8.createElement("td", props),
|
|
1898
3125
|
// Generic
|
|
1899
|
-
div: (props) =>
|
|
3126
|
+
div: (props) => React8.createElement("div", props)
|
|
1900
3127
|
};
|
|
1901
3128
|
}
|
|
1902
3129
|
function getDefaultTableElements(overrides) {
|
|
1903
|
-
|
|
1904
|
-
Table: (props) =>
|
|
1905
|
-
Thead: (props) =>
|
|
1906
|
-
Tbody: (props) =>
|
|
1907
|
-
Tr: (props) =>
|
|
1908
|
-
Th: (props) =>
|
|
1909
|
-
Td: (props) =>
|
|
1910
|
-
};
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
function mapHtmlToReact(html, elements) {
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
doc.body.childNodes.forEach((node, index) => {
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
}
|
|
1922
|
-
});
|
|
1923
|
-
return React4.createElement(React4.Fragment, {}, ...children);
|
|
3130
|
+
return { ...{
|
|
3131
|
+
Table: (props) => React8.createElement("table", props),
|
|
3132
|
+
Thead: (props) => React8.createElement("thead", props),
|
|
3133
|
+
Tbody: (props) => React8.createElement("tbody", props),
|
|
3134
|
+
Tr: (props) => React8.createElement("tr", props),
|
|
3135
|
+
Th: (props) => React8.createElement("th", props),
|
|
3136
|
+
Td: (props) => React8.createElement("td", props)
|
|
3137
|
+
}, ...overrides || {} };
|
|
3138
|
+
}
|
|
3139
|
+
var DEFAULT_LITERAL_TAGS2 = /* @__PURE__ */ new Set(["code", "pre", "script", "style", "textarea"]);
|
|
3140
|
+
function mapHtmlToReact(html, elements, literalTagContent, parseMarkdown) {
|
|
3141
|
+
let ParserClass = typeof DOMParser < "u" ? DOMParser : typeof window < "u" ? window.DOMParser : void 0;
|
|
3142
|
+
if (!ParserClass) return null;
|
|
3143
|
+
let doc = new ParserClass().parseFromString(html, "text/html"), children = [], literalTags = literalTagContent ? /* @__PURE__ */ new Set([...DEFAULT_LITERAL_TAGS2, ...literalTagContent.map((t) => t.toLowerCase())]) : DEFAULT_LITERAL_TAGS2;
|
|
3144
|
+
return doc.body.childNodes.forEach((node, index) => {
|
|
3145
|
+
let element = toReact(node, elements, `root-${index}`, void 0, literalTags, !1, parseMarkdown);
|
|
3146
|
+
element && children.push(element);
|
|
3147
|
+
}), React8.createElement(React8.Fragment, {}, ...children);
|
|
1924
3148
|
}
|
|
1925
|
-
|
|
3149
|
+
var TABLE_TEXT_FORBIDDEN_PARENTS = /* @__PURE__ */ new Set(["table", "thead", "tbody", "tfoot", "tr", "colgroup"]);
|
|
3150
|
+
function toReact(node, elements, key, parentTag, literalTags, parentIsLiteral, parseMarkdown) {
|
|
1926
3151
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
1927
|
-
|
|
1928
|
-
|
|
3152
|
+
let text = node.textContent ?? "";
|
|
3153
|
+
if (parentTag && TABLE_TEXT_FORBIDDEN_PARENTS.has(parentTag) && text.trim().length === 0)
|
|
3154
|
+
return null;
|
|
3155
|
+
let content = parentIsLiteral || !parseMarkdown ? text : parseMarkdown(text);
|
|
3156
|
+
return React8.createElement(React8.Fragment, { key }, content);
|
|
1929
3157
|
}
|
|
1930
|
-
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
3158
|
+
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
1931
3159
|
return null;
|
|
1932
|
-
}
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
const props = {};
|
|
1936
|
-
for (const attr of Array.from(el.attributes)) {
|
|
1937
|
-
const name = attr.name === "class" ? "className" : attr.name;
|
|
3160
|
+
let el = node, tag = el.tagName.toLowerCase(), isLiteral = parentIsLiteral || (literalTags ? literalTags.has(tag) : !1), props = {};
|
|
3161
|
+
for (let attr of Array.from(el.attributes)) {
|
|
3162
|
+
let name = attr.name === "class" ? "className" : attr.name;
|
|
1938
3163
|
props[name] = attr.value;
|
|
1939
3164
|
}
|
|
1940
|
-
|
|
3165
|
+
if (tag === "textarea")
|
|
3166
|
+
return React8.createElement(elements[tag] ?? tag, { ...props, key, defaultValue: el.textContent ?? "" });
|
|
3167
|
+
let children = [];
|
|
1941
3168
|
el.childNodes.forEach((childNode, childIndex) => {
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
children.push(child);
|
|
1945
|
-
}
|
|
3169
|
+
let child = toReact(childNode, elements, `${key}-${childIndex}`, tag, literalTags, isLiteral, parseMarkdown);
|
|
3170
|
+
child && children.push(child);
|
|
1946
3171
|
});
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
if (component) {
|
|
1950
|
-
return React4.createElement(component, { ...props, key }, elementChildren);
|
|
1951
|
-
}
|
|
1952
|
-
return React4.createElement(tag, { ...props, key }, elementChildren);
|
|
3172
|
+
let component = elements[tag], elementChildren = children.length > 0 ? children : void 0;
|
|
3173
|
+
return component ? React8.createElement(component, { ...props, key }, elementChildren) : React8.createElement(tag, { ...props, key }, elementChildren);
|
|
1953
3174
|
}
|
|
1954
3175
|
function attrsToProps(attrs) {
|
|
1955
3176
|
if (!attrs) return {};
|
|
1956
|
-
|
|
1957
|
-
for (
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
if (
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
3177
|
+
let result = {};
|
|
3178
|
+
for (let [key, value] of Object.entries(attrs)) {
|
|
3179
|
+
let lower = key.toLowerCase();
|
|
3180
|
+
if (!isForbiddenAttribute2(lower))
|
|
3181
|
+
if (key === "class")
|
|
3182
|
+
result.className = value;
|
|
3183
|
+
else if (key === "style")
|
|
3184
|
+
result.style = parseStyleAttribute2(value);
|
|
3185
|
+
else if (key === "tabindex" || key === "tabIndex") {
|
|
3186
|
+
let numericValue = Number(value);
|
|
3187
|
+
Number.isNaN(numericValue) || (result.tabIndex = numericValue);
|
|
3188
|
+
} else if (lower === "href") {
|
|
3189
|
+
let safe = defaultUrlTransform4(value, "href", { source: "html" });
|
|
3190
|
+
safe != null && (result.href = safe);
|
|
3191
|
+
} else if (lower === "src") {
|
|
3192
|
+
let safe = defaultUrlTransform4(value, "src", { source: "html" });
|
|
3193
|
+
safe != null && (result.src = safe);
|
|
3194
|
+
} else if (lower === "action") {
|
|
3195
|
+
let safe = defaultUrlTransform4(value, "href", { source: "html" });
|
|
3196
|
+
safe != null && (result.action = safe);
|
|
3197
|
+
} else if (lower === "formaction") {
|
|
3198
|
+
let safe = defaultUrlTransform4(value, "href", { source: "html" });
|
|
3199
|
+
safe != null && (result.formAction = safe);
|
|
3200
|
+
} else if (lower === "xlink:href" || lower === "xlinkhref") {
|
|
3201
|
+
let safe = defaultUrlTransform4(value, "href", { source: "html" });
|
|
3202
|
+
safe != null && (result.xlinkHref = safe);
|
|
3203
|
+
} else
|
|
3204
|
+
result[key] = value;
|
|
1970
3205
|
}
|
|
1971
3206
|
return result;
|
|
1972
3207
|
}
|
|
@@ -1974,48 +3209,36 @@ function escapeHtml(value) {
|
|
|
1974
3209
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1975
3210
|
}
|
|
1976
3211
|
function parseStyleAttribute2(value) {
|
|
1977
|
-
|
|
3212
|
+
let style = {};
|
|
1978
3213
|
if (!value) return style;
|
|
1979
|
-
|
|
1980
|
-
for (
|
|
3214
|
+
let parts = value.split(";");
|
|
3215
|
+
for (let part of parts) {
|
|
1981
3216
|
if (!part.trim()) continue;
|
|
1982
|
-
|
|
1983
|
-
if (
|
|
1984
|
-
|
|
1985
|
-
|
|
3217
|
+
let separator = part.indexOf(":");
|
|
3218
|
+
if (separator <= 0) continue;
|
|
3219
|
+
let prop = part.slice(0, separator).trim(), val = part.slice(separator + 1).trim();
|
|
3220
|
+
if (!isSafeStyleDeclaration2(prop, val)) continue;
|
|
3221
|
+
let cssProperty = prop.startsWith("--") ? prop : prop.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
3222
|
+
style[cssProperty] = val;
|
|
1986
3223
|
}
|
|
1987
3224
|
return style;
|
|
1988
3225
|
}
|
|
1989
|
-
function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRenderers) {
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
3226
|
+
function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRenderers, htmlElements, literalTagContent, urlTransform) {
|
|
3227
|
+
return renderMixedParagraphSegments(segments, inlineComponents, inlineHtmlRenderers, htmlElements, literalTagContent, urlTransform);
|
|
3228
|
+
}
|
|
3229
|
+
function renderMixedParagraphSegments(segments, inlineComponents, inlineHtmlRenderers, htmlElements, literalTagContent, urlTransform, registry, animationContext, htmlTrees, renderOwnedHtml) {
|
|
3230
|
+
let result = [], inlineBuffer = [], inlineGroupIndex = 0, pushRenderedNodes = (nodes, target, baseKey) => {
|
|
1994
3231
|
nodes.forEach((node, idx) => {
|
|
1995
|
-
if (node
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
target.push(node.key === key ? node : React4.cloneElement(node, { key }));
|
|
1999
|
-
} else if (typeof node === "string" || typeof node === "number") {
|
|
2000
|
-
target.push(React4.createElement(React4.Fragment, { key }, node));
|
|
2001
|
-
} else {
|
|
2002
|
-
target.push(React4.createElement(React4.Fragment, { key }, node));
|
|
2003
|
-
}
|
|
3232
|
+
if (node == null) return;
|
|
3233
|
+
let key = `${baseKey}-${idx}`;
|
|
3234
|
+
React8.isValidElement(node) ? target.push(node.key === key ? node : React8.cloneElement(node, { key })) : typeof node == "string" || typeof node == "number" ? target.push(React8.createElement(React8.Fragment, { key }, node)) : target.push(React8.createElement(React8.Fragment, { key }, node));
|
|
2004
3235
|
});
|
|
2005
|
-
}
|
|
2006
|
-
|
|
2007
|
-
if (value === null || value === void 0) {
|
|
2008
|
-
return [];
|
|
2009
|
-
}
|
|
2010
|
-
return Array.isArray(value) ? value : [value];
|
|
2011
|
-
};
|
|
2012
|
-
const flushInline = () => {
|
|
2013
|
-
if (inlineBuffer.length === 0) {
|
|
3236
|
+
}, ensureArray = (value) => value == null ? [] : Array.isArray(value) ? value : [value], flushInline = () => {
|
|
3237
|
+
if (inlineBuffer.length === 0)
|
|
2014
3238
|
return;
|
|
2015
|
-
}
|
|
2016
|
-
const key = `paragraph-inline-group-${inlineGroupIndex++}`;
|
|
3239
|
+
let key = `paragraph-inline-group-${inlineGroupIndex++}`;
|
|
2017
3240
|
result.push(
|
|
2018
|
-
|
|
3241
|
+
React8.createElement(
|
|
2019
3242
|
"p",
|
|
2020
3243
|
{
|
|
2021
3244
|
key,
|
|
@@ -2023,109 +3246,90 @@ function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRend
|
|
|
2023
3246
|
},
|
|
2024
3247
|
inlineBuffer
|
|
2025
3248
|
)
|
|
2026
|
-
);
|
|
2027
|
-
inlineBuffer = [];
|
|
3249
|
+
), inlineBuffer = [];
|
|
2028
3250
|
};
|
|
2029
|
-
segments.forEach((segment, index) => {
|
|
2030
|
-
|
|
3251
|
+
return segments.forEach((segment, index) => {
|
|
3252
|
+
let key = `paragraph-segment-${index}`;
|
|
2031
3253
|
switch (segment.kind) {
|
|
2032
3254
|
case "text": {
|
|
2033
|
-
|
|
3255
|
+
let inlineNodes = Array.isArray(segment.inline) ? segment.inline : [];
|
|
2034
3256
|
if (inlineNodes.length === 0) {
|
|
2035
|
-
|
|
2036
|
-
inlineBuffer.push(React4.createElement(React4.Fragment, { key }, segment.value));
|
|
2037
|
-
}
|
|
3257
|
+
segment.value && inlineBuffer.push(React8.createElement(React8.Fragment, { key }, segment.value));
|
|
2038
3258
|
break;
|
|
2039
3259
|
}
|
|
2040
|
-
let chunk = []
|
|
2041
|
-
const pushChunk = (chunkNodes, chunkKey) => {
|
|
3260
|
+
let chunk = [], pushChunk = (chunkNodes, chunkKey) => {
|
|
2042
3261
|
if (chunkNodes.length === 0) return;
|
|
2043
|
-
|
|
3262
|
+
let rendered = renderInlineNodes(chunkNodes, inlineComponents, urlTransform, registry, "p", animationContext);
|
|
2044
3263
|
pushRenderedNodes(ensureArray(rendered), inlineBuffer, chunkKey);
|
|
2045
3264
|
};
|
|
2046
3265
|
inlineNodes.forEach((inlineNode, inlineIdx) => {
|
|
2047
3266
|
if (inlineNode.kind === "math-display") {
|
|
2048
|
-
pushChunk(chunk, `${key}-chunk-${inlineIdx}`);
|
|
2049
|
-
|
|
2050
|
-
flushInline();
|
|
2051
|
-
const rendered = renderInlineNodes([inlineNode], inlineComponents);
|
|
3267
|
+
pushChunk(chunk, `${key}-chunk-${inlineIdx}`), chunk = [], flushInline();
|
|
3268
|
+
let rendered = renderInlineNodes([inlineNode], inlineComponents, urlTransform, registry, "p", animationContext);
|
|
2052
3269
|
pushRenderedNodes(ensureArray(rendered), result, `${key}-math-${inlineIdx}`);
|
|
2053
|
-
} else
|
|
3270
|
+
} else
|
|
2054
3271
|
chunk.push(inlineNode);
|
|
2055
|
-
|
|
2056
|
-
});
|
|
2057
|
-
pushChunk(chunk, `${key}-chunk-tail`);
|
|
3272
|
+
}), pushChunk(chunk, `${key}-chunk-tail`);
|
|
2058
3273
|
break;
|
|
2059
3274
|
}
|
|
2060
3275
|
case "mdx": {
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
if (status === "compiled") {
|
|
2064
|
-
element = React4.createElement("span", { className: "markdown-mdx-inline", "data-mdx-status": "compiled" });
|
|
2065
|
-
} else if (status === "error") {
|
|
2066
|
-
const message = segment.value || "MDX error";
|
|
2067
|
-
element = React4.createElement("span", { className: "markdown-mdx-inline text-destructive", "data-mdx-status": "error" }, message);
|
|
2068
|
-
} else {
|
|
2069
|
-
element = React4.createElement("span", { className: "markdown-mdx-inline", "data-mdx-status": status }, segment.value);
|
|
2070
|
-
}
|
|
2071
|
-
inlineBuffer.push(React4.createElement(React4.Fragment, { key }, element));
|
|
3276
|
+
let element = React8.createElement("span", { className: "markdown-mdx-inline" }, segment.value);
|
|
3277
|
+
inlineBuffer.push(React8.createElement(React8.Fragment, { key }, element));
|
|
2072
3278
|
break;
|
|
2073
3279
|
}
|
|
2074
3280
|
case "html": {
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
3281
|
+
let html = segment.sanitized ?? segment.value, isBlockLevel = isBlockLevelHtml(html);
|
|
3282
|
+
if (registry && htmlTrees?.[index] !== void 0) {
|
|
3283
|
+
let rendered = renderOwnedHtml ? renderOwnedHtml(htmlTrees[index]) : registry.renderHtmlTree(htmlTrees[index]);
|
|
3284
|
+
isBlockLevel ? (flushInline(), pushRenderedNodes(ensureArray(rendered), result, key)) : pushRenderedNodes(ensureArray(rendered), inlineBuffer, key);
|
|
3285
|
+
break;
|
|
3286
|
+
}
|
|
3287
|
+
let parseMarkdown = (text) => !text || !text.includes("*") && !text.includes("_") && !text.includes("[") && !text.includes("`") && !text.includes("#") ? text : renderInlineNodes(new InlineParser().parse(text), inlineComponents, urlTransform, registry, "p", animationContext), element = renderInlineHtmlSegment(segment.value, segment.sanitized, {
|
|
2078
3288
|
key,
|
|
2079
|
-
renderers: inlineHtmlRenderers
|
|
3289
|
+
renderers: inlineHtmlRenderers,
|
|
3290
|
+
htmlElements,
|
|
3291
|
+
literalTagContent,
|
|
3292
|
+
urlTransform,
|
|
3293
|
+
parseMarkdown
|
|
2080
3294
|
});
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
} else if (element) {
|
|
2095
|
-
inlineBuffer.push(element);
|
|
2096
|
-
}
|
|
3295
|
+
isBlockLevel ? (flushInline(), element ? result.push(element) : html && result.push(
|
|
3296
|
+
React8.createElement("div", {
|
|
3297
|
+
key,
|
|
3298
|
+
className: "markdown-inline-html-block",
|
|
3299
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
3300
|
+
})
|
|
3301
|
+
)) : element ? inlineBuffer.push(element) : html && inlineBuffer.push(
|
|
3302
|
+
React8.createElement("span", {
|
|
3303
|
+
key,
|
|
3304
|
+
className: "markdown-inline-html",
|
|
3305
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
3306
|
+
})
|
|
3307
|
+
);
|
|
2097
3308
|
break;
|
|
2098
3309
|
}
|
|
2099
3310
|
default:
|
|
2100
3311
|
break;
|
|
2101
3312
|
}
|
|
2102
|
-
})
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
"
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
inlineBuffer
|
|
2113
|
-
)
|
|
2114
|
-
];
|
|
2115
|
-
}
|
|
2116
|
-
return result;
|
|
3313
|
+
}), flushInline(), result.length === 0 ? [
|
|
3314
|
+
React8.createElement(
|
|
3315
|
+
"p",
|
|
3316
|
+
{
|
|
3317
|
+
key: "paragraph-inline-group-0",
|
|
3318
|
+
className: "markdown-paragraph"
|
|
3319
|
+
},
|
|
3320
|
+
inlineBuffer
|
|
3321
|
+
)
|
|
3322
|
+
] : result;
|
|
2117
3323
|
}
|
|
2118
3324
|
function isBlockLevelHtml(html) {
|
|
2119
|
-
if (!html) return
|
|
2120
|
-
|
|
2121
|
-
if (!trimmed.startsWith("<"))
|
|
2122
|
-
return
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
}
|
|
2128
|
-
const tag = match[1].toLowerCase();
|
|
3325
|
+
if (!html) return !1;
|
|
3326
|
+
let trimmed = html.trim();
|
|
3327
|
+
if (!trimmed.startsWith("<"))
|
|
3328
|
+
return !1;
|
|
3329
|
+
let match = trimmed.match(/^<([A-Za-z][\w:-]*)\b/);
|
|
3330
|
+
if (!match)
|
|
3331
|
+
return !1;
|
|
3332
|
+
let tag = match[1].toLowerCase();
|
|
2129
3333
|
return BLOCK_LEVEL_TAGS.has(tag);
|
|
2130
3334
|
}
|
|
2131
3335
|
var BLOCK_LEVEL_TAGS = /* @__PURE__ */ new Set([
|
|
@@ -2161,12 +3365,45 @@ var BLOCK_LEVEL_TAGS = /* @__PURE__ */ new Set([
|
|
|
2161
3365
|
"math"
|
|
2162
3366
|
]);
|
|
2163
3367
|
export {
|
|
3368
|
+
AnimationTimeline,
|
|
2164
3369
|
BottomStickScrollArea,
|
|
3370
|
+
CodeBlockCopyButton,
|
|
3371
|
+
CodeBlockDownloadButton,
|
|
3372
|
+
CodeControlsBar,
|
|
2165
3373
|
ComponentRegistry,
|
|
3374
|
+
DEFAULT_ANIMATED_OPTIONS,
|
|
3375
|
+
DEFAULT_CONTROLS_LABELS,
|
|
3376
|
+
DefaultDiffRenderer,
|
|
2166
3377
|
DefaultLinkSafetyModal,
|
|
2167
|
-
|
|
3378
|
+
DocumentMathMacroScope,
|
|
3379
|
+
DocumentMathMacroScopeContext,
|
|
3380
|
+
KaTeXBlockMath,
|
|
3381
|
+
KaTeXInlineMath,
|
|
3382
|
+
LANGUAGE_EXTENSION_MAP,
|
|
3383
|
+
MathExpressionCompletenessContext,
|
|
3384
|
+
STREAM_MDX_ANIMATION_CSS,
|
|
3385
|
+
TableControlsBar,
|
|
3386
|
+
copyToClipboard,
|
|
2168
3387
|
defaultInlineComponents,
|
|
3388
|
+
defaultUrlTransform3 as defaultUrlTransform,
|
|
3389
|
+
downloadFile,
|
|
3390
|
+
escapeCsvCell,
|
|
3391
|
+
escapeTsvCell,
|
|
3392
|
+
getCodeSnippetFilename,
|
|
3393
|
+
getExtensionForLanguage,
|
|
3394
|
+
inlineToPlainText,
|
|
3395
|
+
loadKaTeX,
|
|
2169
3396
|
mapHtmlToReact,
|
|
2170
3397
|
renderInlineNodes,
|
|
2171
|
-
renderParagraphMixedSegments
|
|
3398
|
+
renderParagraphMixedSegments,
|
|
3399
|
+
resolveAnimatedOptions,
|
|
3400
|
+
resolveCodeControls,
|
|
3401
|
+
resolveControlsConfig,
|
|
3402
|
+
resolveMermaidControls,
|
|
3403
|
+
resolveTableControls,
|
|
3404
|
+
splitTextSegments,
|
|
3405
|
+
splitWordSegments,
|
|
3406
|
+
tableToCsv,
|
|
3407
|
+
tableToMarkdown,
|
|
3408
|
+
tableToTsv
|
|
2172
3409
|
};
|