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

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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={exports:{}};exports.__module=e;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.__exports=e;
2
2
  //# sourceMappingURL=index.cjs10.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"});var e={exports:{}};exports.__module=e;
2
2
  //# sourceMappingURL=index.cjs9.js.map
@@ -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=index.es10.js.map
@@ -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=index.es9.js.map
@@ -1,25 +1,29 @@
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 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(" "),ke=(c,s)=>!s||!c.trim()?c:c.replace(/^(\s*<[a-zA-Z][\w:-]*)(\s[^>]*?)?>/,(i,N,M="")=>{const d=M.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);if(!d)return i;const O=Ve(d[2]);return O===d[2]?i:`${N}${M.replace(d[0],`class=${d[1]}${O}${d[1]}`)}>`}),De=({content:c,type:s,className:i,styleLoadingText:N,scriptLoadingText:M,fullScreenButtonText:d,hideFullScreen:O=!1,mode:h="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),[$,ve]=t.useState(!1),Se=s==="sandbox",f=h==="blackboard",C=f&&s==="sandbox",x=C&&we,W=t.useRef(""),V=t.useMemo(()=>s==="sandbox"?c:"",[c,s]),r=t.useMemo(()=>ke(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]),[k,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 D=t.useMemo(()=>C?H.inspectViewportHeightFromHtmlRootString(k).viewportHeightCss:null,[k,C]);t.useEffect(()=>{se.current=D},[D]);const ie=!!D,j=f&&s==="sandbox"?ne?"100%":D??`${He}px`:void 0;t.useEffect(()=>{if(h!=="blackboard"){W.current=r;return}const n=W.current;!(n&&r.startsWith(n))&&n&&Re(l=>l+1),W.current=r},[h,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${h==="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
+ ${h==="blackboard"?"html, body, #root { height: 100%; }":""}
10
+ html, body { margin: 0; padding: 0; overflow: ${h==="blackboard"?"auto":"hidden"}; }
11
11
  *, *::before, *::after { box-sizing: border-box; }
12
12
  html.measuring-height, html.measuring-height body,
13
13
  html.measuring-height #root, html.measuring-height .sandbox-wrapper {
14
14
  height: auto !important; min-height: 0 !important;
15
15
  }
16
- html.measuring-height * {
17
- min-height: 0 !important;
16
+ html.measuring-height * { min-height: 0 !important; }
17
+ html.measuring-height [class*="h-screen"],
18
+ html.measuring-height [class*="min-h-screen"],
19
+ html.measuring-height [class*="h-dvh"],
20
+ html.measuring-height [class*="min-h-dvh"] {
21
+ height: auto !important; min-height: 0 !important;
18
22
  }
19
23
  </style>
20
24
  </head>
21
25
  <body>
22
26
  <div id="root"></div>
23
27
  </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;
28
+ </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||$)return;const n=Math.round(B*9/16);return{height:Math.max(n,J)}},[f,B,J,$]),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:k,styleLoadingText:N,scriptLoadingText:M,resetToken:ee,hasRootVhHeight:ie,mode:h,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)}},[k,N,M,ee,h]);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:$?"退出全屏":d||"全屏浏览"}),h==="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=De;
25
29
  //# 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 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 * { min-height: 0 !important; }\n html.measuring-height [class*=\"h-screen\"],\n html.measuring-height [class*=\"min-h-screen\"],\n html.measuring-height [class*=\"h-dvh\"],\n html.measuring-height [class*=\"min-h-dvh\"] {\n height: auto !important; 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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"}
@@ -2,25 +2,25 @@ import { j as M } from "../../_virtual/jsx-runtime.es.js";
2
2
  import O, { useRef as s, useState as y, useCallback as Ne, useEffect as m, useMemo as _e } from "react";
3
3
  import { createRoot as Oe } from "react-dom/client";
4
4
  import Ve from "./SandboxApp.es.js";
