markdown-flow-ui 0.1.83-beta.10 → 0.1.83-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/@braintree_sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-input@1.8.0_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-input/es/BaseInput.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/ResizableTextArea.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/TextArea.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/index.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/index.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/remark-custom-variable.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/remark-interaction.js +1 -1
- package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/style-to-object@1.0.11/node_modules/style-to-object/cjs/index.js +1 -1
- package/dist/_virtual/index10.js +2 -2
- package/dist/_virtual/index2.js +5 -2
- package/dist/_virtual/index2.js.map +1 -1
- package/dist/_virtual/index3.js +2 -4
- package/dist/_virtual/index3.js.map +1 -1
- package/dist/_virtual/index4.js +4 -5
- package/dist/_virtual/index4.js.map +1 -1
- package/dist/_virtual/index7.js +2 -2
- package/dist/components/ContentRender/ContentRender.js +35 -32
- package/dist/components/ContentRender/ContentRender.js.map +1 -1
- package/dist/components/ContentRender/IframeSandbox.js +31 -30
- package/dist/components/ContentRender/IframeSandbox.js.map +1 -1
- package/dist/components/ui/inputGroup/textarea.js +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import $ from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/hel
|
|
|
2
2
|
import oe from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/extends.js";
|
|
3
3
|
import r from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/defineProperty.js";
|
|
4
4
|
import te from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/typeof.js";
|
|
5
|
-
import d from "../../../../../../../../../_virtual/
|
|
5
|
+
import d from "../../../../../../../../../_virtual/index2.js";
|
|
6
6
|
import l, { useRef as q, cloneElement as ie } from "react";
|
|
7
7
|
import { hasPrefixSuffix as re, hasAddon as de } from "./utils/commonUtils.js";
|
|
8
8
|
var xe = /* @__PURE__ */ l.forwardRef(function(e, z) {
|
|
@@ -4,7 +4,7 @@ import w from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/hel
|
|
|
4
4
|
import J from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/typeof.js";
|
|
5
5
|
import s from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/slicedToArray.js";
|
|
6
6
|
import K from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js";
|
|
7
|
-
import Q from "../../../../../../../../../_virtual/
|
|
7
|
+
import Q from "../../../../../../../../../_virtual/index2.js";
|
|
8
8
|
import ee from "../../../../rc-resize-observer@1.4.3_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-resize-observer/es/index.js";
|
|
9
9
|
import M from "../../../../rc-util@5.44.4_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-util/es/hooks/useLayoutEffect.js";
|
|
10
10
|
import te from "../../../../rc-util@5.44.4_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-util/es/hooks/useMergedState.js";
|
|
@@ -4,7 +4,7 @@ import d from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/hel
|
|
|
4
4
|
import Ae from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js";
|
|
5
5
|
import x from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/slicedToArray.js";
|
|
6
6
|
import Fe from "../../../../@babel_runtime@7.28.4/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js";
|
|
7
|
-
import h from "../../../../../../../../../_virtual/
|
|
7
|
+
import h from "../../../../../../../../../_virtual/index2.js";
|
|
8
8
|
import Ne from "../../../../rc-input@1.8.0_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-input/es/BaseInput.js";
|
|
9
9
|
import Te from "../../../../rc-util@5.44.4_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-util/es/hooks/useMergedState.js";
|
|
10
10
|
import o, { useRef as Y, useImperativeHandle as $e, useEffect as Ie } from "react";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import t from "./TextArea.js";
|
|
2
|
-
import "../../../../../../../../../_virtual/
|
|
2
|
+
import "../../../../../../../../../_virtual/index2.js";
|
|
3
3
|
import "../../../../rc-resize-observer@1.4.3_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-resize-observer/es/index.js";
|
|
4
4
|
import "../../../../rc-util@5.44.4_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-util/es/hooks/useLayoutEffect.js";
|
|
5
5
|
import "react";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as e } from "../../../../../../../../../_virtual/
|
|
1
|
+
import { __exports as e } from "../../../../../../../../../_virtual/index3.js";
|
|
2
2
|
import { __require as _ } from "./remark-custom-variable.js";
|
|
3
3
|
import { __require as m } from "./remark-flow.js";
|
|
4
4
|
import { __require as f } from "./remark-interaction.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __exports as a } from "../../../../../../../../../_virtual/remark-custom-variable.js";
|
|
2
|
-
import g from "../../../../../../../../../_virtual/
|
|
2
|
+
import g from "../../../../../../../../../_virtual/index4.js";
|
|
3
3
|
import { __require as h } from "./interaction-parser.js";
|
|
4
4
|
var m;
|
|
5
5
|
function C() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __exports as n } from "../../../../../../../../../_virtual/remark-interaction.js";
|
|
2
|
-
import I from "../../../../../../../../../_virtual/
|
|
2
|
+
import I from "../../../../../../../../../_virtual/index4.js";
|
|
3
3
|
import { __require as g } from "./interaction-parser.js";
|
|
4
4
|
var m;
|
|
5
5
|
function k() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as r } from "../../../../../../../../../_virtual/
|
|
1
|
+
import { __exports as r } from "../../../../../../../../../_virtual/index9.js";
|
|
2
2
|
import { __require as p } from "../../../../inline-style-parser@0.2.4/node_modules/inline-style-parser/index.js";
|
|
3
3
|
var f;
|
|
4
4
|
function q() {
|
package/dist/_virtual/index10.js
CHANGED
package/dist/_virtual/index2.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { getDefaultExportFromCjs as r } from "./_commonjsHelpers.js";
|
|
2
|
+
import { __require as s } from "../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.js";
|
|
3
|
+
var e = s();
|
|
4
|
+
const t = /* @__PURE__ */ r(e);
|
|
2
5
|
export {
|
|
3
|
-
|
|
6
|
+
t as default
|
|
4
7
|
};
|
|
5
8
|
//# sourceMappingURL=index2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index2.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
package/dist/_virtual/index3.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import * as r from "../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unist-util-visit@5.0.0/node_modules/unist-util-visit/index.js";
|
|
3
|
-
const m = /* @__PURE__ */ e(r);
|
|
1
|
+
var r = {};
|
|
4
2
|
export {
|
|
5
|
-
|
|
3
|
+
r as __exports
|
|
6
4
|
};
|
|
7
5
|
//# sourceMappingURL=index3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index3.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
package/dist/_virtual/index4.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
const t = /* @__PURE__ */ r(e);
|
|
1
|
+
import { getAugmentedNamespace as e } from "./_commonjsHelpers.js";
|
|
2
|
+
import * as r from "../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unist-util-visit@5.0.0/node_modules/unist-util-visit/index.js";
|
|
3
|
+
const m = /* @__PURE__ */ e(r);
|
|
5
4
|
export {
|
|
6
|
-
|
|
5
|
+
m as default
|
|
7
6
|
};
|
|
8
7
|
//# sourceMappingURL=index4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
package/dist/_virtual/index7.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { j as t } from "../../_virtual/jsx-runtime.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
/* empty css */
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import U, { useMemo as L, useRef as V, useEffect as A } from "react";
|
|
5
|
+
import W from "../../_virtual/index.js";
|
|
6
6
|
/* empty css */
|
|
7
7
|
/* empty css */
|
|
8
|
-
import
|
|
8
|
+
import q from "./CodeBlock.js";
|
|
9
9
|
import G from "./plugins/CustomVariable.js";
|
|
10
10
|
import z from "./plugins/MermaidChart.js";
|
|
11
11
|
import K from "./useTypewriterStateMachine.js";
|
|
@@ -24,7 +24,7 @@ import oe from "../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rem
|
|
|
24
24
|
import ae from "../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-breaks@4.0.0/node_modules/remark-breaks/lib/index.js";
|
|
25
25
|
const ie = ({ svg: s }) => {
|
|
26
26
|
const c = V(null);
|
|
27
|
-
return
|
|
27
|
+
return A(() => {
|
|
28
28
|
const o = c.current;
|
|
29
29
|
if (!o) return;
|
|
30
30
|
const a = o.shadowRoot ?? o.attachShadow({ mode: "open" }), f = "content-render-svg-style";
|
|
@@ -44,17 +44,17 @@ const ie = ({ svg: s }) => {
|
|
|
44
44
|
if (!b) return;
|
|
45
45
|
const u = b.trim().split(/[\s,]+/).map((w) => Number(w));
|
|
46
46
|
if (u.length !== 4 || u.some(Number.isNaN)) return;
|
|
47
|
-
const [, , h,
|
|
47
|
+
const [, , h, m] = u, j = r.getAttribute("width"), y = r.getAttribute("height"), N = !!j && j !== "0", k = !!y && y !== "0";
|
|
48
48
|
if (!N && !k) {
|
|
49
|
-
g = !0, r.classList.add("content-render-svg-el--responsive"), r.classList.remove("content-render-svg-el--fixed"), r.style.width = "100%", r.style.height = "auto", !r.style.aspectRatio &&
|
|
49
|
+
g = !0, r.classList.add("content-render-svg-el--responsive"), r.classList.remove("content-render-svg-el--fixed"), r.style.width = "100%", r.style.height = "auto", !r.style.aspectRatio && m > 0 && (r.style.aspectRatio = `${h} / ${m}`);
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
|
-
d = !0, r.classList.add("content-render-svg-el--fixed"), r.classList.remove("content-render-svg-el--responsive"), !N && h > 0 && r.setAttribute("width", `${h}`), !k &&
|
|
52
|
+
d = !0, r.classList.add("content-render-svg-el--fixed"), r.classList.remove("content-render-svg-el--responsive"), !N && h > 0 && r.setAttribute("width", `${h}`), !k && m > 0 && r.setAttribute("height", `${m}`);
|
|
53
53
|
});
|
|
54
54
|
const v = g && !d;
|
|
55
55
|
o.classList.toggle("content-render-svg--responsive", v), o.classList.toggle("content-render-svg--fixed", !v);
|
|
56
56
|
}, [s]), /* @__PURE__ */ t.jsx("div", { className: "content-render-svg-scroll", children: /* @__PURE__ */ t.jsx("div", { className: "content-render-svg", ref: c }) });
|
|
57
|
-
}, ce = [se, oe,
|
|
57
|
+
}, ce = [se, oe, W, ae], le = [
|
|
58
58
|
D,
|
|
59
59
|
te,
|
|
60
60
|
J,
|
|
@@ -64,7 +64,7 @@ const ie = ({ svg: s }) => {
|
|
|
64
64
|
ee,
|
|
65
65
|
{
|
|
66
66
|
remarkPlugins: ce,
|
|
67
|
-
rehypePlugins:
|
|
67
|
+
rehypePlugins: le,
|
|
68
68
|
components: c,
|
|
69
69
|
children: s
|
|
70
70
|
}
|
|
@@ -75,7 +75,7 @@ const ie = ({ svg: s }) => {
|
|
|
75
75
|
typingSpeed: a = 30,
|
|
76
76
|
enableTypewriter: f = !1,
|
|
77
77
|
defaultButtonText: i,
|
|
78
|
-
defaultInputText:
|
|
78
|
+
defaultInputText: B,
|
|
79
79
|
defaultSelectedValues: x,
|
|
80
80
|
readonly: g = !1,
|
|
81
81
|
onTypeFinished: d,
|
|
@@ -84,14 +84,14 @@ const ie = ({ svg: s }) => {
|
|
|
84
84
|
copiedButtonText: b,
|
|
85
85
|
sandboxLoadingText: u,
|
|
86
86
|
sandboxStyleLoadingText: h,
|
|
87
|
-
sandboxScriptLoadingText:
|
|
87
|
+
sandboxScriptLoadingText: m,
|
|
88
88
|
sandboxFullscreenButtonText: j,
|
|
89
89
|
sandboxMode: y = "content",
|
|
90
90
|
onClickCustomButtonAfterContent: N,
|
|
91
91
|
beforeSend: k
|
|
92
92
|
// tooltipMinLength,
|
|
93
93
|
}) => {
|
|
94
|
-
const
|
|
94
|
+
const I = L(
|
|
95
95
|
() => H(s),
|
|
96
96
|
[s]
|
|
97
97
|
), w = {
|
|
@@ -111,7 +111,7 @@ const ie = ({ svg: s }) => {
|
|
|
111
111
|
...e,
|
|
112
112
|
readonly: g,
|
|
113
113
|
defaultButtonText: i,
|
|
114
|
-
defaultInputText:
|
|
114
|
+
defaultInputText: B,
|
|
115
115
|
defaultSelectedValues: x,
|
|
116
116
|
onSend: o,
|
|
117
117
|
beforeSend: k,
|
|
@@ -119,20 +119,20 @@ const ie = ({ svg: s }) => {
|
|
|
119
119
|
}
|
|
120
120
|
),
|
|
121
121
|
code: (e) => {
|
|
122
|
-
const { className: n, children:
|
|
122
|
+
const { className: n, children: l, ...M } = e;
|
|
123
123
|
if (/language-(\w+)/.exec(n || "")?.[1] === "mermaid") {
|
|
124
|
-
const $ =
|
|
125
|
-
return /* @__PURE__ */ t.jsx(z, { chart: $, frozen:
|
|
124
|
+
const $ = l?.toString().replace(/\n$/, "") || "", F = Y(s, $);
|
|
125
|
+
return /* @__PURE__ */ t.jsx(z, { chart: $, frozen: F });
|
|
126
126
|
}
|
|
127
|
-
return /* @__PURE__ */ t.jsx("code", { className: n, ...M, children:
|
|
127
|
+
return /* @__PURE__ */ t.jsx("code", { className: n, ...M, children: l });
|
|
128
128
|
},
|
|
129
129
|
table: ({ ...e }) => /* @__PURE__ */ t.jsx("div", { className: "content-render-table-container", children: /* @__PURE__ */ t.jsx("table", { className: "content-render-table", ...e }) }),
|
|
130
130
|
th: ({ ...e }) => /* @__PURE__ */ t.jsx("th", { className: "content-render-th", ...e }),
|
|
131
131
|
td: ({ ...e }) => /* @__PURE__ */ t.jsx("td", { className: "content-render-td", ...e }),
|
|
132
132
|
tr: ({ ...e }) => /* @__PURE__ */ t.jsx("tr", { className: "content-render-tr", ...e }),
|
|
133
133
|
li: ({ node: e, ...n }) => {
|
|
134
|
-
const
|
|
135
|
-
return typeof
|
|
134
|
+
const l = e?.properties?.className;
|
|
135
|
+
return typeof l == "string" && l.includes("task-list-item") || Array.isArray(l) && l.includes("task-list-item") ? /* @__PURE__ */ t.jsx("li", { className: "content-render-task-list-item", ...n }) : /* @__PURE__ */ t.jsx("li", { ...n });
|
|
136
136
|
},
|
|
137
137
|
ol: ({ ...e }) => /* @__PURE__ */ t.jsx("ol", { className: "content-render-ol", ...e }),
|
|
138
138
|
ul: ({ ...e }) => /* @__PURE__ */ t.jsx("ul", { className: "content-render-ul", ...e }),
|
|
@@ -147,41 +147,44 @@ const ie = ({ svg: s }) => {
|
|
|
147
147
|
) : /* @__PURE__ */ t.jsx("input", { ...e }),
|
|
148
148
|
a: ({ children: e, ...n }) => /* @__PURE__ */ t.jsx("a", { target: "_blank", rel: "noopener noreferrer", ...n, children: e }),
|
|
149
149
|
pre: (e) => /* @__PURE__ */ t.jsx(
|
|
150
|
-
|
|
150
|
+
q,
|
|
151
151
|
{
|
|
152
152
|
...e,
|
|
153
153
|
copyButtonText: r,
|
|
154
154
|
copiedButtonText: b
|
|
155
155
|
}
|
|
156
156
|
)
|
|
157
|
-
}, { displayContent: C, isComplete:
|
|
157
|
+
}, { displayContent: C, isComplete: T } = K({
|
|
158
158
|
// processMarkdownText will let code block printf("You win!\n") become printf("You win!<br/>");
|
|
159
159
|
// content: processMarkdownText(content),
|
|
160
|
-
content:
|
|
160
|
+
content: I,
|
|
161
161
|
typingSpeed: a,
|
|
162
162
|
disabled: !f
|
|
163
|
-
}),
|
|
164
|
-
() => E(s),
|
|
163
|
+
}), S = L(
|
|
164
|
+
() => E(s, !0),
|
|
165
165
|
[s]
|
|
166
|
-
)
|
|
166
|
+
);
|
|
167
|
+
console.log("renderSegments=====", s, S);
|
|
168
|
+
const p = S.some(
|
|
167
169
|
(e) => e.type === "sandbox"
|
|
168
|
-
), _ =
|
|
170
|
+
), _ = L(
|
|
169
171
|
() => X(C),
|
|
170
172
|
[C]
|
|
171
173
|
), R = V(!1);
|
|
172
|
-
return
|
|
173
|
-
p ||
|
|
174
|
-
}, [p,
|
|
174
|
+
return A(() => {
|
|
175
|
+
p || T && !R.current && (R.current = !0, d?.());
|
|
176
|
+
}, [p, T, d]), A(() => {
|
|
175
177
|
p || (R.current = !1);
|
|
176
|
-
}, [p, s]), p ? /* @__PURE__ */ t.jsx("div", { className: "content-render markdown-body", children:
|
|
178
|
+
}, [p, s]), p ? /* @__PURE__ */ t.jsx("div", { className: "content-render markdown-body", children: S.map(
|
|
177
179
|
(e, n) => e.type === "sandbox" ? /* @__PURE__ */ t.jsx(
|
|
178
180
|
Z,
|
|
179
181
|
{
|
|
182
|
+
hideFullScreen: !0,
|
|
180
183
|
content: e.value,
|
|
181
184
|
className: "content-render-iframe",
|
|
182
185
|
loadingText: u,
|
|
183
186
|
styleLoadingText: h,
|
|
184
|
-
scriptLoadingText:
|
|
187
|
+
scriptLoadingText: m,
|
|
185
188
|
fullScreenButtonText: j,
|
|
186
189
|
mode: y
|
|
187
190
|
},
|
|
@@ -217,7 +220,7 @@ const ie = ({ svg: s }) => {
|
|
|
217
220
|
if (e.type === "svg")
|
|
218
221
|
return /* @__PURE__ */ t.jsx(ie, { svg: e.value }, n);
|
|
219
222
|
}),
|
|
220
|
-
c && /* @__PURE__ */ t.jsx("div", { className: "content-render-custom-bar", children:
|
|
223
|
+
c && /* @__PURE__ */ t.jsx("div", { className: "content-render-custom-bar", children: U.createElement(c, {
|
|
221
224
|
content: s,
|
|
222
225
|
displayContent: C,
|
|
223
226
|
onSend: o
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentRender.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport useTypewriterStateMachine from \"./useTypewriterStateMachine\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport { splitContentSegments } from \"./utils/split-content\";\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n /**\n+ * Callback invoked when the custom button after content is clicked.\n+ * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n+ * @example\n+ * ```tsx\n+ * <ContentRender\n+ * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n+ * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n+ * />\n+ * ```\n+ */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n onTypeFinished?: () => void;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n template.innerHTML = svg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const hasWidth = !!widthAttr && widthAttr !== \"0\";\n const hasHeight = !!heightAttr && heightAttr !== \"0\";\n const shouldUseResponsiveSize = !hasWidth && !hasHeight;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (!hasWidth && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (!hasHeight && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins = [remarkGfm, remarkMath, remarkFlow, remarkBreaks];\n\nconst rehypePlugins = [\n preserveCustomVariableProperties,\n rehypeRaw,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n customRenderBar,\n onSend,\n typingSpeed = 30,\n enableTypewriter = false,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n onTypeFinished,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n sandboxFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(content),\n [content]\n );\n\n // Use custom Hook to handle typewriter effect\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={defaultButtonText}\n defaultInputText={defaultInputText}\n defaultSelectedValues={defaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n confirmButtonText={confirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(content, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n />\n ),\n };\n\n const { displayContent, isComplete } = useTypewriterStateMachine({\n // processMarkdownText will let code block printf(\"You win!\\n\") become printf(\"You win!<br/>\");\n // content: processMarkdownText(content),\n content: normalizedContent,\n typingSpeed,\n disabled: !enableTypewriter,\n });\n\n const renderSegments = useMemo(\n () => splitContentSegments(content),\n [content]\n );\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(displayContent),\n [displayContent]\n );\n\n const hasCompleted = useRef(false);\n\n useEffect(() => {\n if (hasSandbox) return;\n if (isComplete && !hasCompleted.current) {\n hasCompleted.current = true; // Mark as completed\n onTypeFinished?.(); // Call the passed callback\n }\n }, [hasSandbox, isComplete, onTypeFinished]);\n\n useEffect(() => {\n if (hasSandbox) return;\n hasCompleted.current = false; // Reset completion status when content changes\n }, [hasSandbox, content]);\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {renderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n content={segment.value}\n className=\"content-render-iframe\"\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n fullScreenButtonText={sandboxFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <MarkdownRenderer\n key={`md-${idx}`}\n components={components}\n content={normalizeInlineHtml(segment.value)}\n />\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","hasWidth","hasHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","ContentRender","content","customRenderBar","onSend","typingSpeed","enableTypewriter","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","onTypeFinished","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","sandboxFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","normalizedContent","useMemo","normalizeInlineHtml","children","props","CustomButtonInputVariable","className","rest","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","displayContent","isComplete","useTypewriterStateMachine","renderSegments","splitContentSegments","hasSandbox","segment","segments","parseMarkdownSegments","hasCompleted","idx","IframeSandbox","jsxs","seg","index","React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ContentRender.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport useTypewriterStateMachine from \"./useTypewriterStateMachine\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport { splitContentSegments } from \"./utils/split-content\";\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n /**\n+ * Callback invoked when the custom button after content is clicked.\n+ * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n+ * @example\n+ * ```tsx\n+ * <ContentRender\n+ * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n+ * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n+ * />\n+ * ```\n+ */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n onTypeFinished?: () => void;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n template.innerHTML = svg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const hasWidth = !!widthAttr && widthAttr !== \"0\";\n const hasHeight = !!heightAttr && heightAttr !== \"0\";\n const shouldUseResponsiveSize = !hasWidth && !hasHeight;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (!hasWidth && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (!hasHeight && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins = [remarkGfm, remarkMath, remarkFlow, remarkBreaks];\n\nconst rehypePlugins = [\n preserveCustomVariableProperties,\n rehypeRaw,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n customRenderBar,\n onSend,\n typingSpeed = 30,\n enableTypewriter = false,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n onTypeFinished,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n sandboxFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(content),\n [content]\n );\n\n // Use custom Hook to handle typewriter effect\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={defaultButtonText}\n defaultInputText={defaultInputText}\n defaultSelectedValues={defaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n confirmButtonText={confirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(content, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n />\n ),\n };\n\n const { displayContent, isComplete } = useTypewriterStateMachine({\n // processMarkdownText will let code block printf(\"You win!\\n\") become printf(\"You win!<br/>\");\n // content: processMarkdownText(content),\n content: normalizedContent,\n typingSpeed,\n disabled: !enableTypewriter,\n });\n\n const renderSegments = useMemo(\n () => splitContentSegments(content, true),\n [content]\n );\n console.log(\"renderSegments=====\", content, renderSegments);\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(displayContent),\n [displayContent]\n );\n\n const hasCompleted = useRef(false);\n\n useEffect(() => {\n if (hasSandbox) return;\n if (isComplete && !hasCompleted.current) {\n hasCompleted.current = true; // Mark as completed\n onTypeFinished?.(); // Call the passed callback\n }\n }, [hasSandbox, isComplete, onTypeFinished]);\n\n useEffect(() => {\n if (hasSandbox) return;\n hasCompleted.current = false; // Reset completion status when content changes\n }, [hasSandbox, content]);\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {renderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n content={segment.value}\n className=\"content-render-iframe\"\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n fullScreenButtonText={sandboxFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <MarkdownRenderer\n key={`md-${idx}`}\n components={components}\n content={normalizeInlineHtml(segment.value)}\n />\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","hasWidth","hasHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","ContentRender","content","customRenderBar","onSend","typingSpeed","enableTypewriter","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","onTypeFinished","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","sandboxFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","normalizedContent","useMemo","normalizeInlineHtml","children","props","CustomButtonInputVariable","className","rest","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","displayContent","isComplete","useTypewriterStateMachine","renderSegments","splitContentSegments","hasSandbox","segment","segments","parseMarkdownSegments","hasCompleted","idx","IframeSandbox","jsxs","seg","index","React"],"mappings":"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"}
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import { j as l } from "../../_virtual/jsx-runtime.js";
|
|
2
|
-
import
|
|
3
|
-
import { createRoot as
|
|
4
|
-
import
|
|
5
|
-
import { splitContentSegments as
|
|
6
|
-
import
|
|
2
|
+
import D, { useRef as c, useState as p, useEffect as a } from "react";
|
|
3
|
+
import { createRoot as _ } from "react-dom/client";
|
|
4
|
+
import P from "./SandboxApp.js";
|
|
5
|
+
import { splitContentSegments as W } from "./utils/split-content.js";
|
|
6
|
+
import Y from "./ContentRender.js";
|
|
7
7
|
const V = ({
|
|
8
8
|
content: u,
|
|
9
9
|
type: j,
|
|
10
|
-
className:
|
|
10
|
+
className: $,
|
|
11
11
|
loadingText: v,
|
|
12
12
|
styleLoadingText: x,
|
|
13
13
|
scriptLoadingText: R,
|
|
14
14
|
fullScreenButtonText: m,
|
|
15
15
|
hideFullScreen: y = !1,
|
|
16
|
-
mode:
|
|
16
|
+
mode: r = "content"
|
|
17
17
|
}) => {
|
|
18
|
-
const C =
|
|
19
|
-
}), [,
|
|
20
|
-
const t =
|
|
21
|
-
return (
|
|
18
|
+
const C = c(null), i = c(null), f = c(null), w = c(null), d = c(() => {
|
|
19
|
+
}), [k, F] = p(480), [E, H] = p(0), [M, N] = p(!1), h = c(""), o = D.useMemo(() => {
|
|
20
|
+
const t = W(u).filter((s) => s.type === "sandbox");
|
|
21
|
+
return (r === "blackboard" ? t[t.length - 1]?.value || "" : t.map((s) => s.value).join(`
|
|
22
22
|
`)) || "";
|
|
23
|
-
}, [u,
|
|
23
|
+
}, [u, r]);
|
|
24
24
|
a(() => {
|
|
25
|
-
if (
|
|
26
|
-
h.current =
|
|
25
|
+
if (r !== "blackboard") {
|
|
26
|
+
h.current = o;
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
const e = h.current;
|
|
30
|
-
!(e &&
|
|
31
|
-
}, [
|
|
30
|
+
!(e && o.startsWith(e)) && e && H((n) => n + 1), h.current = o;
|
|
31
|
+
}, [o, r]), a(() => {
|
|
32
32
|
const e = i.current;
|
|
33
33
|
if (!e) return;
|
|
34
34
|
const t = e.contentDocument;
|
|
@@ -47,28 +47,28 @@ const V = ({
|
|
|
47
47
|
</html>`), t.close(), w.current = t;
|
|
48
48
|
const n = t.getElementById("root");
|
|
49
49
|
if (!n) return;
|
|
50
|
-
const
|
|
51
|
-
f.current =
|
|
50
|
+
const s = _(n);
|
|
51
|
+
f.current = s;
|
|
52
52
|
const b = () => {
|
|
53
53
|
if (!i.current || !t.body) return;
|
|
54
|
-
const
|
|
55
|
-
|
|
54
|
+
const z = t.body.getBoundingClientRect(), I = t.documentElement?.getBoundingClientRect(), O = z.height, S = I?.height || 0, A = Math.max(O, S), B = Math.max(200, Math.ceil(A));
|
|
55
|
+
F(B);
|
|
56
56
|
};
|
|
57
57
|
d.current = b, b();
|
|
58
58
|
const g = new ResizeObserver(() => b());
|
|
59
59
|
return g.observe(t.body), n && g.observe(n), () => {
|
|
60
60
|
g.disconnect(), setTimeout(() => {
|
|
61
|
-
|
|
61
|
+
s.unmount(), f.current = null, w.current = null, d.current = () => {
|
|
62
62
|
};
|
|
63
63
|
}, 0);
|
|
64
64
|
};
|
|
65
65
|
}, []), a(() => {
|
|
66
66
|
const e = () => {
|
|
67
|
-
|
|
67
|
+
N(!!document.fullscreenElement);
|
|
68
68
|
};
|
|
69
69
|
return document.addEventListener("fullscreenchange", e), () => document.removeEventListener("fullscreenchange", e);
|
|
70
70
|
}, []);
|
|
71
|
-
const
|
|
71
|
+
const q = () => {
|
|
72
72
|
const e = C.current || i.current;
|
|
73
73
|
if (e) {
|
|
74
74
|
if (document.fullscreenElement) {
|
|
@@ -84,9 +84,9 @@ const V = ({
|
|
|
84
84
|
const e = f.current;
|
|
85
85
|
e && (e.render(
|
|
86
86
|
/* @__PURE__ */ l.jsx(
|
|
87
|
-
|
|
87
|
+
P,
|
|
88
88
|
{
|
|
89
|
-
html:
|
|
89
|
+
html: o,
|
|
90
90
|
loadingText: v,
|
|
91
91
|
styleLoadingText: x,
|
|
92
92
|
scriptLoadingText: R,
|
|
@@ -98,7 +98,7 @@ const V = ({
|
|
|
98
98
|
), requestAnimationFrame(() => d.current?.()));
|
|
99
99
|
}, [
|
|
100
100
|
u,
|
|
101
|
-
|
|
101
|
+
o,
|
|
102
102
|
v,
|
|
103
103
|
x,
|
|
104
104
|
R,
|
|
@@ -114,20 +114,21 @@ const V = ({
|
|
|
114
114
|
"button",
|
|
115
115
|
{
|
|
116
116
|
type: "button",
|
|
117
|
-
onClick:
|
|
117
|
+
onClick: q,
|
|
118
118
|
className: "absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",
|
|
119
|
-
children:
|
|
119
|
+
children: M ? "退出全屏" : m || "全屏浏览"
|
|
120
120
|
}
|
|
121
121
|
),
|
|
122
|
-
|
|
122
|
+
r === "blackboard" && j === "markdown" ? /* @__PURE__ */ l.jsx(Y, { content: u }) : /* @__PURE__ */ l.jsx(
|
|
123
123
|
"iframe",
|
|
124
124
|
{
|
|
125
125
|
ref: i,
|
|
126
126
|
sandbox: "allow-scripts allow-same-origin",
|
|
127
127
|
allow: "fullscreen",
|
|
128
128
|
allowFullScreen: !0,
|
|
129
|
-
className: "w-full
|
|
129
|
+
className: "w-full",
|
|
130
130
|
style: {
|
|
131
|
+
height: r === "blackboard" ? "100%" : `${k}px`
|
|
131
132
|
// height: `${height}px`,
|
|
132
133
|
// margin: "16px 0",
|
|
133
134
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IframeSandbox.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport SandboxApp from \"./SandboxApp\";\nimport { splitContentSegments } from \"./utils/split-content\";\nimport ContentRender from \"./ContentRender\";\nexport interface IframeSandboxProps {\n content: string;\n className?: string;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n fullScreenButtonText?: string;\n hideFullScreen?: boolean;\n mode?: \"content\" | \"blackboard\";\n type: \"sandbox\" | \"markdown\";\n}\n\nconst IframeSandbox: React.FC<IframeSandboxProps> = ({\n content,\n type,\n className,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n hideFullScreen = false,\n mode = \"content\",\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const rootRef = useRef<Root | null>(null);\n const docRef = useRef<Document | null>(null);\n const updateHeightRef = useRef<() => void>(() => {});\n const [, setHeight] = useState(480);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const prevHtmlRef = useRef<string>(\"\");\n const htmlContent = React.useMemo(() => {\n const segments = splitContentSegments(content);\n // console.log('segments=====', segments);\n const sandboxSegments = segments.filter((seg) => seg.type === \"sandbox\");\n const sandboxContent =\n mode === \"blackboard\"\n ? sandboxSegments[sandboxSegments.length - 1]?.value || \"\"\n : sandboxSegments.map((seg) => seg.value).join(\"\\n\");\n return sandboxContent || \"\";\n }, [content, mode]);\n\n useEffect(() => {\n if (mode !== \"blackboard\") {\n prevHtmlRef.current = htmlContent;\n return;\n }\n const prev = prevHtmlRef.current;\n const isContinuation = prev && htmlContent.startsWith(prev);\n if (!isContinuation && prev) {\n setResetToken((token) => token + 1);\n }\n prevHtmlRef.current = htmlContent;\n }, [htmlContent, mode]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return undefined;\n\n const doc = iframe.contentDocument;\n if (!doc) return undefined;\n\n doc.open();\n doc.write(`<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <style>\n html, body { margin: 0; padding: 0; }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n docRef.current = doc;\n\n const rootEl = doc.getElementById(\"root\");\n if (!rootEl) return undefined;\n\n const root = createRoot(rootEl);\n rootRef.current = root;\n\n const updateHeight = () => {\n if (!iframeRef.current || !doc.body) return;\n const bodyRect = doc.body.getBoundingClientRect();\n const htmlRect = doc.documentElement?.getBoundingClientRect();\n const bodyHeight = bodyRect.height;\n const htmlHeight = htmlRect?.height || 0;\n const contentHeight = Math.max(bodyHeight, htmlHeight);\n const nextHeight = Math.max(200, Math.ceil(contentHeight));\n setHeight(nextHeight);\n };\n updateHeightRef.current = updateHeight;\n\n updateHeight();\n\n const resizeObserver = new ResizeObserver(() => updateHeight());\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n return () => {\n resizeObserver.disconnect();\n // Defer unmount to avoid React warning when parent is mid-render\n setTimeout(() => {\n root.unmount();\n rootRef.current = null;\n docRef.current = null;\n updateHeightRef.current = () => {};\n }, 0);\n };\n }, []);\n\n useEffect(() => {\n const onFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", onFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", onFullscreenChange);\n }, []);\n\n const toggleFullscreen = () => {\n const target = containerRef.current || iframeRef.current;\n if (!target) return;\n if (document.fullscreenElement) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n if (target.requestFullscreen) {\n target.requestFullscreen().catch(() => {});\n }\n };\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n\n root.render(\n <SandboxApp\n html={htmlContent}\n loadingText={loadingText}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n fullScreenButtonText={fullScreenButtonText}\n hideFullScreen={hideFullScreen}\n resetToken={resetToken}\n />\n );\n requestAnimationFrame(() => updateHeightRef.current?.());\n }, [\n content,\n htmlContent,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n resetToken,\n ]);\n\n return (\n <div\n ref={containerRef}\n className={\n \"w-full h-full overflow-auto relative flex flex-col justify-center\"\n }\n >\n {!hideFullScreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className={\n \"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer\"\n }\n >\n {isFullscreen ? \"退出全屏\" : fullScreenButtonText || \"全屏浏览\"}\n </button>\n )}\n {mode === \"blackboard\" && type === \"markdown\" ? (\n <ContentRender content={content} />\n ) : (\n <iframe\n ref={iframeRef}\n sandbox=\"allow-scripts allow-same-origin\"\n allow=\"fullscreen\"\n allowFullScreen\n className={(className, \"w-full h-full\")}\n style={\n {\n // height: `${height}px`,\n // margin: \"16px 0\",\n }\n }\n />\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["IframeSandbox","content","type","className","loadingText","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","containerRef","useRef","iframeRef","rootRef","docRef","updateHeightRef","setHeight","useState","resetToken","setResetToken","isFullscreen","setIsFullscreen","prevHtmlRef","htmlContent","React","sandboxSegments","splitContentSegments","seg","useEffect","prev","token","iframe","doc","rootEl","root","createRoot","updateHeight","bodyRect","htmlRect","bodyHeight","htmlHeight","contentHeight","nextHeight","resizeObserver","onFullscreenChange","toggleFullscreen","target","jsx","SandboxApp","jsxs","ContentRender"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IframeSandbox.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport SandboxApp from \"./SandboxApp\";\nimport { splitContentSegments } from \"./utils/split-content\";\nimport ContentRender from \"./ContentRender\";\nexport interface IframeSandboxProps {\n content: string;\n className?: string;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n fullScreenButtonText?: string;\n hideFullScreen?: boolean;\n mode?: \"content\" | \"blackboard\";\n type: \"sandbox\" | \"markdown\";\n}\n\nconst IframeSandbox: React.FC<IframeSandboxProps> = ({\n content,\n type,\n className,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n hideFullScreen = false,\n mode = \"content\",\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const rootRef = useRef<Root | null>(null);\n const docRef = useRef<Document | null>(null);\n const updateHeightRef = useRef<() => void>(() => {});\n const [height, setHeight] = useState(480);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const prevHtmlRef = useRef<string>(\"\");\n const htmlContent = React.useMemo(() => {\n const segments = splitContentSegments(content);\n // console.log('segments=====', segments);\n const sandboxSegments = segments.filter((seg) => seg.type === \"sandbox\");\n const sandboxContent =\n mode === \"blackboard\"\n ? sandboxSegments[sandboxSegments.length - 1]?.value || \"\"\n : sandboxSegments.map((seg) => seg.value).join(\"\\n\");\n return sandboxContent || \"\";\n }, [content, mode]);\n\n useEffect(() => {\n if (mode !== \"blackboard\") {\n prevHtmlRef.current = htmlContent;\n return;\n }\n const prev = prevHtmlRef.current;\n const isContinuation = prev && htmlContent.startsWith(prev);\n if (!isContinuation && prev) {\n setResetToken((token) => token + 1);\n }\n prevHtmlRef.current = htmlContent;\n }, [htmlContent, mode]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return undefined;\n\n const doc = iframe.contentDocument;\n if (!doc) return undefined;\n\n doc.open();\n doc.write(`<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <style>\n html, body { margin: 0; padding: 0; }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n docRef.current = doc;\n\n const rootEl = doc.getElementById(\"root\");\n if (!rootEl) return undefined;\n\n const root = createRoot(rootEl);\n rootRef.current = root;\n\n const updateHeight = () => {\n if (!iframeRef.current || !doc.body) return;\n const bodyRect = doc.body.getBoundingClientRect();\n const htmlRect = doc.documentElement?.getBoundingClientRect();\n const bodyHeight = bodyRect.height;\n const htmlHeight = htmlRect?.height || 0;\n const contentHeight = Math.max(bodyHeight, htmlHeight);\n const nextHeight = Math.max(200, Math.ceil(contentHeight));\n setHeight(nextHeight);\n };\n updateHeightRef.current = updateHeight;\n\n updateHeight();\n\n const resizeObserver = new ResizeObserver(() => updateHeight());\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n return () => {\n resizeObserver.disconnect();\n // Defer unmount to avoid React warning when parent is mid-render\n setTimeout(() => {\n root.unmount();\n rootRef.current = null;\n docRef.current = null;\n updateHeightRef.current = () => {};\n }, 0);\n };\n }, []);\n\n useEffect(() => {\n const onFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", onFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", onFullscreenChange);\n }, []);\n\n const toggleFullscreen = () => {\n const target = containerRef.current || iframeRef.current;\n if (!target) return;\n if (document.fullscreenElement) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n if (target.requestFullscreen) {\n target.requestFullscreen().catch(() => {});\n }\n };\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n\n root.render(\n <SandboxApp\n html={htmlContent}\n loadingText={loadingText}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n fullScreenButtonText={fullScreenButtonText}\n hideFullScreen={hideFullScreen}\n resetToken={resetToken}\n />\n );\n requestAnimationFrame(() => updateHeightRef.current?.());\n }, [\n content,\n htmlContent,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n resetToken,\n ]);\n\n return (\n <div\n ref={containerRef}\n className={\n \"w-full h-full overflow-auto relative flex flex-col justify-center\"\n }\n >\n {!hideFullScreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className={\n \"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer\"\n }\n >\n {isFullscreen ? \"退出全屏\" : fullScreenButtonText || \"全屏浏览\"}\n </button>\n )}\n {mode === \"blackboard\" && type === \"markdown\" ? (\n <ContentRender content={content} />\n ) : (\n <iframe\n ref={iframeRef}\n sandbox=\"allow-scripts allow-same-origin\"\n allow=\"fullscreen\"\n allowFullScreen\n className={(className, \"w-full\")}\n style={{\n height: mode === \"blackboard\" ? \"100%\" : `${height}px`,\n // height: `${height}px`,\n // margin: \"16px 0\",\n }}\n />\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["IframeSandbox","content","type","className","loadingText","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","containerRef","useRef","iframeRef","rootRef","docRef","updateHeightRef","height","setHeight","useState","resetToken","setResetToken","isFullscreen","setIsFullscreen","prevHtmlRef","htmlContent","React","sandboxSegments","splitContentSegments","seg","useEffect","prev","token","iframe","doc","rootEl","root","createRoot","updateHeight","bodyRect","htmlRect","bodyHeight","htmlHeight","contentHeight","nextHeight","resizeObserver","onFullscreenChange","toggleFullscreen","target","jsx","SandboxApp","jsxs","ContentRender"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { j as i } from "../../../_virtual/jsx-runtime.js";
|
|
2
2
|
import * as d from "react";
|
|
3
3
|
import n from "../../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/TextArea.js";
|
|
4
|
-
import "../../../_virtual/
|
|
4
|
+
import "../../../_virtual/index2.js";
|
|
5
5
|
import "../../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-resize-observer@1.4.3_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-resize-observer/es/index.js";
|
|
6
6
|
import "../../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-util@5.44.4_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-util/es/hooks/useLayoutEffect.js";
|
|
7
7
|
import "../../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-util@5.44.4_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-util/es/raf.js";
|