markdown-flow-ui 0.1.104-alpha.8 → 0.1.105

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 (41) hide show
  1. package/dist/_virtual/index.cjs4.js +1 -1
  2. package/dist/_virtual/index.cjs6.js +1 -1
  3. package/dist/_virtual/index.cjs7.js +1 -1
  4. package/dist/_virtual/index.cjs8.js +1 -1
  5. package/dist/_virtual/index.es4.js +5 -5
  6. package/dist/_virtual/index.es6.js +5 -5
  7. package/dist/_virtual/index.es7.js +2 -3
  8. package/dist/_virtual/index.es7.js.map +1 -1
  9. package/dist/_virtual/index.es8.js +3 -2
  10. package/dist/_virtual/index.es8.js.map +1 -1
  11. package/dist/components/ContentRender/IframeSandbox.cjs.js +11 -12
  12. package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
  13. package/dist/components/ContentRender/IframeSandbox.es.js +196 -203
  14. package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
  15. package/dist/components/ui/inputGroup/textarea.cjs.js +1 -1
  16. package/dist/components/ui/inputGroup/textarea.es.js +1 -1
  17. package/dist/node_modules/@braintree/sanitize-url/dist/index.cjs.js +1 -1
  18. package/dist/node_modules/@braintree/sanitize-url/dist/index.es.js +1 -1
  19. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-AAMF2YG6.cjs.js +1 -1
  20. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-AAMF2YG6.es.js +1 -1
  21. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-OMD6QJNC.cjs.js +1 -1
  22. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-OMD6QJNC.es.js +1 -1
  23. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-U37J5Y7L.cjs.js +1 -1
  24. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-U37J5Y7L.es.js +1 -1
  25. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-WV7ZQ7D5.cjs.js +1 -1
  26. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-WV7ZQ7D5.es.js +1 -1
  27. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-4MX5Z3NR.cjs.js +1 -1
  28. package/dist/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-4MX5Z3NR.es.js +1 -1
  29. package/dist/node_modules/rc-input/es/BaseInput.cjs.js +1 -1
  30. package/dist/node_modules/rc-input/es/BaseInput.es.js +1 -1
  31. package/dist/node_modules/rc-textarea/es/ResizableTextArea.cjs.js +1 -1
  32. package/dist/node_modules/rc-textarea/es/ResizableTextArea.es.js +1 -1
  33. package/dist/node_modules/rc-textarea/es/TextArea.cjs.js +1 -1
  34. package/dist/node_modules/rc-textarea/es/TextArea.es.js +1 -1
  35. package/dist/node_modules/rc-textarea/es/index.cjs.js +1 -1
  36. package/dist/node_modules/rc-textarea/es/index.es.js +1 -1
  37. package/dist/node_modules/style-to-object/cjs/index.cjs.js +1 -1
  38. package/dist/node_modules/style-to-object/cjs/index.es.js +1 -1
  39. package/dist/node_modules/unified/lib/index.cjs.js +1 -1
  40. package/dist/node_modules/unified/lib/index.es.js +1 -1
  41. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./_commonjsHelpers.cjs.js"),r=require("../node_modules/classnames/index.cjs.js");var s=r.__require();const t=e.getDefaultExportFromCjs(s);exports.default=t;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./_commonjsHelpers.cjs.js"),t=require("../node_modules/extend/index.cjs.js");var r=t.__require();const o=e.getDefaultExportFromCjs(r);exports.default=o;
2
2
  //# sourceMappingURL=index.cjs4.js.map
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./_commonjsHelpers.cjs.js"),t=require("../node_modules/extend/index.cjs.js");var r=t.__require();const o=e.getDefaultExportFromCjs(r);exports.default=o;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./_commonjsHelpers.cjs.js"),r=require("../node_modules/classnames/index.cjs.js");var s=r.__require();const t=e.getDefaultExportFromCjs(s);exports.default=t;
2
2
  //# sourceMappingURL=index.cjs6.js.map
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../node_modules/@braintree/sanitize-url/dist/index.cjs.js");var r=e.__require();exports.distExports=r;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.__exports=e;
2
2
  //# sourceMappingURL=index.cjs7.js.map
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.__exports=e;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../node_modules/@braintree/sanitize-url/dist/index.cjs.js");var r=e.__require();exports.distExports=r;
2
2
  //# sourceMappingURL=index.cjs8.js.map
@@ -1,8 +1,8 @@
1
- import { getDefaultExportFromCjs as r } from "./_commonjsHelpers.es.js";
2
- import { __require as s } from "../node_modules/classnames/index.es.js";
3
- var e = s();
4
- const t = /* @__PURE__ */ r(e);
1
+ import { getDefaultExportFromCjs as e } from "./_commonjsHelpers.es.js";
2
+ import { __require as r } from "../node_modules/extend/index.es.js";
3
+ var t = r();
4
+ const a = /* @__PURE__ */ e(t);
5
5
  export {
6
- t as default
6
+ a as default
7
7
  };
8
8
  //# sourceMappingURL=index.es4.js.map
@@ -1,8 +1,8 @@
1
- import { getDefaultExportFromCjs as e } from "./_commonjsHelpers.es.js";
2
- import { __require as r } from "../node_modules/extend/index.es.js";
3
- var t = r();
4
- const a = /* @__PURE__ */ e(t);
1
+ import { getDefaultExportFromCjs as r } from "./_commonjsHelpers.es.js";
2
+ import { __require as s } from "../node_modules/classnames/index.es.js";
3
+ var e = s();
4
+ const t = /* @__PURE__ */ r(e);
5
5
  export {
6
- a as default
6
+ t as default
7
7
  };
8
8
  //# sourceMappingURL=index.es6.js.map
@@ -1,6 +1,5 @@
1
- import { __require as r } from "../node_modules/@braintree/sanitize-url/dist/index.es.js";
2
- var i = r();
1
+ var r = {};
3
2
  export {
4
- i as d
3
+ r as __exports
5
4
  };
6
5
  //# sourceMappingURL=index.es7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"index.es7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,5 +1,6 @@
1
- var r = {};
1
+ import { __require as r } from "../node_modules/@braintree/sanitize-url/dist/index.es.js";
2
+ var i = r();
2
3
  export {
3
- r as __exports
4
+ i as d
4
5
  };
5
6
  //# sourceMappingURL=index.es8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es8.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index.es8.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,25 +1,24 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const S=require("../../_virtual/jsx-runtime.cjs.js"),t=require("react"),Ae=require("react-dom/client"),je=require("./SandboxApp.cjs.js"),Fe=require("./ContentRender.cjs.js"),H=require("./utils/iframe-viewport-height.cjs.js"),be=require("../../lib/sandboxInteraction.cjs.js");let Z=null;const Ie=()=>(Z||(Z=Promise.resolve().then(()=>require("./blackboard-vendor.cjs.js")).then(c=>c.injectBlackboardLibraries)),Z),Ne=/<img\b[^>]*>/i,Oe=180,_e=240,Ve=c=>c.split(/\s+/).filter(Boolean).map(s=>{const i=s.split(":");return i[i.length-1]!=="h-screen"&&i[i.length-1]!=="min-h-screen"?s:(i[i.length-1]="h-full",i.join(":"))}).join(" "),De=(c,s)=>!s||!c.trim()?c:c.replace(/^(\s*<[a-zA-Z][\w:-]*)(\s[^>]*?)?>/,(i,N,M="")=>{const h=M.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);if(!h)return i;const O=Ve(h[2]);return O===h[2]?i:`${N}${M.replace(h[0],`class=${h[1]}${O}${h[1]}`)}>`}),ke=({content:c,type:s,className:i,styleLoadingText:N,scriptLoadingText:M,fullScreenButtonText:h,hideFullScreen:O=!1,mode:d="content",replaceRootScreenHeightWithFull:we=!1})=>{const _=t.useRef(null),m=t.useRef(null),q=t.useRef(null),y=t.useRef(()=>{}),[He,xe]=t.useState(480),[J,Ee]=t.useState(0),[B,K]=t.useState(0),L=t.useRef(!1),Q=t.useRef(0),[ee,Re]=t.useState(0),[W,ve]=t.useState(!1),Se=s==="sandbox",f=d==="blackboard",C=f&&s==="sandbox",x=C&&we,$=t.useRef(""),V=t.useMemo(()=>s==="sandbox"?c:"",[c,s]),r=t.useMemo(()=>De(V,x),[V,x]),te=t.useMemo(()=>x?H.inspectViewportHeightFromHtmlRootString(V):H.EMPTY_ROOT_HEIGHT_META,[V,x]),ne=t.useMemo(()=>x&&te.hasFullViewportHeight,[te.hasFullViewportHeight,x]),[D,re]=t.useState(r),oe=t.useRef(r),z=t.useRef(r),T=t.useRef(null),A=t.useRef(null),se=t.useRef(null),E=t.useCallback(n=>{if(typeof window>"u")return;const e=Date.now();e-Q.current<_e||(Q.current=e,window.postMessage({source:be.SANDBOX_INTERACTION_MESSAGE_SOURCE,type:be.SANDBOX_INTERACTION_MESSAGE_TYPE,eventType:n},window.location.origin))},[]),G=()=>{T.current!==null&&(window.clearTimeout(T.current),T.current=null)},Me=()=>{A.current!==null&&(window.cancelAnimationFrame(A.current),A.current=null)};t.useEffect(()=>()=>{G(),Me()},[]),t.useEffect(()=>{const n=oe.current;oe.current=r;const e=!!n&&r.length>n.length&&r.startsWith(n),l=Ne.test(r);if(!(e&&l)){G(),z.current=r,re(r);return}z.current=r,G(),T.current=window.setTimeout(()=>{re(z.current),T.current=null},Oe)},[r]);const k=t.useMemo(()=>C?H.inspectViewportHeightFromHtmlRootString(D).viewportHeightCss:null,[D,C]);t.useEffect(()=>{se.current=k},[k]);const ie=!!k,j=f&&s==="sandbox"?ne?"100%":k??`${He}px`:void 0;t.useEffect(()=>{if(d!=="blackboard"){$.current=r;return}const n=$.current;!(n&&r.startsWith(n))&&n&&Re(l=>l+1),$.current=r},[d,r]),t.useEffect(()=>{const n=m.current;if(!n)return;const e=n.contentDocument;if(!e)return;e.open(),e.write(`<!DOCTYPE html>
