markdown-flow-ui 0.1.97 → 0.1.99-beta.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.
Files changed (70) hide show
  1. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/@braintree_sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.cjs.js +1 -1
  2. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/@braintree_sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.es.js +1 -1
  3. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.cjs.js +1 -1
  4. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.es.js +1 -1
  5. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/hast-util-to-jsx-runtime@2.3.6/node_modules/hast-util-to-jsx-runtime/lib/index.cjs.js +1 -1
  6. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/hast-util-to-jsx-runtime@2.3.6/node_modules/hast-util-to-jsx-runtime/lib/index.es.js +1 -1
  7. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-YG6GDRKO.cjs.js +1 -1
  8. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-YG6GDRKO.es.js +1 -1
  9. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-S3R3BYOJ.cjs.js +1 -1
  10. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-S3R3BYOJ.es.js +1 -1
  11. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-TZMSLE5B.cjs.js +1 -1
  12. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-TZMSLE5B.es.js +1 -1
  13. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-LVOFAZNH.cjs.js +1 -1
  14. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-LVOFAZNH.es.js +1 -1
  15. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-WL72ISMW.cjs.js +1 -1
  16. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-WL72ISMW.es.js +1 -1
  17. 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.cjs.js +1 -1
  18. 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.es.js +1 -1
  19. 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.cjs.js +1 -1
  20. 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.es.js +1 -1
  21. 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.cjs.js +1 -1
  22. 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.es.js +1 -1
  23. 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.cjs.js +1 -1
  24. 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.es.js +1 -1
  25. package/dist/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/ref.cjs.js +1 -1
  26. package/dist/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/ref.es.js +1 -1
  27. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/index.cjs.js +1 -1
  28. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/index.es.js +1 -1
  29. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/style-to-object@1.0.11/node_modules/style-to-object/cjs/index.cjs.js +1 -1
  30. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/style-to-object@1.0.11/node_modules/style-to-object/cjs/index.es.js +1 -1
  31. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.cjs.js +1 -1
  32. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.es.js +1 -1
  33. package/dist/_virtual/index.cjs10.js +1 -1
  34. package/dist/_virtual/index.cjs11.js +1 -1
  35. package/dist/_virtual/index.cjs2.js +1 -1
  36. package/dist/_virtual/index.cjs3.js +1 -1
  37. package/dist/_virtual/index.cjs5.js +1 -1
  38. package/dist/_virtual/index.cjs6.js +1 -1
  39. package/dist/_virtual/index.cjs7.js +1 -1
  40. package/dist/_virtual/index.cjs8.js +1 -1
  41. package/dist/_virtual/index.cjs9.js +1 -1
  42. package/dist/_virtual/index.es10.js +2 -3
  43. package/dist/_virtual/index.es10.js.map +1 -1
  44. package/dist/_virtual/index.es11.js +3 -2
  45. package/dist/_virtual/index.es11.js.map +1 -1
  46. package/dist/_virtual/index.es2.js +2 -5
  47. package/dist/_virtual/index.es2.js.map +1 -1
  48. package/dist/_virtual/index.es3.js +5 -2
  49. package/dist/_virtual/index.es3.js.map +1 -1
  50. package/dist/_virtual/index.es5.js +5 -2
  51. package/dist/_virtual/index.es5.js.map +1 -1
  52. package/dist/_virtual/index.es6.js +4 -4
  53. package/dist/_virtual/index.es7.js +2 -5
  54. package/dist/_virtual/index.es7.js.map +1 -1
  55. package/dist/_virtual/index.es8.js +3 -2
  56. package/dist/_virtual/index.es8.js.map +1 -1
  57. package/dist/_virtual/index.es9.js +2 -3
  58. package/dist/_virtual/index.es9.js.map +1 -1
  59. package/dist/components/ContentRender/IframeSandbox.cjs.js +31 -4
  60. package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
  61. package/dist/components/ContentRender/IframeSandbox.es.js +181 -132
  62. package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
  63. package/dist/components/ContentRender/SandboxApp.cjs.js +4 -5
  64. package/dist/components/ContentRender/SandboxApp.cjs.js.map +1 -1
  65. package/dist/components/ContentRender/SandboxApp.es.js +128 -93
  66. package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
  67. package/dist/components/ui/inputGroup/textarea.cjs.js +1 -1
  68. package/dist/components/ui/inputGroup/textarea.es.js +1 -1
  69. package/dist/markdown-flow-ui-lib.css +1 -1
  70. package/package.json +1 -1
