markdown-flow-ui 0.1.99 → 0.1.100-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 (83) hide show
  1. package/dist/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/ellipsis-vertical.cjs.js +7 -0
  2. package/dist/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/ellipsis-vertical.cjs.js.map +1 -0
  3. package/dist/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/ellipsis-vertical.es.js +17 -0
  4. package/dist/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/ellipsis-vertical.es.js.map +1 -0
  5. package/dist/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/file-pen-line.cjs.js +7 -0
  6. package/dist/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/file-pen-line.cjs.js.map +1 -0
  7. package/dist/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/file-pen-line.es.js +29 -0
  8. package/dist/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/file-pen-line.es.js.map +1 -0
  9. package/dist/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/maximize.cjs.js +7 -0
  10. package/dist/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/maximize.cjs.js.map +1 -0
  11. package/dist/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/maximize.es.js +18 -0
  12. package/dist/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/maximize.es.js.map +1 -0
  13. package/dist/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/rotate-ccw.cjs.js +7 -0
  14. package/dist/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/rotate-ccw.cjs.js.map +1 -0
  15. package/dist/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/rotate-ccw.es.js +16 -0
  16. package/dist/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/rotate-ccw.es.js.map +1 -0
  17. package/dist/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/rotate-cw.cjs.js +7 -0
  18. package/dist/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/rotate-cw.cjs.js.map +1 -0
  19. package/dist/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/rotate-cw.es.js +16 -0
  20. package/dist/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/rotate-cw.es.js.map +1 -0
  21. package/dist/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/volume-2.cjs.js +7 -0
  22. package/dist/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/volume-2.cjs.js.map +1 -0
  23. package/dist/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/volume-2.es.js +23 -0
  24. package/dist/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/volume-2.es.js.map +1 -0
  25. package/dist/_virtual/index.cjs.js +1 -1
  26. package/dist/_virtual/index.es.js +1 -0
  27. package/dist/assets/markdown-flow-ui.css +1 -1
  28. package/dist/components/ContentRender/IframeSandbox.cjs.js +3 -3
  29. package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
  30. package/dist/components/ContentRender/IframeSandbox.es.js +212 -164
  31. package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
  32. package/dist/components/ContentRender/SandboxApp.cjs.js +2 -2
  33. package/dist/components/ContentRender/SandboxApp.cjs.js.map +1 -1
  34. package/dist/components/ContentRender/SandboxApp.es.js +21 -21
  35. package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
  36. package/dist/components/ContentRender/index.cjs.js +1 -1
  37. package/dist/components/ContentRender/index.es.js +6 -5
  38. package/dist/components/MarkdownFlow/MarkdownFlow.cjs.js +1 -1
  39. package/dist/components/MarkdownFlow/MarkdownFlow.cjs.js.map +1 -1
  40. package/dist/components/MarkdownFlow/MarkdownFlow.es.js +2 -2
  41. package/dist/components/Slide/Player.cjs.js +2 -0
  42. package/dist/components/Slide/Player.cjs.js.map +1 -0
  43. package/dist/components/Slide/Player.d.ts +19 -0
  44. package/dist/components/Slide/Player.es.js +327 -0
  45. package/dist/components/Slide/Player.es.js.map +1 -0
  46. package/dist/components/Slide/Slide.cjs.js +2 -0
  47. package/dist/components/Slide/Slide.cjs.js.map +1 -0
  48. package/dist/components/Slide/Slide.d.ts +12 -0
  49. package/dist/components/Slide/Slide.es.js +394 -0
  50. package/dist/components/Slide/Slide.es.js.map +1 -0
  51. package/dist/components/Slide/Slide.stories.d.ts +47 -0
  52. package/dist/components/Slide/diff-utils.cjs.js +5 -0
  53. package/dist/components/Slide/diff-utils.cjs.js.map +1 -0
  54. package/dist/components/Slide/diff-utils.d.ts +18 -0
  55. package/dist/components/Slide/diff-utils.es.js +113 -0
  56. package/dist/components/Slide/diff-utils.es.js.map +1 -0
  57. package/dist/components/Slide/index.d.ts +12 -0
  58. package/dist/components/Slide/interaction-defaults.cjs.js +2 -0
  59. package/dist/components/Slide/interaction-defaults.cjs.js.map +1 -0
  60. package/dist/components/Slide/interaction-defaults.d.ts +23 -0
  61. package/dist/components/Slide/interaction-defaults.es.js +85 -0
  62. package/dist/components/Slide/interaction-defaults.es.js.map +1 -0
  63. package/dist/components/Slide/types.d.ts +24 -0
  64. package/dist/components/Slide/useSlide.cjs.js +2 -0
  65. package/dist/components/Slide/useSlide.cjs.js.map +1 -0
  66. package/dist/components/Slide/useSlide.d.ts +21 -0
  67. package/dist/components/Slide/useSlide.es.js +102 -0
  68. package/dist/components/Slide/useSlide.es.js.map +1 -0
  69. package/dist/components/index.d.ts +5 -0
  70. package/dist/index.cjs.js +1 -1
  71. package/dist/index.es.js +21 -9
  72. package/dist/index.es.js.map +1 -1
  73. package/dist/lib/browserUserActivation.cjs.js +2 -0
  74. package/dist/lib/browserUserActivation.cjs.js.map +1 -0
  75. package/dist/lib/browserUserActivation.d.ts +5 -0
  76. package/dist/lib/browserUserActivation.es.js +13 -0
  77. package/dist/lib/browserUserActivation.es.js.map +1 -0
  78. package/dist/markdown-flow-ui-lib.css +1 -1
  79. package/dist/renderer.cjs.js +1 -1
  80. package/dist/renderer.d.ts +3 -2
  81. package/dist/renderer.es.js +20 -8
  82. package/dist/renderer.es.js.map +1 -1
  83. package/package.json +1 -1