2
- <html${d==="blackboard"?' style="height: 100%;"':""}>
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const x=require("../../_virtual/jsx-runtime.cjs.js"),t=require("react"),Te=require("react-dom/client"),Ae=require("./SandboxApp.cjs.js"),je=require("./ContentRender.cjs.js"),p=require("./utils/iframe-viewport-height.cjs.js"),be=require("../../lib/sandboxInteraction.cjs.js");let Y=null;const Fe=()=>(Y||(Y=Promise.resolve().then(()=>require("./blackboard-vendor.cjs.js")).then(c=>c.injectBlackboardLibraries)),Y),Ie=/<img\b[^>]*>/i,Ne=180,Oe=240,_e=c=>c.split(/\s+/).filter(Boolean).map(s=>{const i=s.split(":");return i[i.length-1]!=="h-screen"&&i[i.length-1]!=="min-h-screen"?s:(i[i.length-1]="h-full",i.join(":"))}).join(" "),Ve=(c,s)=>!s||!c.trim()?c:c.replace(/^(\s*<[a-zA-Z][\w:-]*)(\s[^>]*?)?>/,(i,I,E="")=>{const a=E.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);if(!a)return i;const N=_e(a[2]);return N===a[2]?i:`${I}${E.replace(a[0],`class=${a[1]}${N}${a[1]}`)}>`}),ke=({content:c,type:s,className:i,styleLoadingText:I,scriptLoadingText:E,fullScreenButtonText:a,hideFullScreen:N=!1,mode:l="content",replaceRootScreenHeightWithFull:pe=!1})=>{const O=t.useRef(null),m=t.useRef(null),P=t.useRef(null),R=t.useRef(()=>{}),[we,He]=t.useState(480),[Z,xe]=t.useState(0),[q,J]=t.useState(0),B=t.useRef(!1),K=t.useRef(0),[Q,Ee]=t.useState(0),[L,Re]=t.useState(!1),ve=s==="sandbox",f=l==="blackboard",v=f&&s==="sandbox",w=v&&pe,$=t.useRef(""),_=t.useMemo(()=>s==="sandbox"?c:"",[c,s]),r=t.useMemo(()=>Ve(_,w),[_,w]),ee=t.useMemo(()=>w?p.inspectViewportHeightFromHtmlRootString(_):p.EMPTY_ROOT_HEIGHT_META,[_,w]),te=t.useMemo(()=>w&&ee.hasFullViewportHeight,[ee.hasFullViewportHeight,w]),[V,ne]=t.useState(r),re=t.useRef(r),W=t.useRef(r),S=t.useRef(null),M=t.useRef(null),oe=t.useRef(null),H=t.useCallback(n=>{if(typeof window>"u")return;const e=Date.now();e-K.current<Oe||(K.current=e,window.postMessage({source:be.SANDBOX_INTERACTION_MESSAGE_SOURCE,type:be.SANDBOX_INTERACTION_MESSAGE_TYPE,eventType:n},window.location.origin))},[]),z=()=>{S.current!==null&&(window.clearTimeout(S.current),S.current=null)},Se=()=>{M.current!==null&&(window.cancelAnimationFrame(M.current),M.current=null)};t.useEffect(()=>()=>{z(),Se()},[]),t.useEffect(()=>{const n=re.current;re.current=r;const e=!!n&&r.length>n.length&&r.startsWith(n),u=Ie.test(r);if(!(e&&u)){z(),W.current=r,ne(r);return}W.current=r,z(),S.current=window.setTimeout(()=>{ne(W.current),S.current=null},Ne)},[r]);const k=t.useMemo(()=>v?p.inspectViewportHeightFromHtmlRootString(V).viewportHeightCss:null,[V,v]);t.useEffect(()=>{oe.current=k},[k]);const se=!!k,C=f&&s==="sandbox"?te?"100%":k??`${we}px`:void 0;t.useEffect(()=>{if(l!=="blackboard"){$.current=r;return}const n=$.current;!(n&&r.startsWith(n))&&n&&Ee(u=>u+1),$.current=r},[l,r]),t.useEffect(()=>{const n=m.current;if(!n)return;const e=n.contentDocument;if(!e)return;e.open(),e.write(`<!DOCTYPE html>
2
+ <html${l==="blackboard"?' style="height: 100%;"':""}>
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <style>
7
7
  :root { color-scheme: light; }
8
8
  html, body, #root { width: 100%; }
9
- ${d==="blackboard"?"html, body, #root { height: 100%; }":""}
10
- html, body { margin: 0; padding: 0; overflow: auto; }
9
+ ${l==="blackboard"?"html, body, #root { height: 100%; }":""}
10
+ html, body { margin: 0; padding: 0; overflow: ${l==="blackboard"?"auto":"hidden"}; }
11
11
  *, *::before, *::after { box-sizing: border-box; }
12
- html.measuring-height, html.measuring-height body,
13
- html.measuring-height #root, html.measuring-height .sandbox-wrapper {
14
- height: auto !important; min-height: 0 !important;
15
- }
16
- html.measuring-height * {
17
- min-height: 0 !important;
18
- }
12
+ ${l!=="blackboard"?`
13
+ .h-screen { height: auto !important; }
14
+ .min-h-screen { min-height: auto !important; }
15
+ .h-dvh, .h-svh, .h-lvh { height: auto !important; }
16
+ .min-h-dvh, .min-h-svh, .min-h-lvh { min-height: auto !important; }
17
+ `:""}
19
18
  </style>
20
19
  </head>
21
20
  <body>
22
21
  <div id="root"></div>
23
22
  </body>
24
- </html>`),e.close(),e.documentElement.setAttribute("data-theme","light"),e.documentElement.style.colorScheme="light",e.body?.style.setProperty("color-scheme","light");const l=f&&s==="sandbox",U=()=>E("pointerdown"),le=()=>E("mousedown"),ue=()=>E("touchstart");l&&(e.addEventListener("pointerdown",U,!0),e.addEventListener("mousedown",le,!0),e.addEventListener("touchstart",ue,!0));const g=e.getElementById("root");if(!g)return;const ae=Ae.createRoot(g);q.current=ae;let F=!1;const he=o=>({heightAttrValue:o.getAttribute("height"),styleAttrValue:o.getAttribute("style"),classAttrValue:o.getAttribute("class")}),de=o=>{const p=Array.from(o.children);return p.length===1?p[0]:null},Te=()=>{if(!C||!m.current||!e.body)return null;const o=m.current.ownerDocument?.documentElement?.clientHeight||window.innerHeight,p=se.current,P=p?H.parseExplicitHeight(p,o):null;if(P!==null)return Math.ceil(P);const b=e.body.querySelector(".sandbox-wrapper")?.firstElementChild;if(!b)return null;const u=Array.from(b.children),a=u.length===1?u[0]:null,w=H.inspectViewportHeightFromNodeChain(a,{getNode:he,getSingleChild:de}).viewportHeightCss;if(w){const v=H.parseExplicitHeight(w,o);if(v!==null)return Math.ceil(v)}const R=H.resolveExplicitHeightFromNodeChain(a,o,{getNode:he,getSingleChild:de});return R!==null?Math.ceil(R):null},X=()=>{if(!m.current||!e.body)return;if(!f){if(L.current)return;L.current=!0;const b=_.current?.clientWidth||0,u=b>0?Math.round(b*9/16):480,a=m.current,ge=a.style.height;e.documentElement.classList.add("measuring-height"),a.style.height=u+"px",e.body.offsetHeight;const w=Math.max(e.body.scrollHeight,e.documentElement?.scrollHeight||0,g?.scrollHeight||0);let R=u;w>u&&(a.style.height=w+"px",e.body.offsetHeight,Math.max(e.body.scrollHeight,e.documentElement?.scrollHeight||0,g?.scrollHeight||0)<=w+5?R=w:R=u),e.documentElement.classList.remove("measuring-height"),a.style.height=ge,Ee(v=>{const pe=Math.max(200,Math.ceil(R));return v===pe?v:pe}),setTimeout(()=>{L.current=!1},50);return}const o=e.body.scrollHeight,p=e.documentElement?.scrollHeight||0,P=g?.scrollHeight||0,fe=Math.max(o,p,P);if(C){const b=Te(),u=Math.max(200,b??Math.ceil(fe));xe(a=>a===u?a:u)}},I=()=>{requestAnimationFrame(()=>{F||X()})};y.current=I,X(),I(),Se&&Ie().then(o=>{F||(o(e),requestAnimationFrame(()=>{F||I()}))}).catch(()=>{F||I()});const Y=new ResizeObserver(()=>X());Y.observe(e.body),g&&Y.observe(g);const me=new MutationObserver(()=>{I()});return me.observe(e.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class"]}),()=>{F=!0,Y.disconnect(),me.disconnect(),l&&(e.removeEventListener("pointerdown",U,!0),e.removeEventListener("mousedown",le,!0),e.removeEventListener("touchstart",ue,!0)),setTimeout(()=>{ae.unmount(),q.current=null,y.current=()=>{}},0)}},[]),t.useEffect(()=>{const n=()=>{ve(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",n),()=>document.removeEventListener("fullscreenchange",n)},[]),t.useEffect(()=>{const n=_.current;if(!n)return;const e=new ResizeObserver(l=>{K(l[0]?.contentRect.width??n.clientWidth)});return e.observe(n),K(n.clientWidth),()=>e.disconnect()},[]);const ce=t.useMemo(()=>{if(f||B===0||W)return;const n=Math.round(B*9/16);return{height:Math.max(n,J)}},[f,B,J,W]),ye=()=>{const n=_.current||m.current;if(n){if(document.fullscreenElement){document.exitFullscreen().catch(()=>{});return}n.requestFullscreen&&n.requestFullscreen().catch(()=>{})}};t.useEffect(()=>{const n=q.current;if(!n)return;n.render(S.jsxRuntimeExports.jsx(je.default,{html:D,styleLoadingText:N,scriptLoadingText:M,resetToken:ee,hasRootVhHeight:ie,mode:d,stretchRootHeight:ne})),A.current=window.requestAnimationFrame(()=>{y.current?.(),A.current=null});const e=setTimeout(()=>y.current?.(),100),l=setTimeout(()=>y.current?.(),500);return()=>{clearTimeout(e),clearTimeout(l)}},[D,N,M,ee,d]);const Ce=["w-full relative content-render-iframe-sandbox",f?"h-full overflow-auto flex flex-col":ce?"overflow-hidden flex items-center justify-center":"aspect-[16/9] overflow-hidden flex items-center justify-center"].filter(Boolean).join(" ");return S.jsxRuntimeExports.jsxs("div",{ref:_,"data-root-vh":ie?"true":"false",className:Ce,style:j?{height:j,minHeight:j}:ce,children:[!O&&S.jsxRuntimeExports.jsx("button",{type:"button",onClick:ye,className:"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",children:W?"退出全屏":h||"全屏浏览"}),d==="blackboard"&&s==="markdown"?S.jsxRuntimeExports.jsx("div",{onMouseDown:()=>E("mousedown"),onPointerDown:()=>E("pointerdown"),onTouchStart:()=>E("touchstart"),children:S.jsxRuntimeExports.jsx(Fe.default,{content:c})}):S.jsxRuntimeExports.jsx("iframe",{ref:m,sandbox:"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",allow:"fullscreen",allowFullScreen:!0,className:[i,"w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),style:{height:j??"100%",minHeight:j,margin:"auto"}})]})};exports.default=ke;
23
+ </html>`),e.close(),e.documentElement.setAttribute("data-theme","light"),e.documentElement.style.colorScheme="light",e.body?.style.setProperty("color-scheme","light");const u=f&&s==="sandbox",G=()=>H("pointerdown"),ce=()=>H("mousedown"),le=()=>H("touchstart");u&&(e.addEventListener("pointerdown",G,!0),e.addEventListener("mousedown",ce,!0),e.addEventListener("touchstart",le,!0));const y=e.getElementById("root");if(!y)return;const ue=Te.createRoot(y);P.current=ue;let T=!1;const ae=o=>({heightAttrValue:o.getAttribute("height"),styleAttrValue:o.getAttribute("style"),classAttrValue:o.getAttribute("class")}),he=o=>{const g=Array.from(o.children);return g.length===1?g[0]:null},ye=()=>{if(!v||!m.current||!e.body)return null;const o=m.current.ownerDocument?.documentElement?.clientHeight||window.innerHeight,g=oe.current,D=g?p.parseExplicitHeight(g,o):null;if(D!==null)return Math.ceil(D);const h=e.body.querySelector(".sandbox-wrapper")?.firstElementChild;if(!h)return null;const d=Array.from(h.children),b=d.length===1?d[0]:null,j=p.inspectViewportHeightFromNodeChain(b,{getNode:ae,getSingleChild:he}).viewportHeightCss;if(j){const ge=p.parseExplicitHeight(j,o);if(ge!==null)return Math.ceil(ge)}const F=p.resolveExplicitHeightFromNodeChain(b,o,{getNode:ae,getSingleChild:he});return F!==null?Math.ceil(F):null},U=()=>{if(!m.current||!e.body)return;if(!f){if(B.current)return;B.current=!0;const h=m.current,d=O.current?.clientWidth||0,b=h.style.height;if(d>0){h.style.height=d+"px",e.body.offsetHeight;const fe=e.body.scrollHeight;h.style.height=b,xe(j=>{const F=Math.max(200,Math.ceil(fe));return j===F?j:F})}setTimeout(()=>{B.current=!1},50);return}const o=e.body.scrollHeight,g=e.documentElement?.scrollHeight||0,D=y?.scrollHeight||0,me=Math.max(o,g,D);if(v){const h=ye(),d=Math.max(200,h??Math.ceil(me));He(b=>b===d?b:d)}},A=()=>{requestAnimationFrame(()=>{T||U()})};R.current=A,U(),A(),ve&&Fe().then(o=>{T||(o(e),requestAnimationFrame(()=>{T||A()}))}).catch(()=>{T||A()});const X=new ResizeObserver(()=>U());X.observe(e.body),y&&X.observe(y);const de=new MutationObserver(()=>{A()});return de.observe(e.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class"]}),()=>{T=!0,X.disconnect(),de.disconnect(),u&&(e.removeEventListener("pointerdown",G,!0),e.removeEventListener("mousedown",ce,!0),e.removeEventListener("touchstart",le,!0)),setTimeout(()=>{ue.unmount(),P.current=null,R.current=()=>{}},0)}},[]),t.useEffect(()=>{const n=()=>{Re(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",n),()=>document.removeEventListener("fullscreenchange",n)},[]),t.useEffect(()=>{const n=O.current;if(!n)return;const e=new ResizeObserver(u=>{J(u[0]?.contentRect.width??n.clientWidth)});return e.observe(n),J(n.clientWidth),()=>e.disconnect()},[]);const ie=t.useMemo(()=>{if(f||q===0||L)return;const n=Math.round(q*9/16);return{height:Math.max(n,Z)}},[f,q,Z,L]),Me=()=>{const n=O.current||m.current;if(n){if(document.fullscreenElement){document.exitFullscreen().catch(()=>{});return}n.requestFullscreen&&n.requestFullscreen().catch(()=>{})}};t.useEffect(()=>{const n=P.current;if(!n)return;n.render(x.jsxRuntimeExports.jsx(Ae.default,{html:V,styleLoadingText:I,scriptLoadingText:E,resetToken:Q,hasRootVhHeight:se,mode:l,stretchRootHeight:te})),M.current=window.requestAnimationFrame(()=>{R.current?.(),M.current=null});const e=setTimeout(()=>R.current?.(),100),u=setTimeout(()=>R.current?.(),500);return()=>{clearTimeout(e),clearTimeout(u)}},[V,I,E,Q,l]);const Ce=["w-full relative content-render-iframe-sandbox",f?"h-full overflow-auto flex flex-col":ie?"overflow-hidden flex items-center justify-center":"aspect-[16/9] overflow-hidden flex items-center justify-center"].filter(Boolean).join(" ");return x.jsxRuntimeExports.jsxs("div",{ref:O,"data-root-vh":se?"true":"false",className:Ce,style:C?{height:C,minHeight:C}:ie,children:[!N&&x.jsxRuntimeExports.jsx("button",{type:"button",onClick:Me,className:"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",children:L?"退出全屏":a||"全屏浏览"}),l==="blackboard"&&s==="markdown"?x.jsxRuntimeExports.jsx("div",{onMouseDown:()=>H("mousedown"),onPointerDown:()=>H("pointerdown"),onTouchStart:()=>H("touchstart"),children:x.jsxRuntimeExports.jsx(je.default,{content:c})}):x.jsxRuntimeExports.jsx("iframe",{ref:m,sandbox:"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",allow:"fullscreen",allowFullScreen:!0,className:[i,"w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),style:{height:C??"100%",minHeight:C,margin:"auto"}})]})};exports.default=ke;
25
24
  //# sourceMappingURL=IframeSandbox.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IframeSandbox.cjs.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport SandboxApp from \"./SandboxApp\";\nimport ContentRender from \"./ContentRender\";\nimport {\n EMPTY_ROOT_HEIGHT_META,\n inspectViewportHeightFromHtmlRootString,\n inspectViewportHeightFromNodeChain,\n parseExplicitHeight,\n resolveExplicitHeightFromNodeChain,\n} from \"./utils/iframe-viewport-height\";\nimport {\n SANDBOX_INTERACTION_MESSAGE_SOURCE,\n SANDBOX_INTERACTION_MESSAGE_TYPE,\n} from \"../../lib/sandboxInteraction\";\n\ntype InjectBlackboardLibraries =\n typeof import(\"./blackboard-vendor\").injectBlackboardLibraries;\n\n// Cache the sandbox vendor loader so every iframe reuses the same preload request.\nlet blackboardVendorPromise: Promise<InjectBlackboardLibraries> | null = null;\n\nconst loadBlackboardVendor = () => {\n if (!blackboardVendorPromise) {\n blackboardVendorPromise = import(\"./blackboard-vendor\").then(\n (m) => m.injectBlackboardLibraries\n );\n }\n\n return blackboardVendorPromise;\n};\n\nconst COMPLETE_IMAGE_TAG_PATTERN = /<img\\b[^>]*>/i;\nconst POST_IMAGE_STREAM_DEBOUNCE_MS = 180;\nconst SANDBOX_INTERACTION_THROTTLE_MS = 240;\n\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 replaceRootScreenHeightWithFull?: boolean;\n}\n\nconst replaceRootScreenHeightToken = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => {\n const segments = token.split(\":\");\n if (\n segments[segments.length - 1] !== \"h-screen\" &&\n segments[segments.length - 1] !== \"min-h-screen\"\n ) {\n return token;\n }\n segments[segments.length - 1] = \"h-full\";\n return segments.join(\":\");\n })\n .join(\" \");\n\nconst replaceRootScreenHeightWithFullClass = (\n html: string,\n enabled: boolean\n) => {\n if (!enabled || !html.trim()) {\n return html;\n }\n\n return html.replace(\n /^(\\s*<[a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/,\n (match, tagStart: string, attrs = \"\") => {\n const classMatch = attrs.match(/\\bclass\\s*=\\s*([\"'])([^\"']*)\\1/i);\n\n if (!classMatch) {\n return match;\n }\n\n const nextClassName = replaceRootScreenHeightToken(classMatch[2]);\n\n if (nextClassName === classMatch[2]) {\n return match;\n }\n\n return `${tagStart}${attrs.replace(\n classMatch[0],\n `class=${classMatch[1]}${nextClassName}${classMatch[1]}`\n )}>`;\n }\n );\n};\n\nconst IframeSandbox: React.FC<IframeSandboxProps> = ({\n content,\n type,\n className,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n hideFullScreen = false,\n mode = \"content\",\n replaceRootScreenHeightWithFull = false,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const rootRef = useRef<Root | null>(null);\n const updateHeightRef = useRef<() => void>(() => {});\n const [height, setHeight] = useState(480);\n const [contentHeight, setContentHeight] = useState(0);\n const [containerWidth, setContainerWidth] = useState(0);\n const isMeasuringContentRef = useRef(false);\n const lastSandboxInteractionTimeRef = useRef(0);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const shouldInjectSandboxVendor = type === \"sandbox\";\n\n const isBlackboardMode = mode === \"blackboard\";\n const shouldMeasureDynamicHeight = isBlackboardMode && type === \"sandbox\";\n const shouldProcessRootScreenHeight =\n shouldMeasureDynamicHeight && replaceRootScreenHeightWithFull;\n const prevHtmlRef = useRef<string>(\"\");\n const htmlContent = React.useMemo(\n () => (type === \"sandbox\" ? content : \"\"),\n [content, type]\n );\n const normalizedHtmlContent = React.useMemo(\n () =>\n replaceRootScreenHeightWithFullClass(\n htmlContent,\n shouldProcessRootScreenHeight\n ),\n [htmlContent, shouldProcessRootScreenHeight]\n );\n const originalRootHeightMeta = React.useMemo(\n () =>\n shouldProcessRootScreenHeight\n ? inspectViewportHeightFromHtmlRootString(htmlContent)\n : EMPTY_ROOT_HEIGHT_META,\n [htmlContent, shouldProcessRootScreenHeight]\n );\n const shouldStretchRootHeight = React.useMemo(\n () =>\n shouldProcessRootScreenHeight &&\n originalRootHeightMeta.hasFullViewportHeight,\n [\n originalRootHeightMeta.hasFullViewportHeight,\n shouldProcessRootScreenHeight,\n ]\n );\n const [renderHtmlContent, setRenderHtmlContent] = useState(\n normalizedHtmlContent\n );\n const prevIncomingHtmlRef = useRef(normalizedHtmlContent);\n const pendingHtmlRef = useRef(normalizedHtmlContent);\n const deferRenderTimerRef = useRef<number | null>(null);\n const initialPaintFrameRef = useRef<number | null>(null);\n const renderViewportHeightCssRef = useRef<string | null>(null);\n\n const emitSandboxInteraction = useCallback((eventType: string) => {\n if (typeof window === \"undefined\") {\n return;\n }\n const now = Date.now();\n if (\n now - lastSandboxInteractionTimeRef.current <\n SANDBOX_INTERACTION_THROTTLE_MS\n ) {\n return;\n }\n lastSandboxInteractionTimeRef.current = now;\n window.postMessage(\n {\n source: SANDBOX_INTERACTION_MESSAGE_SOURCE,\n type: SANDBOX_INTERACTION_MESSAGE_TYPE,\n eventType,\n },\n window.location.origin\n );\n }, []);\n\n const clearDeferredRenderTimer = () => {\n if (deferRenderTimerRef.current === null) return;\n window.clearTimeout(deferRenderTimerRef.current);\n deferRenderTimerRef.current = null;\n };\n\n const clearInitialPaintFrames = () => {\n if (initialPaintFrameRef.current !== null) {\n window.cancelAnimationFrame(initialPaintFrameRef.current);\n initialPaintFrameRef.current = null;\n }\n };\n\n useEffect(\n () => () => {\n clearDeferredRenderTimer();\n clearInitialPaintFrames();\n },\n []\n );\n\n useEffect(() => {\n const prevIncomingHtml = prevIncomingHtmlRef.current;\n prevIncomingHtmlRef.current = normalizedHtmlContent;\n\n const isAppendOnlyStream =\n !!prevIncomingHtml &&\n normalizedHtmlContent.length > prevIncomingHtml.length &&\n normalizedHtmlContent.startsWith(prevIncomingHtml);\n const containsCompleteImage = COMPLETE_IMAGE_TAG_PATTERN.test(\n normalizedHtmlContent\n );\n const shouldDeferRender = isAppendOnlyStream && containsCompleteImage;\n\n if (!shouldDeferRender) {\n clearDeferredRenderTimer();\n pendingHtmlRef.current = normalizedHtmlContent;\n setRenderHtmlContent(normalizedHtmlContent);\n return;\n }\n\n pendingHtmlRef.current = normalizedHtmlContent;\n clearDeferredRenderTimer();\n deferRenderTimerRef.current = window.setTimeout(() => {\n setRenderHtmlContent(pendingHtmlRef.current);\n deferRenderTimerRef.current = null;\n }, POST_IMAGE_STREAM_DEBOUNCE_MS);\n }, [normalizedHtmlContent]);\n\n const rootViewportHeightCss = React.useMemo(() => {\n if (!shouldMeasureDynamicHeight) {\n return null;\n }\n\n return inspectViewportHeightFromHtmlRootString(renderHtmlContent)\n .viewportHeightCss;\n }, [renderHtmlContent, shouldMeasureDynamicHeight]);\n\n useEffect(() => {\n renderViewportHeightCssRef.current = rootViewportHeightCss;\n }, [rootViewportHeightCss]);\n\n const hasRootVhHeight = Boolean(rootViewportHeightCss);\n const sandboxViewportHeight =\n isBlackboardMode && type === \"sandbox\"\n ? shouldStretchRootHeight\n ? \"100%\"\n : (rootViewportHeightCss ?? `${height}px`)\n : undefined;\n useEffect(() => {\n if (mode !== \"blackboard\") {\n prevHtmlRef.current = normalizedHtmlContent;\n return;\n }\n const prev = prevHtmlRef.current;\n const isContinuation = prev && normalizedHtmlContent.startsWith(prev);\n if (!isContinuation && prev) {\n setResetToken((token) => token + 1);\n }\n prevHtmlRef.current = normalizedHtmlContent;\n }, [mode, normalizedHtmlContent]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return undefined;\n\n const doc = iframe.contentDocument;\n if (!doc) return undefined;\n\n doc.open();\n doc.write(`<!DOCTYPE html>\n<html${mode === \"blackboard\" ? ' style=\"height: 100%;\"' : \"\"}>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n :root { color-scheme: light; }\n html, body, #root { width: 100%; }\n ${mode === \"blackboard\" ? \"html, body, #root { height: 100%; }\" : \"\"}\n html, body { margin: 0; padding: 0; overflow: auto; }\n *, *::before, *::after { box-sizing: border-box; }\n html.measuring-height, html.measuring-height body,\n html.measuring-height #root, html.measuring-height .sandbox-wrapper {\n height: auto !important; min-height: 0 !important;\n }\n html.measuring-height * {\n min-height: 0 !important;\n }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n\n // Force iframe theme to stay in light mode regardless of host OS preference.\n doc.documentElement.setAttribute(\"data-theme\", \"light\");\n doc.documentElement.style.colorScheme = \"light\";\n doc.body?.style.setProperty(\"color-scheme\", \"light\");\n\n const shouldBridgeSandboxInteraction =\n isBlackboardMode && type === \"sandbox\";\n const handleSandboxPointerDown = () =>\n emitSandboxInteraction(\"pointerdown\");\n const handleSandboxMouseDown = () => emitSandboxInteraction(\"mousedown\");\n const handleSandboxTouchStart = () => emitSandboxInteraction(\"touchstart\");\n\n if (shouldBridgeSandboxInteraction) {\n doc.addEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.addEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.addEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n\n const rootEl = doc.getElementById(\"root\");\n if (!rootEl) return undefined;\n\n const root = createRoot(rootEl);\n rootRef.current = root;\n let isDestroyed = false;\n const getHeightInspectionNode = (node: HTMLElement) => ({\n heightAttrValue: node.getAttribute(\"height\"),\n styleAttrValue: node.getAttribute(\"style\"),\n classAttrValue: node.getAttribute(\"class\"),\n });\n const getSingleChildElement = (node: HTMLElement) => {\n const childElements = Array.from(node.children) as HTMLElement[];\n\n return childElements.length === 1 ? childElements[0] : null;\n };\n\n const resolveExplicitHeight = () => {\n if (!shouldMeasureDynamicHeight) return null;\n if (!iframeRef.current || !doc.body) return null;\n const parentViewportHeight =\n iframeRef.current.ownerDocument?.documentElement?.clientHeight ||\n window.innerHeight;\n // Reuse parsed height metadata from the current html snapshot first to\n // avoid re-inspecting the same DOM chain on every height tick.\n const precomputedViewportHeightCss = renderViewportHeightCssRef.current;\n const parsed = precomputedViewportHeightCss\n ? parseExplicitHeight(\n precomputedViewportHeightCss,\n parentViewportHeight\n )\n : null;\n\n if (parsed !== null) {\n return Math.ceil(parsed);\n }\n\n const wrapper = doc.body.querySelector(\n \".sandbox-wrapper\"\n ) as HTMLElement | null;\n const container = wrapper?.firstElementChild as HTMLElement | null;\n if (!container) return null;\n const containerChildren = Array.from(container.children) as HTMLElement[];\n const rootContentElement =\n containerChildren.length === 1 ? containerChildren[0] : null;\n const runtimeHeightMeta = inspectViewportHeightFromNodeChain(\n rootContentElement,\n {\n getNode: getHeightInspectionNode,\n getSingleChild: getSingleChildElement,\n }\n );\n const runtimeViewportHeightCss = runtimeHeightMeta.viewportHeightCss;\n\n if (runtimeViewportHeightCss) {\n const runtimeViewportHeight = parseExplicitHeight(\n runtimeViewportHeightCss,\n parentViewportHeight\n );\n\n if (runtimeViewportHeight !== null) {\n return Math.ceil(runtimeViewportHeight);\n }\n }\n\n const explicitPixelHeight = resolveExplicitHeightFromNodeChain(\n rootContentElement,\n parentViewportHeight,\n {\n getNode: getHeightInspectionNode,\n getSingleChild: getSingleChildElement,\n }\n );\n\n return explicitPixelHeight !== null\n ? Math.ceil(explicitPixelHeight)\n : null;\n };\n\n const updateHeight = () => {\n if (!iframeRef.current || !doc.body) return;\n\n if (!isBlackboardMode) {\n // Guard: prevent re-entrant measurement.\n if (isMeasuringContentRef.current) return;\n isMeasuringContentRef.current = true;\n\n const cw = containerRef.current?.clientWidth || 0;\n const refH = cw > 0 ? Math.round((cw * 9) / 16) : 480;\n\n const iframe = iframeRef.current;\n const prevH = iframe.style.height;\n\n // Add measuring-height class on <html> (outside MutationObserver\n // scope, which only observes doc.body) to neutralize min-height.\n doc.documentElement.classList.add(\"measuring-height\");\n\n // --- Pass 1: measure at the 16:9 reference viewport ---\n iframe.style.height = refH + \"px\";\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n doc.body.offsetHeight; // force layout\n const s1 = Math.max(\n doc.body.scrollHeight,\n doc.documentElement?.scrollHeight || 0,\n rootEl?.scrollHeight || 0\n );\n\n let finalH = refH;\n\n if (s1 > refH) {\n // Content overflows 16:9. Check whether the overflow is stable\n // (real content) or viewport-dependent (vh/vmin feedback loop).\n // --- Pass 2: measure at s1 to test stability ---\n iframe.style.height = s1 + \"px\";\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n doc.body.offsetHeight; // force layout\n const s2 = Math.max(\n doc.body.scrollHeight,\n doc.documentElement?.scrollHeight || 0,\n rootEl?.scrollHeight || 0\n );\n\n if (s2 <= s1 + 5) {\n // Stable: real content overflow → grow to fit.\n finalH = s1;\n } else {\n // Unstable: content uses viewport-relative units and will\n // always overflow. Stay at 16:9 minimum.\n finalH = refH;\n }\n }\n\n // Restore\n doc.documentElement.classList.remove(\"measuring-height\");\n iframe.style.height = prevH;\n\n setContentHeight((prev) => {\n const next = Math.max(200, Math.ceil(finalH));\n return prev === next ? prev : next;\n });\n\n // Release guard after observers settle.\n setTimeout(() => {\n isMeasuringContentRef.current = false;\n }, 50);\n return;\n }\n\n // Blackboard mode: use existing measurement logic\n const bodyScrollH = doc.body.scrollHeight;\n const htmlScrollH = doc.documentElement?.scrollHeight || 0;\n const rootScrollH = rootEl?.scrollHeight || 0;\n const measuredHeight = Math.max(bodyScrollH, htmlScrollH, rootScrollH);\n\n if (shouldMeasureDynamicHeight) {\n const explicitHeight = resolveExplicitHeight();\n const nextHeight = Math.max(\n 200,\n explicitHeight ?? Math.ceil(measuredHeight)\n );\n setHeight((prevHeight) =>\n prevHeight === nextHeight ? prevHeight : nextHeight\n );\n }\n };\n const scheduleHeightUpdate = () => {\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n updateHeight();\n });\n };\n updateHeightRef.current = scheduleHeightUpdate;\n\n updateHeight();\n scheduleHeightUpdate();\n\n if (shouldInjectSandboxVendor) {\n // Inject Tailwind/DaisyUI/GSAP before rendering sandbox content to avoid FOUC.\n loadBlackboardVendor()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n })\n .catch(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n }\n\n const resizeObserver = new ResizeObserver(() => updateHeight());\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n // MutationObserver: detect DOM changes that ResizeObserver might miss\n // (e.g. content injected by scripts, images loading, dynamic rendering)\n const mutationObserver = new MutationObserver(() => {\n scheduleHeightUpdate();\n });\n mutationObserver.observe(doc.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"style\", \"class\"],\n });\n\n return () => {\n isDestroyed = true;\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n if (shouldBridgeSandboxInteraction) {\n doc.removeEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.removeEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.removeEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n // Defer unmount to avoid React warning when parent is mid-render\n setTimeout(() => {\n root.unmount();\n rootRef.current = null;\n 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 // Track container width for computing min-height in content mode\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n setContainerWidth(entries[0]?.contentRect.width ?? el.clientWidth);\n });\n ro.observe(el);\n setContainerWidth(el.clientWidth);\n return () => ro.disconnect();\n }, []);\n\n // Content mode: min 16:9 aspect ratio, grow to fit content (no scrollbar)\n const contentModeStyle = useMemo<React.CSSProperties | undefined>(() => {\n if (isBlackboardMode || containerWidth === 0 || isFullscreen)\n return undefined;\n const minH = Math.round((containerWidth * 9) / 16);\n const h = Math.max(minH, contentHeight);\n return { height: h };\n }, [isBlackboardMode, containerWidth, contentHeight, isFullscreen]);\n\n const toggleFullscreen = () => {\n const target = containerRef.current || iframeRef.current;\n if (!target) return;\n if (document.fullscreenElement) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n if (target.requestFullscreen) {\n target.requestFullscreen().catch(() => {});\n }\n };\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n\n root.render(\n <SandboxApp\n html={renderHtmlContent}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n stretchRootHeight={shouldStretchRootHeight}\n />\n );\n\n // Schedule multiple measurements to catch async content (scripts, images, styles).\n initialPaintFrameRef.current = window.requestAnimationFrame(() => {\n updateHeightRef.current?.();\n initialPaintFrameRef.current = null;\n });\n const t1 = setTimeout(() => updateHeightRef.current?.(), 100);\n const t2 = setTimeout(() => updateHeightRef.current?.(), 500);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n };\n }, [\n renderHtmlContent,\n styleLoadingText,\n scriptLoadingText,\n resetToken,\n mode,\n ]);\n const containerClassName = [\n \"w-full relative content-render-iframe-sandbox\",\n isBlackboardMode\n ? \"h-full overflow-auto flex flex-col\"\n : contentModeStyle\n ? \"overflow-hidden flex items-center justify-center\"\n : \"aspect-[16/9] overflow-hidden flex items-center justify-center\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n ref={containerRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className={containerClassName}\n style={\n sandboxViewportHeight\n ? {\n height: sandboxViewportHeight,\n minHeight: sandboxViewportHeight,\n }\n : contentModeStyle\n }\n >\n {!hideFullScreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className={\n \"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer\"\n }\n >\n {isFullscreen ? \"退出全屏\" : fullScreenButtonText || \"全屏浏览\"}\n </button>\n )}\n {mode === \"blackboard\" && type === \"markdown\" ? (\n <div\n onMouseDown={() => emitSandboxInteraction(\"mousedown\")}\n onPointerDown={() => emitSandboxInteraction(\"pointerdown\")}\n onTouchStart={() => emitSandboxInteraction(\"touchstart\")}\n >\n <ContentRender content={content} />\n </div>\n ) : (\n <iframe\n ref={iframeRef}\n sandbox=\"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\"\n allow=\"fullscreen\"\n allowFullScreen\n className={[className, \"w-full h-full mx-auto my-auto block\"]\n .filter(Boolean)\n .join(\" \")}\n style={{\n height: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n margin: \"auto\",\n }}\n />\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","loadBlackboardVendor","m","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_THROTTLE_MS","replaceRootScreenHeightToken","className","token","segments","replaceRootScreenHeightWithFullClass","html","enabled","match","tagStart","attrs","classMatch","nextClassName","IframeSandbox","content","type","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","replaceRootScreenHeightWithFull","containerRef","useRef","iframeRef","rootRef","updateHeightRef","height","setHeight","useState","contentHeight","setContentHeight","containerWidth","setContainerWidth","isMeasuringContentRef","lastSandboxInteractionTimeRef","resetToken","setResetToken","isFullscreen","setIsFullscreen","shouldInjectSandboxVendor","isBlackboardMode","shouldMeasureDynamicHeight","shouldProcessRootScreenHeight","prevHtmlRef","htmlContent","React","normalizedHtmlContent","originalRootHeightMeta","inspectViewportHeightFromHtmlRootString","EMPTY_ROOT_HEIGHT_META","shouldStretchRootHeight","renderHtmlContent","setRenderHtmlContent","prevIncomingHtmlRef","pendingHtmlRef","deferRenderTimerRef","initialPaintFrameRef","renderViewportHeightCssRef","emitSandboxInteraction","useCallback","eventType","now","SANDBOX_INTERACTION_MESSAGE_SOURCE","SANDBOX_INTERACTION_MESSAGE_TYPE","clearDeferredRenderTimer","clearInitialPaintFrames","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","rootViewportHeightCss","hasRootVhHeight","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","rootEl","root","createRoot","isDestroyed","getHeightInspectionNode","node","getSingleChildElement","childElements","resolveExplicitHeight","parentViewportHeight","precomputedViewportHeightCss","parsed","parseExplicitHeight","container","containerChildren","rootContentElement","runtimeViewportHeightCss","inspectViewportHeightFromNodeChain","runtimeViewportHeight","explicitPixelHeight","resolveExplicitHeightFromNodeChain","updateHeight","cw","refH","prevH","s1","finalH","next","bodyScrollH","htmlScrollH","rootScrollH","measuredHeight","explicitHeight","nextHeight","prevHeight","scheduleHeightUpdate","inject","resizeObserver","mutationObserver","onFullscreenChange","el","ro","entries","contentModeStyle","useMemo","minH","toggleFullscreen","target","jsx","SandboxApp","t1","t2","containerClassName","jsxs","ContentRender"],"mappings":"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"}
1
+ {"version":3,"file":"IframeSandbox.cjs.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport SandboxApp from \"./SandboxApp\";\nimport ContentRender from \"./ContentRender\";\nimport {\n EMPTY_ROOT_HEIGHT_META,\n inspectViewportHeightFromHtmlRootString,\n inspectViewportHeightFromNodeChain,\n parseExplicitHeight,\n resolveExplicitHeightFromNodeChain,\n} from \"./utils/iframe-viewport-height\";\nimport {\n SANDBOX_INTERACTION_MESSAGE_SOURCE,\n SANDBOX_INTERACTION_MESSAGE_TYPE,\n} from \"../../lib/sandboxInteraction\";\n\ntype InjectBlackboardLibraries =\n typeof import(\"./blackboard-vendor\").injectBlackboardLibraries;\n\n// Cache the sandbox vendor loader so every iframe reuses the same preload request.\nlet blackboardVendorPromise: Promise<InjectBlackboardLibraries> | null = null;\n\nconst loadBlackboardVendor = () => {\n if (!blackboardVendorPromise) {\n blackboardVendorPromise = import(\"./blackboard-vendor\").then(\n (m) => m.injectBlackboardLibraries\n );\n }\n\n return blackboardVendorPromise;\n};\n\nconst COMPLETE_IMAGE_TAG_PATTERN = /<img\\b[^>]*>/i;\nconst POST_IMAGE_STREAM_DEBOUNCE_MS = 180;\nconst SANDBOX_INTERACTION_THROTTLE_MS = 240;\n\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 replaceRootScreenHeightWithFull?: boolean;\n}\n\nconst replaceRootScreenHeightToken = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => {\n const segments = token.split(\":\");\n if (\n segments[segments.length - 1] !== \"h-screen\" &&\n segments[segments.length - 1] !== \"min-h-screen\"\n ) {\n return token;\n }\n segments[segments.length - 1] = \"h-full\";\n return segments.join(\":\");\n })\n .join(\" \");\n\nconst replaceRootScreenHeightWithFullClass = (\n html: string,\n enabled: boolean\n) => {\n if (!enabled || !html.trim()) {\n return html;\n }\n\n return html.replace(\n /^(\\s*<[a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/,\n (match, tagStart: string, attrs = \"\") => {\n const classMatch = attrs.match(/\\bclass\\s*=\\s*([\"'])([^\"']*)\\1/i);\n\n if (!classMatch) {\n return match;\n }\n\n const nextClassName = replaceRootScreenHeightToken(classMatch[2]);\n\n if (nextClassName === classMatch[2]) {\n return match;\n }\n\n return `${tagStart}${attrs.replace(\n classMatch[0],\n `class=${classMatch[1]}${nextClassName}${classMatch[1]}`\n )}>`;\n }\n );\n};\n\nconst IframeSandbox: React.FC<IframeSandboxProps> = ({\n content,\n type,\n className,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n hideFullScreen = false,\n mode = \"content\",\n replaceRootScreenHeightWithFull = false,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const rootRef = useRef<Root | null>(null);\n const updateHeightRef = useRef<() => void>(() => {});\n const [height, setHeight] = useState(480);\n const [contentHeight, setContentHeight] = useState(0);\n const [containerWidth, setContainerWidth] = useState(0);\n const isMeasuringContentRef = useRef(false);\n const lastSandboxInteractionTimeRef = useRef(0);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const shouldInjectSandboxVendor = type === \"sandbox\";\n\n const isBlackboardMode = mode === \"blackboard\";\n const shouldMeasureDynamicHeight = isBlackboardMode && type === \"sandbox\";\n const shouldProcessRootScreenHeight =\n shouldMeasureDynamicHeight && replaceRootScreenHeightWithFull;\n const prevHtmlRef = useRef<string>(\"\");\n const htmlContent = React.useMemo(\n () => (type === \"sandbox\" ? content : \"\"),\n [content, type]\n );\n const normalizedHtmlContent = React.useMemo(\n () =>\n replaceRootScreenHeightWithFullClass(\n htmlContent,\n shouldProcessRootScreenHeight\n ),\n [htmlContent, shouldProcessRootScreenHeight]\n );\n const originalRootHeightMeta = React.useMemo(\n () =>\n shouldProcessRootScreenHeight\n ? inspectViewportHeightFromHtmlRootString(htmlContent)\n : EMPTY_ROOT_HEIGHT_META,\n [htmlContent, shouldProcessRootScreenHeight]\n );\n const shouldStretchRootHeight = React.useMemo(\n () =>\n shouldProcessRootScreenHeight &&\n originalRootHeightMeta.hasFullViewportHeight,\n [\n originalRootHeightMeta.hasFullViewportHeight,\n shouldProcessRootScreenHeight,\n ]\n );\n const [renderHtmlContent, setRenderHtmlContent] = useState(\n normalizedHtmlContent\n );\n const prevIncomingHtmlRef = useRef(normalizedHtmlContent);\n const pendingHtmlRef = useRef(normalizedHtmlContent);\n const deferRenderTimerRef = useRef<number | null>(null);\n const initialPaintFrameRef = useRef<number | null>(null);\n const renderViewportHeightCssRef = useRef<string | null>(null);\n\n const emitSandboxInteraction = useCallback((eventType: string) => {\n if (typeof window === \"undefined\") {\n return;\n }\n const now = Date.now();\n if (\n now - lastSandboxInteractionTimeRef.current <\n SANDBOX_INTERACTION_THROTTLE_MS\n ) {\n return;\n }\n lastSandboxInteractionTimeRef.current = now;\n window.postMessage(\n {\n source: SANDBOX_INTERACTION_MESSAGE_SOURCE,\n type: SANDBOX_INTERACTION_MESSAGE_TYPE,\n eventType,\n },\n window.location.origin\n );\n }, []);\n\n const clearDeferredRenderTimer = () => {\n if (deferRenderTimerRef.current === null) return;\n window.clearTimeout(deferRenderTimerRef.current);\n deferRenderTimerRef.current = null;\n };\n\n const clearInitialPaintFrames = () => {\n if (initialPaintFrameRef.current !== null) {\n window.cancelAnimationFrame(initialPaintFrameRef.current);\n initialPaintFrameRef.current = null;\n }\n };\n\n useEffect(\n () => () => {\n clearDeferredRenderTimer();\n clearInitialPaintFrames();\n },\n []\n );\n\n useEffect(() => {\n const prevIncomingHtml = prevIncomingHtmlRef.current;\n prevIncomingHtmlRef.current = normalizedHtmlContent;\n\n const isAppendOnlyStream =\n !!prevIncomingHtml &&\n normalizedHtmlContent.length > prevIncomingHtml.length &&\n normalizedHtmlContent.startsWith(prevIncomingHtml);\n const containsCompleteImage = COMPLETE_IMAGE_TAG_PATTERN.test(\n normalizedHtmlContent\n );\n const shouldDeferRender = isAppendOnlyStream && containsCompleteImage;\n\n if (!shouldDeferRender) {\n clearDeferredRenderTimer();\n pendingHtmlRef.current = normalizedHtmlContent;\n setRenderHtmlContent(normalizedHtmlContent);\n return;\n }\n\n pendingHtmlRef.current = normalizedHtmlContent;\n clearDeferredRenderTimer();\n deferRenderTimerRef.current = window.setTimeout(() => {\n setRenderHtmlContent(pendingHtmlRef.current);\n deferRenderTimerRef.current = null;\n }, POST_IMAGE_STREAM_DEBOUNCE_MS);\n }, [normalizedHtmlContent]);\n\n const rootViewportHeightCss = React.useMemo(() => {\n if (!shouldMeasureDynamicHeight) {\n return null;\n }\n\n return inspectViewportHeightFromHtmlRootString(renderHtmlContent)\n .viewportHeightCss;\n }, [renderHtmlContent, shouldMeasureDynamicHeight]);\n\n useEffect(() => {\n renderViewportHeightCssRef.current = rootViewportHeightCss;\n }, [rootViewportHeightCss]);\n\n const hasRootVhHeight = Boolean(rootViewportHeightCss);\n const sandboxViewportHeight =\n isBlackboardMode && type === \"sandbox\"\n ? shouldStretchRootHeight\n ? \"100%\"\n : (rootViewportHeightCss ?? `${height}px`)\n : undefined;\n useEffect(() => {\n if (mode !== \"blackboard\") {\n prevHtmlRef.current = normalizedHtmlContent;\n return;\n }\n const prev = prevHtmlRef.current;\n const isContinuation = prev && normalizedHtmlContent.startsWith(prev);\n if (!isContinuation && prev) {\n setResetToken((token) => token + 1);\n }\n prevHtmlRef.current = normalizedHtmlContent;\n }, [mode, normalizedHtmlContent]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return undefined;\n\n const doc = iframe.contentDocument;\n if (!doc) return undefined;\n\n doc.open();\n doc.write(`<!DOCTYPE html>\n<html${mode === \"blackboard\" ? ' style=\"height: 100%;\"' : \"\"}>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n :root { color-scheme: light; }\n html, body, #root { width: 100%; }\n ${mode === \"blackboard\" ? \"html, body, #root { height: 100%; }\" : \"\"}\n html, body { margin: 0; padding: 0; overflow: ${mode === \"blackboard\" ? \"auto\" : \"hidden\"}; }\n *, *::before, *::after { box-sizing: border-box; }\n ${mode !== \"blackboard\" ? `\n .h-screen { height: auto !important; }\n .min-h-screen { min-height: auto !important; }\n .h-dvh, .h-svh, .h-lvh { height: auto !important; }\n .min-h-dvh, .min-h-svh, .min-h-lvh { min-height: auto !important; }\n ` : \"\"}\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n\n // Force iframe theme to stay in light mode regardless of host OS preference.\n doc.documentElement.setAttribute(\"data-theme\", \"light\");\n doc.documentElement.style.colorScheme = \"light\";\n doc.body?.style.setProperty(\"color-scheme\", \"light\");\n\n const shouldBridgeSandboxInteraction =\n isBlackboardMode && type === \"sandbox\";\n const handleSandboxPointerDown = () =>\n emitSandboxInteraction(\"pointerdown\");\n const handleSandboxMouseDown = () => emitSandboxInteraction(\"mousedown\");\n const handleSandboxTouchStart = () => emitSandboxInteraction(\"touchstart\");\n\n if (shouldBridgeSandboxInteraction) {\n doc.addEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.addEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.addEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n\n const rootEl = doc.getElementById(\"root\");\n if (!rootEl) return undefined;\n\n const root = createRoot(rootEl);\n rootRef.current = root;\n let isDestroyed = false;\n const getHeightInspectionNode = (node: HTMLElement) => ({\n heightAttrValue: node.getAttribute(\"height\"),\n styleAttrValue: node.getAttribute(\"style\"),\n classAttrValue: node.getAttribute(\"class\"),\n });\n const getSingleChildElement = (node: HTMLElement) => {\n const childElements = Array.from(node.children) as HTMLElement[];\n\n return childElements.length === 1 ? childElements[0] : null;\n };\n\n const resolveExplicitHeight = () => {\n if (!shouldMeasureDynamicHeight) return null;\n if (!iframeRef.current || !doc.body) return null;\n const parentViewportHeight =\n iframeRef.current.ownerDocument?.documentElement?.clientHeight ||\n window.innerHeight;\n // Reuse parsed height metadata from the current html snapshot first to\n // avoid re-inspecting the same DOM chain on every height tick.\n const precomputedViewportHeightCss = renderViewportHeightCssRef.current;\n const parsed = precomputedViewportHeightCss\n ? parseExplicitHeight(\n precomputedViewportHeightCss,\n parentViewportHeight\n )\n : null;\n\n if (parsed !== null) {\n return Math.ceil(parsed);\n }\n\n const wrapper = doc.body.querySelector(\n \".sandbox-wrapper\"\n ) as HTMLElement | null;\n const container = wrapper?.firstElementChild as HTMLElement | null;\n if (!container) return null;\n const containerChildren = Array.from(container.children) as HTMLElement[];\n const rootContentElement =\n containerChildren.length === 1 ? containerChildren[0] : null;\n const runtimeHeightMeta = inspectViewportHeightFromNodeChain(\n rootContentElement,\n {\n getNode: getHeightInspectionNode,\n getSingleChild: getSingleChildElement,\n }\n );\n const runtimeViewportHeightCss = runtimeHeightMeta.viewportHeightCss;\n\n if (runtimeViewportHeightCss) {\n const runtimeViewportHeight = parseExplicitHeight(\n runtimeViewportHeightCss,\n parentViewportHeight\n );\n\n if (runtimeViewportHeight !== null) {\n return Math.ceil(runtimeViewportHeight);\n }\n }\n\n const explicitPixelHeight = resolveExplicitHeightFromNodeChain(\n rootContentElement,\n parentViewportHeight,\n {\n getNode: getHeightInspectionNode,\n getSingleChild: getSingleChildElement,\n }\n );\n\n return explicitPixelHeight !== null\n ? Math.ceil(explicitPixelHeight)\n : null;\n };\n\n const updateHeight = () => {\n if (!iframeRef.current || !doc.body) return;\n\n if (!isBlackboardMode) {\n // Guard: prevent re-entrant measurement from ResizeObserver /\n // MutationObserver callbacks triggered by our own height changes.\n if (isMeasuringContentRef.current) return;\n isMeasuringContentRef.current = true;\n\n // Content mode height measurement strategy:\n // The iframe CSS overrides .h-screen/.min-h-screen to height:auto,\n // removing viewport-height constraints. But content may still use\n // vmin units (font-size, padding, gap) which depend on\n // min(width, height). To get a stable measurement, temporarily\n // set iframe height >= containerWidth so vmin = width/100 (constant).\n const iframe = iframeRef.current;\n const cw = containerRef.current?.clientWidth || 0;\n const prevH = iframe.style.height;\n\n if (cw > 0) {\n iframe.style.height = cw + \"px\";\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n doc.body.offsetHeight; // force layout\n\n const measuredH = doc.body.scrollHeight;\n\n // Restore iframe to let React control it via contentModeStyle\n iframe.style.height = prevH;\n\n setContentHeight((prev) => {\n const next = Math.max(200, Math.ceil(measuredH));\n return prev === next ? prev : next;\n });\n }\n\n setTimeout(() => {\n isMeasuringContentRef.current = false;\n }, 50);\n return;\n }\n\n // Blackboard mode: use existing measurement logic\n const bodyScrollH = doc.body.scrollHeight;\n const htmlScrollH = doc.documentElement?.scrollHeight || 0;\n const rootScrollH = rootEl?.scrollHeight || 0;\n const measuredHeight = Math.max(bodyScrollH, htmlScrollH, rootScrollH);\n\n if (shouldMeasureDynamicHeight) {\n const explicitHeight = resolveExplicitHeight();\n const nextHeight = Math.max(\n 200,\n explicitHeight ?? Math.ceil(measuredHeight)\n );\n setHeight((prevHeight) =>\n prevHeight === nextHeight ? prevHeight : nextHeight\n );\n }\n };\n const scheduleHeightUpdate = () => {\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n updateHeight();\n });\n };\n updateHeightRef.current = scheduleHeightUpdate;\n\n updateHeight();\n scheduleHeightUpdate();\n\n if (shouldInjectSandboxVendor) {\n // Inject Tailwind/DaisyUI/GSAP before rendering sandbox content to avoid FOUC.\n loadBlackboardVendor()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n })\n .catch(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n }\n\n const resizeObserver = new ResizeObserver(() => updateHeight());\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n // MutationObserver: detect DOM changes that ResizeObserver might miss\n // (e.g. content injected by scripts, images loading, dynamic rendering)\n const mutationObserver = new MutationObserver(() => {\n scheduleHeightUpdate();\n });\n mutationObserver.observe(doc.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"style\", \"class\"],\n });\n\n return () => {\n isDestroyed = true;\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n if (shouldBridgeSandboxInteraction) {\n doc.removeEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.removeEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.removeEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n // Defer unmount to avoid React warning when parent is mid-render\n setTimeout(() => {\n root.unmount();\n rootRef.current = null;\n 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 // Track container width for computing min-height in content mode\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n setContainerWidth(entries[0]?.contentRect.width ?? el.clientWidth);\n });\n ro.observe(el);\n setContainerWidth(el.clientWidth);\n return () => ro.disconnect();\n }, []);\n\n // Content mode: min 16:9 aspect ratio, grow to fit content (no scrollbar)\n const contentModeStyle = useMemo<React.CSSProperties | undefined>(() => {\n if (isBlackboardMode || containerWidth === 0 || isFullscreen)\n return undefined;\n const minH = Math.round((containerWidth * 9) / 16);\n const h = Math.max(minH, contentHeight);\n return { height: h };\n }, [isBlackboardMode, containerWidth, contentHeight, isFullscreen]);\n\n const toggleFullscreen = () => {\n const target = containerRef.current || iframeRef.current;\n if (!target) return;\n if (document.fullscreenElement) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n if (target.requestFullscreen) {\n target.requestFullscreen().catch(() => {});\n }\n };\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n\n root.render(\n <SandboxApp\n html={renderHtmlContent}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n stretchRootHeight={shouldStretchRootHeight}\n />\n );\n\n // Schedule multiple measurements to catch async content (scripts, images, styles).\n initialPaintFrameRef.current = window.requestAnimationFrame(() => {\n updateHeightRef.current?.();\n initialPaintFrameRef.current = null;\n });\n const t1 = setTimeout(() => updateHeightRef.current?.(), 100);\n const t2 = setTimeout(() => updateHeightRef.current?.(), 500);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n };\n }, [\n renderHtmlContent,\n styleLoadingText,\n scriptLoadingText,\n resetToken,\n mode,\n ]);\n const containerClassName = [\n \"w-full relative content-render-iframe-sandbox\",\n isBlackboardMode\n ? \"h-full overflow-auto flex flex-col\"\n : contentModeStyle\n ? \"overflow-hidden flex items-center justify-center\"\n : \"aspect-[16/9] overflow-hidden flex items-center justify-center\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n ref={containerRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className={containerClassName}\n style={\n sandboxViewportHeight\n ? {\n height: sandboxViewportHeight,\n minHeight: sandboxViewportHeight,\n }\n : contentModeStyle\n }\n >\n {!hideFullScreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className={\n \"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer\"\n }\n >\n {isFullscreen ? \"退出全屏\" : fullScreenButtonText || \"全屏浏览\"}\n </button>\n )}\n {mode === \"blackboard\" && type === \"markdown\" ? (\n <div\n onMouseDown={() => emitSandboxInteraction(\"mousedown\")}\n onPointerDown={() => emitSandboxInteraction(\"pointerdown\")}\n onTouchStart={() => emitSandboxInteraction(\"touchstart\")}\n >\n <ContentRender content={content} />\n </div>\n ) : (\n <iframe\n ref={iframeRef}\n sandbox=\"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\"\n allow=\"fullscreen\"\n allowFullScreen\n className={[className, \"w-full h-full mx-auto my-auto block\"]\n .filter(Boolean)\n .join(\" \")}\n style={{\n height: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n margin: \"auto\",\n }}\n />\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","loadBlackboardVendor","m","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_THROTTLE_MS","replaceRootScreenHeightToken","className","token","segments","replaceRootScreenHeightWithFullClass","html","enabled","match","tagStart","attrs","classMatch","nextClassName","IframeSandbox","content","type","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","replaceRootScreenHeightWithFull","containerRef","useRef","iframeRef","rootRef","updateHeightRef","height","setHeight","useState","contentHeight","setContentHeight","containerWidth","setContainerWidth","isMeasuringContentRef","lastSandboxInteractionTimeRef","resetToken","setResetToken","isFullscreen","setIsFullscreen","shouldInjectSandboxVendor","isBlackboardMode","shouldMeasureDynamicHeight","shouldProcessRootScreenHeight","prevHtmlRef","htmlContent","React","normalizedHtmlContent","originalRootHeightMeta","inspectViewportHeightFromHtmlRootString","EMPTY_ROOT_HEIGHT_META","shouldStretchRootHeight","renderHtmlContent","setRenderHtmlContent","prevIncomingHtmlRef","pendingHtmlRef","deferRenderTimerRef","initialPaintFrameRef","renderViewportHeightCssRef","emitSandboxInteraction","useCallback","eventType","now","SANDBOX_INTERACTION_MESSAGE_SOURCE","SANDBOX_INTERACTION_MESSAGE_TYPE","clearDeferredRenderTimer","clearInitialPaintFrames","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","rootViewportHeightCss","hasRootVhHeight","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","rootEl","root","createRoot","isDestroyed","getHeightInspectionNode","node","getSingleChildElement","childElements","resolveExplicitHeight","parentViewportHeight","precomputedViewportHeightCss","parsed","parseExplicitHeight","container","containerChildren","rootContentElement","runtimeViewportHeightCss","inspectViewportHeightFromNodeChain","runtimeViewportHeight","explicitPixelHeight","resolveExplicitHeightFromNodeChain","updateHeight","cw","prevH","measuredH","next","bodyScrollH","htmlScrollH","rootScrollH","measuredHeight","explicitHeight","nextHeight","prevHeight","scheduleHeightUpdate","inject","resizeObserver","mutationObserver","onFullscreenChange","el","ro","entries","contentModeStyle","useMemo","minH","toggleFullscreen","target","jsx","SandboxApp","t1","t2","containerClassName","jsxs","ContentRender"],"mappings":"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"}