markdown-flow-ui 0.1.118-dev.1 → 0.1.118-dev.2
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.
- package/dist/_virtual/index.cjs10.js +1 -1
- package/dist/_virtual/index.cjs11.js +1 -1
- package/dist/_virtual/index.cjs12.js +1 -1
- package/dist/_virtual/index.cjs5.js +1 -1
- package/dist/_virtual/index.cjs6.js +1 -1
- package/dist/_virtual/index.cjs9.js +1 -1
- package/dist/_virtual/index.es10.js +3 -3
- package/dist/_virtual/index.es11.js +2 -2
- package/dist/_virtual/index.es12.js +2 -2
- package/dist/_virtual/index.es5.js +4 -4
- package/dist/_virtual/index.es6.js +4 -4
- package/dist/_virtual/index.es9.js +3 -3
- package/dist/components/ContentRender/SandboxApp.cjs.js +12 -11
- package/dist/components/ContentRender/SandboxApp.cjs.js.map +1 -1
- package/dist/components/ContentRender/SandboxApp.es.js +82 -82
- package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
- package/dist/node_modules/@braintree/sanitize-url/dist/index.cjs.js +1 -1
- package/dist/node_modules/@braintree/sanitize-url/dist/index.es.js +1 -1
- package/dist/node_modules/hast-util-to-jsx-runtime/lib/index.cjs.js +1 -1
- package/dist/node_modules/hast-util-to-jsx-runtime/lib/index.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-AAMF2YG6.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-AAMF2YG6.cjs.js.map +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-AAMF2YG6.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-OMD6QJNC.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-OMD6QJNC.cjs.js.map +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-OMD6QJNC.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-U37J5Y7L.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-U37J5Y7L.cjs.js.map +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-U37J5Y7L.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-WV7ZQ7D5.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-WV7ZQ7D5.cjs.js.map +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-WV7ZQ7D5.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-4MX5Z3NR.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-4MX5Z3NR.cjs.js.map +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-4MX5Z3NR.es.js +1 -1
- package/dist/node_modules/rc-util/es/ref.cjs.js +1 -1
- package/dist/node_modules/rc-util/es/ref.cjs.js.map +1 -1
- package/dist/node_modules/rc-util/es/ref.es.js +1 -1
- package/dist/node_modules/rc-util/node_modules/react-is/index.cjs.js +1 -1
- package/dist/node_modules/rc-util/node_modules/react-is/index.es.js +1 -1
- package/dist/node_modules/unified/lib/index.cjs.js +1 -1
- package/dist/node_modules/unified/lib/index.es.js +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../node_modules/
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../node_modules/@braintree/sanitize-url/dist/index.cjs.js");var r=e.__require();exports.distExports=r;
|
|
2
2
|
//# sourceMappingURL=index.cjs10.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={exports:{}};exports.__module=e;
|
|
2
2
|
//# sourceMappingURL=index.cjs11.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.__exports=e;
|
|
2
2
|
//# sourceMappingURL=index.cjs12.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./_commonjsHelpers.cjs.js"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./_commonjsHelpers.cjs.js"),r=require("../node_modules/style-to-js/cjs/index.cjs.js");var t=r.__require();const o=e.getDefaultExportFromCjs(t);exports.default=o;
|
|
2
2
|
//# sourceMappingURL=index.cjs5.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./_commonjsHelpers.cjs.js"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./_commonjsHelpers.cjs.js"),t=require("../node_modules/extend/index.cjs.js");var r=t.__require();const o=e.getDefaultExportFromCjs(r);exports.default=o;
|
|
2
2
|
//# sourceMappingURL=index.cjs6.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../node_modules
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../node_modules/rc-util/node_modules/react-is/index.cjs.js");var r=e.__require();exports.reactIsExports=r;
|
|
2
2
|
//# sourceMappingURL=index.cjs9.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { __require as r } from "../node_modules/
|
|
2
|
-
var
|
|
1
|
+
import { __require as r } from "../node_modules/@braintree/sanitize-url/dist/index.es.js";
|
|
2
|
+
var i = r();
|
|
3
3
|
export {
|
|
4
|
-
|
|
4
|
+
i as d
|
|
5
5
|
};
|
|
6
6
|
//# sourceMappingURL=index.es10.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getDefaultExportFromCjs as
|
|
2
|
-
import { __require as
|
|
3
|
-
var t =
|
|
4
|
-
const a = /* @__PURE__ */
|
|
1
|
+
import { getDefaultExportFromCjs as r } from "./_commonjsHelpers.es.js";
|
|
2
|
+
import { __require as o } from "../node_modules/style-to-js/cjs/index.es.js";
|
|
3
|
+
var t = o();
|
|
4
|
+
const a = /* @__PURE__ */ r(t);
|
|
5
5
|
export {
|
|
6
6
|
a as default
|
|
7
7
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getDefaultExportFromCjs as
|
|
2
|
-
import { __require as
|
|
3
|
-
var t =
|
|
4
|
-
const a = /* @__PURE__ */
|
|
1
|
+
import { getDefaultExportFromCjs as e } from "./_commonjsHelpers.es.js";
|
|
2
|
+
import { __require as r } from "../node_modules/extend/index.es.js";
|
|
3
|
+
var t = r();
|
|
4
|
+
const a = /* @__PURE__ */ e(t);
|
|
5
5
|
export {
|
|
6
6
|
a as default
|
|
7
7
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { __require as r } from "../node_modules
|
|
2
|
-
var
|
|
1
|
+
import { __require as r } from "../node_modules/rc-util/node_modules/react-is/index.es.js";
|
|
2
|
+
var a = r();
|
|
3
3
|
export {
|
|
4
|
-
|
|
4
|
+
a as r
|
|
5
5
|
};
|
|
6
6
|
//# sourceMappingURL=index.es9.js.map
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const A=require("../../_virtual/jsx-runtime.cjs.js"),t=require("react"),J=require("../ui/loading-overlay-card.cjs.js"),X=["src","srcset","sizes","alt","class","width","height","style","loading","decoding","crossorigin","referrerpolicy","fetchpriority"],L=
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const A=require("../../_virtual/jsx-runtime.cjs.js"),t=require("react"),J=require("../ui/loading-overlay-card.cjs.js"),X=["src","srcset","sizes","alt","class","width","height","style","loading","decoding","crossorigin","referrerpolicy","fetchpriority"],L=a=>X.map(r=>`${r}:${a.getAttribute(r)||""}`).join("|"),Y=a=>{const r=new Map;return a.querySelectorAll("img").forEach(f=>{const c=f,n=L(c),d=r.get(n)||[];d.push(c),r.set(n,d)}),r},Z=(a,r)=>{const f=Array.from(a.attributes),c=new Set(f.map(n=>n.name));Array.from(r.attributes).forEach(n=>{c.has(n.name)||r.removeAttribute(n.name)}),f.forEach(n=>{r.setAttribute(n.name,n.value)})},ee=(a,r)=>{r.size&&a.querySelectorAll("img").forEach(f=>{const c=f,n=L(c),d=r.get(n),p=d?.shift();p&&(Z(c,p),c.replaceWith(p),d&&d.length===0&&r.delete(n))})},te=({html:a,styleLoadingText:r,scriptLoadingText:f,resetToken:c=0,mode:n="content",hasRootVhHeight:d=!1,stretchRootHeight:p=!1,enableScaling:q=!1,disableLoadingOverlay:I=!1})=>{const j=t.useRef(null),[U,v]=t.useState(!1),[W,E]=t.useState(!1),N=t.useRef([]),_=t.useRef([]),k=t.useRef(0),D=t.useRef(0),y=t.useRef(null),g=t.useRef(null),x=t.useRef(!1),b=t.useRef(!1),G=t.useRef(!1),H=t.useRef(c),V=200,u=s=>{s.current&&(clearTimeout(s.current),s.current=null)},B=(s,i,l,T)=>{const h=performance.now()-l.current,C=Math.max(0,V-h);u(i),i.current=window.setTimeout(()=>{s(!1),T?.(),i.current=null},C)};t.useEffect(()=>{const s=j.current?.ownerDocument;if(!s)return;const i="sandbox-spinner-style";let l=s.getElementById(i);l||(l=s.createElement("style"),l.id=i,s.head?.appendChild(l)),l.textContent=`
|
|
2
2
|
.sandbox-wrapper { align-items: center; }
|
|
3
3
|
.sandbox-container { position: relative; width: 100%; }
|
|
4
4
|
.sandbox-container svg,
|
|
5
5
|
.sandbox-container img { display: block; margin-left: auto; margin-right: auto; }
|
|
6
|
-
/*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
6
|
+
/* Hide scroll UI without removing scroll semantics. Content roots with
|
|
7
|
+
inline style="height:100vh; overflow-y:auto" are the signal that
|
|
8
|
+
IframeSandbox.getInnerScrollableHeight relies on to grow the iframe
|
|
9
|
+
when content exceeds the viewport. We must not change overflow-y,
|
|
10
|
+
but sub-pixel rounding (1px below the +1 detection threshold) can
|
|
11
|
+
still surface a phantom scrollbar on content that visually fits.
|
|
12
|
+
Hide the scrollbar UI globally; when content truly overflows the
|
|
13
|
+
iframe is resized and no scrollbar would render anyway. */
|
|
14
|
+
.sandbox-container *::-webkit-scrollbar { display: none; }
|
|
15
|
+
.sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }
|
|
15
16
|
.justify-\\[safe_center\\]{
|
|
16
17
|
justify-content: safe center;
|
|
17
18
|
}
|
|
18
19
|
.overflow-y-auto { overflow-y: visible !important; }
|
|
19
|
-
`},[]),t.useEffect(()=>{
|
|
20
|
+
`},[]),t.useEffect(()=>{c!==H.current&&(G.current=!1,H.current=c),u(y),u(g),x.current=!1,b.current=!1;const s=j.current;if(!s)return;const i=s.ownerDocument,l=i?.body;if(!l)return;const T=Y(s);N.current.forEach(e=>e.remove()),N.current=[],_.current.forEach(e=>e.remove()),_.current=[],v(!1),E(!1);const h=i.createElement("div");h.innerHTML=a;const C=(a.match(/<script[\s>]/gi)||[]).length,O=(a.match(/<\/script>/gi)||[]).length,P=C>0&&C===O,w=[];Array.from(h.querySelectorAll("style, script")).forEach(e=>{if(e.tagName.toLowerCase()==="style"){const o=i.createElement("style");o.textContent=e.textContent||"",Array.from(e.attributes).forEach(m=>{o.setAttribute(m.name,m.value)}),w.push(o)}else{const o=i.createElement("script");Array.from(e.attributes).forEach(m=>{o.setAttribute(m.name,m.value)}),o.textContent=e.textContent||"",w.push(o)}e.remove()}),ee(h,T);const F=w.some(e=>e.tagName.toLowerCase()==="style"),z=w.some(e=>e.tagName.toLowerCase()==="script");F&&(x.current=!0,k.current=performance.now(),u(y),v(!0)),z&&(b.current=!0,D.current=performance.now(),u(g),E(!0)),!!h.firstElementChild&&(G.current=!0);const Q=Array.from(h.childNodes);s.replaceChildren(...Q),w.forEach(e=>{if(e.tagName.toLowerCase()==="style"){i.head?.appendChild(e),N.current.push(e);return}if(P){const o=e,m=o.textContent||"";if(!o.src)try{new Function(m)}catch{o.remove();return}try{l.appendChild(o),_.current.push(o)}catch{o.remove()}}else e.remove()}),q&&s.ownerDocument?.defaultView?.__mdf_triggerFitContent?.(),requestAnimationFrame(()=>{F&&B(v,y,k,()=>{x.current=!1}),z&&B(E,g,D,()=>{b.current=!1})})},[a,c,q]),t.useEffect(()=>()=>{u(y),u(g)},[]),t.useEffect(()=>{I&&(u(y),u(g),x.current=!1,b.current=!1,v(!1),E(!1))},[I]);const R=I?null:W||b.current?f||"Building scripts cache...":U||x.current?r||"Building styles...":null,M=n==="blackboard",S=M&&p,$={position:"relative",width:"100%",height:"100%",display:"flex",flexDirection:"column",justifyContent:S?"flex-start":M?"space-around":"flex-start"},K={pointerEvents:R?"none":void 0,margin:M?void 0:"auto 0",width:"100%",height:S?"100%":void 0,minHeight:S?0:void 0,flex:S?"1 1 auto":void 0};return A.jsxRuntimeExports.jsxs("div",{"data-root-vh":d?"true":"false",className:"sandbox-wrapper",style:$,"aria-busy":!!R,children:[A.jsxRuntimeExports.jsx("div",{ref:j,className:"sandbox-container",style:K}),R&&A.jsxRuntimeExports.jsx("div",{style:{position:"absolute",inset:0,zIndex:20,display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:A.jsxRuntimeExports.jsx(J.default,{message:R})})]})};exports.default=te;
|
|
20
21
|
//# sourceMappingURL=SandboxApp.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxApp.cjs.js","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport type { ScalingWindow } from \"./utils/iframe-scaling\";\n\nexport interface SandboxAppProps {\n html: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n hasRootVhHeight?: boolean;\n stretchRootHeight?: boolean;\n enableScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nconst IMAGE_REUSE_ATTRIBUTES = [\n \"src\",\n \"srcset\",\n \"sizes\",\n \"alt\",\n \"class\",\n \"width\",\n \"height\",\n \"style\",\n \"loading\",\n \"decoding\",\n \"crossorigin\",\n \"referrerpolicy\",\n \"fetchpriority\",\n];\n\nconst getImageReuseKey = (image: HTMLImageElement) =>\n IMAGE_REUSE_ATTRIBUTES.map(\n (attribute) => `${attribute}:${image.getAttribute(attribute) || \"\"}`\n ).join(\"|\");\n\nconst collectReusableImages = (root: ParentNode) => {\n const imageMap = new Map<string, HTMLImageElement[]>();\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n const key = getImageReuseKey(image);\n const bucket = imageMap.get(key) || [];\n bucket.push(image);\n imageMap.set(key, bucket);\n });\n return imageMap;\n};\n\nconst syncImageAttributes = (\n sourceImage: HTMLImageElement,\n targetImage: HTMLImageElement\n) => {\n const sourceAttributes = Array.from(sourceImage.attributes);\n const sourceAttributeNames = new Set(\n sourceAttributes.map((attribute) => attribute.name)\n );\n\n Array.from(targetImage.attributes).forEach((attribute) => {\n if (!sourceAttributeNames.has(attribute.name)) {\n targetImage.removeAttribute(attribute.name);\n }\n });\n\n sourceAttributes.forEach((attribute) => {\n targetImage.setAttribute(attribute.name, attribute.value);\n });\n};\n\nconst reuseRenderedImages = (\n root: ParentNode,\n imageMap: Map<string, HTMLImageElement[]>\n) => {\n if (!imageMap.size) return;\n\n root.querySelectorAll(\"img\").forEach((node) => {\n const nextImage = node as HTMLImageElement;\n const key = getImageReuseKey(nextImage);\n const bucket = imageMap.get(key);\n const preservedImage = bucket?.shift();\n if (!preservedImage) return;\n\n syncImageAttributes(nextImage, preservedImage);\n nextImage.replaceWith(preservedImage);\n\n if (bucket && bucket.length === 0) {\n imageMap.delete(key);\n }\n });\n};\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n hasRootVhHeight = false,\n stretchRootHeight = false,\n enableScaling = false,\n disableLoadingOverlay = false,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const hasRenderedContentRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n .sandbox-wrapper { align-items: center; }\n .sandbox-container { position: relative; width: 100%; }\n .sandbox-container svg,\n .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }\n /* Sub-pixel rounding (clamp() font-size + fractional flex children) can push\n scrollHeight 1px past clientHeight, producing a phantom scrollbar on a\n user content root that visually fits. Non-blackboard sandboxes have a\n fixed aspect-[16/9] iframe, so the user root must not own scroll.\n Blackboard mode is excluded: IframeSandbox measures inner overflow:auto\n roots to grow the iframe (see IframeSandbox.tsx getInnerScrollableHeight). */\n .sandbox-wrapper:not([data-mode=\"blackboard\"]) .sandbox-container > * {\n overflow: clip !important;\n }\n .justify-\\\\[safe_center\\\\]{\n justify-content: safe center;\n }\n .overflow-y-auto { overflow-y: visible !important; }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n hasRenderedContentRef.current = false;\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n const reusableImages = collectReusableImages(container);\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n // const hasRenderedBefore = hasRenderedContentRef.current;\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n const wrapper = doc.createElement(\"div\");\n wrapper.innerHTML = html;\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n reuseRenderedImages(wrapper, reusableImages);\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const hasFirstElement = !!wrapper.firstElementChild;\n if (hasFirstElement) {\n hasRenderedContentRef.current = true;\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n container.replaceChildren(...contentNodes);\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n if (enableScaling) {\n const win = container.ownerDocument?.defaultView as ScalingWindow | null;\n win?.__mdf_triggerFitContent?.();\n }\n\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n }, [html, resetToken, enableScaling]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n }, [disableLoadingOverlay]);\n\n const overlayMessage = (() => {\n if (disableLoadingOverlay) {\n return null;\n }\n\n if (isGeneratingScripts || hasScriptsRef.current)\n return scriptLoadingText || \"Building scripts cache...\";\n if (isGeneratingStyles || hasStylesRef.current)\n return styleLoadingText || \"Building styles...\";\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n const shouldStretchRootHeight = isBlackboard && stretchRootHeight;\n const sandboxWrapperStyle: React.CSSProperties = {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n // Keep blackboard scroll behavior while centering content in non-blackboard mode\n justifyContent: shouldStretchRootHeight\n ? \"flex-start\"\n : isBlackboard\n ? \"space-around\"\n : \"flex-start\",\n };\n const sandboxContainerStyle: React.CSSProperties = {\n pointerEvents: overlayMessage ? \"none\" : undefined,\n margin: isBlackboard ? undefined : \"auto 0\",\n width: \"100%\",\n height: shouldStretchRootHeight ? \"100%\" : undefined,\n minHeight: shouldStretchRootHeight ? 0 : undefined,\n flex: shouldStretchRootHeight ? \"1 1 auto\" : undefined,\n };\n\n return (\n <div\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n data-mode={mode}\n className=\"sandbox-wrapper\"\n style={sandboxWrapperStyle}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n className=\"sandbox-container\"\n style={sandboxContainerStyle}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 20,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n }}\n >\n <LoadingOverlayCard message={overlayMessage} />\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["IMAGE_REUSE_ATTRIBUTES","getImageReuseKey","image","attribute","collectReusableImages","root","imageMap","node","key","bucket","syncImageAttributes","sourceImage","targetImage","sourceAttributes","sourceAttributeNames","reuseRenderedImages","nextImage","preservedImage","SandboxApp","html","styleLoadingText","scriptLoadingText","resetToken","mode","hasRootVhHeight","stretchRootHeight","enableScaling","disableLoadingOverlay","containerRef","useRef","isGeneratingStyles","setIsGeneratingStyles","useState","isGeneratingScripts","setIsGeneratingScripts","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","hasRenderedContentRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","reusableImages","wrapper","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","contentNodes","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","jsx","LoadingOverlayCard"],"mappings":"mOAgBMA,EAAyB,CAC7B,MACA,SACA,QACA,MACA,QACA,QACA,SACA,QACA,UACA,WACA,cACA,iBACA,eACF,EAEMC,EAAoBC,GACxBF,EAAuB,IACpBG,GAAc,GAAGA,CAAS,IAAID,EAAM,aAAaC,CAAS,GAAK,EAAE,EACpE,EAAE,KAAK,GAAG,EAENC,EAAyBC,GAAqB,CAClD,MAAMC,MAAe,IACrB,OAAAD,EAAK,iBAAiB,KAAK,EAAE,QAASE,GAAS,CAC7C,MAAML,EAAQK,EACRC,EAAMP,EAAiBC,CAAK,EAC5BO,EAASH,EAAS,IAAIE,CAAG,GAAK,CAAA,EACpCC,EAAO,KAAKP,CAAK,EACjBI,EAAS,IAAIE,EAAKC,CAAM,CAC1B,CAAC,EACMH,CACT,EAEMI,EAAsB,CAC1BC,EACAC,IACG,CACH,MAAMC,EAAmB,MAAM,KAAKF,EAAY,UAAU,EACpDG,EAAuB,IAAI,IAC/BD,EAAiB,IAAKV,GAAcA,EAAU,IAAI,CAAA,EAGpD,MAAM,KAAKS,EAAY,UAAU,EAAE,QAAST,GAAc,CACnDW,EAAqB,IAAIX,EAAU,IAAI,GAC1CS,EAAY,gBAAgBT,EAAU,IAAI,CAE9C,CAAC,EAEDU,EAAiB,QAASV,GAAc,CACtCS,EAAY,aAAaT,EAAU,KAAMA,EAAU,KAAK,CAC1D,CAAC,CACH,EAEMY,GAAsB,CAC1BV,EACAC,IACG,CACEA,EAAS,MAEdD,EAAK,iBAAiB,KAAK,EAAE,QAASE,GAAS,CAC7C,MAAMS,EAAYT,EACZC,EAAMP,EAAiBe,CAAS,EAChCP,EAASH,EAAS,IAAIE,CAAG,EACzBS,EAAiBR,GAAQ,MAAA,EAC1BQ,IAELP,EAAoBM,EAAWC,CAAc,EAC7CD,EAAU,YAAYC,CAAc,EAEhCR,GAAUA,EAAO,SAAW,GAC9BH,EAAS,OAAOE,CAAG,EAEvB,CAAC,CACH,EAEMU,GAAwC,CAAC,CAC7C,KAAAC,EACA,iBAAAC,EACA,kBAAAC,EACA,WAAAC,EAAa,EACb,KAAAC,EAAO,UACP,gBAAAC,EAAkB,GAClB,kBAAAC,EAAoB,GACpB,cAAAC,EAAgB,GAChB,sBAAAC,EAAwB,EAC1B,IAAM,CACJ,MAAMC,EAAeC,EAAAA,OAAuB,IAAI,EAC1C,CAACC,EAAoBC,CAAqB,EAAIC,EAAAA,SAAS,EAAK,EAC5D,CAACC,EAAqBC,CAAsB,EAAIF,EAAAA,SAAS,EAAK,EAC9DG,EAAoBN,EAAAA,OAA2B,EAAE,EACjDO,EAAqBP,EAAAA,OAA4B,EAAE,EACnDQ,EAAgBR,EAAAA,OAAO,CAAC,EACxBS,EAAiBT,EAAAA,OAAO,CAAC,EACzBU,EAAgBV,EAAAA,OAAsB,IAAI,EAC1CW,EAAiBX,EAAAA,OAAsB,IAAI,EAC3CY,EAAeZ,EAAAA,OAAO,EAAK,EAC3Ba,EAAgBb,EAAAA,OAAO,EAAK,EAC5Bc,EAAwBd,EAAAA,OAAO,EAAK,EACpCe,EAAoBf,EAAAA,OAAOP,CAAU,EACrCuB,EAAiB,IAEjBC,EAAcC,GAAoD,CAClEA,EAAS,UACX,aAAaA,EAAS,OAAO,EAC7BA,EAAS,QAAU,KAEvB,EAEMC,EAA8B,CAClCC,EACAF,EACAG,EACAC,IACG,CACH,MAAMC,EAAU,YAAY,IAAA,EAAQF,EAAS,QACvCG,EAAQ,KAAK,IAAI,EAAGR,EAAiBO,CAAO,EAClDN,EAAWC,CAAQ,EACnBA,EAAS,QAAU,OAAO,WAAW,IAAM,CACzCE,EAAO,EAAK,EACZE,IAAA,EACAJ,EAAS,QAAU,IACrB,EAAGM,CAAK,CACV,EAEAC,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAM3B,EAAa,SAAS,cAClC,GAAI,CAAC2B,EAAK,OACV,MAAMC,EAAU,wBAChB,IAAIC,EAAUF,EAAI,eAAeC,CAAO,EACnCC,IACHA,EAAUF,EAAI,cAAc,OAAO,EACnCE,EAAQ,GAAKD,EACbD,EAAI,MAAM,YAAYE,CAAO,GAE/BA,EAAQ,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAmBxB,EAAG,CAAA,CAAE,EAELH,EAAAA,UAAU,IAAM,CACVhC,IAAesB,EAAkB,UACnCD,EAAsB,QAAU,GAChCC,EAAkB,QAAUtB,GAE9BwB,EAAWP,CAAa,EACxBO,EAAWN,CAAc,EACzBC,EAAa,QAAU,GACvBC,EAAc,QAAU,GAExB,MAAMgB,EAAY9B,EAAa,QAC/B,GAAI,CAAC8B,EAAW,OAChB,MAAMH,EAAMG,EAAU,cAChBC,EAAOJ,GAAK,KAClB,GAAI,CAACI,EAAM,OACX,MAAMC,EAAiBxD,EAAsBsD,CAAS,EAEtDvB,EAAkB,QAAQ,QAAS5B,GAASA,EAAK,QAAQ,EACzD4B,EAAkB,QAAU,CAAA,EAC5BC,EAAmB,QAAQ,QAAS7B,GAASA,EAAK,QAAQ,EAC1D6B,EAAmB,QAAU,CAAA,EAG7BL,EAAsB,EAAK,EAC3BG,EAAuB,EAAK,EAC5B,MAAM2B,EAAUN,EAAI,cAAc,KAAK,EACvCM,EAAQ,UAAY1C,EAEpB,MAAM2C,GAAmB3C,EAAK,MAAM,gBAAgB,GAAK,CAAA,GAAI,OACvD4C,GAAoB5C,EAAK,MAAM,cAAc,GAAK,CAAA,GAAI,OACtD6C,EACJF,EAAkB,GAAKA,IAAoBC,EAEvCE,EAA+B,CAAA,EAErC,MAAM,KAAKJ,EAAQ,iBAAiB,eAAe,CAAC,EAAE,QAAStD,GAAS,CACtE,GAAIA,EAAK,QAAQ,YAAA,IAAkB,QAAS,CAC1C,MAAM2D,EAASX,EAAI,cAAc,OAAO,EACxCW,EAAO,YAAc3D,EAAK,aAAe,GACzC,MAAM,KAAKA,EAAK,UAAU,EAAE,QAAS4D,GAAS,CAC5CD,EAAO,aAAaC,EAAK,KAAMA,EAAK,KAAK,CAC3C,CAAC,EACDF,EAAc,KAAKC,CAAM,CAC3B,KAAO,CACL,MAAME,EAAcb,EAAI,cAAc,QAAQ,EAC9C,MAAM,KAAKhD,EAAK,UAAU,EAAE,QAAS4D,GAAS,CAC5CC,EAAY,aAAaD,EAAK,KAAMA,EAAK,KAAK,CAChD,CAAC,EACDC,EAAY,YAAc7D,EAAK,aAAe,GAC9C0D,EAAc,KAAKG,CAAW,CAChC,CACA7D,EAAK,OAAA,CACP,CAAC,EACDQ,GAAoB8C,EAASD,CAAc,EAE3C,MAAMS,EAAYJ,EAAc,KAC7B1D,GAASA,EAAK,QAAQ,gBAAkB,OAAA,EAErC+D,EAAaL,EAAc,KAC9B1D,GAASA,EAAK,QAAQ,gBAAkB,QAAA,EAEvC8D,IACF5B,EAAa,QAAU,GACvBJ,EAAc,QAAU,YAAY,IAAA,EACpCS,EAAWP,CAAa,EACxBR,EAAsB,EAAI,GAExBuC,IACF5B,EAAc,QAAU,GACxBJ,EAAe,QAAU,YAAY,IAAA,EACrCQ,EAAWN,CAAc,EACzBN,EAAuB,EAAI,GAGL,CAAC,CAAC2B,EAAQ,oBAEhClB,EAAsB,QAAU,IAGlC,MAAM4B,EAAe,MAAM,KAAKV,EAAQ,UAAU,EAClDH,EAAU,gBAAgB,GAAGa,CAAY,EAEzCN,EAAc,QAAS1D,GAAS,CAC9B,GAAIA,EAAK,QAAQ,YAAA,IAAkB,QAAS,CAC1CgD,EAAI,MAAM,YAAYhD,CAAI,EAC1B4B,EAAkB,QAAQ,KAAK5B,CAAwB,EACvD,MACF,CAEA,GAAIyD,EAAsB,CACxB,MAAMQ,EAAajE,EACbkE,EAAaD,EAAW,aAAe,GAG7C,GAFuB,CAACA,EAAW,IAGjC,GAAI,CAGF,IAAI,SAASC,CAAU,CACzB,MAAQ,CACND,EAAW,OAAA,EACX,MACF,CAGF,GAAI,CACFb,EAAK,YAAYa,CAAU,EAC3BpC,EAAmB,QAAQ,KAAKoC,CAAU,CAC5C,MAAQ,CACNA,EAAW,OAAA,CACb,CACF,MAEEjE,EAAK,OAAA,CAET,CAAC,EACGmB,GACUgC,EAAU,eAAe,aAChC,0BAAA,EAGP,sBAAsB,IAAM,CACtBW,GACFrB,EACEjB,EACAQ,EACAF,EACA,IAAM,CACJI,EAAa,QAAU,EACzB,CAAA,EAGA6B,GACFtB,EACEd,EACAM,EACAF,EACA,IAAM,CACJI,EAAc,QAAU,EAC1B,CAAA,CAGN,CAAC,CACH,EAAG,CAACvB,EAAMG,EAAYI,CAAa,CAAC,EAEpC4B,EAAAA,UACE,IAAM,IAAM,CACVR,EAAWP,CAAa,EACxBO,EAAWN,CAAc,CAC3B,EACA,CAAA,CAAC,EAGHc,EAAAA,UAAU,IAAM,CACT3B,IAILmB,EAAWP,CAAa,EACxBO,EAAWN,CAAc,EACzBC,EAAa,QAAU,GACvBC,EAAc,QAAU,GACxBX,EAAsB,EAAK,EAC3BG,EAAuB,EAAK,EAC9B,EAAG,CAACP,CAAqB,CAAC,EAE1B,MAAM+C,EACA/C,EACK,KAGLM,GAAuBS,EAAc,QAChCrB,GAAqB,4BAC1BS,GAAsBW,EAAa,QAC9BrB,GAAoB,qBACtB,KAGHuD,EAAepD,IAAS,aACxBqD,EAA0BD,GAAgBlD,EAC1CoD,EAA2C,CAC/C,SAAU,WACV,MAAO,OACP,OAAQ,OACR,QAAS,OACT,cAAe,SAEf,eAAgBD,EACZ,aACAD,EACE,eACA,YAAA,EAEFG,EAA6C,CACjD,cAAeJ,EAAiB,OAAS,OACzC,OAAQC,EAAe,OAAY,SACnC,MAAO,OACP,OAAQC,EAA0B,OAAS,OAC3C,UAAWA,EAA0B,EAAI,OACzC,KAAMA,EAA0B,WAAa,MAAA,EAG/C,OACEG,EAAAA,kBAAAA,KAAC,MAAA,CACC,eAAcvD,EAAkB,OAAS,QACzC,YAAWD,EACX,UAAU,kBACV,MAAOsD,EACP,YAAW,CAAC,CAACH,EAEb,SAAA,CAAAM,EAAAA,kBAAAA,IAAC,MAAA,CACC,IAAKpD,EACL,UAAU,oBACV,MAAOkD,CAAA,CAAA,EAERJ,GACCM,EAAAA,kBAAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,MAAO,EACP,OAAQ,GACR,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,cAAe,MAAA,EAGjB,SAAAA,EAAAA,kBAAAA,IAACC,EAAAA,QAAA,CAAmB,QAASP,CAAA,CAAgB,CAAA,CAAA,CAC/C,CAAA,CAAA,CAIR"}
|
|
1
|
+
{"version":3,"file":"SandboxApp.cjs.js","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport type { ScalingWindow } from \"./utils/iframe-scaling\";\n\nexport interface SandboxAppProps {\n html: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n hasRootVhHeight?: boolean;\n stretchRootHeight?: boolean;\n enableScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nconst IMAGE_REUSE_ATTRIBUTES = [\n \"src\",\n \"srcset\",\n \"sizes\",\n \"alt\",\n \"class\",\n \"width\",\n \"height\",\n \"style\",\n \"loading\",\n \"decoding\",\n \"crossorigin\",\n \"referrerpolicy\",\n \"fetchpriority\",\n];\n\nconst getImageReuseKey = (image: HTMLImageElement) =>\n IMAGE_REUSE_ATTRIBUTES.map(\n (attribute) => `${attribute}:${image.getAttribute(attribute) || \"\"}`\n ).join(\"|\");\n\nconst collectReusableImages = (root: ParentNode) => {\n const imageMap = new Map<string, HTMLImageElement[]>();\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n const key = getImageReuseKey(image);\n const bucket = imageMap.get(key) || [];\n bucket.push(image);\n imageMap.set(key, bucket);\n });\n return imageMap;\n};\n\nconst syncImageAttributes = (\n sourceImage: HTMLImageElement,\n targetImage: HTMLImageElement\n) => {\n const sourceAttributes = Array.from(sourceImage.attributes);\n const sourceAttributeNames = new Set(\n sourceAttributes.map((attribute) => attribute.name)\n );\n\n Array.from(targetImage.attributes).forEach((attribute) => {\n if (!sourceAttributeNames.has(attribute.name)) {\n targetImage.removeAttribute(attribute.name);\n }\n });\n\n sourceAttributes.forEach((attribute) => {\n targetImage.setAttribute(attribute.name, attribute.value);\n });\n};\n\nconst reuseRenderedImages = (\n root: ParentNode,\n imageMap: Map<string, HTMLImageElement[]>\n) => {\n if (!imageMap.size) return;\n\n root.querySelectorAll(\"img\").forEach((node) => {\n const nextImage = node as HTMLImageElement;\n const key = getImageReuseKey(nextImage);\n const bucket = imageMap.get(key);\n const preservedImage = bucket?.shift();\n if (!preservedImage) return;\n\n syncImageAttributes(nextImage, preservedImage);\n nextImage.replaceWith(preservedImage);\n\n if (bucket && bucket.length === 0) {\n imageMap.delete(key);\n }\n });\n};\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n hasRootVhHeight = false,\n stretchRootHeight = false,\n enableScaling = false,\n disableLoadingOverlay = false,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const hasRenderedContentRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n .sandbox-wrapper { align-items: center; }\n .sandbox-container { position: relative; width: 100%; }\n .sandbox-container svg,\n .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }\n /* Hide scroll UI without removing scroll semantics. Content roots with\n inline style=\"height:100vh; overflow-y:auto\" are the signal that\n IframeSandbox.getInnerScrollableHeight relies on to grow the iframe\n when content exceeds the viewport. We must not change overflow-y,\n but sub-pixel rounding (1px below the +1 detection threshold) can\n still surface a phantom scrollbar on content that visually fits.\n Hide the scrollbar UI globally; when content truly overflows the\n iframe is resized and no scrollbar would render anyway. */\n .sandbox-container *::-webkit-scrollbar { display: none; }\n .sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }\n .justify-\\\\[safe_center\\\\]{\n justify-content: safe center;\n }\n .overflow-y-auto { overflow-y: visible !important; }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n hasRenderedContentRef.current = false;\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n const reusableImages = collectReusableImages(container);\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n // const hasRenderedBefore = hasRenderedContentRef.current;\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n const wrapper = doc.createElement(\"div\");\n wrapper.innerHTML = html;\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n reuseRenderedImages(wrapper, reusableImages);\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const hasFirstElement = !!wrapper.firstElementChild;\n if (hasFirstElement) {\n hasRenderedContentRef.current = true;\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n container.replaceChildren(...contentNodes);\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n if (enableScaling) {\n const win = container.ownerDocument?.defaultView as ScalingWindow | null;\n win?.__mdf_triggerFitContent?.();\n }\n\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n }, [html, resetToken, enableScaling]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n }, [disableLoadingOverlay]);\n\n const overlayMessage = (() => {\n if (disableLoadingOverlay) {\n return null;\n }\n\n if (isGeneratingScripts || hasScriptsRef.current)\n return scriptLoadingText || \"Building scripts cache...\";\n if (isGeneratingStyles || hasStylesRef.current)\n return styleLoadingText || \"Building styles...\";\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n const shouldStretchRootHeight = isBlackboard && stretchRootHeight;\n const sandboxWrapperStyle: React.CSSProperties = {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n // Keep blackboard scroll behavior while centering content in non-blackboard mode\n justifyContent: shouldStretchRootHeight\n ? \"flex-start\"\n : isBlackboard\n ? \"space-around\"\n : \"flex-start\",\n };\n const sandboxContainerStyle: React.CSSProperties = {\n pointerEvents: overlayMessage ? \"none\" : undefined,\n margin: isBlackboard ? undefined : \"auto 0\",\n width: \"100%\",\n height: shouldStretchRootHeight ? \"100%\" : undefined,\n minHeight: shouldStretchRootHeight ? 0 : undefined,\n flex: shouldStretchRootHeight ? \"1 1 auto\" : undefined,\n };\n\n return (\n <div\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className=\"sandbox-wrapper\"\n style={sandboxWrapperStyle}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n className=\"sandbox-container\"\n style={sandboxContainerStyle}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 20,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n }}\n >\n <LoadingOverlayCard message={overlayMessage} />\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["IMAGE_REUSE_ATTRIBUTES","getImageReuseKey","image","attribute","collectReusableImages","root","imageMap","node","key","bucket","syncImageAttributes","sourceImage","targetImage","sourceAttributes","sourceAttributeNames","reuseRenderedImages","nextImage","preservedImage","SandboxApp","html","styleLoadingText","scriptLoadingText","resetToken","mode","hasRootVhHeight","stretchRootHeight","enableScaling","disableLoadingOverlay","containerRef","useRef","isGeneratingStyles","setIsGeneratingStyles","useState","isGeneratingScripts","setIsGeneratingScripts","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","hasRenderedContentRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","reusableImages","wrapper","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","contentNodes","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","jsx","LoadingOverlayCard"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { j as I } from "../../_virtual/jsx-runtime.es.js";
|
|
2
|
-
import { useRef as i, useState as
|
|
2
|
+
import { useRef as i, useState as U, useEffect as R } from "react";
|
|
3
3
|
import Y from "../ui/loading-overlay-card.es.js";
|
|
4
4
|
const Z = [
|
|
5
5
|
"src",
|
|
@@ -15,160 +15,161 @@ const Z = [
|
|
|
15
15
|
"crossorigin",
|
|
16
16
|
"referrerpolicy",
|
|
17
17
|
"fetchpriority"
|
|
18
|
-
], W = (
|
|
19
|
-
(t) => `${t}:${
|
|
20
|
-
).join("|"), ee = (
|
|
18
|
+
], W = (c) => Z.map(
|
|
19
|
+
(t) => `${t}:${c.getAttribute(t) || ""}`
|
|
20
|
+
).join("|"), ee = (c) => {
|
|
21
21
|
const t = /* @__PURE__ */ new Map();
|
|
22
|
-
return
|
|
23
|
-
const o = f,
|
|
24
|
-
d.push(o), t.set(
|
|
22
|
+
return c.querySelectorAll("img").forEach((f) => {
|
|
23
|
+
const o = f, n = W(o), d = t.get(n) || [];
|
|
24
|
+
d.push(o), t.set(n, d);
|
|
25
25
|
}), t;
|
|
26
|
-
}, te = (
|
|
27
|
-
const f = Array.from(
|
|
28
|
-
f.map((
|
|
26
|
+
}, te = (c, t) => {
|
|
27
|
+
const f = Array.from(c.attributes), o = new Set(
|
|
28
|
+
f.map((n) => n.name)
|
|
29
29
|
);
|
|
30
|
-
Array.from(t.attributes).forEach((
|
|
31
|
-
o.has(
|
|
32
|
-
}), f.forEach((
|
|
33
|
-
t.setAttribute(
|
|
30
|
+
Array.from(t.attributes).forEach((n) => {
|
|
31
|
+
o.has(n.name) || t.removeAttribute(n.name);
|
|
32
|
+
}), f.forEach((n) => {
|
|
33
|
+
t.setAttribute(n.name, n.value);
|
|
34
34
|
});
|
|
35
|
-
}, re = (
|
|
36
|
-
t.size &&
|
|
37
|
-
const o = f,
|
|
38
|
-
|
|
35
|
+
}, re = (c, t) => {
|
|
36
|
+
t.size && c.querySelectorAll("img").forEach((f) => {
|
|
37
|
+
const o = f, n = W(o), d = t.get(n), p = d?.shift();
|
|
38
|
+
p && (te(o, p), o.replaceWith(p), d && d.length === 0 && t.delete(n));
|
|
39
39
|
});
|
|
40
40
|
}, ie = ({
|
|
41
|
-
html:
|
|
41
|
+
html: c,
|
|
42
42
|
styleLoadingText: t,
|
|
43
43
|
scriptLoadingText: f,
|
|
44
44
|
resetToken: o = 0,
|
|
45
|
-
mode:
|
|
45
|
+
mode: n = "content",
|
|
46
46
|
hasRootVhHeight: d = !1,
|
|
47
|
-
stretchRootHeight:
|
|
48
|
-
enableScaling:
|
|
47
|
+
stretchRootHeight: p = !1,
|
|
48
|
+
enableScaling: D = !1,
|
|
49
49
|
disableLoadingOverlay: N = !1
|
|
50
50
|
}) => {
|
|
51
|
-
const j = i(null), [
|
|
52
|
-
|
|
53
|
-
}, L = (
|
|
54
|
-
const
|
|
55
|
-
u(
|
|
56
|
-
|
|
51
|
+
const j = i(null), [V, v] = U(!1), [$, S] = U(!1), T = i([]), _ = i([]), G = i(0), H = i(0), y = i(null), g = i(null), b = i(!1), w = i(!1), B = i(!1), F = i(o), K = 200, u = (r) => {
|
|
52
|
+
r.current && (clearTimeout(r.current), r.current = null);
|
|
53
|
+
}, L = (r, a, l, k) => {
|
|
54
|
+
const h = performance.now() - l.current, A = Math.max(0, K - h);
|
|
55
|
+
u(a), a.current = window.setTimeout(() => {
|
|
56
|
+
r(!1), k?.(), a.current = null;
|
|
57
57
|
}, A);
|
|
58
58
|
};
|
|
59
59
|
R(() => {
|
|
60
|
-
const
|
|
61
|
-
if (!
|
|
62
|
-
const
|
|
63
|
-
let l =
|
|
64
|
-
l || (l =
|
|
60
|
+
const r = j.current?.ownerDocument;
|
|
61
|
+
if (!r) return;
|
|
62
|
+
const a = "sandbox-spinner-style";
|
|
63
|
+
let l = r.getElementById(a);
|
|
64
|
+
l || (l = r.createElement("style"), l.id = a, r.head?.appendChild(l)), l.textContent = `
|
|
65
65
|
.sandbox-wrapper { align-items: center; }
|
|
66
66
|
.sandbox-container { position: relative; width: 100%; }
|
|
67
67
|
.sandbox-container svg,
|
|
68
68
|
.sandbox-container img { display: block; margin-left: auto; margin-right: auto; }
|
|
69
|
-
/*
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
69
|
+
/* Hide scroll UI without removing scroll semantics. Content roots with
|
|
70
|
+
inline style="height:100vh; overflow-y:auto" are the signal that
|
|
71
|
+
IframeSandbox.getInnerScrollableHeight relies on to grow the iframe
|
|
72
|
+
when content exceeds the viewport. We must not change overflow-y,
|
|
73
|
+
but sub-pixel rounding (1px below the +1 detection threshold) can
|
|
74
|
+
still surface a phantom scrollbar on content that visually fits.
|
|
75
|
+
Hide the scrollbar UI globally; when content truly overflows the
|
|
76
|
+
iframe is resized and no scrollbar would render anyway. */
|
|
77
|
+
.sandbox-container *::-webkit-scrollbar { display: none; }
|
|
78
|
+
.sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }
|
|
78
79
|
.justify-\\[safe_center\\]{
|
|
79
80
|
justify-content: safe center;
|
|
80
81
|
}
|
|
81
82
|
.overflow-y-auto { overflow-y: visible !important; }
|
|
82
83
|
`;
|
|
83
84
|
}, []), R(() => {
|
|
84
|
-
o !== F.current && (
|
|
85
|
-
const
|
|
86
|
-
if (!
|
|
87
|
-
const
|
|
85
|
+
o !== F.current && (B.current = !1, F.current = o), u(y), u(g), b.current = !1, w.current = !1;
|
|
86
|
+
const r = j.current;
|
|
87
|
+
if (!r) return;
|
|
88
|
+
const a = r.ownerDocument, l = a?.body;
|
|
88
89
|
if (!l) return;
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const A = (
|
|
94
|
-
Array.from(
|
|
90
|
+
const k = ee(r);
|
|
91
|
+
T.current.forEach((e) => e.remove()), T.current = [], _.current.forEach((e) => e.remove()), _.current = [], v(!1), S(!1);
|
|
92
|
+
const h = a.createElement("div");
|
|
93
|
+
h.innerHTML = c;
|
|
94
|
+
const A = (c.match(/<script[\s>]/gi) || []).length, O = (c.match(/<\/script>/gi) || []).length, P = A > 0 && A === O, x = [];
|
|
95
|
+
Array.from(h.querySelectorAll("style, script")).forEach((e) => {
|
|
95
96
|
if (e.tagName.toLowerCase() === "style") {
|
|
96
|
-
const s =
|
|
97
|
-
s.textContent = e.textContent || "", Array.from(e.attributes).forEach((
|
|
98
|
-
s.setAttribute(
|
|
99
|
-
}),
|
|
97
|
+
const s = a.createElement("style");
|
|
98
|
+
s.textContent = e.textContent || "", Array.from(e.attributes).forEach((m) => {
|
|
99
|
+
s.setAttribute(m.name, m.value);
|
|
100
|
+
}), x.push(s);
|
|
100
101
|
} else {
|
|
101
|
-
const s =
|
|
102
|
-
Array.from(e.attributes).forEach((
|
|
103
|
-
s.setAttribute(
|
|
104
|
-
}), s.textContent = e.textContent || "",
|
|
102
|
+
const s = a.createElement("script");
|
|
103
|
+
Array.from(e.attributes).forEach((m) => {
|
|
104
|
+
s.setAttribute(m.name, m.value);
|
|
105
|
+
}), s.textContent = e.textContent || "", x.push(s);
|
|
105
106
|
}
|
|
106
107
|
e.remove();
|
|
107
|
-
}), re(
|
|
108
|
-
const q =
|
|
108
|
+
}), re(h, k);
|
|
109
|
+
const q = x.some(
|
|
109
110
|
(e) => e.tagName.toLowerCase() === "style"
|
|
110
|
-
), z =
|
|
111
|
+
), z = x.some(
|
|
111
112
|
(e) => e.tagName.toLowerCase() === "script"
|
|
112
113
|
);
|
|
113
|
-
q && (
|
|
114
|
-
const X = Array.from(
|
|
115
|
-
|
|
114
|
+
q && (b.current = !0, G.current = performance.now(), u(y), v(!0)), z && (w.current = !0, H.current = performance.now(), u(g), S(!0)), !!h.firstElementChild && (B.current = !0);
|
|
115
|
+
const X = Array.from(h.childNodes);
|
|
116
|
+
r.replaceChildren(...X), x.forEach((e) => {
|
|
116
117
|
if (e.tagName.toLowerCase() === "style") {
|
|
117
|
-
|
|
118
|
+
a.head?.appendChild(e), T.current.push(e);
|
|
118
119
|
return;
|
|
119
120
|
}
|
|
120
121
|
if (P) {
|
|
121
|
-
const s = e,
|
|
122
|
+
const s = e, m = s.textContent || "";
|
|
122
123
|
if (!s.src)
|
|
123
124
|
try {
|
|
124
|
-
new Function(
|
|
125
|
+
new Function(m);
|
|
125
126
|
} catch {
|
|
126
127
|
s.remove();
|
|
127
128
|
return;
|
|
128
129
|
}
|
|
129
130
|
try {
|
|
130
|
-
l.appendChild(s),
|
|
131
|
+
l.appendChild(s), _.current.push(s);
|
|
131
132
|
} catch {
|
|
132
133
|
s.remove();
|
|
133
134
|
}
|
|
134
135
|
} else
|
|
135
136
|
e.remove();
|
|
136
|
-
}),
|
|
137
|
+
}), D && r.ownerDocument?.defaultView?.__mdf_triggerFitContent?.(), requestAnimationFrame(() => {
|
|
137
138
|
q && L(
|
|
138
|
-
|
|
139
|
+
v,
|
|
139
140
|
y,
|
|
140
|
-
|
|
141
|
+
G,
|
|
141
142
|
() => {
|
|
142
|
-
|
|
143
|
+
b.current = !1;
|
|
143
144
|
}
|
|
144
145
|
), z && L(
|
|
145
146
|
S,
|
|
146
147
|
g,
|
|
147
|
-
|
|
148
|
+
H,
|
|
148
149
|
() => {
|
|
149
|
-
|
|
150
|
+
w.current = !1;
|
|
150
151
|
}
|
|
151
152
|
);
|
|
152
153
|
});
|
|
153
|
-
}, [
|
|
154
|
+
}, [c, o, D]), R(
|
|
154
155
|
() => () => {
|
|
155
156
|
u(y), u(g);
|
|
156
157
|
},
|
|
157
158
|
[]
|
|
158
159
|
), R(() => {
|
|
159
|
-
N && (u(y), u(g),
|
|
160
|
+
N && (u(y), u(g), b.current = !1, w.current = !1, v(!1), S(!1));
|
|
160
161
|
}, [N]);
|
|
161
|
-
const E = N ? null : $ ||
|
|
162
|
+
const E = N ? null : $ || w.current ? f || "Building scripts cache..." : V || b.current ? t || "Building styles..." : null, M = n === "blackboard", C = M && p, Q = {
|
|
162
163
|
position: "relative",
|
|
163
164
|
width: "100%",
|
|
164
165
|
height: "100%",
|
|
165
166
|
display: "flex",
|
|
166
167
|
flexDirection: "column",
|
|
167
168
|
// Keep blackboard scroll behavior while centering content in non-blackboard mode
|
|
168
|
-
justifyContent: C ? "flex-start" :
|
|
169
|
+
justifyContent: C ? "flex-start" : M ? "space-around" : "flex-start"
|
|
169
170
|
}, J = {
|
|
170
171
|
pointerEvents: E ? "none" : void 0,
|
|
171
|
-
margin:
|
|
172
|
+
margin: M ? void 0 : "auto 0",
|
|
172
173
|
width: "100%",
|
|
173
174
|
height: C ? "100%" : void 0,
|
|
174
175
|
minHeight: C ? 0 : void 0,
|
|
@@ -178,7 +179,6 @@ const Z = [
|
|
|
178
179
|
"div",
|
|
179
180
|
{
|
|
180
181
|
"data-root-vh": d ? "true" : "false",
|
|
181
|
-
"data-mode": r,
|
|
182
182
|
className: "sandbox-wrapper",
|
|
183
183
|
style: Q,
|
|
184
184
|
"aria-busy": !!E,
|