@@ -1,99 +1,119 @@
1
- import { j as R } from "../../_virtual/jsx-runtime.es.js";
2
- import U, { useRef as h, useState as j, useEffect as x } 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((i) => i.injectBlackboardLibraries), ut = /<img\b[^>]*>/i, at = 180, J = (i) => i.split(/\s+/).filter(Boolean).map((r) => r.split(":").pop() || r), Y = (i) => {
8
- const r = i.trim().toLowerCase();
9
- if (!r) return null;
10
- const d = r.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);
11
- return d ? `${d[1]}${d[2].toLowerCase()}` : null;
12
- }, Z = (i) => {
13
- if (!i.trim()) return null;
14
- const r = J(i);
15
- if (r.includes("h-screen") || r.includes("h-dvh"))
1
+ import { j as u } from "../../_virtual/jsx-runtime.es.js";
2
+ import se, { useRef as d, useState as A, useCallback as ve, useEffect as C } from "react";
3
+ import { createRoot as xe } from "react-dom/client";
4
+ import Ee from "./SandboxApp.es.js";
5
+ import { splitContentSegments as ye } from "./utils/split-content.es.js";
6
+ import Ce from "./ContentRender.es.js";
7
+ import Re from "../../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.es.js";
8
+ let G = null;
9
+ const ce = () => (G || (G = import("./blackboard-vendor.es.js").then(
10
+ (s) => s.injectBlackboardLibraries
11
+ )), G);
12
+ typeof window < "u" && ce();
13
+ const He = /<img\b[^>]*>/i, Se = 180, Te = "markdown-flow-ui:sandbox", Ae = "interaction", Me = 240, ae = (s) => s.split(/\s+/).filter(Boolean).map((n) => n.split(":").pop() || n), ie = (s) => {
14
+ const n = s.trim().toLowerCase();
15
+ if (!n) return null;
16
+ const m = n.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);
17
+ return m ? `${m[1]}${m[2].toLowerCase()}` : null;
18
+ }, le = (s) => {
19
+ if (!s.trim()) return null;
20
+ const n = ae(s);
21
+ if (n.includes("h-screen") || n.includes("h-dvh"))
16
22
  return "100dvh";
17
- if (r.includes("h-svh"))
23
+ if (n.includes("h-svh"))
18
24
  return "100svh";
19
- if (r.includes("h-lvh"))
25
+ if (n.includes("h-lvh"))
20
26
  return "100lvh";
21
- const d = r.find(
22
- (E) => /^h-\[[0-9.]+(vh|dvh|svh|lvh)\]$/i.test(E)
27
+ const m = n.find(
28
+ (M) => /^h-\[[0-9.]+(vh|dvh|svh|lvh)\]$/i.test(M)
23
29
  );
24
- if (!d) return null;
25
- const v = d.match(/^h-\[([0-9.]+)(vh|dvh|svh|lvh)\]$/i);
26
- return v ? `${v[1]}${v[2].toLowerCase()}` : null;
27
- }, vt = ({
28
- content: i,
29
- type: r,
30
- className: d,
31
- loadingText: v,
32
- styleLoadingText: E,
33
- scriptLoadingText: S,
34
- fullScreenButtonText: z,
35
- hideFullScreen: V = !1,
36
- mode: a = "content"
30
+ if (!m) return null;
31
+ const p = m.match(/^h-\[([0-9.]+)(vh|dvh|svh|lvh)\]$/i);
32
+ return p ? `${p[1]}${p[2].toLowerCase()}` : null;
33
+ }, Oe = ({
34
+ content: s,
35
+ type: n,
36
+ className: m,
37
+ loadingText: p,
38
+ styleLoadingText: M,
39
+ scriptLoadingText: U,
40
+ fullScreenButtonText: j,
41
+ hideFullScreen: W = !1,
42
+ mode: h = "content"
37
43
  }) => {
38
- const O = h(null), w = h(null), F = h(null), L = h(null), $ = h(() => {
39
- }), [, K] = j(480), [q, Q] = j(0), [X, tt] = j(!1), et = a === "blackboard", N = h(""), n = U.useMemo(() => {
40
- const e = it(i).filter((l) => l.type === "sandbox");
41
- return (a === "blackboard" ? e[e.length - 1]?.value || "" : e.map((l) => l.value).join(`
44
+ const X = d(null), E = d(null), _ = d(null), Y = d(null), D = d(() => {
45
+ }), [ue, de] = A(480), Z = d(0), [J, he] = A(0), [me, fe] = A(!1), [L, O] = A(
46
+ n !== "sandbox"
47
+ ), B = h === "blackboard", F = d(""), r = se.useMemo(() => {
48
+ const e = ye(s).filter((l) => l.type === "sandbox");
49
+ return (h === "blackboard" ? e[e.length - 1]?.value || "" : e.map((l) => l.value).join(`
42
50
  `)) || "";
43
- }, [i, a]), [k, P] = j(n), G = h(n), B = h(n), H = h(null), _ = () => {
44
- H.current !== null && (window.clearTimeout(H.current), H.current = null);
51
+ }, [s, h]), [k, K] = A(r), Q = d(r), z = d(r), R = d(null), y = ve((t) => {
52
+ if (typeof window > "u")
53
+ return;
54
+ const e = Date.now();
55
+ e - Z.current < Me || (Z.current = e, window.postMessage(
56
+ {
57
+ source: Te,
58
+ type: Ae,
59
+ eventType: t
60
+ },
61
+ window.location.origin
62
+ ));
63
+ }, []), $ = () => {
64
+ R.current !== null && (window.clearTimeout(R.current), R.current = null);
45
65
  };
46
- x(
66
+ C(
47
67
  () => () => {
48
- _();
68
+ $();
49
69
  },
50
70
  []
51
- ), x(() => {
52
- const t = G.current;
53
- G.current = n;
54
- const e = !!t && n.length > t.length && n.startsWith(t), o = ut.test(n);
55
- if (!(e && o)) {
56
- _(), B.current = n, P(n);
71
+ ), C(() => {
72
+ const t = Q.current;
73
+ Q.current = r;
74
+ const e = !!t && r.length > t.length && r.startsWith(t), i = He.test(r);
75
+ if (!(e && i)) {
76
+ $(), z.current = r, K(r);
57
77
  return;
58
78
  }
59
- B.current = n, _(), H.current = window.setTimeout(() => {
60
- P(B.current), H.current = null;
61
- }, at);
62
- }, [n]);
63
- const W = !!U.useMemo(() => {
79
+ z.current = r, $(), R.current = window.setTimeout(() => {
80
+ K(z.current), R.current = null;
81
+ }, Se);
82
+ }, [r]);
83
+ const ee = se.useMemo(() => {
64
84
  const t = k.trim();
65
85
  if (!t) return null;
66
86
  const e = t.match(/^<([a-zA-Z][\w:-]*)(\s[^>]*?)?>/);
67
87
  if (!e) return null;
68
- const o = e[2] || "", l = o.match(/\bheight\s*=\s*["']([^"']+)["']/i);
88
+ const i = e[2] || "", l = i.match(/\bheight\s*=\s*["']([^"']+)["']/i);
69
89
  if (l) {
70
- const f = Y(l[1]);
90
+ const f = ie(l[1]);
71
91
  if (f) return f;
72
92
  }
73
- const C = o.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(
93
+ const S = i.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(
74
94
  /\bheight\s*:\s*([^;]+)/i
75
95
  )?.[1];
76
- if (C) {
77
- const f = Y(C);
96
+ if (S) {
97
+ const f = ie(S);
78
98
  if (f) return f;
79
99
  }
80
- const M = o.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1];
81
- return M ? Z(M) : null;
82
- }, [k]);
83
- x(() => {
84
- if (a !== "blackboard") {
85
- N.current = n;
100
+ const g = i.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1];
101
+ return g ? le(g) : null;
102
+ }, [k]), te = !!ee, ne = n === "sandbox", H = B && n === "sandbox" ? ee ?? `${ue}px` : void 0;
103
+ C(() => {
104
+ if (h !== "blackboard") {
105
+ F.current = r;
86
106
  return;
87
107
  }
88
- const t = N.current;
89
- !(t && n.startsWith(t)) && t && Q((o) => o + 1), N.current = n;
90
- }, [n, a]), x(() => {
91
- const t = w.current;
108
+ const t = F.current;
109
+ !(t && r.startsWith(t)) && t && he((i) => i + 1), F.current = r;
110
+ }, [r, h]), C(() => {
111
+ const t = E.current;
92
112
  if (!t) return;
93
113
  const e = t.contentDocument;
94
114
  if (!e) return;
95
115
  e.open(), e.write(`<!DOCTYPE html>
96
- <html${a === "blackboard" ? ' style="height: 100%;"' : ""}>
116
+ <html${h === "blackboard" ? ' style="height: 100%;"' : ""}>
97
117
  <head>
98
118
  <meta charset="utf-8" />
99
119
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -106,78 +126,82 @@ const ct = () => import("./blackboard-vendor.es.js").then((i) => i.injectBlackbo
106
126
  <body>
107
127
  <div id="root"></div>
108
128
  </body>
109
- </html>`), e.close(), L.current = e;
110
- const o = e.getElementById("root");
111
- if (!o) return;
112
- const l = ot(o);
113
- F.current = l;
114
- let y = !1;
115
- const C = (c, m) => {
116
- const s = c.trim().toLowerCase();
117
- if (!s) return null;
118
- const u = Number.parseFloat(s);
119
- return Number.isNaN(u) ? null : /(dvh|svh|lvh|vh)$/i.test(s) ? u / 100 * m : s.endsWith("px") || /^[0-9.]+$/.test(s) ? u : null;
120
- }, M = (c, m) => {
129
+ </html>`), e.close(), Y.current = e;
130
+ const i = B && n === "sandbox", l = () => y("pointerdown"), V = () => y("mousedown"), S = () => y("touchstart");
131
+ i && (e.addEventListener("pointerdown", l, !0), e.addEventListener("mousedown", V, !0), e.addEventListener("touchstart", S, !0));
132
+ const g = e.getElementById("root");
133
+ if (!g) return;
134
+ const f = xe(g);
135
+ _.current = f;
136
+ let T = !1;
137
+ const oe = (c, b) => {
138
+ const o = c.trim().toLowerCase();
139
+ if (!o) return null;
140
+ const a = Number.parseFloat(o);
141
+ return Number.isNaN(a) ? null : /(dvh|svh|lvh|vh)$/i.test(o) ? a / 100 * b : o.endsWith("px") || /^[0-9.]+$/.test(o) ? a : null;
142
+ }, ge = (c, b) => {
121
143
  if (!c.trim()) return null;
122
- const s = Z(c);
123
- if (s)
124
- return C(s, m);
125
- const p = J(c).find(
126
- (A) => /^h-\[[0-9.]+px\]$/i.test(A)
144
+ const o = le(c);
145
+ if (o)
146
+ return oe(o, b);
147
+ const w = ae(c).find(
148
+ (I) => /^h-\[[0-9.]+px\]$/i.test(I)
127
149
  );
128
- if (!p) return null;
129
- const g = p.match(/^h-\[([0-9.]+)px\]$/i);
130
- if (!g) return null;
131
- const b = Number.parseFloat(g[1]);
132
- return Number.isNaN(b) ? null : b;
133
- }, f = () => {
134
- if (!w.current || !e.body) return null;
135
- const m = e.body.querySelector(
150
+ if (!w) return null;
151
+ const v = w.match(/^h-\[([0-9.]+)px\]$/i);
152
+ if (!v) return null;
153
+ const x = Number.parseFloat(v[1]);
154
+ return Number.isNaN(x) ? null : x;
155
+ }, we = () => {
156
+ if (!E.current || !e.body) return null;
157
+ const b = e.body.querySelector(
136
158
  ".sandbox-wrapper"
137
159
  )?.firstElementChild;
138
- if (!m) return null;
139
- const s = Array.from(m.children);
140
- if (s.length !== 1) return null;
141
- const u = s[0], p = u.style.height || u.getAttribute("height"), g = w.current.ownerDocument?.documentElement?.clientHeight || window.innerHeight, b = p ? C(p, g) : null;
142
- if (b !== null)
143
- return Math.ceil(b);
144
- const A = M(
145
- u.getAttribute("class") || "",
146
- g
160
+ if (!b) return null;
161
+ const o = Array.from(b.children);
162
+ if (o.length !== 1) return null;
163
+ const a = o[0], w = a.style.height || a.getAttribute("height"), v = E.current.ownerDocument?.documentElement?.clientHeight || window.innerHeight, x = w ? oe(w, v) : null;
164
+ if (x !== null)
165
+ return Math.ceil(x);
166
+ const I = ge(
167
+ a.getAttribute("class") || "",
168
+ v
147
169
  );
148
- return A !== null ? Math.ceil(A) : null;
149
- }, D = () => {
150
- if (!w.current || !e.body) return;
151
- const c = e.body.getBoundingClientRect(), m = e.documentElement?.getBoundingClientRect(), s = c.height, u = m?.height || 0, p = Math.max(s, u), g = f(), b = Math.max(
170
+ return I !== null ? Math.ceil(I) : null;
171
+ }, P = () => {
172
+ if (!E.current || !e.body) return;
173
+ const c = e.body.getBoundingClientRect(), b = e.documentElement?.getBoundingClientRect(), o = c.height, a = b?.height || 0, w = Math.max(o, a), v = we(), x = Math.max(
152
174
  200,
153
- g ?? Math.ceil(p)
175
+ v ?? Math.ceil(w)
154
176
  );
155
- K(b);
156
- }, T = () => {
177
+ de(x);
178
+ }, N = () => {
157
179
  requestAnimationFrame(() => {
158
- y || D();
180
+ T || P();
159
181
  });
160
182
  };
161
- $.current = T, D(), T(), ct().then((c) => {
162
- y || (c(e), T());
183
+ D.current = N, P(), N(), ne ? ce().then((c) => {
184
+ T || (c(e), requestAnimationFrame(() => {
185
+ T || (O(!0), N());
186
+ }));
163
187
  }).catch(() => {
164
- y || T();
165
- });
166
- const I = new ResizeObserver(() => D());
167
- return I.observe(e.body), o && I.observe(o), () => {
168
- y = !0, I.disconnect(), setTimeout(() => {
169
- l.unmount(), F.current = null, L.current = null, $.current = () => {
188
+ T || (O(!0), N());
189
+ }) : O(!0);
190
+ const q = new ResizeObserver(() => P());
191
+ return q.observe(e.body), g && q.observe(g), () => {
192
+ T = !0, q.disconnect(), i && (e.removeEventListener("pointerdown", l, !0), e.removeEventListener("mousedown", V, !0), e.removeEventListener("touchstart", S, !0)), setTimeout(() => {
193
+ f.unmount(), _.current = null, Y.current = null, D.current = () => {
170
194
  };
171
195
  }, 0);
172
196
  };
173
- }, []), x(() => {
197
+ }, []), C(() => {
174
198
  const t = () => {
175
- tt(!!document.fullscreenElement);
199
+ fe(!!document.fullscreenElement);
176
200
  };
177
201
  return document.addEventListener("fullscreenchange", t), () => document.removeEventListener("fullscreenchange", t);
178
202
  }, []);
179
- const nt = () => {
180
- const t = O.current || w.current;
203
+ const be = () => {
204
+ const t = X.current || E.current;
181
205
  if (t) {
182
206
  if (document.fullscreenElement) {
183
207
  document.exitFullscreen().catch(() => {
@@ -188,72 +212,96 @@ const ct = () => import("./blackboard-vendor.es.js").then((i) => i.injectBlackbo
188
212
  });
189
213
  }
190
214
  };
191
- x(() => {
192
- const t = F.current;
193
- t && (t.render(
194
- /* @__PURE__ */ R.jsx(
195
- st,
215
+ C(() => {
216
+ const t = _.current;
217
+ !t || !L || (t.render(
218
+ /* @__PURE__ */ u.jsx(
219
+ Ee,
196
220
  {
197
221
  html: k,
198
- loadingText: v,
199
- styleLoadingText: E,
200
- scriptLoadingText: S,
201
- fullScreenButtonText: z,
202
- hideFullScreen: V,
203
- resetToken: q,
204
- hasRootVhHeight: W,
205
- mode: a
222
+ loadingText: p,
223
+ styleLoadingText: M,
224
+ scriptLoadingText: U,
225
+ fullScreenButtonText: j,
226
+ hideFullScreen: W,
227
+ resetToken: J,
228
+ hasRootVhHeight: te,
229
+ mode: h
206
230
  }
207
231
  )
208
- ), requestAnimationFrame(() => $.current?.()));
232
+ ), requestAnimationFrame(() => D.current?.()));
209
233
  }, [
210
234
  k,
211
- v,
212
- E,
213
- S,
214
- z,
215
- q,
216
- a
235
+ p,
236
+ M,
237
+ U,
238
+ j,
239
+ J,
240
+ h,
241
+ L
217
242
  ]);
218
- const rt = [
243
+ const pe = [
219
244
  "w-full relative content-render-iframe-sandbox",
220
- et ? "h-full overflow-auto flex flex-col" : "aspect-[16/9] overflow-hidden flex items-center justify-center"
221
- ].filter(Boolean).join(" ");
222
- return /* @__PURE__ */ R.jsxs(
245
+ B ? "h-full overflow-auto flex flex-col" : "aspect-[16/9] overflow-hidden flex items-center justify-center"
246
+ ].filter(Boolean).join(" "), re = ne && !L;
247
+ return /* @__PURE__ */ u.jsxs(
223
248
  "div",
224
249
  {
225
- ref: O,
226
- "data-root-vh": W ? "true" : "false",
227
- className: rt,
250
+ ref: X,
251
+ "data-root-vh": te ? "true" : "false",
252
+ className: pe,
253
+ style: H ? {
254
+ height: H,
255
+ minHeight: H
256
+ } : void 0,
228
257
  children: [
229
- !V && /* @__PURE__ */ R.jsx(
258
+ !W && /* @__PURE__ */ u.jsx(
230
259
  "button",
231
260
  {
232
261
  type: "button",
233
- onClick: nt,
262
+ onClick: be,
234
263
  className: "absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",
235
- children: X ? "退出全屏" : z || "全屏浏览"
264
+ children: me ? "退出全屏" : j || "全屏浏览"
236
265
  }
237
266
  ),
238
- a === "blackboard" && r === "markdown" ? /* @__PURE__ */ R.jsx(lt, { content: i }) : /* @__PURE__ */ R.jsx(
239
- "iframe",
267
+ h === "blackboard" && n === "markdown" ? /* @__PURE__ */ u.jsx(
268
+ "div",
240
269
  {
241
- ref: w,
242
- sandbox: "allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",
243
- allow: "fullscreen",
244
- allowFullScreen: !0,
245
- className: [d, "w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),
246
- style: {
247
- height: "100%",
248
- margin: "auto"
249
- }
270
+ onMouseDown: () => y("mousedown"),
271
+ onPointerDown: () => y("pointerdown"),
272
+ onTouchStart: () => y("touchstart"),
273
+ children: /* @__PURE__ */ u.jsx(Ce, { content: s })
250
274
  }
251
- )
275
+ ) : /* @__PURE__ */ u.jsxs(u.Fragment, { children: [
276
+ /* @__PURE__ */ u.jsx(
277
+ "iframe",
278
+ {
279
+ ref: E,
280
+ sandbox: "allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",
281
+ allow: "fullscreen",
282
+ allowFullScreen: !0,
283
+ className: [m, "w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),
284
+ style: {
285
+ height: H ?? "100%",
286
+ minHeight: H,
287
+ margin: "auto",
288
+ visibility: re ? "hidden" : "visible"
289
+ }
290
+ }
291
+ ),
292
+ re ? /* @__PURE__ */ u.jsx("div", { className: "pointer-events-none absolute inset-0 z-20 flex items-center justify-center", children: /* @__PURE__ */ u.jsx(
293
+ Re,
294
+ {
295
+ "aria-label": p || "Preparing sandbox styles",
296
+ className: "text-primary h-7 w-7 animate-spin"
297
+ }
298
+ ) }) : null
299
+ ] })
252
300
  ]
253
301
  }
254
302
  );
255
303
  };
256
304
  export {
257
- vt as default
305
+ Oe as default
258
306
  };
259
307
  //# 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);\n\nconst COMPLETE_IMAGE_TAG_PATTERN = /<img\\b[^>]*>/i;\nconst POST_IMAGE_STREAM_DEBOUNCE_MS = 180;\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 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","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","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, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport { Loader2 } from \"lucide-react\";\nimport SandboxApp from \"./SandboxApp\";\nimport { splitContentSegments } from \"./utils/split-content\";\nimport ContentRender from \"./ContentRender\";\n\ntype InjectBlackboardLibraries =\n typeof import(\"./blackboard-vendor\").injectBlackboardLibraries;\n\n// Cache the sandbox vendor loader so every iframe reuses the same preload request.\nlet blackboardVendorPromise: Promise<InjectBlackboardLibraries> | null = null;\n\nconst loadBlackboardVendor = () => {\n if (!blackboardVendorPromise) {\n blackboardVendorPromise = import(\"./blackboard-vendor\").then(\n (m) => m.injectBlackboardLibraries\n );\n }\n\n return blackboardVendorPromise;\n};\n\n// Warm the sandbox vendor chunk as early as possible in the browser.\nif (typeof window !== \"undefined\") {\n void loadBlackboardVendor();\n}\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 [height, setHeight] = useState(480);\n const lastSandboxInteractionTimeRef = useRef(0);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [isSandboxVendorReady, setIsSandboxVendorReady] = useState(\n type !== \"sandbox\"\n );\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 emitSandboxInteraction = useCallback((eventType: string) => {\n if (typeof window === \"undefined\") {\n return;\n }\n const now = Date.now();\n if (\n now - lastSandboxInteractionTimeRef.current <\n SANDBOX_INTERACTION_THROTTLE_MS\n ) {\n return;\n }\n lastSandboxInteractionTimeRef.current = now;\n window.postMessage(\n {\n source: SANDBOX_INTERACTION_MESSAGE_SOURCE,\n type: SANDBOX_INTERACTION_MESSAGE_TYPE,\n eventType,\n },\n window.location.origin\n );\n }, []);\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 const shouldInjectSandboxVendor = type === \"sandbox\";\n const sandboxViewportHeight =\n isBlackboardMode && type === \"sandbox\"\n ? (rootViewportHeightCss ?? `${height}px`)\n : undefined;\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 shouldBridgeSandboxInteraction =\n isBlackboardMode && type === \"sandbox\";\n const handleSandboxPointerDown = () =>\n emitSandboxInteraction(\"pointerdown\");\n const handleSandboxMouseDown = () => emitSandboxInteraction(\"mousedown\");\n const handleSandboxTouchStart = () => emitSandboxInteraction(\"touchstart\");\n\n if (shouldBridgeSandboxInteraction) {\n doc.addEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.addEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.addEventListener(\"touchstart\", handleSandboxTouchStart, true);\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 if (!shouldInjectSandboxVendor) {\n setIsSandboxVendorReady(true);\n } else {\n // Inject Tailwind/DaisyUI/GSAP before rendering sandbox content to avoid FOUC.\n loadBlackboardVendor()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n setIsSandboxVendorReady(true);\n scheduleHeightUpdate();\n });\n })\n .catch(() => {\n if (isDestroyed) return;\n setIsSandboxVendorReady(true);\n scheduleHeightUpdate();\n });\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 if (shouldBridgeSandboxInteraction) {\n doc.removeEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.removeEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.removeEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\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 || !isSandboxVendorReady) 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 isSandboxVendorReady,\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 const shouldShowSandboxLoading =\n shouldInjectSandboxVendor && !isSandboxVendorReady;\n\n return (\n <div\n ref={containerRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className={containerClassName}\n style={\n sandboxViewportHeight\n ? {\n height: sandboxViewportHeight,\n minHeight: sandboxViewportHeight,\n }\n : undefined\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 <div\n onMouseDown={() => emitSandboxInteraction(\"mousedown\")}\n onPointerDown={() => emitSandboxInteraction(\"pointerdown\")}\n onTouchStart={() => emitSandboxInteraction(\"touchstart\")}\n >\n <ContentRender content={content} />\n </div>\n ) : (\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: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n margin: \"auto\",\n visibility: shouldShowSandboxLoading ? \"hidden\" : \"visible\",\n }}\n />\n {shouldShowSandboxLoading ? (\n <div className=\"pointer-events-none absolute inset-0 z-20 flex items-center justify-center\">\n <Loader2\n aria-label={loadingText || \"Preparing sandbox styles\"}\n className=\"text-primary h-7 w-7 animate-spin\"\n />\n </div>\n ) : null}\n </>\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","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","height","setHeight","useState","lastSandboxInteractionTimeRef","resetToken","setResetToken","isFullscreen","setIsFullscreen","isSandboxVendorReady","setIsSandboxVendorReady","isBlackboardMode","prevHtmlRef","htmlContent","React","sandboxSegments","splitContentSegments","seg","renderHtmlContent","setRenderHtmlContent","prevIncomingHtmlRef","pendingHtmlRef","deferRenderTimerRef","emitSandboxInteraction","useCallback","eventType","now","clearDeferredRenderTimer","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","rootViewportHeightCss","rootMatch","attrs","heightAttrMatch","explicitHeightCss","styleHeightMatch","styleHeightCss","classAttrMatch","hasRootVhHeight","shouldInjectSandboxVendor","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","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","shouldShowSandboxLoading","jsxs","ContentRender","Fragment","Loader2"],"mappings":"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"}