@@ -1,79 +1,99 @@
1
- import { j as H } from "../../_virtual/jsx-runtime.es.js";
2
- import I, { useRef as w, useState as N, useEffect as M } from "react";
3
- import { createRoot as Q } from "react-dom/client";
4
- import X from "./SandboxApp.es.js";
5
- import { splitContentSegments as tt } from "./utils/split-content.es.js";
6
- import et from "./ContentRender.es.js";
7
- const nt = () => import("./blackboard-vendor.es.js").then((n) => n.injectBlackboardLibraries), _ = (n) => n.split(/\s+/).filter(Boolean).map((r) => r.split(":").pop() || r), O = (n) => {
8
- const r = n.trim().toLowerCase();
1
+ import { j as T } from "../../_virtual/jsx-runtime.es.js";
2
+ import X, { useRef as h, useState as N, useEffect as y } from "react";
3
+ import { createRoot as ot } from "react-dom/client";
4
+ import st from "./SandboxApp.es.js";
5
+ import { splitContentSegments as it } from "./utils/split-content.es.js";
6
+ import lt from "./ContentRender.es.js";
7
+ const ct = () => import("./blackboard-vendor.es.js").then((l) => l.injectBlackboardLibraries), at = /<img\b[^>]*>/i, ut = 180, ht = "markdown-flow-ui:sandbox", dt = "interaction", mt = 240, Z = (l) => l.split(/\s+/).filter(Boolean).map((r) => r.split(":").pop() || r), J = (l) => {
8
+ const r = l.trim().toLowerCase();
9
9
  if (!r) return null;
10
- const u = r.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);
11
- return u ? `${u[1]}${u[2].toLowerCase()}` : null;
12
- }, W = (n) => {
13
- if (!n.trim()) return null;
14
- const r = _(n);
10
+ const d = r.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);
11
+ return d ? `${d[1]}${d[2].toLowerCase()}` : null;
12
+ }, Y = (l) => {
13
+ if (!l.trim()) return null;
14
+ const r = Z(l);
15
15
  if (r.includes("h-screen") || r.includes("h-dvh"))
16
16
  return "100dvh";
17
17
  if (r.includes("h-svh"))
18
18
  return "100svh";
19
19
  if (r.includes("h-lvh"))
20
20
  return "100lvh";
21
- const u = r.find(
22
- (C) => /^h-\[[0-9.]+(vh|dvh|svh|lvh)\]$/i.test(C)
21
+ const d = r.find(
22
+ (H) => /^h-\[[0-9.]+(vh|dvh|svh|lvh)\]$/i.test(H)
23
23
  );
24
- if (!u) return null;
25
- const g = u.match(/^h-\[([0-9.]+)(vh|dvh|svh|lvh)\]$/i);
26
- return g ? `${g[1]}${g[2].toLowerCase()}` : null;
27
- }, ut = ({
28
- content: n,
24
+ if (!d) return null;
25
+ const b = d.match(/^h-\[([0-9.]+)(vh|dvh|svh|lvh)\]$/i);
26
+ return b ? `${b[1]}${b[2].toLowerCase()}` : null;
27
+ }, Et = ({
28
+ content: l,
29
29
  type: r,
30
- className: u,
31
- loadingText: g,
32
- styleLoadingText: C,
33
- scriptLoadingText: T,
34
- fullScreenButtonText: j,
35
- hideFullScreen: V = !1,
36
- mode: c = "content"
30
+ className: d,
31
+ loadingText: b,
32
+ styleLoadingText: H,
33
+ scriptLoadingText: D,
34
+ fullScreenButtonText: S,
35
+ hideFullScreen: F = !1,
36
+ mode: u = "content"
37
37
  }) => {
38
- const q = w(null), v = w(null), z = w(null), L = w(null), F = w(() => {
39
- }), [, P] = N(480), [D, U] = N(0), [Y, Z] = N(!1), G = c === "blackboard", $ = w(""), h = I.useMemo(() => {
40
- const t = tt(n).filter((a) => a.type === "sandbox");
41
- return (c === "blackboard" ? t[t.length - 1]?.value || "" : t.map((a) => a.value).join(`
38
+ const L = h(null), v = h(null), _ = h(null), P = h(null), O = h(() => {
39
+ }), [, K] = N(480), [V, Q] = N(0), [tt, et] = N(!1), q = u === "blackboard", $ = h(""), n = X.useMemo(() => {
40
+ const t = it(l).filter((c) => c.type === "sandbox");
41
+ return (u === "blackboard" ? t[t.length - 1]?.value || "" : t.map((c) => c.value).join(`
42
42
  `)) || "";
43
- }, [n, c]), S = !!I.useMemo(() => {
44
- const e = h.trim();
43
+ }, [l, u]), [R, G] = N(n), U = h(n), B = h(n), E = h(null), I = () => {
44
+ E.current !== null && (window.clearTimeout(E.current), E.current = null);
45
+ };
46
+ y(
47
+ () => () => {
48
+ I();
49
+ },
50
+ []
51
+ ), y(() => {
52
+ const e = U.current;
53
+ U.current = n;
54
+ const t = !!e && n.length > e.length && n.startsWith(e), s = at.test(n);
55
+ if (!(t && s)) {
56
+ I(), B.current = n, G(n);
57
+ return;
58
+ }
59
+ B.current = n, I(), E.current = window.setTimeout(() => {
60
+ G(B.current), E.current = null;
61
+ }, ut);
62
+ }, [n]);
63
+ const W = !!X.useMemo(() => {
64
+ const e = R.trim();
45
65
  if (!e) return null;
46
66
  const t = e.match(/^<([a-zA-Z][\w:-]*)(\s[^>]*?)?>/);
47
67
  if (!t) return null;
48
- const s = t[2] || "", a = s.match(/\bheight\s*=\s*["']([^"']+)["']/i);
49
- if (a) {
50
- const m = O(a[1]);
51
- if (m) return m;
68
+ const s = t[2] || "", c = s.match(/\bheight\s*=\s*["']([^"']+)["']/i);
69
+ if (c) {
70
+ const f = J(c[1]);
71
+ if (f) return f;
52
72
  }
53
- const y = s.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(
73
+ const C = s.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(
54
74
  /\bheight\s*:\s*([^;]+)/i
55
75
  )?.[1];
56
- if (y) {
57
- const m = O(y);
58
- if (m) return m;
76
+ if (C) {
77
+ const f = J(C);
78
+ if (f) return f;
59
79
  }
60
- const k = s.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1];
61
- return k ? W(k) : null;
62
- }, [h]);
63
- M(() => {
64
- if (c !== "blackboard") {
65
- $.current = h;
80
+ const M = s.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1];
81
+ return M ? Y(M) : null;
82
+ }, [R]);
83
+ y(() => {
84
+ if (u !== "blackboard") {
85
+ $.current = n;
66
86
  return;
67
87
  }
68
88
  const e = $.current;
69
- !(e && h.startsWith(e)) && e && U((s) => s + 1), $.current = h;
70
- }, [h, c]), M(() => {
89
+ !(e && n.startsWith(e)) && e && Q((s) => s + 1), $.current = n;
90
+ }, [n, u]), y(() => {
71
91
  const e = v.current;
72
92
  if (!e) return;
73
93
  const t = e.contentDocument;
74
94
  if (!t) return;
75
- t.open(), t.write(`<!DOCTYPE html>
76
- <html${c === "blackboard" ? ' style="height: 100%;"' : ""}>
95
+ if (t.open(), t.write(`<!DOCTYPE html>
96
+ <html${u === "blackboard" ? ' style="height: 100%;"' : ""}>
77
97
  <head>
78
98
  <meta charset="utf-8" />
79
99
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -86,78 +106,108 @@ const nt = () => import("./blackboard-vendor.es.js").then((n) => n.injectBlackbo
86
106
  <body>
87
107
  <div id="root"></div>
88
108
  </body>
89
- </html>`), t.close(), L.current = t;
109
+ </html>`), t.close(), P.current = t, q && r === "sandbox") {
110
+ const o = t.createElement("script");
111
+ o.type = "text/javascript", o.text = `(() => {
112
+ const source = ${JSON.stringify(ht)};
113
+ const type = ${JSON.stringify(dt)};
114
+ const throttleMs = ${mt};
115
+ let lastMessageTime = 0;
116
+
117
+ const notifyParent = (eventType) => {
118
+ const now = Date.now();
119
+ if (eventType === "wheel" && now - lastMessageTime < throttleMs) {
120
+ return;
121
+ }
122
+ lastMessageTime = now;
123
+ window.parent.postMessage({ source, type, eventType }, "*");
124
+ };
125
+
126
+ window.addEventListener("pointerdown", () => notifyParent("pointerdown"), {
127
+ capture: true,
128
+ passive: true,
129
+ });
130
+ window.addEventListener("touchstart", () => notifyParent("touchstart"), {
131
+ capture: true,
132
+ passive: true,
133
+ });
134
+ window.addEventListener("wheel", () => notifyParent("wheel"), {
135
+ passive: true,
136
+ });
137
+ window.addEventListener("keydown", () => notifyParent("keydown"), true);
138
+ })();`, t.head.appendChild(o);
139
+ }
90
140
  const s = t.getElementById("root");
91
141
  if (!s) return;
92
- const a = Q(s);
93
- z.current = a;
142
+ const c = ot(s);
143
+ _.current = c;
94
144
  let x = !1;
95
- const y = (i, d) => {
96
- const o = i.trim().toLowerCase();
97
- if (!o) return null;
98
- const l = Number.parseFloat(o);
99
- return Number.isNaN(l) ? null : /(dvh|svh|lvh|vh)$/i.test(o) ? l / 100 * d : o.endsWith("px") || /^[0-9.]+$/.test(o) ? l : null;
100
- }, k = (i, d) => {
101
- if (!i.trim()) return null;
102
- const o = W(i);
103
- if (o)
104
- return y(o, d);
105
- const f = _(i).find(
106
- (E) => /^h-\[[0-9.]+px\]$/i.test(E)
145
+ const C = (o, m) => {
146
+ const i = o.trim().toLowerCase();
147
+ if (!i) return null;
148
+ const a = Number.parseFloat(i);
149
+ return Number.isNaN(a) ? null : /(dvh|svh|lvh|vh)$/i.test(i) ? a / 100 * m : i.endsWith("px") || /^[0-9.]+$/.test(i) ? a : null;
150
+ }, M = (o, m) => {
151
+ if (!o.trim()) return null;
152
+ const i = Y(o);
153
+ if (i)
154
+ return C(i, m);
155
+ const p = Z(o).find(
156
+ (k) => /^h-\[[0-9.]+px\]$/i.test(k)
107
157
  );
108
- if (!f) return null;
109
- const p = f.match(/^h-\[([0-9.]+)px\]$/i);
110
158
  if (!p) return null;
111
- const b = Number.parseFloat(p[1]);
112
- return Number.isNaN(b) ? null : b;
113
- }, m = () => {
159
+ const g = p.match(/^h-\[([0-9.]+)px\]$/i);
160
+ if (!g) return null;
161
+ const w = Number.parseFloat(g[1]);
162
+ return Number.isNaN(w) ? null : w;
163
+ }, f = () => {
114
164
  if (!v.current || !t.body) return null;
115
- const d = t.body.querySelector(
165
+ const m = t.body.querySelector(
116
166
  ".sandbox-wrapper"
117
167
  )?.firstElementChild;
118
- if (!d) return null;
119
- const o = Array.from(d.children);
120
- if (o.length !== 1) return null;
121
- const l = o[0], f = l.style.height || l.getAttribute("height"), p = v.current.ownerDocument?.documentElement?.clientHeight || window.innerHeight, b = f ? y(f, p) : null;
122
- if (b !== null)
123
- return Math.ceil(b);
124
- const E = k(
125
- l.getAttribute("class") || "",
126
- p
168
+ if (!m) return null;
169
+ const i = Array.from(m.children);
170
+ if (i.length !== 1) return null;
171
+ const a = i[0], p = a.style.height || a.getAttribute("height"), g = v.current.ownerDocument?.documentElement?.clientHeight || window.innerHeight, w = p ? C(p, g) : null;
172
+ if (w !== null)
173
+ return Math.ceil(w);
174
+ const k = M(
175
+ a.getAttribute("class") || "",
176
+ g
127
177
  );
128
- return E !== null ? Math.ceil(E) : null;
129
- }, A = () => {
178
+ return k !== null ? Math.ceil(k) : null;
179
+ }, j = () => {
130
180
  if (!v.current || !t.body) return;
131
- const i = t.body.getBoundingClientRect(), d = t.documentElement?.getBoundingClientRect(), o = i.height, l = d?.height || 0, f = Math.max(o, l), p = m(), b = Math.max(
181
+ const o = t.body.getBoundingClientRect(), m = t.documentElement?.getBoundingClientRect(), i = o.height, a = m?.height || 0, p = Math.max(i, a), g = f(), w = Math.max(
132
182
  200,
133
- p ?? Math.ceil(f)
183
+ g ?? Math.ceil(p)
134
184
  );
135
- P(b);
136
- }, R = () => {
185
+ K(w);
186
+ }, A = () => {
137
187
  requestAnimationFrame(() => {
138
- x || A();
188
+ x || j();
139
189
  });
140
190
  };
141
- F.current = R, A(), R(), nt().then((i) => {
142
- x || (i(t), R());
191
+ O.current = A, j(), A(), ct().then((o) => {
192
+ x || (o(t), A());
143
193
  }).catch(() => {
144
- x || R();
194
+ x || A();
145
195
  });
146
- const B = new ResizeObserver(() => A());
147
- return B.observe(t.body), s && B.observe(s), () => {
148
- x = !0, B.disconnect(), setTimeout(() => {
149
- a.unmount(), z.current = null, L.current = null, F.current = () => {
196
+ const z = new ResizeObserver(() => j());
197
+ return z.observe(t.body), s && z.observe(s), () => {
198
+ x = !0, z.disconnect(), setTimeout(() => {
199
+ c.unmount(), _.current = null, P.current = null, O.current = () => {
150
200
  };
151
201
  }, 0);
152
202
  };
153
- }, []), M(() => {
203
+ }, []), y(() => {
154
204
  const e = () => {
155
- Z(!!document.fullscreenElement);
205
+ et(!!document.fullscreenElement);
156
206
  };
157
207
  return document.addEventListener("fullscreenchange", e), () => document.removeEventListener("fullscreenchange", e);
158
208
  }, []);
159
- const J = () => {
160
- const e = q.current || v.current;
209
+ const nt = () => {
210
+ const e = L.current || v.current;
161
211
  if (e) {
162
212
  if (document.fullscreenElement) {
163
213
  document.exitFullscreen().catch(() => {
@@ -168,62 +218,61 @@ const nt = () => import("./blackboard-vendor.es.js").then((n) => n.injectBlackbo
168
218
  });
169
219
  }
170
220
  };
171
- M(() => {
172
- const e = z.current;
221
+ y(() => {
222
+ const e = _.current;
173
223
  e && (e.render(
174
- /* @__PURE__ */ H.jsx(
175
- X,
224
+ /* @__PURE__ */ T.jsx(
225
+ st,
176
226
  {
177
- html: h,
178
- loadingText: g,
179
- styleLoadingText: C,
180
- scriptLoadingText: T,
181
- fullScreenButtonText: j,
182
- hideFullScreen: V,
183
- resetToken: D,
184
- hasRootVhHeight: S,
185
- mode: c
227
+ html: R,
228
+ loadingText: b,
229
+ styleLoadingText: H,
230
+ scriptLoadingText: D,
231
+ fullScreenButtonText: S,
232
+ hideFullScreen: F,
233
+ resetToken: V,
234
+ hasRootVhHeight: W,
235
+ mode: u
186
236
  }
187
237
  )
188
- ), requestAnimationFrame(() => F.current?.()));
238
+ ), requestAnimationFrame(() => O.current?.()));
189
239
  }, [
190
- n,
191
- h,
192
- g,
193
- C,
194
- T,
195
- j,
240
+ R,
241
+ b,
242
+ H,
196
243
  D,
197
- c
244
+ S,
245
+ V,
246
+ u
198
247
  ]);
199
- const K = [
248
+ const rt = [
200
249
  "w-full relative content-render-iframe-sandbox",
201
- G ? "h-full overflow-auto flex flex-col" : "aspect-[16/9] overflow-hidden flex items-center justify-center"
250
+ q ? "h-full overflow-auto flex flex-col" : "aspect-[16/9] overflow-hidden flex items-center justify-center"
202
251
  ].filter(Boolean).join(" ");
203
- return /* @__PURE__ */ H.jsxs(
252
+ return /* @__PURE__ */ T.jsxs(
204
253
  "div",
205
254
  {
206
- ref: q,
207
- "data-root-vh": S ? "true" : "false",
208
- className: K,
255
+ ref: L,
256
+ "data-root-vh": W ? "true" : "false",
257
+ className: rt,
209
258
  children: [
210
- !V && /* @__PURE__ */ H.jsx(
259
+ !F && /* @__PURE__ */ T.jsx(
211
260
  "button",
212
261
  {
213
262
  type: "button",
214
- onClick: J,
263
+ onClick: nt,
215
264
  className: "absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",
216
- children: Y ? "退出全屏" : j || "全屏浏览"
265
+ children: tt ? "退出全屏" : S || "全屏浏览"
217
266
  }
218
267
  ),
219
- c === "blackboard" && r === "markdown" ? /* @__PURE__ */ H.jsx(et, { content: n }) : /* @__PURE__ */ H.jsx(
268
+ u === "blackboard" && r === "markdown" ? /* @__PURE__ */ T.jsx(lt, { content: l }) : /* @__PURE__ */ T.jsx(
220
269
  "iframe",
221
270
  {
222
271
  ref: v,
223
272
  sandbox: "allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",
224
273
  allow: "fullscreen",
225
274
  allowFullScreen: !0,
226
- className: [u, "w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),
275
+ className: [d, "w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),
227
276
  style: {
228
277
  height: "100%",
229
278
  margin: "auto"
@@ -235,6 +284,6 @@ const nt = () => import("./blackboard-vendor.es.js").then((n) => n.injectBlackbo
235
284
  );
236
285
  };
237
286
  export {
238
- ut as default
287
+ Et as default
239
288
  };
240
289
  //# sourceMappingURL=IframeSandbox.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IframeSandbox.es.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\";\n// Lazy-load iframe vendor libraries and inject them into the sandbox document.\nconst loadBlackboardVendor = () =>\n import(\"./blackboard-vendor\").then((m) => m.injectBlackboardLibraries);\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 normalizeTailwindHeightTokens = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.split(\":\").pop() || token);\n\nconst parseViewportHeightCss = (value: string) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const matched = normalized.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);\n if (!matched) return null;\n return `${matched[1]}${matched[2].toLowerCase()}`;\n};\n\nconst extractViewportHeightFromTailwindClass = (className: string) => {\n if (!className.trim()) return null;\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n if (\n normalizedTokens.includes(\"h-screen\") ||\n normalizedTokens.includes(\"h-dvh\")\n ) {\n return \"100dvh\";\n }\n if (normalizedTokens.includes(\"h-svh\")) {\n return \"100svh\";\n }\n if (normalizedTokens.includes(\"h-lvh\")) {\n return \"100lvh\";\n }\n const arbitraryToken = normalizedTokens.find((token) =>\n /^h-\\[[0-9.]+(vh|dvh|svh|lvh)\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(/^h-\\[([0-9.]+)(vh|dvh|svh|lvh)\\]$/i);\n if (!matched) return null;\n return `${matched[1]}${matched[2].toLowerCase()}`;\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 isBlackboardMode = mode === \"blackboard\";\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 const rootViewportHeightCss = React.useMemo(() => {\n const normalized = htmlContent.trim();\n if (!normalized) return null;\n const rootMatch = normalized.match(/^<([a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/);\n if (!rootMatch) return null;\n const attrs = rootMatch[2] || \"\";\n const heightAttrMatch = attrs.match(/\\bheight\\s*=\\s*[\"']([^\"']+)[\"']/i);\n if (heightAttrMatch) {\n const explicitHeightCss = parseViewportHeightCss(heightAttrMatch[1]);\n if (explicitHeightCss) return explicitHeightCss;\n }\n const styleAttrMatch = attrs.match(/\\bstyle\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleHeightMatch = styleAttrMatch?.match(\n /\\bheight\\s*:\\s*([^;]+)/i\n )?.[1];\n if (styleHeightMatch) {\n const styleHeightCss = parseViewportHeightCss(styleHeightMatch);\n if (styleHeightCss) return styleHeightCss;\n }\n const classAttrMatch = attrs.match(/\\bclass\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n if (!classAttrMatch) return null;\n return extractViewportHeightFromTailwindClass(classAttrMatch);\n }, [htmlContent]);\n const hasRootVhHeight = Boolean(rootViewportHeightCss);\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${mode === \"blackboard\" ? ' style=\"height: 100%;\"' : \"\"}>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n html, body, #root { width: 100%; height: 100%; }\n html, body { margin: 0; padding: 0; overflow: auto; }\n *, *::before, *::after { box-sizing: border-box; }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n\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 let isDestroyed = false;\n\n const parseExplicitHeight = (\n value: string,\n parentViewportHeight: number\n ) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const numeric = Number.parseFloat(normalized);\n if (Number.isNaN(numeric)) return null;\n if (/(dvh|svh|lvh|vh)$/i.test(normalized)) {\n return (numeric / 100) * parentViewportHeight;\n }\n if (normalized.endsWith(\"px\") || /^[0-9.]+$/.test(normalized)) {\n return numeric;\n }\n return null;\n };\n const parseTailwindHeightClass = (\n className: string,\n parentViewportHeight: number\n ) => {\n if (!className.trim()) return null;\n const viewportHeightCss =\n extractViewportHeightFromTailwindClass(className);\n if (viewportHeightCss) {\n return parseExplicitHeight(viewportHeightCss, parentViewportHeight);\n }\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n const arbitraryToken = normalizedTokens.find((token) =>\n /^h-\\[[0-9.]+px\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(/^h-\\[([0-9.]+)px\\]$/i);\n if (!matched) return null;\n const numeric = Number.parseFloat(matched[1]);\n if (Number.isNaN(numeric)) return null;\n return numeric;\n };\n\n const resolveExplicitHeight = () => {\n if (!iframeRef.current || !doc.body) return null;\n const wrapper = doc.body.querySelector(\n \".sandbox-wrapper\"\n ) as HTMLElement | null;\n const container = wrapper?.firstElementChild as HTMLElement | null;\n if (!container) return null;\n const elements = Array.from(container.children) as HTMLElement[];\n if (elements.length !== 1) return null;\n const target = elements[0];\n const heightValue = target.style.height || target.getAttribute(\"height\");\n const parentViewportHeight =\n iframeRef.current.ownerDocument?.documentElement?.clientHeight ||\n window.innerHeight;\n const parsed = heightValue\n ? parseExplicitHeight(heightValue, parentViewportHeight)\n : null;\n if (parsed !== null) {\n return Math.ceil(parsed);\n }\n const classHeight = parseTailwindHeightClass(\n target.getAttribute(\"class\") || \"\",\n parentViewportHeight\n );\n return classHeight !== null ? Math.ceil(classHeight) : null;\n };\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 explicitHeight = resolveExplicitHeight();\n const nextHeight = Math.max(\n 200,\n explicitHeight ?? Math.ceil(contentHeight)\n );\n setHeight(nextHeight);\n };\n const scheduleHeightUpdate = () => {\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n updateHeight();\n });\n };\n updateHeightRef.current = scheduleHeightUpdate;\n\n updateHeight();\n scheduleHeightUpdate();\n\n // Inject Tailwind/DaisyUI/GSAP into iframe for all sandbox modes.\n // Dynamic import keeps ~3.3 MB of vendor libs out of the main bundle.\n // Tailwind's MutationObserver ensures styles apply even if content renders first.\n loadBlackboardVendor()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n scheduleHeightUpdate();\n })\n .catch(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n\n const resizeObserver = new ResizeObserver(() => updateHeight());\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n return () => {\n isDestroyed = true;\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 hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n />\n );\n requestAnimationFrame(() => updateHeightRef.current?.());\n }, [\n content,\n htmlContent,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n resetToken,\n mode,\n ]);\n const containerClassName = [\n \"w-full relative content-render-iframe-sandbox\",\n isBlackboardMode\n ? \"h-full overflow-auto flex flex-col\"\n : \"aspect-[16/9] overflow-hidden flex items-center justify-center\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n ref={containerRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className={containerClassName}\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 allow-popups allow-popups-to-escape-sandbox\"\n allow=\"fullscreen\"\n allowFullScreen\n className={[className, \"w-full h-full mx-auto my-auto block\"]\n .filter(Boolean)\n .join(\" \")}\n style={{\n height: \"100%\",\n margin: \"auto\",\n }}\n />\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["loadBlackboardVendor","m","normalizeTailwindHeightTokens","className","token","parseViewportHeightCss","value","normalized","matched","extractViewportHeightFromTailwindClass","normalizedTokens","arbitraryToken","IframeSandbox","content","type","loadingText","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","containerRef","useRef","iframeRef","rootRef","docRef","updateHeightRef","setHeight","useState","resetToken","setResetToken","isFullscreen","setIsFullscreen","isBlackboardMode","prevHtmlRef","htmlContent","React","sandboxSegments","splitContentSegments","seg","hasRootVhHeight","rootMatch","attrs","heightAttrMatch","explicitHeightCss","styleHeightMatch","styleHeightCss","classAttrMatch","useEffect","prev","iframe","doc","rootEl","root","createRoot","isDestroyed","parseExplicitHeight","parentViewportHeight","numeric","parseTailwindHeightClass","viewportHeightCss","resolveExplicitHeight","container","elements","target","heightValue","parsed","classHeight","updateHeight","bodyRect","htmlRect","bodyHeight","htmlHeight","contentHeight","explicitHeight","nextHeight","scheduleHeightUpdate","inject","resizeObserver","onFullscreenChange","toggleFullscreen","jsx","SandboxApp","containerClassName","jsxs","ContentRender"],"mappings":"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"}
1
+ {"version":3,"file":"IframeSandbox.es.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\";\n// Lazy-load iframe vendor libraries and inject them into the sandbox document.\nconst loadBlackboardVendor = () =>\n import(\"./blackboard-vendor\").then((m) => m.injectBlackboardLibraries);\n\nconst COMPLETE_IMAGE_TAG_PATTERN = /<img\\b[^>]*>/i;\nconst POST_IMAGE_STREAM_DEBOUNCE_MS = 180;\nconst SANDBOX_INTERACTION_MESSAGE_SOURCE = \"markdown-flow-ui:sandbox\";\nconst SANDBOX_INTERACTION_MESSAGE_TYPE = \"interaction\";\nconst SANDBOX_INTERACTION_THROTTLE_MS = 240;\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 normalizeTailwindHeightTokens = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.split(\":\").pop() || token);\n\nconst parseViewportHeightCss = (value: string) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const matched = normalized.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);\n if (!matched) return null;\n return `${matched[1]}${matched[2].toLowerCase()}`;\n};\n\nconst extractViewportHeightFromTailwindClass = (className: string) => {\n if (!className.trim()) return null;\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n if (\n normalizedTokens.includes(\"h-screen\") ||\n normalizedTokens.includes(\"h-dvh\")\n ) {\n return \"100dvh\";\n }\n if (normalizedTokens.includes(\"h-svh\")) {\n return \"100svh\";\n }\n if (normalizedTokens.includes(\"h-lvh\")) {\n return \"100lvh\";\n }\n const arbitraryToken = normalizedTokens.find((token) =>\n /^h-\\[[0-9.]+(vh|dvh|svh|lvh)\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(/^h-\\[([0-9.]+)(vh|dvh|svh|lvh)\\]$/i);\n if (!matched) return null;\n return `${matched[1]}${matched[2].toLowerCase()}`;\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 isBlackboardMode = mode === \"blackboard\";\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 const [renderHtmlContent, setRenderHtmlContent] = useState(htmlContent);\n const prevIncomingHtmlRef = useRef(htmlContent);\n const pendingHtmlRef = useRef(htmlContent);\n const deferRenderTimerRef = useRef<number | null>(null);\n\n const clearDeferredRenderTimer = () => {\n if (deferRenderTimerRef.current === null) return;\n window.clearTimeout(deferRenderTimerRef.current);\n deferRenderTimerRef.current = null;\n };\n\n useEffect(\n () => () => {\n clearDeferredRenderTimer();\n },\n []\n );\n\n useEffect(() => {\n const prevIncomingHtml = prevIncomingHtmlRef.current;\n prevIncomingHtmlRef.current = htmlContent;\n\n const isAppendOnlyStream =\n !!prevIncomingHtml &&\n htmlContent.length > prevIncomingHtml.length &&\n htmlContent.startsWith(prevIncomingHtml);\n const containsCompleteImage = COMPLETE_IMAGE_TAG_PATTERN.test(htmlContent);\n const shouldDeferRender = isAppendOnlyStream && containsCompleteImage;\n\n if (!shouldDeferRender) {\n clearDeferredRenderTimer();\n pendingHtmlRef.current = htmlContent;\n setRenderHtmlContent(htmlContent);\n return;\n }\n\n pendingHtmlRef.current = htmlContent;\n clearDeferredRenderTimer();\n deferRenderTimerRef.current = window.setTimeout(() => {\n setRenderHtmlContent(pendingHtmlRef.current);\n deferRenderTimerRef.current = null;\n }, POST_IMAGE_STREAM_DEBOUNCE_MS);\n }, [htmlContent]);\n\n const rootViewportHeightCss = React.useMemo(() => {\n const normalized = renderHtmlContent.trim();\n if (!normalized) return null;\n const rootMatch = normalized.match(/^<([a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/);\n if (!rootMatch) return null;\n const attrs = rootMatch[2] || \"\";\n const heightAttrMatch = attrs.match(/\\bheight\\s*=\\s*[\"']([^\"']+)[\"']/i);\n if (heightAttrMatch) {\n const explicitHeightCss = parseViewportHeightCss(heightAttrMatch[1]);\n if (explicitHeightCss) return explicitHeightCss;\n }\n const styleAttrMatch = attrs.match(/\\bstyle\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleHeightMatch = styleAttrMatch?.match(\n /\\bheight\\s*:\\s*([^;]+)/i\n )?.[1];\n if (styleHeightMatch) {\n const styleHeightCss = parseViewportHeightCss(styleHeightMatch);\n if (styleHeightCss) return styleHeightCss;\n }\n const classAttrMatch = attrs.match(/\\bclass\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n if (!classAttrMatch) return null;\n return extractViewportHeightFromTailwindClass(classAttrMatch);\n }, [renderHtmlContent]);\n const hasRootVhHeight = Boolean(rootViewportHeightCss);\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${mode === \"blackboard\" ? ' style=\"height: 100%;\"' : \"\"}>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n html, body, #root { width: 100%; height: 100%; }\n html, body { margin: 0; padding: 0; overflow: auto; }\n *, *::before, *::after { box-sizing: border-box; }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n\n docRef.current = doc;\n\n if (isBlackboardMode && type === \"sandbox\") {\n const interactionBridgeScript = doc.createElement(\"script\");\n interactionBridgeScript.type = \"text/javascript\";\n interactionBridgeScript.text = `(() => {\n const source = ${JSON.stringify(SANDBOX_INTERACTION_MESSAGE_SOURCE)};\n const type = ${JSON.stringify(SANDBOX_INTERACTION_MESSAGE_TYPE)};\n const throttleMs = ${SANDBOX_INTERACTION_THROTTLE_MS};\n let lastMessageTime = 0;\n\n const notifyParent = (eventType) => {\n const now = Date.now();\n if (eventType === \"wheel\" && now - lastMessageTime < throttleMs) {\n return;\n }\n lastMessageTime = now;\n window.parent.postMessage({ source, type, eventType }, \"*\");\n };\n\n window.addEventListener(\"pointerdown\", () => notifyParent(\"pointerdown\"), {\n capture: true,\n passive: true,\n });\n window.addEventListener(\"touchstart\", () => notifyParent(\"touchstart\"), {\n capture: true,\n passive: true,\n });\n window.addEventListener(\"wheel\", () => notifyParent(\"wheel\"), {\n passive: true,\n });\n window.addEventListener(\"keydown\", () => notifyParent(\"keydown\"), true);\n})();`;\n doc.head.appendChild(interactionBridgeScript);\n }\n\n const rootEl = doc.getElementById(\"root\");\n if (!rootEl) return undefined;\n\n const root = createRoot(rootEl);\n rootRef.current = root;\n let isDestroyed = false;\n\n const parseExplicitHeight = (\n value: string,\n parentViewportHeight: number\n ) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const numeric = Number.parseFloat(normalized);\n if (Number.isNaN(numeric)) return null;\n if (/(dvh|svh|lvh|vh)$/i.test(normalized)) {\n return (numeric / 100) * parentViewportHeight;\n }\n if (normalized.endsWith(\"px\") || /^[0-9.]+$/.test(normalized)) {\n return numeric;\n }\n return null;\n };\n const parseTailwindHeightClass = (\n className: string,\n parentViewportHeight: number\n ) => {\n if (!className.trim()) return null;\n const viewportHeightCss =\n extractViewportHeightFromTailwindClass(className);\n if (viewportHeightCss) {\n return parseExplicitHeight(viewportHeightCss, parentViewportHeight);\n }\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n const arbitraryToken = normalizedTokens.find((token) =>\n /^h-\\[[0-9.]+px\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(/^h-\\[([0-9.]+)px\\]$/i);\n if (!matched) return null;\n const numeric = Number.parseFloat(matched[1]);\n if (Number.isNaN(numeric)) return null;\n return numeric;\n };\n\n const resolveExplicitHeight = () => {\n if (!iframeRef.current || !doc.body) return null;\n const wrapper = doc.body.querySelector(\n \".sandbox-wrapper\"\n ) as HTMLElement | null;\n const container = wrapper?.firstElementChild as HTMLElement | null;\n if (!container) return null;\n const elements = Array.from(container.children) as HTMLElement[];\n if (elements.length !== 1) return null;\n const target = elements[0];\n const heightValue = target.style.height || target.getAttribute(\"height\");\n const parentViewportHeight =\n iframeRef.current.ownerDocument?.documentElement?.clientHeight ||\n window.innerHeight;\n const parsed = heightValue\n ? parseExplicitHeight(heightValue, parentViewportHeight)\n : null;\n if (parsed !== null) {\n return Math.ceil(parsed);\n }\n const classHeight = parseTailwindHeightClass(\n target.getAttribute(\"class\") || \"\",\n parentViewportHeight\n );\n return classHeight !== null ? Math.ceil(classHeight) : null;\n };\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 explicitHeight = resolveExplicitHeight();\n const nextHeight = Math.max(\n 200,\n explicitHeight ?? Math.ceil(contentHeight)\n );\n setHeight(nextHeight);\n };\n const scheduleHeightUpdate = () => {\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n updateHeight();\n });\n };\n updateHeightRef.current = scheduleHeightUpdate;\n\n updateHeight();\n scheduleHeightUpdate();\n\n // Inject Tailwind/DaisyUI/GSAP into iframe for all sandbox modes.\n // Dynamic import keeps ~3.3 MB of vendor libs out of the main bundle.\n // Tailwind's MutationObserver ensures styles apply even if content renders first.\n loadBlackboardVendor()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n scheduleHeightUpdate();\n })\n .catch(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n\n const resizeObserver = new ResizeObserver(() => updateHeight());\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n return () => {\n isDestroyed = true;\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={renderHtmlContent}\n loadingText={loadingText}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n fullScreenButtonText={fullScreenButtonText}\n hideFullScreen={hideFullScreen}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n />\n );\n requestAnimationFrame(() => updateHeightRef.current?.());\n }, [\n renderHtmlContent,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n resetToken,\n mode,\n ]);\n const containerClassName = [\n \"w-full relative content-render-iframe-sandbox\",\n isBlackboardMode\n ? \"h-full overflow-auto flex flex-col\"\n : \"aspect-[16/9] overflow-hidden flex items-center justify-center\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n ref={containerRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className={containerClassName}\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 allow-popups allow-popups-to-escape-sandbox\"\n allow=\"fullscreen\"\n allowFullScreen\n className={[className, \"w-full h-full mx-auto my-auto block\"]\n .filter(Boolean)\n .join(\" \")}\n style={{\n height: \"100%\",\n margin: \"auto\",\n }}\n />\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["loadBlackboardVendor","m","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_MESSAGE_SOURCE","SANDBOX_INTERACTION_MESSAGE_TYPE","SANDBOX_INTERACTION_THROTTLE_MS","normalizeTailwindHeightTokens","className","token","parseViewportHeightCss","value","normalized","matched","extractViewportHeightFromTailwindClass","normalizedTokens","arbitraryToken","IframeSandbox","content","type","loadingText","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","containerRef","useRef","iframeRef","rootRef","docRef","updateHeightRef","setHeight","useState","resetToken","setResetToken","isFullscreen","setIsFullscreen","isBlackboardMode","prevHtmlRef","htmlContent","React","sandboxSegments","splitContentSegments","seg","renderHtmlContent","setRenderHtmlContent","prevIncomingHtmlRef","pendingHtmlRef","deferRenderTimerRef","clearDeferredRenderTimer","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","hasRootVhHeight","rootMatch","attrs","heightAttrMatch","explicitHeightCss","styleHeightMatch","styleHeightCss","classAttrMatch","prev","iframe","doc","interactionBridgeScript","rootEl","root","createRoot","isDestroyed","parseExplicitHeight","parentViewportHeight","numeric","parseTailwindHeightClass","viewportHeightCss","resolveExplicitHeight","container","elements","target","heightValue","parsed","classHeight","updateHeight","bodyRect","htmlRect","bodyHeight","htmlHeight","contentHeight","explicitHeight","nextHeight","scheduleHeightUpdate","inject","resizeObserver","onFullscreenChange","toggleFullscreen","jsx","SandboxApp","containerClassName","jsxs","ContentRender"],"mappings":"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"}
@@ -1,12 +1,11 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const b=require("../../_virtual/jsx-runtime.cjs.js"),t=require("react"),K=require("../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/lucide-react@0.525.0_react@19.0.1/node_modules/lucide-react/dist/esm/icons/loader-circle.cjs.js"),U=({html:l,styleLoadingText:B,scriptLoadingText:G,resetToken:f=0,mode:F="content",hasRootVhHeight:W=!1})=>{const _=t.useRef(null),R=t.useRef(null),[,N]=t.useState(!0),[k,S]=t.useState(!1),[z,v]=t.useState(!1),E=t.useRef([]),w=t.useRef([]),A=t.useRef(0),I=t.useRef(0),d=t.useRef(null),p=t.useRef(null),m=t.useRef(!1),h=t.useRef(!1),C=t.useRef(!1),M=t.useRef(f),H=200,o=r=>{r.current&&(clearTimeout(r.current),r.current=null)},L=(r,s,a,y)=>{const i=performance.now()-a.current,g=Math.max(0,H-i);o(s),s.current=window.setTimeout(()=>{r(!1),y?.(),s.current=null},g)};t.useEffect(()=>{const r=R.current?.ownerDocument;if(!r)return;const s="sandbox-spinner-style";let a=r.getElementById(s);a||(a=r.createElement("style"),a.id=s,r.head?.appendChild(a)),a.textContent=`
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const v=require("../../_virtual/jsx-runtime.cjs.js"),t=require("react"),J=require("../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/lucide-react@0.525.0_react@19.0.1/node_modules/lucide-react/dist/esm/icons/loader-circle.cjs.js"),X=["src","srcset","sizes","alt","class","width","height","style","loading","decoding","crossorigin","referrerpolicy"],F=a=>X.map(r=>`${r}:${a.getAttribute(r)||""}`).join("|"),Y=a=>{const r=new Map;return a.querySelectorAll("img").forEach(l=>{const c=l,n=F(c),f=r.get(n)||[];f.push(c),r.set(n,f)}),r},Z=(a,r)=>{const l=Array.from(a.attributes),c=new Set(l.map(n=>n.name));Array.from(r.attributes).forEach(n=>{c.has(n.name)||r.removeAttribute(n.name)}),l.forEach(n=>{r.setAttribute(n.name,n.value)})},ee=(a,r)=>{r.size&&a.querySelectorAll("img").forEach(l=>{const c=l,n=F(c),f=r.get(n),h=f?.shift();h&&(Z(c,h),c.replaceWith(h),f&&f.length===0&&r.delete(n))})},te=({html:a,styleLoadingText:r,scriptLoadingText:l,resetToken:c=0,mode:n="content",hasRootVhHeight:f=!1})=>{const h=t.useRef(null),w=t.useRef(null),[,k]=t.useState(!0),[H,A]=t.useState(!1),[O,C]=t.useState(!1),I=t.useRef([]),j=t.useRef([]),q=t.useRef(0),L=t.useRef(0),g=t.useRef(null),x=t.useRef(null),b=t.useRef(!1),R=t.useRef(!1),N=t.useRef(!1),_=t.useRef(c),U=200,d=s=>{s.current&&(clearTimeout(s.current),s.current=null)},B=(s,i,u,T)=>{const S=performance.now()-u.current,p=Math.max(0,U-S);d(i),i.current=window.setTimeout(()=>{s(!1),T?.(),i.current=null},p)};t.useEffect(()=>{const s=w.current?.ownerDocument;if(!s)return;const i="sandbox-spinner-style";let u=s.getElementById(i);u||(u=s.createElement("style"),u.id=i,s.head?.appendChild(u)),u.textContent=`
2
2
  @keyframes sandbox-spin { from { transform: rotate(0deg);} to { transform: rotate(360deg);} }
3
3
  .sandbox-wrapper { align-items: center; }
4
4
  .sandbox-container { width: 100%; }
5
5
  .sandbox-container svg,
6
6
  .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }
7
- @media (max-width: 640px) {
8
- .sandbox-wrapper { align-items: stretch; }
9
- .sandbox-wrapper[data-root-vh="true"] .sandbox-container > :first-child { height: auto !important; }
7
+ .justify-\\[safe_center\\]{
8
+ justify-content: safe center;
10
9
  }
11
- `},[]),t.useEffect(()=>{f!==M.current&&(C.current=!1,M.current=f),o(d),o(p),m.current=!1,h.current=!1;const r=R.current;if(!r)return;const s=r.ownerDocument,a=s?.body;if(!a)return;E.current.forEach(e=>e.remove()),E.current=[],w.current.forEach(e=>e.remove()),w.current=[];const y=C.current;N(!y),S(!1),v(!1),r.innerHTML="";const i=document.createElement("div");i.innerHTML=l;const g=(l.match(/<script[\s>]/gi)||[]).length,P=(l.match(/<\/script>/gi)||[]).length,Q=g>0&&g===P,u=[];Array.from(i.querySelectorAll("style, script")).forEach(e=>{if(e.tagName.toLowerCase()==="style"){const n=s.createElement("style");n.textContent=e.textContent||"",Array.from(e.attributes).forEach(c=>{n.setAttribute(c.name,c.value)}),u.push(n)}else{const n=s.createElement("script");Array.from(e.attributes).forEach(c=>{n.setAttribute(c.name,c.value)}),n.textContent=e.textContent||"",u.push(n)}e.remove()});const T=u.some(e=>e.tagName.toLowerCase()==="style"),D=u.some(e=>e.tagName.toLowerCase()==="script");T&&(m.current=!0,A.current=performance.now(),o(d),S(!0)),D&&(h.current=!0,I.current=performance.now(),o(p),v(!0));const q=!!i.firstElementChild;N(!q&&!y),q&&(C.current=!0);const J=Array.from(i.childNodes);r.append(...J),u.forEach(e=>{if(e.tagName.toLowerCase()==="style"){s.head?.appendChild(e),E.current.push(e);return}if(Q){const n=e,c=n.textContent||"";if(!n.src)try{new Function(c)}catch{n.remove();return}try{a.appendChild(n),w.current.push(n)}catch{n.remove()}}else e.remove()}),requestAnimationFrame(()=>{T&&L(S,d,A,()=>{m.current=!1}),D&&L(v,p,I,()=>{h.current=!1})})},[l,f]),t.useEffect(()=>()=>{o(d),o(p)},[]);const x=z||h.current?G||"Building scripts cache...":k||m.current?B||"Building styles...":null,j=F==="blackboard",O={position:"relative",width:"100%",height:j?"100vh":"100%",display:"flex",flexDirection:"column",justifyContent:j?"space-around":"flex-start"},V={pointerEvents:x?"none":void 0,margin:j?void 0:"auto 0",width:"100%"};return b.jsxRuntimeExports.jsxs("div",{ref:_,"data-root-vh":W?"true":"false",className:"sandbox-wrapper",style:O,"aria-busy":!!x,children:[b.jsxRuntimeExports.jsx("div",{ref:R,className:"sandbox-container",style:V}),x&&b.jsxRuntimeExports.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(51, 51, 51, 0.80)",color:"#ffffff",fontSize:16,fontWeight:700,gap:10,pointerEvents:"auto",zIndex:20},children:[b.jsxRuntimeExports.jsx(K.default,{"aria-hidden":!0,size:20,style:{animation:"sandbox-spin 1s linear infinite"}}),x]})]})};exports.default=U;
10
+ `},[]),t.useEffect(()=>{c!==_.current&&(N.current=!1,_.current=c),d(g),d(x),b.current=!1,R.current=!1;const s=w.current;if(!s)return;const i=s.ownerDocument,u=i?.body;if(!u)return;const T=Y(s);I.current.forEach(e=>e.remove()),I.current=[],j.current.forEach(e=>e.remove()),j.current=[];const S=N.current;k(!S),A(!1),C(!1);const p=i.createElement("div");p.innerHTML=a;const D=(a.match(/<script[\s>]/gi)||[]).length,K=(a.match(/<\/script>/gi)||[]).length,P=D>0&&D===K,y=[];Array.from(p.querySelectorAll("style, script")).forEach(e=>{if(e.tagName.toLowerCase()==="style"){const o=i.createElement("style");o.textContent=e.textContent||"",Array.from(e.attributes).forEach(m=>{o.setAttribute(m.name,m.value)}),y.push(o)}else{const o=i.createElement("script");Array.from(e.attributes).forEach(m=>{o.setAttribute(m.name,m.value)}),o.textContent=e.textContent||"",y.push(o)}e.remove()}),ee(p,T);const G=y.some(e=>e.tagName.toLowerCase()==="style"),z=y.some(e=>e.tagName.toLowerCase()==="script");G&&(b.current=!0,q.current=performance.now(),d(g),A(!0)),z&&(R.current=!0,L.current=performance.now(),d(x),C(!0));const W=!!p.firstElementChild;k(!W&&!S),W&&(N.current=!0),s.innerHTML="";const Q=Array.from(p.childNodes);s.append(...Q),y.forEach(e=>{if(e.tagName.toLowerCase()==="style"){i.head?.appendChild(e),I.current.push(e);return}if(P){const o=e,m=o.textContent||"";if(!o.src)try{new Function(m)}catch{o.remove();return}try{u.appendChild(o),j.current.push(o)}catch{o.remove()}}else e.remove()}),requestAnimationFrame(()=>{G&&B(A,g,q,()=>{b.current=!1}),z&&B(C,x,L,()=>{R.current=!1})})},[a,c]),t.useEffect(()=>()=>{d(g),d(x)},[]);const E=O||R.current?l||"Building scripts cache...":H||b.current?r||"Building styles...":null,M=n==="blackboard",V={position:"relative",width:"100%",height:M?"100vh":"100%",display:"flex",flexDirection:"column",justifyContent:M?"space-around":"flex-start"},$={pointerEvents:E?"none":void 0,margin:M?void 0:"auto 0",width:"100%"};return v.jsxRuntimeExports.jsxs("div",{ref:h,"data-root-vh":f?"true":"false",className:"sandbox-wrapper",style:V,"aria-busy":!!E,children:[v.jsxRuntimeExports.jsx("div",{ref:w,className:"sandbox-container",style:$}),E&&v.jsxRuntimeExports.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(51, 51, 51, 0.80)",color:"#ffffff",fontSize:16,fontWeight:700,gap:10,pointerEvents:"auto",zIndex:20},children:[v.jsxRuntimeExports.jsx(J.default,{"aria-hidden":!0,size:20,style:{animation:"sandbox-spin 1s linear infinite"}}),E]})]})};exports.default=te;
12
11
  //# sourceMappingURL=SandboxApp.cjs.js.map