markdown-flow-ui 0.1.83-beta.10 → 0.1.83-beta.12

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