@stream-mdx/react 0.4.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 +385 -4
- package/README.md +141 -16
- 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 +268 -0
- package/dist/components/bottom-stick-scroll-area.d.cts +36 -0
- package/dist/components/bottom-stick-scroll-area.d.ts +36 -0
- package/dist/components/bottom-stick-scroll-area.mjs +249 -0
- 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 +2879 -1295
- package/dist/components/index.d.cts +9 -2
- package/dist/components/index.d.ts +9 -2
- package/dist/components/index.mjs +2842 -1277
- 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 +13180 -5640
- package/dist/index.d.cts +72 -40
- package/dist/index.d.ts +72 -40
- package/dist/index.mjs +12587 -5038
- 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 +7 -8
- package/dist/renderer/patch-batching.d.cts +1 -1
- package/dist/renderer/patch-batching.d.ts +1 -1
- package/dist/renderer/patch-batching.mjs +2 -1
- package/dist/renderer/patch-coalescing.cjs +5 -8
- package/dist/renderer/patch-commit-scheduler.cjs +160 -326
- package/dist/renderer/patch-commit-scheduler.d.cts +28 -4
- package/dist/renderer/patch-commit-scheduler.d.ts +28 -4
- package/dist/renderer/patch-commit-scheduler.mjs +157 -318
- package/dist/renderer/store.cjs +3847 -1099
- package/dist/renderer/store.d.cts +111 -3
- package/dist/renderer/store.d.ts +111 -3
- package/dist/renderer/store.mjs +3847 -1085
- 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 +10939 -3974
- package/dist/renderer.d.cts +100 -29
- package/dist/renderer.d.ts +100 -29
- package/dist/renderer.mjs +10711 -3697
- package/dist/server-regions-CPLHGli0.d.cts +32 -0
- package/dist/server-regions-mUhyoKi7.d.ts +32 -0
- package/dist/server.cjs +10286 -3365
- package/dist/server.d.cts +17 -247
- package/dist/server.d.ts +17 -247
- package/dist/server.mjs +10565 -3619
- package/dist/{streaming-markdown-DOc2uLiP.d.ts → streaming-markdown-yELbJxyH.d.ts} +51 -55
- package/dist/{streaming-markdown-D-JcByd9.d.cts → streaming-markdown-zVwFuaJG.d.cts} +51 -55
- package/dist/streaming-markdown.cjs +11828 -4879
- package/dist/streaming-markdown.d.cts +9 -2
- package/dist/streaming-markdown.d.ts +9 -2
- package/dist/streaming-markdown.mjs +11820 -4821
- 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 +39 -6
- package/dist/utils/inline-html.d.ts +39 -6
- package/dist/utils/inline-html.mjs +237 -134
- package/package.json +52 -18
- package/shadcn/README.md +28 -0
- package/shadcn/bottom-stick-scroll-area.tsx +358 -0
- package/dist/index-D2MYusAM.d.cts +0 -248
- package/dist/index-D2MYusAM.d.ts +0 -248
- 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 -563
- package/dist/mdx-coordinator.d.cts +0 -21
- package/dist/mdx-coordinator.d.ts +0 -21
- package/dist/mdx-coordinator.mjs +0 -529
- package/dist/renderer/node-views.cjs +0 -1642
- package/dist/renderer/node-views.d.cts +0 -12
- package/dist/renderer/node-views.d.ts +0 -12
- package/dist/renderer/node-views.mjs +0 -1616
|
@@ -1,583 +1,1356 @@
|
|
|
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;
|
|
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;
|
|
36
12
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
13
|
+
|
|
14
|
+
// src/components/bottom-stick-scroll-area.tsx
|
|
15
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
16
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
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;
|
|
18
|
+
function clamp01(value) {
|
|
19
|
+
return value < 0 ? 0 : value > 1 ? 1 : value;
|
|
20
|
+
}
|
|
21
|
+
function easeOutCubic(value) {
|
|
22
|
+
return 1 - (1 - value) ** 3;
|
|
23
|
+
}
|
|
24
|
+
function joinClasses(...parts) {
|
|
25
|
+
return parts.filter(Boolean).join(" ");
|
|
26
|
+
}
|
|
27
|
+
function measure(viewport) {
|
|
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;
|
|
29
|
+
return { scrollTop, scrollHeight, clientHeight, maxScrollTop, distanceToBottom, isOverflowing };
|
|
42
30
|
}
|
|
43
|
-
function
|
|
44
|
-
if (!
|
|
45
|
-
|
|
46
|
-
|
|
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;
|
|
47
54
|
}
|
|
48
|
-
return globalComponentFactory;
|
|
49
55
|
}
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
function DefaultJumpButton({ canJump, jumpToBottom }) {
|
|
57
|
+
return /* @__PURE__ */ jsx(
|
|
58
|
+
"button",
|
|
59
|
+
{
|
|
60
|
+
type: "button",
|
|
61
|
+
onClick: jumpToBottom,
|
|
62
|
+
"aria-label": "Scroll to bottom",
|
|
63
|
+
style: {
|
|
64
|
+
pointerEvents: canJump ? "auto" : "none",
|
|
65
|
+
borderRadius: 9999,
|
|
66
|
+
border: "1px solid color-mix(in srgb, currentColor 20%, transparent)",
|
|
67
|
+
width: 40,
|
|
68
|
+
height: 40,
|
|
69
|
+
display: "grid",
|
|
70
|
+
placeItems: "center",
|
|
71
|
+
boxShadow: "0 8px 20px rgba(0,0,0,0.18)",
|
|
72
|
+
background: "color-mix(in srgb, var(--background, #fff) 92%, transparent)",
|
|
73
|
+
color: "var(--foreground, #111)",
|
|
74
|
+
cursor: canJump ? "pointer" : "default"
|
|
75
|
+
},
|
|
76
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": !0, children: "\u2193" })
|
|
77
|
+
}
|
|
78
|
+
);
|
|
53
79
|
}
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
80
|
+
function BottomStickScrollArea({
|
|
81
|
+
children,
|
|
82
|
+
className,
|
|
83
|
+
viewportClassName,
|
|
84
|
+
contentClassName,
|
|
85
|
+
showJumpToBottom = !0,
|
|
86
|
+
onDebugStateChange,
|
|
87
|
+
onModeChange,
|
|
88
|
+
debugDomAttributes = !1,
|
|
89
|
+
renderJumpToBottom,
|
|
90
|
+
jumpContainerClassName
|
|
91
|
+
}) {
|
|
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(
|
|
93
|
+
(next) => {
|
|
94
|
+
modeRef.current = next, setMode(next), onModeChange?.(next);
|
|
95
|
+
},
|
|
96
|
+
[onModeChange]
|
|
97
|
+
), updateDebug = useCallback(() => {
|
|
98
|
+
let viewport = viewportRef.current;
|
|
99
|
+
if (!viewport) return;
|
|
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?.({
|
|
102
|
+
mode: modeRef.current,
|
|
103
|
+
isOverflowing: m.isOverflowing,
|
|
104
|
+
distanceToBottom: m.distanceToBottom,
|
|
105
|
+
scrollTop: m.scrollTop,
|
|
106
|
+
maxScrollTop: m.maxScrollTop,
|
|
107
|
+
scrollHeight: m.scrollHeight,
|
|
108
|
+
clientHeight: m.clientHeight,
|
|
109
|
+
programmaticWrites: programmaticWriteCountRef.current
|
|
110
|
+
}), setDistanceToBottom(
|
|
111
|
+
(previous) => Math.abs(previous - m.distanceToBottom) <= 0.1 ? previous : m.distanceToBottom
|
|
112
|
+
);
|
|
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;
|
|
146
|
+
if (!viewport) return;
|
|
147
|
+
if (prefersReducedMotionRef.current) {
|
|
148
|
+
cancelPendingStick(), cancelReturn(), setModeBoth("STICKY_INSTANT"), writeScrollTop(measure(viewport).maxScrollTop), prevScrollTopRef.current = viewport.scrollTop, updateDebug();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
cancelPendingStick(), cancelReturn();
|
|
152
|
+
let initial = measure(viewport);
|
|
153
|
+
if (initial.distanceToBottom <= EPS_BOTTOM_PX) {
|
|
154
|
+
setModeBoth("STICKY_INSTANT"), stickToBottomInstant(), updateDebug();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
let durationMs = Math.max(
|
|
158
|
+
RETURN_MIN_MS,
|
|
159
|
+
Math.min(RETURN_MAX_MS, initial.distanceToBottom / RETURN_PX_PER_MS)
|
|
160
|
+
);
|
|
161
|
+
returnAnimRef.current = {
|
|
162
|
+
startTime: performance.now(),
|
|
163
|
+
startTop: initial.scrollTop,
|
|
164
|
+
durationMs,
|
|
165
|
+
settleFrames: 0
|
|
166
|
+
}, setModeBoth("RETURNING_SMOOTH");
|
|
167
|
+
let tick = (now) => {
|
|
168
|
+
let viewportCurrent = viewportRef.current, anim = returnAnimRef.current;
|
|
169
|
+
if (!viewportCurrent || !anim || modeRef.current !== "RETURNING_SMOOTH") {
|
|
170
|
+
cancelReturn();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
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;
|
|
176
|
+
if (doneByTime && doneBySettle) {
|
|
177
|
+
cancelReturn(), setModeBoth("STICKY_INSTANT"), stickToBottomInstant(), updateDebug();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
updateDebug(), returnRafRef.current = requestAnimationFrame(tick);
|
|
181
|
+
};
|
|
182
|
+
returnRafRef.current = requestAnimationFrame(tick);
|
|
183
|
+
}, [cancelPendingStick, cancelReturn, setModeBoth, stickToBottomInstant, updateDebug, writeScrollTop]), onViewportScroll = useCallback(
|
|
184
|
+
(event) => {
|
|
185
|
+
let viewport = event.currentTarget, m = measure(viewport);
|
|
186
|
+
setIsOverflowing((previous) => previous === m.isOverflowing ? previous : m.isOverflowing);
|
|
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();
|
|
189
|
+
},
|
|
190
|
+
[cancelPendingStick, cancelReturn, setModeBoth, stickToBottomInstant, updateDebug]
|
|
191
|
+
);
|
|
192
|
+
useEffect(() => {
|
|
193
|
+
let viewport = viewportRef.current, content = contentRef.current;
|
|
194
|
+
if (!viewport || !content) return;
|
|
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();
|
|
198
|
+
});
|
|
199
|
+
return observer.observe(content), observer.observe(viewport), () => observer.disconnect();
|
|
200
|
+
}, [stickToBottomInstant, updateDebug]), useLayoutEffect(() => {
|
|
201
|
+
let viewport = viewportRef.current;
|
|
202
|
+
if (!viewport) return;
|
|
203
|
+
setModeBoth("STICKY_INSTANT");
|
|
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();
|
|
212
|
+
}, [cancelPendingStick, cancelReturn]);
|
|
213
|
+
let canJump = isOverflowing && mode === "DETACHED", jumpButton = renderJumpToBottom?.({
|
|
214
|
+
mode,
|
|
215
|
+
canJump,
|
|
216
|
+
isOverflowing,
|
|
217
|
+
distanceToBottom,
|
|
218
|
+
jumpToBottom: startReturnToBottomSmooth
|
|
219
|
+
}) ?? /* @__PURE__ */ jsx(DefaultJumpButton, { canJump, jumpToBottom: startReturnToBottomSmooth }), jumpContainerClassNameBase = "pointer-events-none absolute z-20", jumpContainerStyle = {
|
|
220
|
+
position: "absolute",
|
|
221
|
+
zIndex: 20,
|
|
222
|
+
left: 0,
|
|
223
|
+
right: 0,
|
|
224
|
+
bottom: 12,
|
|
225
|
+
display: "flex",
|
|
226
|
+
justifyContent: "center",
|
|
227
|
+
opacity: canJump ? 1 : 0,
|
|
228
|
+
transform: prefersReducedMotion ? "none" : canJump ? "translateY(0px)" : "translateY(4px)",
|
|
229
|
+
transition: prefersReducedMotion ? "none" : "opacity 150ms ease, transform 150ms ease",
|
|
230
|
+
pointerEvents: "none"
|
|
231
|
+
};
|
|
232
|
+
return /* @__PURE__ */ jsxs("div", { className: joinClasses("relative h-full w-full overflow-hidden", className), children: [
|
|
233
|
+
/* @__PURE__ */ jsx(
|
|
234
|
+
"div",
|
|
235
|
+
{
|
|
236
|
+
ref: viewportRef,
|
|
237
|
+
className: joinClasses("h-full w-full overflow-auto", viewportClassName),
|
|
238
|
+
onScroll: onViewportScroll,
|
|
239
|
+
onWheel: interruptReturnForUserIntent,
|
|
240
|
+
onTouchStart: interruptReturnForUserIntent,
|
|
241
|
+
onKeyDown: onViewportKeyDown,
|
|
242
|
+
"data-testid": "sticky-scroll-viewport",
|
|
243
|
+
children: /* @__PURE__ */ jsx("div", { ref: contentRef, className: joinClasses("flex min-h-full w-full flex-col", contentClassName), children })
|
|
244
|
+
}
|
|
245
|
+
),
|
|
246
|
+
showJumpToBottom ? /* @__PURE__ */ jsx(
|
|
247
|
+
"div",
|
|
248
|
+
{
|
|
249
|
+
className: joinClasses(jumpContainerClassNameBase, jumpContainerClassName),
|
|
250
|
+
style: jumpContainerStyle,
|
|
251
|
+
"aria-hidden": !canJump,
|
|
252
|
+
children: /* @__PURE__ */ jsx("div", { className: canJump ? "pointer-events-auto" : "pointer-events-none", children: jumpButton })
|
|
253
|
+
}
|
|
254
|
+
) : null
|
|
255
|
+
] });
|
|
256
|
+
}
|
|
257
|
+
|
|
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";
|
|
319
|
+
|
|
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;
|
|
61
326
|
}
|
|
62
|
-
var
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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;
|
|
336
|
+
}
|
|
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();
|
|
68
341
|
};
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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;
|
|
76
352
|
}
|
|
77
|
-
|
|
78
|
-
|
|
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;
|
|
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
|
-
}
|
|
353
|
+
if (this.katex) {
|
|
354
|
+
this.recompute(this.katex);
|
|
355
|
+
return;
|
|
98
356
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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);
|
|
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 });
|
|
112
364
|
}
|
|
113
|
-
|
|
114
|
-
this.
|
|
365
|
+
}).finally(() => {
|
|
366
|
+
this.loading = !1;
|
|
367
|
+
}));
|
|
368
|
+
}
|
|
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 };
|
|
115
383
|
try {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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);
|
|
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
|
+
};
|
|
136
399
|
}
|
|
137
|
-
return this.getCompiledInternal(ref);
|
|
138
400
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
401
|
+
this.macroSnapshots[index] = { ...macros }, entry.publish(preparation);
|
|
402
|
+
}
|
|
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
|
|
169
431
|
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
|
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))
|
|
185
439
|
});
|
|
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
440
|
}
|
|
441
|
+
})(), () => {
|
|
442
|
+
active = !1;
|
|
203
443
|
};
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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);
|
|
227
614
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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;
|
|
256
704
|
}
|
|
257
705
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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
|
|
757
|
+
};
|
|
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"
|
|
268
826
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
|
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"
|
|
296
839
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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);
|
|
311
869
|
}
|
|
312
|
-
|
|
870
|
+
} else {
|
|
871
|
+
let data = getTableData?.() ?? { headers, rows, align };
|
|
872
|
+
text = tableToTsv(data.headers, data.rows);
|
|
313
873
|
}
|
|
314
|
-
|
|
315
|
-
if (
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
for (const [key, component] of this.customComponents) {
|
|
320
|
-
merged[key] = component;
|
|
321
|
-
}
|
|
322
|
-
return merged;
|
|
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);
|
|
323
879
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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);
|
|
334
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);
|
|
335
901
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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;
|
|
384
1048
|
}
|
|
385
|
-
|
|
1049
|
+
to {
|
|
1050
|
+
opacity: 1;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
386
1053
|
|
|
387
|
-
|
|
388
|
-
|
|
1054
|
+
@keyframes fadeIn {
|
|
1055
|
+
from {
|
|
1056
|
+
opacity: 0;
|
|
1057
|
+
}
|
|
1058
|
+
to {
|
|
1059
|
+
opacity: 1;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
389
1062
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
function markMdxHydrationStart(id) {
|
|
400
|
-
if (!id) return;
|
|
401
|
-
const entry = entries.get(id) ?? { status: "compiled" };
|
|
402
|
-
if (entry.startedAt === void 0) {
|
|
403
|
-
entry.startedAt = now();
|
|
404
|
-
}
|
|
405
|
-
entry.status = "compiled";
|
|
406
|
-
entries.set(id, entry);
|
|
407
|
-
}
|
|
408
|
-
function markMdxHydrated(id) {
|
|
409
|
-
if (!id) return;
|
|
410
|
-
const entry = entries.get(id) ?? { status: "hydrated" };
|
|
411
|
-
if (entry.startedAt === void 0) {
|
|
412
|
-
entry.startedAt = now();
|
|
413
|
-
}
|
|
414
|
-
entry.hydratedAt = now();
|
|
415
|
-
entry.status = "hydrated";
|
|
416
|
-
entries.set(id, entry);
|
|
417
|
-
lastHydrationMs = entry.startedAt ? entry.hydratedAt - entry.startedAt : null;
|
|
418
|
-
}
|
|
419
|
-
function markMdxHydrationError(id) {
|
|
420
|
-
if (!id) return;
|
|
421
|
-
const entry = entries.get(id) ?? { status: "error" };
|
|
422
|
-
entry.status = "error";
|
|
423
|
-
entries.set(id, entry);
|
|
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
|
+
}
|
|
424
1072
|
}
|
|
425
1073
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
1074
|
+
@keyframes blurIn {
|
|
1075
|
+
from {
|
|
1076
|
+
opacity: 0;
|
|
1077
|
+
filter: blur(4px);
|
|
1078
|
+
}
|
|
1079
|
+
to {
|
|
1080
|
+
opacity: 1;
|
|
1081
|
+
filter: blur(0px);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
429
1084
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
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);
|
|
435
1093
|
}
|
|
436
|
-
return mdxRuntimePromise;
|
|
437
1094
|
}
|
|
438
1095
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
timerId = window.setTimeout(runWithIdle, debounceMs);
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
},
|
|
478
|
-
{ rootMargin: options?.rootMargin ?? "200px 0px" }
|
|
479
|
-
);
|
|
480
|
-
observer.observe(target);
|
|
481
|
-
return () => {
|
|
482
|
-
cancelled = true;
|
|
483
|
-
observer.disconnect();
|
|
484
|
-
if (idleId !== null && typeof globalThis.cancelIdleCallback === "function") {
|
|
485
|
-
globalThis.cancelIdleCallback(idleId);
|
|
486
|
-
}
|
|
487
|
-
if (timerId !== null) {
|
|
488
|
-
window.clearTimeout(timerId);
|
|
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;
|
|
489
1130
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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);
|
|
493
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
|
+
};
|
|
494
1182
|
|
|
495
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";
|
|
496
1186
|
import { removeHeadingMarkers } from "@stream-mdx/core";
|
|
497
|
-
import
|
|
1187
|
+
import React8 from "react";
|
|
498
1188
|
|
|
499
1189
|
// src/utils/inline-html.ts
|
|
500
1190
|
import React3 from "react";
|
|
501
|
-
|
|
502
|
-
|
|
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 = {
|
|
503
1287
|
kbd: (descriptor, ctx) => {
|
|
504
|
-
|
|
505
|
-
const match = BACKTICK_CONTENT.exec(trimmed);
|
|
1288
|
+
let trimmed = descriptor.rawInner.trim(), match = BACKTICK_CONTENT.exec(trimmed);
|
|
506
1289
|
if (match) {
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if (ctx.key !== void 0 && ctx.key !== null) {
|
|
510
|
-
props.key = ctx.key;
|
|
511
|
-
}
|
|
512
|
-
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));
|
|
513
1292
|
}
|
|
514
1293
|
return ctx.defaultRender();
|
|
515
1294
|
}
|
|
516
1295
|
};
|
|
517
1296
|
function renderInlineHtmlSegment(raw, sanitized, options = {}) {
|
|
518
|
-
|
|
519
|
-
if (!descriptor)
|
|
1297
|
+
let descriptor = parseInlineHtmlDescriptor(raw, sanitized);
|
|
1298
|
+
if (!descriptor)
|
|
520
1299
|
return null;
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const defaultRender = () => {
|
|
525
|
-
if (!descriptor.sanitized || descriptor.sanitized.length === 0) {
|
|
526
|
-
if (!descriptor.text) {
|
|
527
|
-
return null;
|
|
528
|
-
}
|
|
529
|
-
if (options.key !== void 0 && options.key !== null) {
|
|
530
|
-
return React3.createElement(React3.Fragment, { key: options.key }, descriptor.text);
|
|
531
|
-
}
|
|
532
|
-
return React3.createElement(React3.Fragment, {}, descriptor.text);
|
|
533
|
-
}
|
|
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;
|
|
534
1303
|
if (isInlineTag) {
|
|
535
|
-
|
|
536
|
-
|
|
1304
|
+
let parsedElement = renderSanitizedHtmlTree(
|
|
1305
|
+
descriptor.sanitized,
|
|
1306
|
+
options.key,
|
|
1307
|
+
options.htmlElements,
|
|
1308
|
+
options.literalTagContent,
|
|
1309
|
+
options.parseMarkdown
|
|
1310
|
+
);
|
|
1311
|
+
if (parsedElement)
|
|
537
1312
|
return parsedElement;
|
|
538
|
-
}
|
|
539
1313
|
}
|
|
540
|
-
|
|
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 = {
|
|
541
1320
|
className,
|
|
542
1321
|
dangerouslySetInnerHTML: { __html: descriptor.sanitized }
|
|
543
1322
|
};
|
|
544
|
-
|
|
545
|
-
props.key = options.key;
|
|
546
|
-
}
|
|
547
|
-
return React3.createElement("span", props);
|
|
1323
|
+
return options.key !== void 0 && options.key !== null && (props.key = options.key), React3.createElement("span", props);
|
|
548
1324
|
};
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
return React3.cloneElement(rendered, { key: options.key });
|
|
556
|
-
}
|
|
557
|
-
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;
|
|
558
1331
|
}
|
|
559
1332
|
}
|
|
560
1333
|
return defaultRender();
|
|
561
1334
|
}
|
|
562
1335
|
function parseInlineHtmlDescriptor(raw, sanitized) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
if (!normalizedSanitized) {
|
|
566
|
-
return null;
|
|
567
|
-
}
|
|
568
|
-
const match = normalizedSanitized.match(/^<([A-Za-z][\w:-]*)(\s[^>]*)?>([\s\S]*)<\/\1>$/);
|
|
569
|
-
if (!match) {
|
|
1336
|
+
let normalizedRaw = typeof raw == "string" ? raw.trim() : "", normalizedSanitized = typeof sanitized == "string" && sanitized.length > 0 ? sanitized.trim() : normalizedRaw;
|
|
1337
|
+
if (!normalizedSanitized)
|
|
570
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 = "";
|
|
571
1347
|
}
|
|
572
|
-
|
|
573
|
-
const tagName = tagNameRaw.toLowerCase();
|
|
574
|
-
const attributes = parseAttributes(attrString);
|
|
575
|
-
let rawInner = "";
|
|
1348
|
+
let tagName = tagNameRaw.toLowerCase(), attributes = parseAttributes(attrString), rawInner = "";
|
|
576
1349
|
if (normalizedRaw) {
|
|
577
|
-
|
|
1350
|
+
let rawMatch = normalizedRaw.match(/^<([A-Za-z][\w:-]*)(\s[^>]*)?>([\s\S]*)<\/\1>$/);
|
|
578
1351
|
rawInner = rawMatch ? rawMatch[3] ?? "" : normalizedRaw;
|
|
579
1352
|
}
|
|
580
|
-
|
|
1353
|
+
let text = extractPlainText(rawInner || sanitizedInner);
|
|
581
1354
|
return {
|
|
582
1355
|
tagName,
|
|
583
1356
|
attributes,
|
|
@@ -589,52 +1362,91 @@ function parseInlineHtmlDescriptor(raw, sanitized) {
|
|
|
589
1362
|
};
|
|
590
1363
|
}
|
|
591
1364
|
function parseAttributes(input) {
|
|
592
|
-
|
|
1365
|
+
let attrs = {};
|
|
593
1366
|
if (!input) return attrs;
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
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];
|
|
598
1370
|
if (!name) continue;
|
|
599
|
-
|
|
600
|
-
attrs[name] = value;
|
|
601
|
-
match = attrPattern.exec(input);
|
|
1371
|
+
let value = match[2] ?? match[3] ?? match[4] ?? "";
|
|
1372
|
+
attrs[name] = value, match = attrPattern.exec(input);
|
|
602
1373
|
}
|
|
603
1374
|
return attrs;
|
|
604
1375
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
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;
|
|
620
1430
|
}
|
|
621
1431
|
return props;
|
|
622
1432
|
}
|
|
623
1433
|
function parseStyleAttribute(value) {
|
|
624
|
-
|
|
1434
|
+
let style = {};
|
|
625
1435
|
if (!value) return style;
|
|
626
|
-
|
|
627
|
-
for (
|
|
1436
|
+
let pairs = value.split(";");
|
|
1437
|
+
for (let pair of pairs) {
|
|
628
1438
|
if (!pair.trim()) continue;
|
|
629
|
-
|
|
630
|
-
if (
|
|
631
|
-
|
|
632
|
-
|
|
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;
|
|
633
1445
|
}
|
|
634
1446
|
return style;
|
|
635
1447
|
}
|
|
636
1448
|
function normalizeTabIndex(value) {
|
|
637
|
-
|
|
1449
|
+
let numeric = Number(value);
|
|
638
1450
|
return Number.isNaN(numeric) ? void 0 : numeric;
|
|
639
1451
|
}
|
|
640
1452
|
function decodeHtmlEntities(value) {
|
|
@@ -642,76 +1454,50 @@ function decodeHtmlEntities(value) {
|
|
|
642
1454
|
}
|
|
643
1455
|
function extractPlainText(value) {
|
|
644
1456
|
if (!value) return "";
|
|
645
|
-
|
|
1457
|
+
let withoutTags = value.replace(/<\/?[^>]+>/g, "");
|
|
646
1458
|
return decodeHtmlEntities(withoutTags);
|
|
647
1459
|
}
|
|
648
|
-
|
|
649
|
-
|
|
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")
|
|
650
1463
|
return null;
|
|
651
|
-
}
|
|
652
1464
|
try {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
const body = doc.body;
|
|
656
|
-
const nodes = Array.from(body.childNodes);
|
|
657
|
-
if (nodes.length === 0) {
|
|
1465
|
+
let body = new DOMParser().parseFromString(html, "text/html").body, nodes = Array.from(body.childNodes);
|
|
1466
|
+
if (nodes.length === 0)
|
|
658
1467
|
return null;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
const children = nodes.map((node, index) => convertDomNode(node, `${baseKey}-${index}`)).filter((child) => child !== null && child !== void 0);
|
|
662
|
-
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)
|
|
663
1470
|
return null;
|
|
664
|
-
}
|
|
665
1471
|
if (children.length === 1) {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
if (key !== void 0 && key !== null) {
|
|
669
|
-
return React3.cloneElement(child, { key });
|
|
670
|
-
}
|
|
671
|
-
return child;
|
|
672
|
-
}
|
|
673
|
-
if (typeof child === "string" || typeof child === "number") {
|
|
674
|
-
if (key !== void 0 && key !== null) {
|
|
675
|
-
return React3.createElement(React3.Fragment, { key }, child);
|
|
676
|
-
}
|
|
677
|
-
return React3.createElement(React3.Fragment, {}, child);
|
|
678
|
-
}
|
|
679
|
-
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);
|
|
680
1474
|
}
|
|
681
1475
|
return React3.createElement(React3.Fragment, { key }, ...children);
|
|
682
1476
|
} catch {
|
|
683
1477
|
return null;
|
|
684
1478
|
}
|
|
685
1479
|
}
|
|
686
|
-
function convertDomNode(node, key) {
|
|
1480
|
+
function convertDomNode(node, key, htmlElements, literalTags, parentIsLiteral, parseMarkdown) {
|
|
687
1481
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
688
|
-
|
|
1482
|
+
let rawText = node.textContent ?? "";
|
|
1483
|
+
return parentIsLiteral || !parseMarkdown ? rawText : parseMarkdown(rawText);
|
|
689
1484
|
}
|
|
690
|
-
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
1485
|
+
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
691
1486
|
return null;
|
|
692
|
-
|
|
693
|
-
const element = node;
|
|
694
|
-
const tagName = element.tagName.toLowerCase();
|
|
695
|
-
const attrs = getElementAttributes(element);
|
|
696
|
-
const props = mapAttributesToProps(attrs);
|
|
1487
|
+
let element = node, tagName = element.tagName.toLowerCase(), attrs = getElementAttributes(element), props = mapAttributesToProps(attrs);
|
|
697
1488
|
props.key = key;
|
|
698
|
-
|
|
1489
|
+
let isLiteral = parentIsLiteral || (literalTags ? literalTags.has(tagName) : !1), children = [];
|
|
699
1490
|
element.childNodes.forEach((child, index) => {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
children.push(converted);
|
|
703
|
-
}
|
|
1491
|
+
let converted = convertDomNode(child, `${key}-${index}`, htmlElements, literalTags, isLiteral, parseMarkdown);
|
|
1492
|
+
converted != null && children.push(converted);
|
|
704
1493
|
});
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
}
|
|
708
|
-
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);
|
|
709
1496
|
}
|
|
710
1497
|
function getElementAttributes(element) {
|
|
711
|
-
|
|
712
|
-
for (
|
|
1498
|
+
let attrs = {};
|
|
1499
|
+
for (let attr of Array.from(element.attributes))
|
|
713
1500
|
attrs[attr.name] = attr.value;
|
|
714
|
-
}
|
|
715
1501
|
return attrs;
|
|
716
1502
|
}
|
|
717
1503
|
var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
|
|
@@ -721,6 +1507,11 @@ var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
721
1507
|
"bdi",
|
|
722
1508
|
"bdo",
|
|
723
1509
|
"br",
|
|
1510
|
+
"img",
|
|
1511
|
+
"input",
|
|
1512
|
+
"picture",
|
|
1513
|
+
"del",
|
|
1514
|
+
"ins",
|
|
724
1515
|
"cite",
|
|
725
1516
|
"code",
|
|
726
1517
|
"data",
|
|
@@ -765,67 +1556,404 @@ var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
765
1556
|
"mtd"
|
|
766
1557
|
]);
|
|
767
1558
|
|
|
768
|
-
// src/components/
|
|
769
|
-
import
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
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 };
|
|
773
1641
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
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;
|
|
817
1692
|
}
|
|
818
|
-
|
|
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
|
|
819
1782
|
};
|
|
820
|
-
|
|
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 = {
|
|
821
1950
|
borderRadius: 8,
|
|
822
1951
|
border: "1px solid var(--border, rgba(0, 0, 0, 0.1))",
|
|
823
1952
|
padding: "6px 12px",
|
|
824
1953
|
background: "var(--background, #fff)",
|
|
825
1954
|
color: "inherit",
|
|
826
1955
|
fontSize: 13
|
|
827
|
-
}
|
|
828
|
-
var primaryButtonStyle = {
|
|
1956
|
+
}, primaryButtonStyle = {
|
|
829
1957
|
...buttonStyle,
|
|
830
1958
|
background: "var(--foreground, #111)",
|
|
831
1959
|
color: "var(--background, #fff)",
|
|
@@ -833,120 +1961,295 @@ var primaryButtonStyle = {
|
|
|
833
1961
|
};
|
|
834
1962
|
|
|
835
1963
|
// src/components/index.ts
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
}
|
|
841
|
-
static getDerivedStateFromError() {
|
|
842
|
-
return { hasError: true };
|
|
843
|
-
}
|
|
844
|
-
componentDidCatch(error) {
|
|
845
|
-
this.props.onError(error);
|
|
846
|
-
}
|
|
847
|
-
componentDidUpdate(prevProps) {
|
|
848
|
-
if (prevProps.resetKey !== this.props.resetKey && this.state.hasError) {
|
|
849
|
-
this.setState({ hasError: false });
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
render() {
|
|
853
|
-
if (this.state.hasError) {
|
|
854
|
-
return null;
|
|
855
|
-
}
|
|
856
|
-
return this.props.children;
|
|
857
|
-
}
|
|
858
|
-
};
|
|
859
|
-
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) {
|
|
860
1968
|
return nodes.map((node, index) => {
|
|
861
|
-
|
|
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;
|
|
862
1973
|
switch (node.kind) {
|
|
863
1974
|
case "text": {
|
|
864
|
-
|
|
865
|
-
if (textComponent && textComponent !== defaultInlineComponents.text)
|
|
866
|
-
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));
|
|
867
2001
|
}
|
|
868
|
-
return
|
|
2002
|
+
return presentInline(React8.createElement(React8.Fragment, { key, children: node.text }));
|
|
869
2003
|
}
|
|
870
|
-
case "strong":
|
|
871
|
-
|
|
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, {
|
|
872
2011
|
key,
|
|
873
|
-
children:
|
|
874
|
-
});
|
|
875
|
-
|
|
876
|
-
|
|
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, {
|
|
877
2028
|
key,
|
|
878
|
-
children:
|
|
879
|
-
});
|
|
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
|
+
}
|
|
880
2038
|
case "strike": {
|
|
881
|
-
|
|
882
|
-
|
|
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, {
|
|
883
2046
|
key,
|
|
884
|
-
children:
|
|
885
|
-
});
|
|
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
|
+
);
|
|
2055
|
+
}
|
|
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
|
+
);
|
|
886
2066
|
}
|
|
887
|
-
case "
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
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(
|
|
891
2082
|
components.link,
|
|
892
2083
|
{
|
|
893
2084
|
key,
|
|
894
|
-
href:
|
|
2085
|
+
...safeHref != null ? { href: safeHref } : {},
|
|
895
2086
|
title: node.title,
|
|
896
|
-
children:
|
|
2087
|
+
children: renderChildren()
|
|
897
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
|
|
898
2095
|
);
|
|
899
|
-
|
|
900
|
-
|
|
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, {
|
|
901
2107
|
key,
|
|
902
|
-
src:
|
|
903
|
-
alt: node.alt,
|
|
2108
|
+
...safeSrc != null ? { src: safeSrc } : {},
|
|
2109
|
+
alt: node.alt ?? "",
|
|
904
2110
|
title: node.title
|
|
905
|
-
});
|
|
906
|
-
|
|
907
|
-
|
|
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
|
+
}
|
|
908
2204
|
default: {
|
|
909
|
-
|
|
2205
|
+
let component = components[node.kind];
|
|
910
2206
|
if (component) {
|
|
911
|
-
|
|
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 } : {} }));
|
|
912
2209
|
}
|
|
913
|
-
return null;
|
|
2210
|
+
return presentInline(React8.createElement(React8.Fragment, { key }, null));
|
|
914
2211
|
}
|
|
915
2212
|
}
|
|
916
2213
|
});
|
|
917
2214
|
}
|
|
918
2215
|
var defaultInlineComponents = {
|
|
919
|
-
text: ({ text }) =>
|
|
920
|
-
strong: ({ children }) =>
|
|
921
|
-
em: ({ children }) =>
|
|
922
|
-
strike: ({ children }) =>
|
|
923
|
-
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(
|
|
924
2221
|
"code",
|
|
925
2222
|
{
|
|
926
2223
|
className: "inline-code"
|
|
927
2224
|
},
|
|
928
2225
|
text
|
|
929
2226
|
),
|
|
930
|
-
link: ({ href, title, children }) =>
|
|
931
|
-
"
|
|
932
|
-
|
|
933
|
-
|
|
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,
|
|
934
2246
|
title,
|
|
935
|
-
className: "markdown-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
children
|
|
940
|
-
),
|
|
941
|
-
image: ({ src, alt, title }) => React4.createElement("img", {
|
|
942
|
-
src,
|
|
943
|
-
alt,
|
|
944
|
-
title,
|
|
945
|
-
className: "markdown-image"
|
|
946
|
-
}),
|
|
947
|
-
br: () => React4.createElement("br"),
|
|
2247
|
+
className: "markdown-image"
|
|
2248
|
+
});
|
|
2249
|
+
},
|
|
2250
|
+
br: () => React8.createElement("br"),
|
|
948
2251
|
// Custom extensible components
|
|
949
|
-
mention: ({ handle }) =>
|
|
2252
|
+
mention: ({ handle }) => React8.createElement(
|
|
950
2253
|
"span",
|
|
951
2254
|
{
|
|
952
2255
|
className: "mention",
|
|
@@ -954,7 +2257,7 @@ var defaultInlineComponents = {
|
|
|
954
2257
|
},
|
|
955
2258
|
`@${handle}`
|
|
956
2259
|
),
|
|
957
|
-
citation: ({ id }) =>
|
|
2260
|
+
citation: ({ id }) => React8.createElement(
|
|
958
2261
|
"span",
|
|
959
2262
|
{
|
|
960
2263
|
className: "citation",
|
|
@@ -962,107 +2265,135 @@ var defaultInlineComponents = {
|
|
|
962
2265
|
},
|
|
963
2266
|
`[${id}]`
|
|
964
2267
|
),
|
|
965
|
-
"math-inline": ({ tex }) =>
|
|
966
|
-
|
|
967
|
-
{
|
|
968
|
-
className: "math-inline",
|
|
969
|
-
"data-tex": tex
|
|
970
|
-
},
|
|
971
|
-
`$${tex}$`
|
|
972
|
-
),
|
|
973
|
-
"math-display": ({ tex }) => React4.createElement(
|
|
974
|
-
"div",
|
|
975
|
-
{
|
|
976
|
-
className: "math-display markdown-math-display",
|
|
977
|
-
"data-tex": tex,
|
|
978
|
-
style: { overflowX: "auto" }
|
|
979
|
-
},
|
|
980
|
-
React4.createElement("span", { className: "math-display-content" }, `$$${tex}$$`)
|
|
981
|
-
),
|
|
2268
|
+
"math-inline": ({ tex, engine }) => React8.createElement(KaTeXInlineMath, { tex, engine }),
|
|
2269
|
+
"math-display": ({ tex, engine }) => React8.createElement(KaTeXBlockMath, { tex, engine }),
|
|
982
2270
|
// Footnote inline reference (superscript anchor)
|
|
983
|
-
"footnote-ref": ({ label, number }) => {
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
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(
|
|
2275
|
+
"sup",
|
|
2276
|
+
{ className: "footnote-ref" },
|
|
2277
|
+
React8.createElement("a", { href, id, "data-label": label, style: { color: "var(--foreground)", textDecoration: "underline" } }, String(n))
|
|
2278
|
+
);
|
|
988
2279
|
}
|
|
989
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
|
+
}
|
|
990
2304
|
var defaultBlockComponents = {
|
|
991
|
-
paragraph: (
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
{
|
|
996
|
-
|
|
997
|
-
},
|
|
998
|
-
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
|
|
999
2311
|
);
|
|
1000
|
-
|
|
1001
|
-
const segments = Array.isArray(meta?.mixedSegments) ? meta?.mixedSegments : void 0;
|
|
2312
|
+
let segments = Array.isArray(meta?.mixedSegments) ? meta?.mixedSegments : void 0;
|
|
1002
2313
|
if (segments && segments.length > 0) {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
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
|
+
);
|
|
1008
2319
|
}
|
|
1009
|
-
|
|
1010
|
-
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 ? [
|
|
1011
2321
|
{
|
|
1012
2322
|
kind: "text",
|
|
1013
2323
|
text: raw
|
|
1014
2324
|
}
|
|
1015
2325
|
] : [];
|
|
1016
|
-
return
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
className: "markdown-paragraph"
|
|
1020
|
-
|
|
1021
|
-
|
|
2326
|
+
return applyBlockPresentationProps(
|
|
2327
|
+
React8.createElement(
|
|
2328
|
+
"p",
|
|
2329
|
+
{ className: "markdown-paragraph" },
|
|
2330
|
+
effectiveInlines.length > 0 ? renderInlineNodes(effectiveInlines, defaultInlineComponents) : raw ?? ""
|
|
2331
|
+
),
|
|
2332
|
+
decoration
|
|
1022
2333
|
);
|
|
1023
2334
|
},
|
|
1024
|
-
heading: (
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
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
|
|
1037
2348
|
);
|
|
1038
2349
|
},
|
|
1039
|
-
code: ({ html, meta, lines, lang, preAttrs, codeAttrs }) => {
|
|
1040
|
-
|
|
1041
|
-
if (
|
|
1042
|
-
|
|
1043
|
-
|
|
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",
|
|
1044
2377
|
/* biome-ignore lint/security/noDangerouslySetInnerHtml: highlighted HTML is generated by our sanitizer */
|
|
1045
2378
|
dangerouslySetInnerHTML: { __html: html }
|
|
1046
2379
|
});
|
|
1047
|
-
|
|
1048
|
-
const code = meta?.code || "";
|
|
2380
|
+
let code = meta?.code || "";
|
|
1049
2381
|
if (lines && lines.length > 0) {
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
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(
|
|
1053
2384
|
"pre",
|
|
1054
2385
|
{
|
|
1055
2386
|
...preAttributes,
|
|
1056
|
-
className:
|
|
2387
|
+
className: preClassName
|
|
1057
2388
|
},
|
|
1058
|
-
|
|
2389
|
+
React8.createElement(
|
|
1059
2390
|
"code",
|
|
1060
2391
|
{
|
|
1061
2392
|
...codeAttributes,
|
|
1062
|
-
|
|
2393
|
+
...codeClassName ? { className: codeClassName } : {}
|
|
1063
2394
|
},
|
|
1064
2395
|
lines.map(
|
|
1065
|
-
(line) =>
|
|
2396
|
+
(line) => React8.createElement("span", {
|
|
1066
2397
|
key: line.id,
|
|
1067
2398
|
className: "line",
|
|
1068
2399
|
/* biome-ignore lint/security/noDangerouslySetInnerHtml: line HTML is sanitized server-side */
|
|
@@ -1072,29 +2403,26 @@ var defaultBlockComponents = {
|
|
|
1072
2403
|
)
|
|
1073
2404
|
);
|
|
1074
2405
|
}
|
|
1075
|
-
return
|
|
1076
|
-
className: `markdown-code-block language-${language
|
|
2406
|
+
return React8.createElement("pre", {
|
|
2407
|
+
className: language ? `markdown-code-block language-${language}` : "markdown-code-block",
|
|
1077
2408
|
children: code
|
|
1078
2409
|
});
|
|
1079
2410
|
},
|
|
1080
|
-
blockquote: ({ inlines, renderedContent }) =>
|
|
2411
|
+
blockquote: ({ inlines, renderedContent }) => React8.createElement(
|
|
1081
2412
|
"blockquote",
|
|
1082
2413
|
{
|
|
1083
2414
|
className: "markdown-blockquote"
|
|
1084
2415
|
},
|
|
1085
2416
|
renderedContent ?? renderInlineNodes(inlines, defaultInlineComponents)
|
|
1086
2417
|
),
|
|
1087
|
-
hr: (props) =>
|
|
2418
|
+
hr: (props) => React8.createElement("hr", props),
|
|
1088
2419
|
list: ({ ordered, items }) => {
|
|
1089
|
-
if (items.length === 0)
|
|
2420
|
+
if (items.length === 0)
|
|
1090
2421
|
return null;
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
} : void 0;
|
|
1096
|
-
const listItems = items.map(
|
|
1097
|
-
(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(
|
|
1098
2426
|
"li",
|
|
1099
2427
|
{
|
|
1100
2428
|
key: index,
|
|
@@ -1105,7 +2433,7 @@ var defaultBlockComponents = {
|
|
|
1105
2433
|
renderInlineNodes(item, defaultInlineComponents)
|
|
1106
2434
|
)
|
|
1107
2435
|
);
|
|
1108
|
-
return
|
|
2436
|
+
return React8.createElement(
|
|
1109
2437
|
tag,
|
|
1110
2438
|
{
|
|
1111
2439
|
className: `markdown-list ${ordered ? "ordered" : "unordered"}`,
|
|
@@ -1114,206 +2442,69 @@ var defaultBlockComponents = {
|
|
|
1114
2442
|
listItems
|
|
1115
2443
|
);
|
|
1116
2444
|
},
|
|
1117
|
-
html: ({ __trustedHtml, elements }) => {
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
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);
|
|
1123
2452
|
}
|
|
1124
|
-
return
|
|
2453
|
+
return React8.createElement("div", {
|
|
1125
2454
|
className: "markdown-html",
|
|
1126
2455
|
/* biome-ignore lint/security/noDangerouslySetInnerHtml: htmlString is sanitized before injection */
|
|
1127
2456
|
dangerouslySetInnerHTML: { __html: htmlString }
|
|
1128
2457
|
});
|
|
1129
2458
|
},
|
|
1130
|
-
mdx: ({
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
const hydrationOptions = hydrationContext?.options;
|
|
1138
|
-
const containerRef = React4.useRef(null);
|
|
1139
|
-
const deferHydration = hydrationOptions?.strategy === "visible";
|
|
1140
|
-
const shouldHydrate = useDeferredRender(
|
|
1141
|
-
containerRef,
|
|
1142
|
-
deferHydration ? {
|
|
1143
|
-
enabled: true,
|
|
1144
|
-
rootMargin: hydrationOptions?.rootMargin,
|
|
1145
|
-
idleTimeoutMs: hydrationOptions?.idleTimeoutMs,
|
|
1146
|
-
debounceMs: hydrationOptions?.debounceMs
|
|
1147
|
-
} : { enabled: false }
|
|
1148
|
-
);
|
|
1149
|
-
const resolvedId = compiledModule?.id ?? (compiledRef?.id && compiledRef.id !== "pending" ? compiledRef.id : void 0);
|
|
1150
|
-
const handleRetry = React4.useCallback(() => {
|
|
1151
|
-
setInternalError(null);
|
|
1152
|
-
setRenderError(null);
|
|
1153
|
-
setComp(null);
|
|
1154
|
-
setRetryKey((prev) => prev + 1);
|
|
1155
|
-
}, []);
|
|
1156
|
-
const handleRuntimeError = React4.useCallback(
|
|
1157
|
-
(error) => {
|
|
1158
|
-
const message2 = error instanceof Error ? error.message : String(error);
|
|
1159
|
-
setRenderError(message2);
|
|
1160
|
-
markMdxHydrationError(resolvedId ?? compiledRef?.id);
|
|
1161
|
-
},
|
|
1162
|
-
[resolvedId, compiledRef?.id]
|
|
1163
|
-
);
|
|
1164
|
-
const effectiveStatus = status ? status : resolvedId ? "compiled" : "pending";
|
|
1165
|
-
const failureMessage = errorMessage ?? internalError ?? renderError ?? null;
|
|
1166
|
-
const moduleDependencies = compiledModule?.dependencies;
|
|
1167
|
-
React4.useEffect(() => {
|
|
1168
|
-
if (!shouldHydrate) {
|
|
1169
|
-
return;
|
|
1170
|
-
}
|
|
1171
|
-
if (status === "error") {
|
|
1172
|
-
markMdxHydrationError(resolvedId ?? compiledRef?.id);
|
|
1173
|
-
return;
|
|
1174
|
-
}
|
|
1175
|
-
let cancelled = false;
|
|
1176
|
-
async function ensure() {
|
|
1177
|
-
let permit = null;
|
|
1178
|
-
try {
|
|
1179
|
-
if (status === "error" || !resolvedId || resolvedId === "pending") {
|
|
1180
|
-
if (!cancelled) {
|
|
1181
|
-
setComp(null);
|
|
1182
|
-
setInternalError(null);
|
|
1183
|
-
}
|
|
1184
|
-
return;
|
|
1185
|
-
}
|
|
1186
|
-
if (hydrationController) {
|
|
1187
|
-
permit = await hydrationController.acquire();
|
|
1188
|
-
if (cancelled) {
|
|
1189
|
-
permit.release();
|
|
1190
|
-
return;
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
setInternalError(null);
|
|
1194
|
-
setRenderError(null);
|
|
1195
|
-
markMdxHydrationStart(resolvedId);
|
|
1196
|
-
const { getMDXComponentFactory: getMDXComponentFactory2, registerInlineMdxModule: registerInlineMdxModule2 } = await loadMdxRuntime();
|
|
1197
|
-
if (compiledModule?.code) {
|
|
1198
|
-
registerInlineMdxModule2({
|
|
1199
|
-
id: compiledModule.id,
|
|
1200
|
-
code: compiledModule.code,
|
|
1201
|
-
dependencies: moduleDependencies ?? []
|
|
1202
|
-
});
|
|
1203
|
-
}
|
|
1204
|
-
const factory = getMDXComponentFactory2();
|
|
1205
|
-
const C = await factory.createComponent({ id: resolvedId });
|
|
1206
|
-
if (!cancelled) {
|
|
1207
|
-
setComp(() => C);
|
|
1208
|
-
setInternalError(null);
|
|
1209
|
-
markMdxHydrated(resolvedId);
|
|
1210
|
-
}
|
|
1211
|
-
} catch (error) {
|
|
1212
|
-
if (!cancelled) {
|
|
1213
|
-
const message2 = error instanceof Error ? error.message : String(error);
|
|
1214
|
-
setInternalError(message2);
|
|
1215
|
-
markMdxHydrationError(resolvedId);
|
|
1216
|
-
}
|
|
1217
|
-
} finally {
|
|
1218
|
-
permit?.release();
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
ensure();
|
|
1222
|
-
return () => {
|
|
1223
|
-
cancelled = true;
|
|
1224
|
-
};
|
|
1225
|
-
}, [compiledModule?.id, compiledModule?.code, moduleDependencies, resolvedId, status, shouldHydrate, retryKey]);
|
|
1226
|
-
const compileMode = compiledModule?.source === "worker" || compiledRef?.id?.startsWith("worker:") ? "worker" : "server";
|
|
1227
|
-
const pendingId = resolvedId && resolvedId !== "pending" ? resolvedId : compiledRef?.id ?? "pending";
|
|
1228
|
-
const waitingForVisibility = deferHydration && !shouldHydrate && Boolean(resolvedId);
|
|
1229
|
-
const pendingLabel = waitingForVisibility ? "MDX ready (hydrate on view)\u2026" : compileMode === "worker" ? "Compiling MDX (client)\u2026" : "Compiling MDX (server)\u2026";
|
|
1230
|
-
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.");
|
|
1231
|
-
const rawFallback = typeof raw === "string" && raw.trim().length > 0 ? React4.createElement("pre", { className: "markdown-mdx-fallback" }, raw) : null;
|
|
1232
|
-
const allowRetry = Boolean(internalError || renderError);
|
|
1233
|
-
const retryButton = allowRetry ? React4.createElement(
|
|
1234
|
-
"button",
|
|
1235
|
-
{
|
|
1236
|
-
type: "button",
|
|
1237
|
-
className: "markdown-mdx-retry",
|
|
1238
|
-
onClick: handleRetry
|
|
1239
|
-
},
|
|
1240
|
-
"Retry hydration"
|
|
1241
|
-
) : null;
|
|
1242
|
-
const errorPanel = React4.createElement(
|
|
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);
|
|
2464
|
+
}
|
|
2465
|
+
return React8.createElement(
|
|
1243
2466
|
"div",
|
|
1244
|
-
{ className: "markdown-mdx-
|
|
1245
|
-
|
|
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 ?? ""))
|
|
1246
2469
|
);
|
|
1247
|
-
if (Comp && !failureMessage) {
|
|
1248
|
-
return React4.createElement(
|
|
1249
|
-
"div",
|
|
1250
|
-
{
|
|
1251
|
-
className: "markdown-mdx",
|
|
1252
|
-
ref: containerRef,
|
|
1253
|
-
"data-mdx-ref": resolvedId ?? compiledRef?.id ?? "compiled",
|
|
1254
|
-
"data-mdx-status": failureMessage ? "error" : "compiled",
|
|
1255
|
-
"data-mdx-mode": compileMode
|
|
1256
|
-
},
|
|
1257
|
-
React4.createElement(
|
|
1258
|
-
MdxRuntimeBoundary,
|
|
1259
|
-
{ resetKey: retryKey, onError: handleRuntimeError },
|
|
1260
|
-
React4.createElement(Comp, {})
|
|
1261
|
-
)
|
|
1262
|
-
);
|
|
1263
|
-
}
|
|
1264
|
-
if (failureMessage) {
|
|
1265
|
-
return React4.createElement(
|
|
1266
|
-
"div",
|
|
1267
|
-
{
|
|
1268
|
-
className: "markdown-mdx",
|
|
1269
|
-
ref: containerRef,
|
|
1270
|
-
"data-mdx-ref": pendingId,
|
|
1271
|
-
"data-mdx-status": "error",
|
|
1272
|
-
"data-mdx-mode": compileMode
|
|
1273
|
-
},
|
|
1274
|
-
errorPanel,
|
|
1275
|
-
rawFallback,
|
|
1276
|
-
retryButton
|
|
1277
|
-
);
|
|
1278
|
-
}
|
|
1279
|
-
if (!Comp) {
|
|
1280
|
-
return React4.createElement(
|
|
1281
|
-
"div",
|
|
1282
|
-
{
|
|
1283
|
-
className: "markdown-mdx",
|
|
1284
|
-
ref: containerRef,
|
|
1285
|
-
"data-mdx-ref": pendingId,
|
|
1286
|
-
"data-mdx-status": "pending",
|
|
1287
|
-
"data-mdx-mode": compileMode
|
|
1288
|
-
},
|
|
1289
|
-
pendingLabel
|
|
1290
|
-
);
|
|
1291
|
-
}
|
|
1292
2470
|
},
|
|
1293
2471
|
// Footnotes block rendered at page end
|
|
1294
2472
|
footnotes: ({ items }) => {
|
|
1295
|
-
if (!items || items.length === 0) return
|
|
1296
|
-
|
|
1297
|
-
(item) =>
|
|
2473
|
+
if (!items || items.length === 0) return React8.createElement(React8.Fragment, null);
|
|
2474
|
+
let listItems = items.map(
|
|
2475
|
+
(item) => React8.createElement(
|
|
1298
2476
|
"li",
|
|
1299
2477
|
{ key: item.number, id: `fn:${item.number}` },
|
|
1300
2478
|
renderInlineNodes(item.inlines, defaultInlineComponents),
|
|
1301
|
-
|
|
1302
|
-
|
|
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
|
+
))
|
|
1303
2495
|
)
|
|
1304
2496
|
);
|
|
1305
|
-
return
|
|
2497
|
+
return React8.createElement("section", { className: "footnotes" }, React8.createElement("hr", {}), React8.createElement("ol", {}, listItems));
|
|
1306
2498
|
},
|
|
1307
2499
|
// Footnote definition placeholders (render nothing)
|
|
1308
|
-
"footnote-def": () =>
|
|
2500
|
+
"footnote-def": () => React8.createElement(React8.Fragment, null),
|
|
1309
2501
|
// Callouts block
|
|
1310
2502
|
callout: ({ kind, inlines = [] }) => {
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
return React4.createElement(
|
|
2503
|
+
let tone = (kind || "NOTE").toUpperCase(), title = tone.charAt(0) + tone.slice(1).toLowerCase();
|
|
2504
|
+
return React8.createElement(
|
|
1314
2505
|
"div",
|
|
1315
2506
|
{ className: `markdown-callout markdown-callout-${tone.toLowerCase()} border rounded p-3 my-3` },
|
|
1316
|
-
|
|
2507
|
+
React8.createElement("div", { className: "font-semibold mb-1" }, title),
|
|
1317
2508
|
inlines.length > 0 ? renderInlineNodes(inlines, defaultInlineComponents) : null
|
|
1318
2509
|
);
|
|
1319
2510
|
},
|
|
@@ -1324,11 +2515,9 @@ var defaultBlockComponents = {
|
|
|
1324
2515
|
align,
|
|
1325
2516
|
elements
|
|
1326
2517
|
}) => {
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
const cellStyle = columnAlign ? { textAlign: columnAlign } : void 0;
|
|
1331
|
-
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(
|
|
1332
2521
|
tag === "th" ? El.Th : El.Td,
|
|
1333
2522
|
{
|
|
1334
2523
|
key: `${rowIdx}-${i}`,
|
|
@@ -1339,54 +2528,228 @@ var defaultBlockComponents = {
|
|
|
1339
2528
|
renderInlineNodes(cell, defaultInlineComponents)
|
|
1340
2529
|
);
|
|
1341
2530
|
});
|
|
1342
|
-
return
|
|
2531
|
+
return React8.createElement(
|
|
1343
2532
|
El.Table,
|
|
1344
2533
|
{ className: "markdown-table" },
|
|
1345
|
-
header && header.length > 0 ?
|
|
1346
|
-
|
|
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(
|
|
1347
2536
|
El.Tbody,
|
|
1348
2537
|
{},
|
|
1349
|
-
rows.map((row, r) =>
|
|
1350
|
-
)
|
|
2538
|
+
rows.map((row, r) => React8.createElement(El.Tr, { key: r }, renderCells(row, "td", r)))
|
|
2539
|
+
) : null
|
|
1351
2540
|
);
|
|
1352
2541
|
}
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
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();
|
|
1357
2549
|
this.inlineComponentMapCache = null;
|
|
1358
|
-
this.
|
|
1359
|
-
this.
|
|
1360
|
-
this.
|
|
1361
|
-
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);
|
|
1362
2557
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
this.
|
|
1368
|
-
this.blockComponentMapCache = null;
|
|
2558
|
+
setLinkSafetyRenderer(renderer) {
|
|
2559
|
+
this.inlineComponents = {
|
|
2560
|
+
...this.inlineComponents,
|
|
2561
|
+
link: renderer ?? defaultInlineComponents.link
|
|
2562
|
+
}, this.inlineComponentMapCache = null;
|
|
1369
2563
|
}
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
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;
|
|
1376
2600
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
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);
|
|
1380
2609
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
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;
|
|
1384
2743
|
}
|
|
1385
2744
|
/**
|
|
1386
2745
|
* Get block component
|
|
1387
2746
|
*/
|
|
1388
2747
|
getBlockComponent(type) {
|
|
1389
|
-
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;
|
|
1390
2753
|
}
|
|
1391
2754
|
/**
|
|
1392
2755
|
* Get inline components
|
|
@@ -1394,112 +2757,309 @@ var ComponentRegistry = class {
|
|
|
1394
2757
|
getInlineComponents() {
|
|
1395
2758
|
return this.inlineComponents;
|
|
1396
2759
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
this.blockComponentMapCache = { ...this.blockComponents };
|
|
1400
|
-
}
|
|
1401
|
-
return this.blockComponentMapCache;
|
|
2760
|
+
getMathEngine() {
|
|
2761
|
+
return this.mathEngine;
|
|
1402
2762
|
}
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
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
|
+
};
|
|
1408
2822
|
}
|
|
1409
2823
|
getTableElements() {
|
|
1410
2824
|
return this.tableElements;
|
|
1411
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
|
+
}
|
|
1412
2852
|
/**
|
|
1413
2853
|
* Render a block
|
|
1414
2854
|
*/
|
|
1415
|
-
renderBlock(block) {
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
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);
|
|
1422
2983
|
}
|
|
1423
2984
|
/**
|
|
1424
2985
|
* Get props for a block based on its type
|
|
1425
2986
|
*/
|
|
1426
|
-
getBlockProps(block) {
|
|
2987
|
+
getBlockProps(block, sourceGuard) {
|
|
2988
|
+
let animCtx = this.getRenderInlineContext(block.isFinalized, block.id, sourceGuard);
|
|
1427
2989
|
switch (block.type) {
|
|
1428
2990
|
case "heading": {
|
|
1429
|
-
|
|
1430
|
-
const inlineNodes = Array.isArray(block.payload.inline) ? block.payload.inline : [];
|
|
1431
|
-
const levelFromMeta = typeof meta.headingLevel === "number" ? meta.headingLevel : void 0;
|
|
1432
|
-
const normalizedLevel = Number.isFinite(levelFromMeta) ? Math.min(Math.max(levelFromMeta, 1), 6) : void 0;
|
|
1433
|
-
const rawHeading = typeof block.payload.raw === "string" ? block.payload.raw : "";
|
|
1434
|
-
const headingText = typeof meta.headingText === "string" && meta.headingText.trim().length > 0 ? meta.headingText : removeHeadingMarkers(rawHeading).trim();
|
|
1435
|
-
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);
|
|
1436
2992
|
return {
|
|
1437
2993
|
level,
|
|
1438
2994
|
inlines: inlineNodes,
|
|
1439
2995
|
text: headingText,
|
|
1440
|
-
meta
|
|
2996
|
+
meta,
|
|
2997
|
+
children: renderedChildren
|
|
1441
2998
|
};
|
|
1442
2999
|
}
|
|
1443
|
-
case "paragraph":
|
|
3000
|
+
case "paragraph": {
|
|
3001
|
+
let segments = block.payload.meta?.mixedSegments;
|
|
1444
3002
|
return {
|
|
1445
3003
|
inlines: block.payload.inline || [],
|
|
1446
3004
|
raw: block.payload.raw,
|
|
1447
|
-
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)
|
|
1448
3018
|
};
|
|
3019
|
+
}
|
|
1449
3020
|
case "blockquote":
|
|
1450
3021
|
return {
|
|
1451
|
-
inlines: block.payload.inline || []
|
|
3022
|
+
inlines: block.payload.inline || [],
|
|
3023
|
+
renderedContent: renderInlineNodes(block.payload.inline || [], this.inlineComponents, this.urlTransform, this, "blockquote", animCtx)
|
|
1452
3024
|
};
|
|
1453
3025
|
case "hr": {
|
|
1454
|
-
|
|
3026
|
+
let range = block.payload.range;
|
|
1455
3027
|
return {
|
|
1456
3028
|
className: "markdown-hr",
|
|
1457
|
-
"data-start": typeof range?.from
|
|
1458
|
-
"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
|
|
1459
3031
|
};
|
|
1460
3032
|
}
|
|
1461
3033
|
case "code":
|
|
1462
3034
|
return {
|
|
1463
3035
|
html: block.payload.highlightedHtml,
|
|
1464
3036
|
meta: block.payload.meta,
|
|
1465
|
-
lang: typeof block.payload.meta?.lang
|
|
3037
|
+
lang: typeof block.payload.meta?.lang == "string" ? String(block.payload.meta?.lang) : void 0
|
|
1466
3038
|
};
|
|
1467
3039
|
case "list": {
|
|
1468
|
-
|
|
3040
|
+
let items = Array.isArray(block.payload.meta?.items) ? block.payload.meta?.items : [];
|
|
1469
3041
|
return {
|
|
1470
|
-
ordered:
|
|
3042
|
+
ordered: !!block.payload.meta?.ordered,
|
|
1471
3043
|
items
|
|
1472
3044
|
};
|
|
1473
3045
|
}
|
|
1474
3046
|
case "html": {
|
|
1475
|
-
|
|
3047
|
+
let isWorkerSanitized = !!(block.payload.sanitizedHtml || block.payload.meta?.sanitized), content = block.payload.sanitizedHtml ?? block.payload.raw ?? "", htmlTree = block.payload.meta?.htmlTree;
|
|
1476
3048
|
return {
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
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
|
|
1481
3054
|
};
|
|
1482
3055
|
}
|
|
1483
3056
|
case "mdx":
|
|
1484
|
-
return
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
const errorMessage = typeof meta?.mdxError === "string" ? String(meta.mdxError) : void 0;
|
|
1489
|
-
const compiledModule = block.payload.compiledMdxModule ?? null;
|
|
1490
|
-
const compiledRef = block.payload.compiledMdxRef ?? (compiledModule ? { id: compiledModule.id } : void 0);
|
|
1491
|
-
return {
|
|
1492
|
-
compiledRef: compiledRef ?? { id: "pending" },
|
|
1493
|
-
compiledModule,
|
|
1494
|
-
status,
|
|
1495
|
-
errorMessage,
|
|
1496
|
-
raw: typeof block.payload.raw === "string" ? block.payload.raw : void 0
|
|
1497
|
-
};
|
|
1498
|
-
})();
|
|
3057
|
+
return {
|
|
3058
|
+
raw: typeof block.payload.raw == "string" ? block.payload.raw : void 0,
|
|
3059
|
+
meta: block.payload.meta
|
|
3060
|
+
};
|
|
1499
3061
|
case "table": {
|
|
1500
|
-
|
|
1501
|
-
const rows = Array.isArray(block.payload.meta?.rows) ? block.payload.meta?.rows : [];
|
|
1502
|
-
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;
|
|
1503
3063
|
return {
|
|
1504
3064
|
header,
|
|
1505
3065
|
rows,
|
|
@@ -1507,17 +3067,14 @@ var ComponentRegistry = class {
|
|
|
1507
3067
|
elements: this.tableElements
|
|
1508
3068
|
};
|
|
1509
3069
|
}
|
|
1510
|
-
case "footnotes":
|
|
1511
|
-
const items = Array.isArray(block.payload.meta?.items) ? block.payload.meta?.items : [];
|
|
3070
|
+
case "footnotes":
|
|
1512
3071
|
return {
|
|
1513
|
-
items
|
|
3072
|
+
items: Array.isArray(block.payload.meta?.items) ? block.payload.meta?.items : []
|
|
1514
3073
|
};
|
|
1515
|
-
}
|
|
1516
3074
|
case "footnote-def":
|
|
1517
3075
|
return {};
|
|
1518
3076
|
case "callout": {
|
|
1519
|
-
|
|
1520
|
-
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 : [];
|
|
1521
3078
|
return {
|
|
1522
3079
|
kind,
|
|
1523
3080
|
inlines: inlineNodes
|
|
@@ -1534,112 +3091,117 @@ var ComponentRegistry = class {
|
|
|
1534
3091
|
* Extract heading level from raw markdown
|
|
1535
3092
|
*/
|
|
1536
3093
|
extractHeadingLevel(raw) {
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
return Math.min(match[1].length, 6);
|
|
1540
|
-
}
|
|
1541
|
-
return 1;
|
|
3094
|
+
let match = raw.match(/^(#{1,6})\s/);
|
|
3095
|
+
return match ? Math.min(match[1].length, 6) : 1;
|
|
1542
3096
|
}
|
|
1543
3097
|
};
|
|
1544
3098
|
function getDefaultHtmlElements() {
|
|
1545
3099
|
return {
|
|
1546
3100
|
// Text semantics
|
|
1547
|
-
p: (props) =>
|
|
1548
|
-
strong: (props) =>
|
|
1549
|
-
em: (props) =>
|
|
1550
|
-
code: (props) =>
|
|
1551
|
-
pre: (props) =>
|
|
1552
|
-
span: (props) =>
|
|
1553
|
-
br: (props) =>
|
|
1554
|
-
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),
|
|
1555
3109
|
// Lists
|
|
1556
|
-
ul: (props) =>
|
|
1557
|
-
ol: (props) =>
|
|
1558
|
-
li: (props) =>
|
|
3110
|
+
ul: (props) => React8.createElement("ul", props),
|
|
3111
|
+
ol: (props) => React8.createElement("ol", props),
|
|
3112
|
+
li: (props) => React8.createElement("li", props),
|
|
1559
3113
|
// Links & media
|
|
1560
|
-
a: (props) =>
|
|
1561
|
-
img: (props) =>
|
|
3114
|
+
a: (props) => React8.createElement("a", props),
|
|
3115
|
+
img: (props) => React8.createElement("img", props),
|
|
1562
3116
|
// Blockquotes
|
|
1563
|
-
blockquote: (props) =>
|
|
3117
|
+
blockquote: (props) => React8.createElement("blockquote", props),
|
|
1564
3118
|
// Tables
|
|
1565
|
-
table: (props) =>
|
|
1566
|
-
thead: (props) =>
|
|
1567
|
-
tbody: (props) =>
|
|
1568
|
-
tr: (props) =>
|
|
1569
|
-
th: (props) =>
|
|
1570
|
-
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),
|
|
1571
3125
|
// Generic
|
|
1572
|
-
div: (props) =>
|
|
3126
|
+
div: (props) => React8.createElement("div", props)
|
|
1573
3127
|
};
|
|
1574
3128
|
}
|
|
1575
3129
|
function getDefaultTableElements(overrides) {
|
|
1576
|
-
|
|
1577
|
-
Table: (props) =>
|
|
1578
|
-
Thead: (props) =>
|
|
1579
|
-
Tbody: (props) =>
|
|
1580
|
-
Tr: (props) =>
|
|
1581
|
-
Th: (props) =>
|
|
1582
|
-
Td: (props) =>
|
|
1583
|
-
};
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
function mapHtmlToReact(html, elements) {
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
doc.body.childNodes.forEach((node, index) => {
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
}
|
|
1595
|
-
});
|
|
1596
|
-
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);
|
|
1597
3148
|
}
|
|
1598
|
-
|
|
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) {
|
|
1599
3151
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
1600
|
-
|
|
1601
|
-
|
|
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);
|
|
1602
3157
|
}
|
|
1603
|
-
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
3158
|
+
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
1604
3159
|
return null;
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
const props = {};
|
|
1609
|
-
for (const attr of Array.from(el.attributes)) {
|
|
1610
|
-
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;
|
|
1611
3163
|
props[name] = attr.value;
|
|
1612
3164
|
}
|
|
1613
|
-
|
|
3165
|
+
if (tag === "textarea")
|
|
3166
|
+
return React8.createElement(elements[tag] ?? tag, { ...props, key, defaultValue: el.textContent ?? "" });
|
|
3167
|
+
let children = [];
|
|
1614
3168
|
el.childNodes.forEach((childNode, childIndex) => {
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
children.push(child);
|
|
1618
|
-
}
|
|
3169
|
+
let child = toReact(childNode, elements, `${key}-${childIndex}`, tag, literalTags, isLiteral, parseMarkdown);
|
|
3170
|
+
child && children.push(child);
|
|
1619
3171
|
});
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
if (component) {
|
|
1623
|
-
return React4.createElement(component, { ...props, key }, elementChildren);
|
|
1624
|
-
}
|
|
1625
|
-
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);
|
|
1626
3174
|
}
|
|
1627
3175
|
function attrsToProps(attrs) {
|
|
1628
3176
|
if (!attrs) return {};
|
|
1629
|
-
|
|
1630
|
-
for (
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
if (
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
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;
|
|
1643
3205
|
}
|
|
1644
3206
|
return result;
|
|
1645
3207
|
}
|
|
@@ -1647,48 +3209,36 @@ function escapeHtml(value) {
|
|
|
1647
3209
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1648
3210
|
}
|
|
1649
3211
|
function parseStyleAttribute2(value) {
|
|
1650
|
-
|
|
3212
|
+
let style = {};
|
|
1651
3213
|
if (!value) return style;
|
|
1652
|
-
|
|
1653
|
-
for (
|
|
3214
|
+
let parts = value.split(";");
|
|
3215
|
+
for (let part of parts) {
|
|
1654
3216
|
if (!part.trim()) continue;
|
|
1655
|
-
|
|
1656
|
-
if (
|
|
1657
|
-
|
|
1658
|
-
|
|
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;
|
|
1659
3223
|
}
|
|
1660
3224
|
return style;
|
|
1661
3225
|
}
|
|
1662
|
-
function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRenderers) {
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
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) => {
|
|
1667
3231
|
nodes.forEach((node, idx) => {
|
|
1668
|
-
if (node
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
target.push(node.key === key ? node : React4.cloneElement(node, { key }));
|
|
1672
|
-
} else if (typeof node === "string" || typeof node === "number") {
|
|
1673
|
-
target.push(React4.createElement(React4.Fragment, { key }, node));
|
|
1674
|
-
} else {
|
|
1675
|
-
target.push(React4.createElement(React4.Fragment, { key }, node));
|
|
1676
|
-
}
|
|
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));
|
|
1677
3235
|
});
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
if (value === null || value === void 0) {
|
|
1681
|
-
return [];
|
|
1682
|
-
}
|
|
1683
|
-
return Array.isArray(value) ? value : [value];
|
|
1684
|
-
};
|
|
1685
|
-
const flushInline = () => {
|
|
1686
|
-
if (inlineBuffer.length === 0) {
|
|
3236
|
+
}, ensureArray = (value) => value == null ? [] : Array.isArray(value) ? value : [value], flushInline = () => {
|
|
3237
|
+
if (inlineBuffer.length === 0)
|
|
1687
3238
|
return;
|
|
1688
|
-
}
|
|
1689
|
-
const key = `paragraph-inline-group-${inlineGroupIndex++}`;
|
|
3239
|
+
let key = `paragraph-inline-group-${inlineGroupIndex++}`;
|
|
1690
3240
|
result.push(
|
|
1691
|
-
|
|
3241
|
+
React8.createElement(
|
|
1692
3242
|
"p",
|
|
1693
3243
|
{
|
|
1694
3244
|
key,
|
|
@@ -1696,109 +3246,90 @@ function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRend
|
|
|
1696
3246
|
},
|
|
1697
3247
|
inlineBuffer
|
|
1698
3248
|
)
|
|
1699
|
-
);
|
|
1700
|
-
inlineBuffer = [];
|
|
3249
|
+
), inlineBuffer = [];
|
|
1701
3250
|
};
|
|
1702
|
-
segments.forEach((segment, index) => {
|
|
1703
|
-
|
|
3251
|
+
return segments.forEach((segment, index) => {
|
|
3252
|
+
let key = `paragraph-segment-${index}`;
|
|
1704
3253
|
switch (segment.kind) {
|
|
1705
3254
|
case "text": {
|
|
1706
|
-
|
|
3255
|
+
let inlineNodes = Array.isArray(segment.inline) ? segment.inline : [];
|
|
1707
3256
|
if (inlineNodes.length === 0) {
|
|
1708
|
-
|
|
1709
|
-
inlineBuffer.push(React4.createElement(React4.Fragment, { key }, segment.value));
|
|
1710
|
-
}
|
|
3257
|
+
segment.value && inlineBuffer.push(React8.createElement(React8.Fragment, { key }, segment.value));
|
|
1711
3258
|
break;
|
|
1712
3259
|
}
|
|
1713
|
-
let chunk = []
|
|
1714
|
-
const pushChunk = (chunkNodes, chunkKey) => {
|
|
3260
|
+
let chunk = [], pushChunk = (chunkNodes, chunkKey) => {
|
|
1715
3261
|
if (chunkNodes.length === 0) return;
|
|
1716
|
-
|
|
3262
|
+
let rendered = renderInlineNodes(chunkNodes, inlineComponents, urlTransform, registry, "p", animationContext);
|
|
1717
3263
|
pushRenderedNodes(ensureArray(rendered), inlineBuffer, chunkKey);
|
|
1718
3264
|
};
|
|
1719
3265
|
inlineNodes.forEach((inlineNode, inlineIdx) => {
|
|
1720
3266
|
if (inlineNode.kind === "math-display") {
|
|
1721
|
-
pushChunk(chunk, `${key}-chunk-${inlineIdx}`);
|
|
1722
|
-
|
|
1723
|
-
flushInline();
|
|
1724
|
-
const rendered = renderInlineNodes([inlineNode], inlineComponents);
|
|
3267
|
+
pushChunk(chunk, `${key}-chunk-${inlineIdx}`), chunk = [], flushInline();
|
|
3268
|
+
let rendered = renderInlineNodes([inlineNode], inlineComponents, urlTransform, registry, "p", animationContext);
|
|
1725
3269
|
pushRenderedNodes(ensureArray(rendered), result, `${key}-math-${inlineIdx}`);
|
|
1726
|
-
} else
|
|
3270
|
+
} else
|
|
1727
3271
|
chunk.push(inlineNode);
|
|
1728
|
-
|
|
1729
|
-
});
|
|
1730
|
-
pushChunk(chunk, `${key}-chunk-tail`);
|
|
3272
|
+
}), pushChunk(chunk, `${key}-chunk-tail`);
|
|
1731
3273
|
break;
|
|
1732
3274
|
}
|
|
1733
3275
|
case "mdx": {
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
if (status === "compiled") {
|
|
1737
|
-
element = React4.createElement("span", { className: "markdown-mdx-inline", "data-mdx-status": "compiled" });
|
|
1738
|
-
} else if (status === "error") {
|
|
1739
|
-
const message = segment.value || "MDX error";
|
|
1740
|
-
element = React4.createElement("span", { className: "markdown-mdx-inline text-destructive", "data-mdx-status": "error" }, message);
|
|
1741
|
-
} else {
|
|
1742
|
-
element = React4.createElement("span", { className: "markdown-mdx-inline", "data-mdx-status": status }, segment.value);
|
|
1743
|
-
}
|
|
1744
|
-
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));
|
|
1745
3278
|
break;
|
|
1746
3279
|
}
|
|
1747
3280
|
case "html": {
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
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, {
|
|
1751
3288
|
key,
|
|
1752
|
-
renderers: inlineHtmlRenderers
|
|
3289
|
+
renderers: inlineHtmlRenderers,
|
|
3290
|
+
htmlElements,
|
|
3291
|
+
literalTagContent,
|
|
3292
|
+
urlTransform,
|
|
3293
|
+
parseMarkdown
|
|
1753
3294
|
});
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
} else if (element) {
|
|
1768
|
-
inlineBuffer.push(element);
|
|
1769
|
-
}
|
|
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
|
+
);
|
|
1770
3308
|
break;
|
|
1771
3309
|
}
|
|
1772
3310
|
default:
|
|
1773
3311
|
break;
|
|
1774
3312
|
}
|
|
1775
|
-
})
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
"
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
inlineBuffer
|
|
1786
|
-
)
|
|
1787
|
-
];
|
|
1788
|
-
}
|
|
1789
|
-
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;
|
|
1790
3323
|
}
|
|
1791
3324
|
function isBlockLevelHtml(html) {
|
|
1792
|
-
if (!html) return
|
|
1793
|
-
|
|
1794
|
-
if (!trimmed.startsWith("<"))
|
|
1795
|
-
return
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
}
|
|
1801
|
-
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();
|
|
1802
3333
|
return BLOCK_LEVEL_TAGS.has(tag);
|
|
1803
3334
|
}
|
|
1804
3335
|
var BLOCK_LEVEL_TAGS = /* @__PURE__ */ new Set([
|
|
@@ -1834,11 +3365,45 @@ var BLOCK_LEVEL_TAGS = /* @__PURE__ */ new Set([
|
|
|
1834
3365
|
"math"
|
|
1835
3366
|
]);
|
|
1836
3367
|
export {
|
|
3368
|
+
AnimationTimeline,
|
|
3369
|
+
BottomStickScrollArea,
|
|
3370
|
+
CodeBlockCopyButton,
|
|
3371
|
+
CodeBlockDownloadButton,
|
|
3372
|
+
CodeControlsBar,
|
|
1837
3373
|
ComponentRegistry,
|
|
3374
|
+
DEFAULT_ANIMATED_OPTIONS,
|
|
3375
|
+
DEFAULT_CONTROLS_LABELS,
|
|
3376
|
+
DefaultDiffRenderer,
|
|
1838
3377
|
DefaultLinkSafetyModal,
|
|
1839
|
-
|
|
3378
|
+
DocumentMathMacroScope,
|
|
3379
|
+
DocumentMathMacroScopeContext,
|
|
3380
|
+
KaTeXBlockMath,
|
|
3381
|
+
KaTeXInlineMath,
|
|
3382
|
+
LANGUAGE_EXTENSION_MAP,
|
|
3383
|
+
MathExpressionCompletenessContext,
|
|
3384
|
+
STREAM_MDX_ANIMATION_CSS,
|
|
3385
|
+
TableControlsBar,
|
|
3386
|
+
copyToClipboard,
|
|
1840
3387
|
defaultInlineComponents,
|
|
3388
|
+
defaultUrlTransform3 as defaultUrlTransform,
|
|
3389
|
+
downloadFile,
|
|
3390
|
+
escapeCsvCell,
|
|
3391
|
+
escapeTsvCell,
|
|
3392
|
+
getCodeSnippetFilename,
|
|
3393
|
+
getExtensionForLanguage,
|
|
3394
|
+
inlineToPlainText,
|
|
3395
|
+
loadKaTeX,
|
|
1841
3396
|
mapHtmlToReact,
|
|
1842
3397
|
renderInlineNodes,
|
|
1843
|
-
renderParagraphMixedSegments
|
|
3398
|
+
renderParagraphMixedSegments,
|
|
3399
|
+
resolveAnimatedOptions,
|
|
3400
|
+
resolveCodeControls,
|
|
3401
|
+
resolveControlsConfig,
|
|
3402
|
+
resolveMermaidControls,
|
|
3403
|
+
resolveTableControls,
|
|
3404
|
+
splitTextSegments,
|
|
3405
|
+
splitWordSegments,
|
|
3406
|
+
tableToCsv,
|
|
3407
|
+
tableToMarkdown,
|
|
3408
|
+
tableToTsv
|
|
1844
3409
|
};
|