5
- import De from "./ContentRender.es.js";
6
- import { inspectViewportHeightFromHtmlRootString as He, EMPTY_ROOT_HEIGHT_META as je, parseExplicitHeight as xe, inspectViewportHeightFromNodeChain as ke, resolveExplicitHeightFromNodeChain as Be } from "./utils/iframe-viewport-height.es.js";
5
+ import ke from "./ContentRender.es.js";
6
+ import { inspectViewportHeightFromHtmlRootString as He, EMPTY_ROOT_HEIGHT_META as De, parseExplicitHeight as xe, inspectViewportHeightFromNodeChain as je, resolveExplicitHeightFromNodeChain as Be } from "./utils/iframe-viewport-height.es.js";
7
7
  import { SANDBOX_INTERACTION_MESSAGE_TYPE as Pe, SANDBOX_INTERACTION_MESSAGE_SOURCE as Le } from "../../lib/sandboxInteraction.es.js";
8
8
  let K = null;
9
- const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
9
+ const $e = () => (K || (K = import("./blackboard-vendor.es.js").then(
10
10
  (l) => l.injectBlackboardLibraries
11
- )), K), $e = /<img\b[^>]*>/i, ze = 180, qe = 240, Ge = (l) => l.split(/\s+/).filter(Boolean).map((o) => {
11
+ )), K), We = /<img\b[^>]*>/i, ze = 180, qe = 240, Ge = (l) => l.split(/\s+/).filter(Boolean).map((o) => {
12
12
  const i = o.split(":");
13
13
  return i[i.length - 1] !== "h-screen" && i[i.length - 1] !== "min-h-screen" ? o : (i[i.length - 1] = "h-full", i.join(":"));
14
14
  }).join(" "), Ue = (l, o) => !o || !l.trim() ? l : l.replace(
15
15
  /^(\s*<[a-zA-Z][\w:-]*)(\s[^>]*?)?>/,
16
16
  (i, V, S = "") => {
17
- const h = S.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);
18
- if (!h)
17
+ const d = S.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);
18
+ if (!d)
19
19
  return i;
20
- const D = Ge(h[2]);
21
- return D === h[2] ? i : `${V}${S.replace(
22
- h[0],
23
- `class=${h[1]}${D}${h[1]}`
20
+ const k = Ge(d[2]);
21
+ return k === d[2] ? i : `${V}${S.replace(
22
+ d[0],
23
+ `class=${d[1]}${k}${d[1]}`
24
24
  )}>`;
25
25
  }
26
26
  ), tt = ({
@@ -29,24 +29,24 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
29
29
  className: i,
30
30
  styleLoadingText: V,
31
31
  scriptLoadingText: S,
32
- fullScreenButtonText: h,
33
- hideFullScreen: D = !1,
34
- mode: d = "content",
32
+ fullScreenButtonText: d,
33
+ hideFullScreen: k = !1,
34
+ mode: h = "content",
35
35
  replaceRootScreenHeightWithFull: Ee = !1
36
36
  }) => {
37
- const j = s(null), g = s(null), W = s(null), C = s(() => {
38
- }), [ve, Re] = y(480), [Q, Me] = y(0), [$, ee] = y(0), z = s(!1), te = s(0), [ne, ye] = y(0), [q, Se] = y(!1), Ce = o === "sandbox", f = d === "blackboard", T = f && o === "sandbox", x = T && Ee, G = s(""), k = O.useMemo(
37
+ const D = s(null), g = s(null), $ = s(null), C = s(() => {
38
+ }), [ve, Re] = y(480), [Q, Me] = y(0), [W, ee] = y(0), z = s(!1), te = s(0), [ne, ye] = y(0), [q, Se] = y(!1), Ce = o === "sandbox", f = h === "blackboard", T = f && o === "sandbox", x = T && Ee, G = s(""), j = O.useMemo(
39
39
  () => o === "sandbox" ? l : "",
40
40
  [l, o]
41
41
  ), n = O.useMemo(
42
42
  () => Ue(
43
- k,
43
+ j,
44
44
  x
45
45
  ),
46
- [k, x]
46
+ [j, x]
47
47
  ), re = O.useMemo(
48
- () => x ? He(k) : je,
49
- [k, x]
48
+ () => x ? He(j) : De,
49
+ [j, x]
50
50
  ), oe = O.useMemo(
51
51
  () => x && re.hasFullViewportHeight,
52
52
  [
@@ -80,7 +80,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
80
80
  ), m(() => {
81
81
  const t = se.current;
82
82
  se.current = n;
83
- const e = !!t && n.length > t.length && n.startsWith(t), c = $e.test(
83
+ const e = !!t && n.length > t.length && n.startsWith(t), c = We.test(
84
84
  n
85
85
  );
86
86
  if (!(e && c)) {
@@ -97,34 +97,38 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
97
97
  }, [P]);
98
98
  const ce = !!P, I = f && o === "sandbox" ? oe ? "100%" : P ?? `${ve}px` : void 0;
99
99
  m(() => {
100
- if (d !== "blackboard") {
100
+ if (h !== "blackboard") {
101
101
  G.current = n;
102
102
  return;
103
103
  }
104
104
  const t = G.current;
105
105
  !(t && n.startsWith(t)) && t && ye((c) => c + 1), G.current = n;
106
- }, [d, n]), m(() => {
106
+ }, [h, n]), m(() => {
107
107
  const t = g.current;
108
108
  if (!t) return;
109
109
  const e = t.contentDocument;
110
110
  if (!e) return;
111
111
  e.open(), e.write(`<!DOCTYPE html>
112
- <html${d === "blackboard" ? ' style="height: 100%;"' : ""}>
112
+ <html${h === "blackboard" ? ' style="height: 100%;"' : ""}>
113
113
  <head>
114
114
  <meta charset="utf-8" />
115
115
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
116
116
  <style>
117
117
  :root { color-scheme: light; }
118
118
  html, body, #root { width: 100%; }
119
- ${d === "blackboard" ? "html, body, #root { height: 100%; }" : ""}
120
- html, body { margin: 0; padding: 0; overflow: auto; }
119
+ ${h === "blackboard" ? "html, body, #root { height: 100%; }" : ""}
120
+ html, body { margin: 0; padding: 0; overflow: ${h === "blackboard" ? "auto" : "hidden"}; }
121
121
  *, *::before, *::after { box-sizing: border-box; }
122
122
  html.measuring-height, html.measuring-height body,
123
123
  html.measuring-height #root, html.measuring-height .sandbox-wrapper {
124
124
  height: auto !important; min-height: 0 !important;
125
125
  }
126
- html.measuring-height * {
127
- min-height: 0 !important;
126
+ html.measuring-height * { min-height: 0 !important; }
127
+ html.measuring-height [class*="h-screen"],
128
+ html.measuring-height [class*="min-h-screen"],
129
+ html.measuring-height [class*="h-dvh"],
130
+ html.measuring-height [class*="min-h-dvh"] {
131
+ height: auto !important; min-height: 0 !important;
128
132
  }
129
133
  </style>
130
134
  </head>
@@ -137,7 +141,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
137
141
  const p = e.getElementById("root");
138
142
  if (!p) return;
139
143
  const de = Oe(p);
140
- W.current = de;
144
+ $.current = de;
141
145
  let N = !1;
142
146
  const me = (r) => ({
143
147
  heightAttrValue: r.getAttribute("height"),
@@ -158,7 +162,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
158
162
  ".sandbox-wrapper"
159
163
  )?.firstElementChild;
160
164
  if (!w) return null;
161
- const u = Array.from(w.children), a = u.length === 1 ? u[0] : null, H = ke(
165
+ const u = Array.from(w.children), a = u.length === 1 ? u[0] : null, H = je(
162
166
  a,
163
167
  {
164
168
  getNode: me,
@@ -187,7 +191,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
187
191
  if (!f) {
188
192
  if (z.current) return;
189
193
  z.current = !0;
190
- const w = j.current?.clientWidth || 0, u = w > 0 ? Math.round(w * 9 / 16) : 480, a = g.current, be = a.style.height;
194
+ const w = D.current?.clientWidth || 0, u = w > 0 ? Math.round(w * 9 / 16) : 480, a = g.current, be = a.style.height;
191
195
  e.documentElement.classList.add("measuring-height"), a.style.height = u + "px", e.body.offsetHeight;
192
196
  const H = Math.max(
193
197
  e.body.scrollHeight,
@@ -222,7 +226,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
222
226
  N || Z();
223
227
  });
224
228
  };
225
- C.current = _, Z(), _(), Ce && We().then((r) => {
229
+ C.current = _, Z(), _(), Ce && $e().then((r) => {
226
230
  N || (r(e), requestAnimationFrame(() => {
227
231
  N || _();
228
232
  }));
@@ -241,7 +245,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
241
245
  attributeFilter: ["style", "class"]
242
246
  }), () => {
243
247
  N = !0, J.disconnect(), fe.disconnect(), c && (e.removeEventListener("pointerdown", Y, !0), e.removeEventListener("mousedown", ae, !0), e.removeEventListener("touchstart", he, !0)), setTimeout(() => {
244
- de.unmount(), W.current = null, C.current = () => {
248
+ de.unmount(), $.current = null, C.current = () => {
245
249
  };
246
250
  }, 0);
247
251
  };
@@ -251,7 +255,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
251
255
  };
252
256
  return document.addEventListener("fullscreenchange", t), () => document.removeEventListener("fullscreenchange", t);
253
257
  }, []), m(() => {
254
- const t = j.current;
258
+ const t = D.current;
255
259
  if (!t) return;
256
260
  const e = new ResizeObserver((c) => {
257
261
  ee(c[0]?.contentRect.width ?? t.clientWidth);
@@ -259,12 +263,12 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
259
263
  return e.observe(t), ee(t.clientWidth), () => e.disconnect();
260
264
  }, []);
261
265
  const ue = _e(() => {
262
- if (f || $ === 0 || q)
266
+ if (f || W === 0 || q)
263
267
  return;
264
- const t = Math.round($ * 9 / 16);
268
+ const t = Math.round(W * 9 / 16);
265
269
  return { height: Math.max(t, Q) };
266
- }, [f, $, Q, q]), Ae = () => {
267
- const t = j.current || g.current;
270
+ }, [f, W, Q, q]), Ae = () => {
271
+ const t = D.current || g.current;
268
272
  if (t) {
269
273
  if (document.fullscreenElement) {
270
274
  document.exitFullscreen().catch(() => {
@@ -276,7 +280,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
276
280
  }
277
281
  };
278
282
  m(() => {
279
- const t = W.current;
283
+ const t = $.current;
280
284
  if (!t) return;
281
285
  t.render(
282
286
  /* @__PURE__ */ M.jsx(
@@ -287,7 +291,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
287
291
  scriptLoadingText: S,
288
292
  resetToken: ne,
289
293
  hasRootVhHeight: ce,
290
- mode: d,
294
+ mode: h,
291
295
  stretchRootHeight: oe
292
296
  }
293
297
  )
@@ -303,7 +307,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
303
307
  V,
304
308
  S,
305
309
  ne,
306
- d
310
+ h
307
311
  ]);
308
312
  const Fe = [
309
313
  "w-full relative content-render-iframe-sandbox",
@@ -312,7 +316,7 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
312
316
  return /* @__PURE__ */ M.jsxs(
313
317
  "div",
314
318
  {
315
- ref: j,
319
+ ref: D,
316
320
  "data-root-vh": ce ? "true" : "false",
317
321
  className: Fe,
318
322
  style: I ? {
@@ -320,22 +324,22 @@ const We = () => (K || (K = import("./blackboard-vendor.es.js").then(
320
324
  minHeight: I
321
325
  } : ue,
322
326
  children: [
323
- !D && /* @__PURE__ */ M.jsx(
327
+ !k && /* @__PURE__ */ M.jsx(
324
328
  "button",
325
329
  {
326
330
  type: "button",
327
331
  onClick: Ae,
328
332
  className: "absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",
329
- children: q ? "退出全屏" : h || "全屏浏览"
333
+ children: q ? "退出全屏" : d || "全屏浏览"
330
334
  }
331
335
  ),
332
- d === "blackboard" && o === "markdown" ? /* @__PURE__ */ M.jsx(
336
+ h === "blackboard" && o === "markdown" ? /* @__PURE__ */ M.jsx(
333
337
  "div",
334
338
  {
335
339
  onMouseDown: () => E("mousedown"),
336
340
  onPointerDown: () => E("pointerdown"),
337
341
  onTouchStart: () => E("touchstart"),
338
- children: /* @__PURE__ */ M.jsx(De, { content: l })
342
+ children: /* @__PURE__ */ M.jsx(ke, { content: l })
339
343
  }
340
344
  ) : /* @__PURE__ */ M.jsx(
341
345
  "iframe",
@@ -1 +1 @@
1
- {"version":3,"file":"IframeSandbox.es.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.es.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 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 * { min-height: 0 !important; }\n html.measuring-height [class*=\"h-screen\"],\n html.measuring-height [class*=\"min-h-screen\"],\n html.measuring-height [class*=\"h-dvh\"],\n html.measuring-height [class*=\"min-h-dvh\"] {\n height: auto !important; 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,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("../../_virtual/index.cjs10.js");/*!
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("../../_virtual/index.cjs9.js");/*!
2
2
  Copyright (c) 2018 Jed Watson.
3
3
  Licensed under the MIT License (MIT), see
4
4
  http://jedwatson.github.io/classnames
@@ -1,4 +1,4 @@
1
- import { __module as s } from "../../_virtual/index.es10.js";
1
+ import { __module as s } from "../../_virtual/index.es9.js";
2
2
  /*!
3
3
  Copyright (c) 2018 Jed Watson.
4
4
  Licensed under the MIT License (MIT), see
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../../../_virtual/index.cjs9.js"),c=require("../../inline-style-parser/index.cjs.js");var o;function v(){if(o)return r.__exports;o=1;var f=r.__exports&&r.__exports.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(r.__exports,"__esModule",{value:!0}),r.__exports.default=a;var s=f(c.__require());function a(e,n){var t=null;if(!e||typeof e!="string")return t;var p=(0,s.default)(e),l=typeof n=="function";return p.forEach(function(u){if(u.type==="declaration"){var i=u.property,_=u.value;l?n(i,_,u):_&&(t=t||{},t[i]=_)}}),t}return r.__exports}exports.__require=v;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../../../_virtual/index.cjs10.js"),c=require("../../inline-style-parser/index.cjs.js");var o;function v(){if(o)return r.__exports;o=1;var f=r.__exports&&r.__exports.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(r.__exports,"__esModule",{value:!0}),r.__exports.default=a;var s=f(c.__require());function a(e,n){var t=null;if(!e||typeof e!="string")return t;var p=(0,s.default)(e),l=typeof n=="function";return p.forEach(function(u){if(u.type==="declaration"){var i=u.property,_=u.value;l?n(i,_,u):_&&(t=t||{},t[i]=_)}}),t}return r.__exports}exports.__require=v;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../../../node_modules/style-to-object/cjs/index.js"],"sourcesContent":["\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.default = StyleToObject;\nvar inline_style_parser_1 = __importDefault(require(\"inline-style-parser\"));\n/**\n * Parses inline style to object.\n *\n * @param style - Inline style.\n * @param iterator - Iterator.\n * @returns - Style object or null.\n *\n * @example Parsing inline style to object:\n *\n * ```js\n * import parse from 'style-to-object';\n * parse('line-height: 42;'); // { 'line-height': '42' }\n * ```\n */\nfunction StyleToObject(style, iterator) {\n var styleObject = null;\n if (!style || typeof style !== 'string') {\n return styleObject;\n }\n var declarations = (0, inline_style_parser_1.default)(style);\n var hasIterator = typeof iterator === 'function';\n declarations.forEach(function (declaration) {\n if (declaration.type !== 'declaration') {\n return;\n }\n var property = declaration.property, value = declaration.value;\n if (hasIterator) {\n iterator(property, value, declaration);\n }\n else if (value) {\n styleObject = styleObject || {};\n styleObject[property] = value;\n }\n });\n return styleObject;\n}\n//# sourceMappingURL=index.js.map"],"names":["__importDefault","this","mod","cjs","StyleToObject","inline_style_parser_1","require$$0","style","iterator","styleObject","declarations","hasIterator","declaration","property","value"],"mappings":"sOACA,IAAIA,EAAmBC,EAAAA,WAAQA,EAAAA,UAAK,iBAAoB,SAAUC,EAAK,CACnE,OAAQA,GAAOA,EAAI,WAAcA,EAAM,CAAE,QAAWA,CAAG,CAC3D,EACA,OAAO,eAAeC,EAAAA,UAAS,aAAc,CAAE,MAAO,GAAM,EAC5DA,EAAAA,UAAA,QAAkBC,EAClB,IAAIC,EAAwBL,EAAgBM,EAAAA,WAA8B,EAe1E,SAASF,EAAcG,EAAOC,EAAU,CACpC,IAAIC,EAAc,KAClB,GAAI,CAACF,GAAS,OAAOA,GAAU,SAC3B,OAAOE,EAEX,IAAIC,KAAmBL,EAAsB,SAASE,CAAK,EACvDI,EAAc,OAAOH,GAAa,WACtC,OAAAE,EAAa,QAAQ,SAAUE,EAAa,CACxC,GAAIA,EAAY,OAAS,cAGzB,KAAIC,EAAWD,EAAY,SAAUE,EAAQF,EAAY,MACrDD,EACAH,EAASK,EAAUC,EAAOF,CAAW,EAEhCE,IACLL,EAAcA,GAAe,CAAA,EAC7BA,EAAYI,CAAQ,EAAIC,GAEpC,CAAK,EACML,CACX","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../node_modules/style-to-object/cjs/index.js"],"sourcesContent":["\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.default = StyleToObject;\nvar inline_style_parser_1 = __importDefault(require(\"inline-style-parser\"));\n/**\n * Parses inline style to object.\n *\n * @param style - Inline style.\n * @param iterator - Iterator.\n * @returns - Style object or null.\n *\n * @example Parsing inline style to object:\n *\n * ```js\n * import parse from 'style-to-object';\n * parse('line-height: 42;'); // { 'line-height': '42' }\n * ```\n */\nfunction StyleToObject(style, iterator) {\n var styleObject = null;\n if (!style || typeof style !== 'string') {\n return styleObject;\n }\n var declarations = (0, inline_style_parser_1.default)(style);\n var hasIterator = typeof iterator === 'function';\n declarations.forEach(function (declaration) {\n if (declaration.type !== 'declaration') {\n return;\n }\n var property = declaration.property, value = declaration.value;\n if (hasIterator) {\n iterator(property, value, declaration);\n }\n else if (value) {\n styleObject = styleObject || {};\n styleObject[property] = value;\n }\n });\n return styleObject;\n}\n//# sourceMappingURL=index.js.map"],"names":["__importDefault","this","mod","cjs","StyleToObject","inline_style_parser_1","require$$0","style","iterator","styleObject","declarations","hasIterator","declaration","property","value"],"mappings":"uOACA,IAAIA,EAAmBC,EAAAA,WAAQA,EAAAA,UAAK,iBAAoB,SAAUC,EAAK,CACnE,OAAQA,GAAOA,EAAI,WAAcA,EAAM,CAAE,QAAWA,CAAG,CAC3D,EACA,OAAO,eAAeC,EAAAA,UAAS,aAAc,CAAE,MAAO,GAAM,EAC5DA,EAAAA,UAAA,QAAkBC,EAClB,IAAIC,EAAwBL,EAAgBM,EAAAA,WAA8B,EAe1E,SAASF,EAAcG,EAAOC,EAAU,CACpC,IAAIC,EAAc,KAClB,GAAI,CAACF,GAAS,OAAOA,GAAU,SAC3B,OAAOE,EAEX,IAAIC,KAAmBL,EAAsB,SAASE,CAAK,EACvDI,EAAc,OAAOH,GAAa,WACtC,OAAAE,EAAa,QAAQ,SAAUE,EAAa,CACxC,GAAIA,EAAY,OAAS,cAGzB,KAAIC,EAAWD,EAAY,SAAUE,EAAQF,EAAY,MACrDD,EACAH,EAASK,EAAUC,EAAOF,CAAW,EAEhCE,IACLL,EAAcA,GAAe,CAAA,EAC7BA,EAAYI,CAAQ,EAAIC,GAEpC,CAAK,EACML,CACX","x_google_ignoreList":[0]}
@@ -1,4 +1,4 @@
1
- import { __exports as r } from "../../../_virtual/index.es9.js";
1
+ import { __exports as r } from "../../../_virtual/index.es10.js";
2
2
  import { __require as v } from "../../inline-style-parser/index.es.js";
3
3
  var f;
4
4
  function j() {
package/package.json CHANGED
@@ -174,7 +174,7 @@
174
174
  ]
175
175
  }
176
176
  },
177
- "version": "0.1.104-alpha.8",
177
+ "version": "0.1.104-alpha.9",
178
178
  "type": "module",
179
179
  "exports": {
180
180
  ".": {