markdown-flow-ui 0.1.100-beta.42 → 0.1.100-beta.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/@braintree_sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.cjs.js +1 -1
  2. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/@braintree_sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.cjs.js.map +1 -1
  3. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/@braintree_sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.es.js +1 -1
  4. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.cjs.js +1 -1
  5. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.es.js +1 -1
  6. package/dist/_virtual/index.cjs10.js +1 -1
  7. package/dist/_virtual/index.cjs9.js +1 -1
  8. package/dist/_virtual/index.es10.js +2 -2
  9. package/dist/_virtual/index.es9.js +2 -2
  10. package/dist/components/ContentRender/IframeSandbox.cjs.js +3 -3
  11. package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
  12. package/dist/components/ContentRender/IframeSandbox.es.js +247 -286
  13. package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
  14. package/dist/components/ContentRender/SandboxApp.cjs.js +2 -2
  15. package/dist/components/ContentRender/SandboxApp.cjs.js.map +1 -1
  16. package/dist/components/ContentRender/SandboxApp.es.js +42 -44
  17. package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
  18. package/dist/lib/interaction-defaults.cjs.js +1 -1
  19. package/dist/lib/interaction-defaults.cjs.js.map +1 -1
  20. package/dist/lib/interaction-defaults.es.js +54 -41
  21. package/dist/lib/interaction-defaults.es.js.map +1 -1
  22. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("../../../../../../../../../../_virtual/index.cjs9.js"),v=require("./constants.cjs.js");var d;function x(){if(d)return c.__exports;d=1,Object.defineProperty(c.__exports,"__esModule",{value:!0}),c.__exports.sanitizeUrl=void 0;var e=v.__require();function m(r){return e.relativeFirstCharacters.indexOf(r[0])>-1}function p(r){var i=r.replace(e.ctrlCharactersRegex,"");return i.replace(e.htmlEntitiesRegex,function(t,a){return String.fromCharCode(a)})}function R(r){return URL.canParse(r)}function l(r){try{return decodeURIComponent(r)}catch{return r}}function f(r){if(!r)return e.BLANK_URL;var i,t=l(r.trim());do t=p(t).replace(e.htmlCtrlEntityRegex,"").replace(e.ctrlCharactersRegex,"").replace(e.whitespaceEscapeCharsRegex,"").trim(),t=l(t),i=t.match(e.ctrlCharactersRegex)||t.match(e.htmlEntitiesRegex)||t.match(e.htmlCtrlEntityRegex)||t.match(e.whitespaceEscapeCharsRegex);while(i&&i.length>0);var a=t;if(!a)return e.BLANK_URL;if(m(a))return a;var u=a.trimStart(),h=u.match(e.urlSchemeRegex);if(!h)return a;var n=h[0].toLowerCase().trim();if(e.invalidProtocolRegex.test(n))return e.BLANK_URL;var s=u.replace(/\\/g,"/");if(n==="mailto:"||n.includes("://"))return s;if(n==="http:"||n==="https:"){if(!R(s))return e.BLANK_URL;var o=new URL(s);return o.protocol=o.protocol.toLowerCase(),o.hostname=o.hostname.toLowerCase(),o.toString()}return s}return c.__exports.sanitizeUrl=f,c.__exports}exports.__require=x;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("../../../../../../../../../../_virtual/index.cjs10.js"),v=require("./constants.cjs.js");var d;function x(){if(d)return c.__exports;d=1,Object.defineProperty(c.__exports,"__esModule",{value:!0}),c.__exports.sanitizeUrl=void 0;var e=v.__require();function m(r){return e.relativeFirstCharacters.indexOf(r[0])>-1}function p(r){var i=r.replace(e.ctrlCharactersRegex,"");return i.replace(e.htmlEntitiesRegex,function(t,a){return String.fromCharCode(a)})}function R(r){return URL.canParse(r)}function l(r){try{return decodeURIComponent(r)}catch{return r}}function f(r){if(!r)return e.BLANK_URL;var i,t=l(r.trim());do t=p(t).replace(e.htmlCtrlEntityRegex,"").replace(e.ctrlCharactersRegex,"").replace(e.whitespaceEscapeCharsRegex,"").trim(),t=l(t),i=t.match(e.ctrlCharactersRegex)||t.match(e.htmlEntitiesRegex)||t.match(e.htmlCtrlEntityRegex)||t.match(e.whitespaceEscapeCharsRegex);while(i&&i.length>0);var a=t;if(!a)return e.BLANK_URL;if(m(a))return a;var u=a.trimStart(),h=u.match(e.urlSchemeRegex);if(!h)return a;var n=h[0].toLowerCase().trim();if(e.invalidProtocolRegex.test(n))return e.BLANK_URL;var s=u.replace(/\\/g,"/");if(n==="mailto:"||n.includes("://"))return s;if(n==="http:"||n==="https:"){if(!R(s))return e.BLANK_URL;var o=new URL(s);return o.protocol=o.protocol.toLowerCase(),o.hostname=o.hostname.toLowerCase(),o.toString()}return s}return c.__exports.sanitizeUrl=f,c.__exports}exports.__require=x;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../../../../../../../../../../node_modules/.pnpm/@braintree+sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.js"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.sanitizeUrl = void 0;\nvar constants_1 = require(\"./constants\");\nfunction isRelativeUrlWithoutProtocol(url) {\n return constants_1.relativeFirstCharacters.indexOf(url[0]) > -1;\n}\nfunction decodeHtmlCharacters(str) {\n var removedNullByte = str.replace(constants_1.ctrlCharactersRegex, \"\");\n return removedNullByte.replace(constants_1.htmlEntitiesRegex, function (match, dec) {\n return String.fromCharCode(dec);\n });\n}\nfunction isValidUrl(url) {\n return URL.canParse(url);\n}\nfunction decodeURI(uri) {\n try {\n return decodeURIComponent(uri);\n }\n catch (e) {\n // Ignoring error\n // It is possible that the URI contains a `%` not associated\n // with URI/URL-encoding.\n return uri;\n }\n}\nfunction sanitizeUrl(url) {\n if (!url) {\n return constants_1.BLANK_URL;\n }\n var charsToDecode;\n var decodedUrl = decodeURI(url.trim());\n do {\n decodedUrl = decodeHtmlCharacters(decodedUrl)\n .replace(constants_1.htmlCtrlEntityRegex, \"\")\n .replace(constants_1.ctrlCharactersRegex, \"\")\n .replace(constants_1.whitespaceEscapeCharsRegex, \"\")\n .trim();\n decodedUrl = decodeURI(decodedUrl);\n charsToDecode =\n decodedUrl.match(constants_1.ctrlCharactersRegex) ||\n decodedUrl.match(constants_1.htmlEntitiesRegex) ||\n decodedUrl.match(constants_1.htmlCtrlEntityRegex) ||\n decodedUrl.match(constants_1.whitespaceEscapeCharsRegex);\n } while (charsToDecode && charsToDecode.length > 0);\n var sanitizedUrl = decodedUrl;\n if (!sanitizedUrl) {\n return constants_1.BLANK_URL;\n }\n if (isRelativeUrlWithoutProtocol(sanitizedUrl)) {\n return sanitizedUrl;\n }\n // Remove any leading whitespace before checking the URL scheme\n var trimmedUrl = sanitizedUrl.trimStart();\n var urlSchemeParseResults = trimmedUrl.match(constants_1.urlSchemeRegex);\n if (!urlSchemeParseResults) {\n return sanitizedUrl;\n }\n var urlScheme = urlSchemeParseResults[0].toLowerCase().trim();\n if (constants_1.invalidProtocolRegex.test(urlScheme)) {\n return constants_1.BLANK_URL;\n }\n var backSanitized = trimmedUrl.replace(/\\\\/g, \"/\");\n // Handle special cases for mailto: and custom deep-link protocols\n if (urlScheme === \"mailto:\" || urlScheme.includes(\"://\")) {\n return backSanitized;\n }\n // For http and https URLs, perform additional validation\n if (urlScheme === \"http:\" || urlScheme === \"https:\") {\n if (!isValidUrl(backSanitized)) {\n return constants_1.BLANK_URL;\n }\n var url_1 = new URL(backSanitized);\n url_1.protocol = url_1.protocol.toLowerCase();\n url_1.hostname = url_1.hostname.toLowerCase();\n return url_1.toString();\n }\n return backSanitized;\n}\nexports.sanitizeUrl = sanitizeUrl;\n"],"names":["dist","constants_1","require$$0","isRelativeUrlWithoutProtocol","url","decodeHtmlCharacters","str","removedNullByte","match","dec","isValidUrl","decodeURI","uri","sanitizeUrl","charsToDecode","decodedUrl","sanitizedUrl","trimmedUrl","urlSchemeParseResults","urlScheme","backSanitized","url_1"],"mappings":"uOACA,OAAO,eAAeA,EAAAA,UAAS,aAAc,CAAE,MAAO,GAAM,EAC5DA,EAAAA,UAAA,YAAsB,OACtB,IAAIC,EAAcC,EAAAA,UAAA,EAClB,SAASC,EAA6BC,EAAK,CACvC,OAAOH,EAAY,wBAAwB,QAAQG,EAAI,CAAC,CAAC,EAAI,EACjE,CACA,SAASC,EAAqBC,EAAK,CAC/B,IAAIC,EAAkBD,EAAI,QAAQL,EAAY,oBAAqB,EAAE,EACrE,OAAOM,EAAgB,QAAQN,EAAY,kBAAmB,SAAUO,EAAOC,EAAK,CAChF,OAAO,OAAO,aAAaA,CAAG,CACtC,CAAK,CACL,CACA,SAASC,EAAWN,EAAK,CACrB,OAAO,IAAI,SAASA,CAAG,CAC3B,CACA,SAASO,EAAUC,EAAK,CACpB,GAAI,CACA,OAAO,mBAAmBA,CAAG,CACrC,MACc,CAIN,OAAOA,CACf,CACA,CACA,SAASC,EAAYT,EAAK,CACtB,GAAI,CAACA,EACD,OAAOH,EAAY,UAEvB,IAAIa,EACAC,EAAaJ,EAAUP,EAAI,KAAI,CAAE,EACrC,GACIW,EAAaV,EAAqBU,CAAU,EACvC,QAAQd,EAAY,oBAAqB,EAAE,EAC3C,QAAQA,EAAY,oBAAqB,EAAE,EAC3C,QAAQA,EAAY,2BAA4B,EAAE,EAClD,KAAI,EACTc,EAAaJ,EAAUI,CAAU,EACjCD,EACIC,EAAW,MAAMd,EAAY,mBAAmB,GAC5Cc,EAAW,MAAMd,EAAY,iBAAiB,GAC9Cc,EAAW,MAAMd,EAAY,mBAAmB,GAChDc,EAAW,MAAMd,EAAY,0BAA0B,QAC1Da,GAAiBA,EAAc,OAAS,GACjD,IAAIE,EAAeD,EACnB,GAAI,CAACC,EACD,OAAOf,EAAY,UAEvB,GAAIE,EAA6Ba,CAAY,EACzC,OAAOA,EAGX,IAAIC,EAAaD,EAAa,UAAS,EACnCE,EAAwBD,EAAW,MAAMhB,EAAY,cAAc,EACvE,GAAI,CAACiB,EACD,OAAOF,EAEX,IAAIG,EAAYD,EAAsB,CAAC,EAAE,YAAW,EAAG,KAAI,EAC3D,GAAIjB,EAAY,qBAAqB,KAAKkB,CAAS,EAC/C,OAAOlB,EAAY,UAEvB,IAAImB,EAAgBH,EAAW,QAAQ,MAAO,GAAG,EAEjD,GAAIE,IAAc,WAAaA,EAAU,SAAS,KAAK,EACnD,OAAOC,EAGX,GAAID,IAAc,SAAWA,IAAc,SAAU,CACjD,GAAI,CAACT,EAAWU,CAAa,EACzB,OAAOnB,EAAY,UAEvB,IAAIoB,EAAQ,IAAI,IAAID,CAAa,EACjC,OAAAC,EAAM,SAAWA,EAAM,SAAS,YAAW,EAC3CA,EAAM,SAAWA,EAAM,SAAS,YAAW,EACpCA,EAAM,SAAQ,CAC7B,CACI,OAAOD,CACX,CACApB,OAAAA,EAAAA,UAAA,YAAsBa","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../../../../../../../../node_modules/.pnpm/@braintree+sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.js"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.sanitizeUrl = void 0;\nvar constants_1 = require(\"./constants\");\nfunction isRelativeUrlWithoutProtocol(url) {\n return constants_1.relativeFirstCharacters.indexOf(url[0]) > -1;\n}\nfunction decodeHtmlCharacters(str) {\n var removedNullByte = str.replace(constants_1.ctrlCharactersRegex, \"\");\n return removedNullByte.replace(constants_1.htmlEntitiesRegex, function (match, dec) {\n return String.fromCharCode(dec);\n });\n}\nfunction isValidUrl(url) {\n return URL.canParse(url);\n}\nfunction decodeURI(uri) {\n try {\n return decodeURIComponent(uri);\n }\n catch (e) {\n // Ignoring error\n // It is possible that the URI contains a `%` not associated\n // with URI/URL-encoding.\n return uri;\n }\n}\nfunction sanitizeUrl(url) {\n if (!url) {\n return constants_1.BLANK_URL;\n }\n var charsToDecode;\n var decodedUrl = decodeURI(url.trim());\n do {\n decodedUrl = decodeHtmlCharacters(decodedUrl)\n .replace(constants_1.htmlCtrlEntityRegex, \"\")\n .replace(constants_1.ctrlCharactersRegex, \"\")\n .replace(constants_1.whitespaceEscapeCharsRegex, \"\")\n .trim();\n decodedUrl = decodeURI(decodedUrl);\n charsToDecode =\n decodedUrl.match(constants_1.ctrlCharactersRegex) ||\n decodedUrl.match(constants_1.htmlEntitiesRegex) ||\n decodedUrl.match(constants_1.htmlCtrlEntityRegex) ||\n decodedUrl.match(constants_1.whitespaceEscapeCharsRegex);\n } while (charsToDecode && charsToDecode.length > 0);\n var sanitizedUrl = decodedUrl;\n if (!sanitizedUrl) {\n return constants_1.BLANK_URL;\n }\n if (isRelativeUrlWithoutProtocol(sanitizedUrl)) {\n return sanitizedUrl;\n }\n // Remove any leading whitespace before checking the URL scheme\n var trimmedUrl = sanitizedUrl.trimStart();\n var urlSchemeParseResults = trimmedUrl.match(constants_1.urlSchemeRegex);\n if (!urlSchemeParseResults) {\n return sanitizedUrl;\n }\n var urlScheme = urlSchemeParseResults[0].toLowerCase().trim();\n if (constants_1.invalidProtocolRegex.test(urlScheme)) {\n return constants_1.BLANK_URL;\n }\n var backSanitized = trimmedUrl.replace(/\\\\/g, \"/\");\n // Handle special cases for mailto: and custom deep-link protocols\n if (urlScheme === \"mailto:\" || urlScheme.includes(\"://\")) {\n return backSanitized;\n }\n // For http and https URLs, perform additional validation\n if (urlScheme === \"http:\" || urlScheme === \"https:\") {\n if (!isValidUrl(backSanitized)) {\n return constants_1.BLANK_URL;\n }\n var url_1 = new URL(backSanitized);\n url_1.protocol = url_1.protocol.toLowerCase();\n url_1.hostname = url_1.hostname.toLowerCase();\n return url_1.toString();\n }\n return backSanitized;\n}\nexports.sanitizeUrl = sanitizeUrl;\n"],"names":["dist","constants_1","require$$0","isRelativeUrlWithoutProtocol","url","decodeHtmlCharacters","str","removedNullByte","match","dec","isValidUrl","decodeURI","uri","sanitizeUrl","charsToDecode","decodedUrl","sanitizedUrl","trimmedUrl","urlSchemeParseResults","urlScheme","backSanitized","url_1"],"mappings":"wOACA,OAAO,eAAeA,EAAAA,UAAS,aAAc,CAAE,MAAO,GAAM,EAC5DA,EAAAA,UAAA,YAAsB,OACtB,IAAIC,EAAcC,EAAAA,UAAA,EAClB,SAASC,EAA6BC,EAAK,CACvC,OAAOH,EAAY,wBAAwB,QAAQG,EAAI,CAAC,CAAC,EAAI,EACjE,CACA,SAASC,EAAqBC,EAAK,CAC/B,IAAIC,EAAkBD,EAAI,QAAQL,EAAY,oBAAqB,EAAE,EACrE,OAAOM,EAAgB,QAAQN,EAAY,kBAAmB,SAAUO,EAAOC,EAAK,CAChF,OAAO,OAAO,aAAaA,CAAG,CACtC,CAAK,CACL,CACA,SAASC,EAAWN,EAAK,CACrB,OAAO,IAAI,SAASA,CAAG,CAC3B,CACA,SAASO,EAAUC,EAAK,CACpB,GAAI,CACA,OAAO,mBAAmBA,CAAG,CACrC,MACc,CAIN,OAAOA,CACf,CACA,CACA,SAASC,EAAYT,EAAK,CACtB,GAAI,CAACA,EACD,OAAOH,EAAY,UAEvB,IAAIa,EACAC,EAAaJ,EAAUP,EAAI,KAAI,CAAE,EACrC,GACIW,EAAaV,EAAqBU,CAAU,EACvC,QAAQd,EAAY,oBAAqB,EAAE,EAC3C,QAAQA,EAAY,oBAAqB,EAAE,EAC3C,QAAQA,EAAY,2BAA4B,EAAE,EAClD,KAAI,EACTc,EAAaJ,EAAUI,CAAU,EACjCD,EACIC,EAAW,MAAMd,EAAY,mBAAmB,GAC5Cc,EAAW,MAAMd,EAAY,iBAAiB,GAC9Cc,EAAW,MAAMd,EAAY,mBAAmB,GAChDc,EAAW,MAAMd,EAAY,0BAA0B,QAC1Da,GAAiBA,EAAc,OAAS,GACjD,IAAIE,EAAeD,EACnB,GAAI,CAACC,EACD,OAAOf,EAAY,UAEvB,GAAIE,EAA6Ba,CAAY,EACzC,OAAOA,EAGX,IAAIC,EAAaD,EAAa,UAAS,EACnCE,EAAwBD,EAAW,MAAMhB,EAAY,cAAc,EACvE,GAAI,CAACiB,EACD,OAAOF,EAEX,IAAIG,EAAYD,EAAsB,CAAC,EAAE,YAAW,EAAG,KAAI,EAC3D,GAAIjB,EAAY,qBAAqB,KAAKkB,CAAS,EAC/C,OAAOlB,EAAY,UAEvB,IAAImB,EAAgBH,EAAW,QAAQ,MAAO,GAAG,EAEjD,GAAIE,IAAc,WAAaA,EAAU,SAAS,KAAK,EACnD,OAAOC,EAGX,GAAID,IAAc,SAAWA,IAAc,SAAU,CACjD,GAAI,CAACT,EAAWU,CAAa,EACzB,OAAOnB,EAAY,UAEvB,IAAIoB,EAAQ,IAAI,IAAID,CAAa,EACjC,OAAAC,EAAM,SAAWA,EAAM,SAAS,YAAW,EAC3CA,EAAM,SAAWA,EAAM,SAAS,YAAW,EACpCA,EAAM,SAAQ,CAC7B,CACI,OAAOD,CACX,CACApB,OAAAA,EAAAA,UAAA,YAAsBa","x_google_ignoreList":[0]}
@@ -1,4 +1,4 @@
1
- import { __exports as c } from "../../../../../../../../../../_virtual/index.es9.js";
1
+ import { __exports as c } from "../../../../../../../../../../_virtual/index.es10.js";
2
2
  import { __require as v } from "./constants.es.js";
3
3
  var m;
4
4
  function g() {
@@ -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"});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,5 +1,5 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const E=require("../../_virtual/jsx-runtime.cjs.js"),o=require("react"),Me=require("react-dom/client"),ye=require("./SandboxApp.cjs.js"),Te=require("./ContentRender.cjs.js"),ae=require("../../lib/sandboxInteraction.cjs.js");let q=null;const Ae=()=>(q||(q=Promise.resolve().then(()=>require("./blackboard-vendor.cjs.js")).then(t=>t.injectBlackboardLibraries)),q),Ne=()=>{const t=performance.now(),e=new Date().toISOString();return console.log("[IframeSandbox][SandboxLoad] start",{startedAt:e}),Ae().then(n=>(console.log("[IframeSandbox][SandboxLoad] done",{startedAt:e,endedAt:new Date().toISOString(),durationMs:Number((performance.now()-t).toFixed(2))}),n)).catch(n=>{throw console.error("[IframeSandbox][SandboxLoad] failed",{startedAt:e,endedAt:new Date().toISOString(),durationMs:Number((performance.now()-t).toFixed(2)),error:n}),n})},Ve=/<img\b[^>]*>/i,Ie=180,Fe=240,_e={viewportHeightCss:null,hasFullViewportHeight:!1},he=t=>t.split(/\s+/).filter(Boolean).map(e=>e.split(":").pop()||e),D=t=>{const e=t.trim().toLowerCase();if(!e)return null;const n=e.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);return n?`${n[1]}${n[2].toLowerCase()}`:null},G=t=>{if(!t.trim())return null;const e=he(t);if(e.includes("h-screen")||e.includes("h-dvh")||e.includes("min-h-screen")||e.includes("min-h-dvh"))return"100dvh";if(e.includes("h-svh")||e.includes("min-h-svh"))return"100svh";if(e.includes("h-lvh")||e.includes("min-h-lvh"))return"100lvh";const n=e.find(l=>/^(h|min-h)-\[[0-9.]+(vh|dvh|svh|lvh)\]$/i.test(l));if(!n)return null;const i=n.match(/^(h|min-h)-\[([0-9.]+)(vh|dvh|svh|lvh)\]$/i);return i?`${i[2]}${i[3].toLowerCase()}`:null},Oe=new Set(["base","link","meta","script","style","template","title"]),de=t=>!Oe.has(t.tagName.toLowerCase()),ke=t=>Array.from(t.childNodes).find(e=>e.nodeType===Node.ELEMENT_NODE&&de(e))||null,De=t=>{const e=[];let n=ke(t);for(;n;){e.push(n);const i=Array.from(n.children).filter(l=>de(l));if(i.length!==1)break;n=i[0]}return e},je=t=>{const e=t.getAttribute("height"),n=e?D(e):null;if(n)return n;const i=t.getAttribute("style")?.match(/\bheight\s*:\s*([^;]+)/i)?.[1]||null,l=i?D(i):null;return l||G(t.getAttribute("class")||"")},me=t=>t==="100vh"||t==="100dvh"||t==="100svh"||t==="100lvh",fe=t=>{const e=De(t);let n=null,i=!1;return e.forEach(l=>{const u=je(l);!n&&u&&(n=u),me(u)&&(i=!0)}),{viewportHeightCss:n,hasFullViewportHeight:i}},Be=t=>{const e=t.trim();if(!e)return{viewportHeightCss:null,hasFullViewportHeight:!1};const i=e.match(/^<([a-zA-Z][\w:-]*)(\s[^>]*?)?>/)?.[2]||"",l=i.match(/\bheight\s*=\s*["']([^"']+)["']/i)?.[1],p=i.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(/\bheight\s*:\s*([^;]+)/i)?.[1],d=i.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1],b=(l?D(l):null)||(p?D(p):null)||(d?G(d):null);return{viewportHeightCss:b,hasFullViewportHeight:me(b)}},ue=t=>{const e=t.trim();if(!e)return _e;if(typeof document>"u")return Be(e);const n=document.createElement("template");return n.innerHTML=e,fe(n.content)},Le=t=>t.split(/\s+/).filter(Boolean).map(e=>{const n=e.split(":");return n[n.length-1]!=="h-screen"&&n[n.length-1]!=="min-h-screen"?e:(n[n.length-1]="h-full",n.join(":"))}).join(" "),Pe=(t,e)=>!e||!t.trim()?t:t.replace(/^(\s*<[a-zA-Z][\w:-]*)(\s[^>]*?)?>/,(n,i,l="")=>{const u=l.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);if(!u)return n;const p=Le(u[2]);return p===u[2]?n:`${i}${l.replace(u[0],`class=${u[1]}${p}${u[1]}`)}>`}),$e=({content:t,type:e,className:n,styleLoadingText:i,scriptLoadingText:l,fullScreenButtonText:u,hideFullScreen:p=!1,mode:d="content",replaceRootScreenHeightWithFull:b=!1})=>{const X=o.useRef(null),v=o.useRef(null),j=o.useRef(null),B=o.useRef(()=>{}),[ge,pe]=o.useState(480),U=o.useRef(0),[Y,be]=o.useState(0),[we,ve]=o.useState(!1),xe=e==="sandbox",L=d==="blackboard",P=o.useRef(""),N=o.useMemo(()=>e==="sandbox"?t:"",[t,e]),c=o.useMemo(()=>Pe(N,b),[N,b]),W=o.useMemo(()=>ue(N),[N]),S=o.useMemo(()=>ue(c),[c]),Z=o.useMemo(()=>b&&W.hasFullViewportHeight,[W.hasFullViewportHeight,b]),[V,J]=o.useState(()=>({html:c,heightMeta:S})),K=o.useRef(c),Q=o.useRef({html:c,heightMeta:S}),R=o.useRef(null),C=o.useRef(null),ee=o.useRef(S.viewportHeightCss),x=o.useCallback(s=>{if(typeof window>"u")return;const r=Date.now();r-U.current<Fe||(U.current=r,window.postMessage({source:ae.SANDBOX_INTERACTION_MESSAGE_SOURCE,type:ae.SANDBOX_INTERACTION_MESSAGE_TYPE,eventType:s},window.location.origin))},[]),te=()=>{R.current!==null&&(window.clearTimeout(R.current),R.current=null)},He=()=>{C.current!==null&&(window.cancelAnimationFrame(C.current),C.current=null)};o.useEffect(()=>()=>{te(),He()},[]),o.useEffect(()=>{ee.current=V.heightMeta.viewportHeightCss},[V.heightMeta.viewportHeightCss]),o.useEffect(()=>{const s=K.current;K.current=c;const r=!!s&&c.length>s.length&&c.startsWith(s),H=Ve.test(c),I=r&&H,y={html:c,heightMeta:S};if(Q.current=y,te(),!I){J(y);return}R.current=window.setTimeout(()=>{J(Q.current),R.current=null},Ie)},[c,S]);const ne=V.html,re=V.heightMeta.viewportHeightCss,oe=!!re,M=L&&e==="sandbox"?Z?"100%":re??`${ge}px`:void 0;o.useEffect(()=>{if(d!=="blackboard"){P.current=c;return}const s=P.current;!(s&&c.startsWith(s))&&s&&be(H=>H+1),P.current=c},[d,c]),o.useEffect(()=>{const s=v.current;if(!s)return;const r=s.contentDocument;if(!r)return;r.open(),r.write(`<!DOCTYPE html>
2
- <html${d==="blackboard"?' style="height: 100%;"':""}>
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const T=require("../../_virtual/jsx-runtime.cjs.js"),r=require("react"),Re=require("react-dom/client"),Ee=require("./SandboxApp.cjs.js"),Se=require("./ContentRender.cjs.js"),ue=require("../../lib/sandboxInteraction.cjs.js");let Z=null;const Ce=()=>(Z||(Z=Promise.resolve().then(()=>require("./blackboard-vendor.cjs.js")).then(n=>n.injectBlackboardLibraries)),Z),Me=()=>{const n=performance.now(),e=new Date().toISOString();return console.log("[IframeSandbox][SandboxLoad] start",{startedAt:e}),Ce().then(o=>(console.log("[IframeSandbox][SandboxLoad] done",{startedAt:e,endedAt:new Date().toISOString(),durationMs:Number((performance.now()-n).toFixed(2))}),o)).catch(o=>{throw console.error("[IframeSandbox][SandboxLoad] failed",{startedAt:e,endedAt:new Date().toISOString(),durationMs:Number((performance.now()-n).toFixed(2)),error:o}),o})},Te=/<img\b[^>]*>/i,ye=180,Ae=240,Fe={viewportHeightCss:null,hasFullViewportHeight:!1},ae=n=>n.split(/\s+/).filter(Boolean).map(e=>e.split(":").pop()||e),$=n=>{const e=n.trim().toLowerCase();if(!e)return null;const o=e.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);return o?`${o[1]}${o[2].toLowerCase()}`:null},J=n=>{if(!n.trim())return null;const e=ae(n);if(e.includes("h-screen")||e.includes("h-dvh")||e.includes("min-h-screen")||e.includes("min-h-dvh"))return"100dvh";if(e.includes("h-svh")||e.includes("min-h-svh"))return"100svh";if(e.includes("h-lvh")||e.includes("min-h-lvh"))return"100lvh";const o=e.find(a=>/^(h|min-h)-\[[0-9.]+(vh|dvh|svh|lvh)\]$/i.test(a));if(!o)return null;const u=o.match(/^(h|min-h)-\[([0-9.]+)(vh|dvh|svh|lvh)\]$/i);return u?`${u[2]}${u[3].toLowerCase()}`:null},Ie=n=>n==="100vh"||n==="100dvh"||n==="100svh"||n==="100lvh",Ve=n=>{const e=n.trim();if(!e)return{viewportHeightCss:null,hasFullViewportHeight:!1};const u=e.match(/^<([a-zA-Z][\w:-]*)(\s[^>]*?)?>/)?.[2]||"",a=u.match(/\bheight\s*=\s*["']([^"']+)["']/i)?.[1],p=u.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(/\bheight\s*:\s*([^;]+)/i)?.[1],h=u.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1],O=(a?$(a):null)||(p?$(p):null)||(h?J(h):null);return{viewportHeightCss:O,hasFullViewportHeight:Ie(O)}},Ne=n=>n.split(/\s+/).filter(Boolean).map(e=>{const o=e.split(":");return o[o.length-1]!=="h-screen"&&o[o.length-1]!=="min-h-screen"?e:(o[o.length-1]="h-full",o.join(":"))}).join(" "),Oe=(n,e)=>!e||!n.trim()?n:n.replace(/^(\s*<[a-zA-Z][\w:-]*)(\s[^>]*?)?>/,(o,u,a="")=>{const m=a.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);if(!m)return o;const p=Ne(m[2]);return p===m[2]?o:`${u}${a.replace(m[0],`class=${m[1]}${p}${m[1]}`)}>`}),je=({content:n,type:e,className:o,styleLoadingText:u,scriptLoadingText:a,fullScreenButtonText:m,hideFullScreen:p=!1,mode:h="content",replaceRootScreenHeightWithFull:O=!1})=>{const K=r.useRef(null),E=r.useRef(null),z=r.useRef(null),L=r.useRef(()=>{}),[he,de]=r.useState(480),Q=r.useRef(0),[ee,me]=r.useState(0),[fe,ge]=r.useState(!1),be=e==="sandbox",j=h==="blackboard",y=j&&e==="sandbox",S=y&&O,P=r.useRef(""),k=r.useMemo(()=>e==="sandbox"?n:"",[n,e]),i=r.useMemo(()=>Oe(k,S),[k,S]),te=r.useMemo(()=>S?Ve(k):Fe,[k,S]),ne=r.useMemo(()=>S&&te.hasFullViewportHeight,[te.hasFullViewportHeight,S]),[D,re]=r.useState(i),oe=r.useRef(i),q=r.useRef(i),A=r.useRef(null),F=r.useRef(null),se=r.useRef(null),C=r.useCallback(s=>{if(typeof window>"u")return;const t=Date.now();t-Q.current<Ae||(Q.current=t,window.postMessage({source:ue.SANDBOX_INTERACTION_MESSAGE_SOURCE,type:ue.SANDBOX_INTERACTION_MESSAGE_TYPE,eventType:s},window.location.origin))},[]),G=()=>{A.current!==null&&(window.clearTimeout(A.current),A.current=null)},pe=()=>{F.current!==null&&(window.cancelAnimationFrame(F.current),F.current=null)};r.useEffect(()=>()=>{G(),pe()},[]),r.useEffect(()=>{const s=oe.current;oe.current=i;const t=!!s&&i.length>s.length&&i.startsWith(s),d=Te.test(i);if(!(t&&d)){G(),q.current=i,re(i);return}q.current=i,G(),A.current=window.setTimeout(()=>{re(q.current),A.current=null},ye)},[i]);const _=r.useMemo(()=>{if(!y)return null;const s=D.trim();if(!s)return null;const t=s.match(/^<([a-zA-Z][\w:-]*)(\s[^>]*?)?>/);if(!t)return null;const d=t[2]||"",M=d.match(/\bheight\s*=\s*["']([^"']+)["']/i);if(M){const g=$(M[1]);if(g)return g}const V=d.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(/\bheight\s*:\s*([^;]+)/i)?.[1];if(V){const g=$(V);if(g)return g}const w=d.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1];return w?J(w):null},[D,y]);r.useEffect(()=>{se.current=_},[_]);const ie=!!_,I=j&&e==="sandbox"?ne?"100%":_??`${he}px`:void 0;r.useEffect(()=>{if(h!=="blackboard"){P.current=i;return}const s=P.current;!(s&&i.startsWith(s))&&s&&me(d=>d+1),P.current=i},[h,i]),r.useEffect(()=>{const s=E.current;if(!s)return;const t=s.contentDocument;if(!t)return;t.open(),t.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" />
@@ -13,5 +13,5 @@
13
13
  <body>
14
14
  <div id="root"></div>
15
15
  </body>
16
- </html>`),r.close(),r.documentElement.setAttribute("data-theme","light"),r.documentElement.style.colorScheme="light",r.body?.style.setProperty("color-scheme","light");const H=L&&e==="sandbox",I=()=>x("pointerdown"),y=()=>x("mousedown"),se=()=>x("touchstart");H&&(r.addEventListener("pointerdown",I,!0),r.addEventListener("mousedown",y,!0),r.addEventListener("touchstart",se,!0));const F=r.getElementById("root");if(!F)return;const ie=Me.createRoot(F);j.current=ie;let T=!1;const _=(a,g)=>{const h=a.trim().toLowerCase();if(!h)return null;const m=Number.parseFloat(h);return Number.isNaN(m)?null:/(dvh|svh|lvh|vh)$/i.test(h)?m/100*g:h.endsWith("px")||/^[0-9.]+$/.test(h)?m:null},Re=(a,g)=>{if(!a.trim())return null;const h=G(a);if(h)return _(h,g);const w=he(a).find(k=>/^h-\[[0-9.]+px\]$/i.test(k));if(!w)return null;const A=w.match(/^h-\[([0-9.]+)px\]$/i);if(!A)return null;const f=Number.parseFloat(A[1]);return Number.isNaN(f)?null:f},Ce=()=>{if(!v.current||!r.body)return null;const a=v.current.ownerDocument?.documentElement?.clientHeight||window.innerHeight,g=ee.current,h=g?_(g,a):null;if(h!==null)return Math.ceil(h);const{viewportHeightCss:m}=fe(r.body),w=m?_(m,a):null;if(w!==null)return Math.ceil(w);const f=r.body.querySelector(".sandbox-wrapper")?.querySelector(".sandbox-container > *");if(!f)return null;const k=f.style.height||f.getAttribute("height"),le=k?_(k,a):null;if(le!==null)return Math.ceil(le);const ce=Re(f.getAttribute("class")||"",a);return ce!==null?Math.ceil(ce):null},$=()=>{if(!v.current||!r.body)return;const a=r.body.getBoundingClientRect(),g=r.documentElement?.getBoundingClientRect(),h=a.height,m=g?.height||0,w=Math.max(h,m),A=Ce(),f=Math.max(200,A??Math.ceil(w));pe(f)},O=()=>{requestAnimationFrame(()=>{T||$()})};B.current=O,$(),O(),xe&&Ne().then(a=>{T||(a(r),requestAnimationFrame(()=>{T||O()}))}).catch(()=>{T||O()});const z=new ResizeObserver(()=>$());return z.observe(r.body),F&&z.observe(F),()=>{T=!0,z.disconnect(),H&&(r.removeEventListener("pointerdown",I,!0),r.removeEventListener("mousedown",y,!0),r.removeEventListener("touchstart",se,!0)),setTimeout(()=>{ie.unmount(),j.current=null,B.current=()=>{}},0)}},[]),o.useEffect(()=>{const s=()=>{ve(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",s),()=>document.removeEventListener("fullscreenchange",s)},[]);const Ee=()=>{const s=X.current||v.current;if(s){if(document.fullscreenElement){document.exitFullscreen().catch(()=>{});return}s.requestFullscreen&&s.requestFullscreen().catch(()=>{})}};o.useEffect(()=>{const s=j.current;s&&(s.render(E.jsxRuntimeExports.jsx(ye.default,{html:ne,styleLoadingText:i,scriptLoadingText:l,resetToken:Y,hasRootVhHeight:oe,mode:d,stretchRootHeight:Z})),C.current=window.requestAnimationFrame(()=>{B.current?.(),C.current=null}))},[ne,i,l,Y,d]);const Se=["w-full relative content-render-iframe-sandbox",L?"h-full overflow-auto flex flex-col":"aspect-[16/9] overflow-hidden flex items-center justify-center"].filter(Boolean).join(" ");return E.jsxRuntimeExports.jsxs("div",{ref:X,"data-root-vh":oe?"true":"false",className:Se,style:M?{height:M,minHeight:M}:void 0,children:[!p&&E.jsxRuntimeExports.jsx("button",{type:"button",onClick:Ee,className:"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",children:we?"退出全屏":u||"全屏浏览"}),d==="blackboard"&&e==="markdown"?E.jsxRuntimeExports.jsx("div",{onMouseDown:()=>x("mousedown"),onPointerDown:()=>x("pointerdown"),onTouchStart:()=>x("touchstart"),children:E.jsxRuntimeExports.jsx(Te.default,{content:t})}):E.jsxRuntimeExports.jsx("iframe",{ref:v,sandbox:"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",allow:"fullscreen",allowFullScreen:!0,className:[n,"w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),style:{height:M??"100%",minHeight:M,margin:"auto",visibility:"visible"}})]})};exports.default=$e;
16
+ </html>`),t.close(),t.documentElement.setAttribute("data-theme","light"),t.documentElement.style.colorScheme="light",t.body?.style.setProperty("color-scheme","light");const d=j&&e==="sandbox",M=()=>C("pointerdown"),W=()=>C("mousedown"),V=()=>C("touchstart");d&&(t.addEventListener("pointerdown",M,!0),t.addEventListener("mousedown",W,!0),t.addEventListener("touchstart",V,!0));const w=t.getElementById("root");if(!w)return;const g=Re.createRoot(w);z.current=g;let N=!1;const U=(l,b)=>{const c=l.trim().toLowerCase();if(!c)return null;const v=Number.parseFloat(c);return Number.isNaN(v)?null:/(dvh|svh|lvh|vh)$/i.test(c)?v/100*b:c.endsWith("px")||/^[0-9.]+$/.test(c)?v:null},xe=(l,b)=>{if(!l.trim())return null;const c=J(l);if(c)return U(c,b);const x=ae(l).find(R=>/^h-\[[0-9.]+px\]$/i.test(R));if(!x)return null;const H=x.match(/^h-\[([0-9.]+)px\]$/i);if(!H)return null;const f=Number.parseFloat(H[1]);return Number.isNaN(f)?null:f},He=()=>{if(!y||!E.current||!t.body)return null;const l=E.current.ownerDocument?.documentElement?.clientHeight||window.innerHeight,b=se.current,c=b?U(b,l):null;if(c!==null)return Math.ceil(c);const x=t.body.querySelector(".sandbox-wrapper")?.firstElementChild;if(!x)return null;const H=Array.from(x.children);if(H.length!==1)return null;const f=H[0],R=f.style.height||f.getAttribute("height"),le=R?U(R,l):null;if(le!==null)return Math.ceil(le);const ce=xe(f.getAttribute("class")||"",l);return ce!==null?Math.ceil(ce):null},X=()=>{if(!y||!E.current||!t.body)return;const l=t.body.getBoundingClientRect(),b=t.documentElement?.getBoundingClientRect(),c=l.height,v=b?.height||0,x=Math.max(c,v),H=He(),f=Math.max(200,H??Math.ceil(x));de(R=>R===f?R:f)},B=()=>{requestAnimationFrame(()=>{N||X()})};L.current=B,X(),B(),be&&Me().then(l=>{N||(l(t),requestAnimationFrame(()=>{N||B()}))}).catch(()=>{N||B()});const Y=new ResizeObserver(()=>X());return Y.observe(t.body),w&&Y.observe(w),()=>{N=!0,Y.disconnect(),d&&(t.removeEventListener("pointerdown",M,!0),t.removeEventListener("mousedown",W,!0),t.removeEventListener("touchstart",V,!0)),setTimeout(()=>{g.unmount(),z.current=null,L.current=()=>{}},0)}},[]),r.useEffect(()=>{const s=()=>{ge(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",s),()=>document.removeEventListener("fullscreenchange",s)},[]);const we=()=>{const s=K.current||E.current;if(s){if(document.fullscreenElement){document.exitFullscreen().catch(()=>{});return}s.requestFullscreen&&s.requestFullscreen().catch(()=>{})}};r.useEffect(()=>{const s=z.current;s&&(s.render(T.jsxRuntimeExports.jsx(Ee.default,{html:D,styleLoadingText:u,scriptLoadingText:a,resetToken:ee,hasRootVhHeight:ie,mode:h,stretchRootHeight:ne})),F.current=window.requestAnimationFrame(()=>{L.current?.(),F.current=null}))},[D,u,a,ee,h]);const ve=["w-full relative content-render-iframe-sandbox",j?"h-full overflow-auto flex flex-col":"aspect-[16/9] overflow-hidden flex items-center justify-center"].filter(Boolean).join(" ");return T.jsxRuntimeExports.jsxs("div",{ref:K,"data-root-vh":ie?"true":"false",className:ve,style:I?{height:I,minHeight:I}:void 0,children:[!p&&T.jsxRuntimeExports.jsx("button",{type:"button",onClick:we,className:"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",children:fe?"退出全屏":m||"全屏浏览"}),h==="blackboard"&&e==="markdown"?T.jsxRuntimeExports.jsx("div",{onMouseDown:()=>C("mousedown"),onPointerDown:()=>C("pointerdown"),onTouchStart:()=>C("touchstart"),children:T.jsxRuntimeExports.jsx(Se.default,{content:n})}):T.jsxRuntimeExports.jsx("iframe",{ref:E,sandbox:"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",allow:"fullscreen",allowFullScreen:!0,className:[o,"w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),style:{height:I??"100%",minHeight:I,margin:"auto",visibility:"visible"}})]})};exports.default=je;
17
17
  //# sourceMappingURL=IframeSandbox.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IframeSandbox.cjs.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport SandboxApp from \"./SandboxApp\";\nimport ContentRender from \"./ContentRender\";\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 loadBlackboardVendorOnDemandWithMetrics = () => {\n const loadStart = performance.now();\n const startedAt = new Date().toISOString();\n console.log(\"[IframeSandbox][SandboxLoad] start\", { startedAt });\n\n return loadBlackboardVendor()\n .then((inject) => {\n console.log(\"[IframeSandbox][SandboxLoad] done\", {\n startedAt,\n endedAt: new Date().toISOString(),\n durationMs: Number((performance.now() - loadStart).toFixed(2)),\n });\n return inject;\n })\n .catch((error) => {\n console.error(\"[IframeSandbox][SandboxLoad] failed\", {\n startedAt,\n endedAt: new Date().toISOString(),\n durationMs: Number((performance.now() - loadStart).toFixed(2)),\n error,\n });\n throw error;\n });\n};\n\nconst COMPLETE_IMAGE_TAG_PATTERN = /<img\\b[^>]*>/i;\nconst POST_IMAGE_STREAM_DEBOUNCE_MS = 180;\nconst SANDBOX_INTERACTION_THROTTLE_MS = 240;\n\ninterface SandboxHeightMeta {\n viewportHeightCss: string | null;\n hasFullViewportHeight: boolean;\n}\n\ninterface SandboxRenderState {\n html: string;\n heightMeta: SandboxHeightMeta;\n}\n\nconst EMPTY_SANDBOX_HEIGHT_META: SandboxHeightMeta = {\n viewportHeightCss: null,\n hasFullViewportHeight: false,\n};\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 normalizeTailwindHeightTokens = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.split(\":\").pop() || token);\n\nconst parseViewportHeightCss = (value: string) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const matched = normalized.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);\n if (!matched) return null;\n return `${matched[1]}${matched[2].toLowerCase()}`;\n};\n\nconst extractViewportHeightFromTailwindClass = (className: string) => {\n if (!className.trim()) return null;\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n if (\n normalizedTokens.includes(\"h-screen\") ||\n normalizedTokens.includes(\"h-dvh\") ||\n normalizedTokens.includes(\"min-h-screen\") ||\n normalizedTokens.includes(\"min-h-dvh\")\n ) {\n return \"100dvh\";\n }\n if (\n normalizedTokens.includes(\"h-svh\") ||\n normalizedTokens.includes(\"min-h-svh\")\n ) {\n return \"100svh\";\n }\n if (\n normalizedTokens.includes(\"h-lvh\") ||\n normalizedTokens.includes(\"min-h-lvh\")\n ) {\n return \"100lvh\";\n }\n const arbitraryToken = normalizedTokens.find((token) =>\n /^(h|min-h)-\\[[0-9.]+(vh|dvh|svh|lvh)\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(\n /^(h|min-h)-\\[([0-9.]+)(vh|dvh|svh|lvh)\\]$/i\n );\n if (!matched) return null;\n return `${matched[2]}${matched[3].toLowerCase()}`;\n};\n\nconst SANDBOX_IGNORED_TAG_NAMES = new Set([\n \"base\",\n \"link\",\n \"meta\",\n \"script\",\n \"style\",\n \"template\",\n \"title\",\n]);\n\nconst isSandboxRenderableElement = (element: Element) =>\n !SANDBOX_IGNORED_TAG_NAMES.has(element.tagName.toLowerCase());\n\nconst getFirstRenderableElementChild = (root: ParentNode) =>\n Array.from(root.childNodes).find(\n (node): node is HTMLElement =>\n node.nodeType === Node.ELEMENT_NODE &&\n isSandboxRenderableElement(node as HTMLElement)\n ) || null;\n\nconst getInspectableSandboxElementChain = (root: ParentNode) => {\n const chain: HTMLElement[] = [];\n let current = getFirstRenderableElementChild(root);\n\n while (current) {\n chain.push(current);\n\n const childElements = Array.from(current.children).filter(\n (element): element is HTMLElement => isSandboxRenderableElement(element)\n );\n\n if (childElements.length !== 1) {\n break;\n }\n\n current = childElements[0];\n }\n\n return chain;\n};\n\nconst extractViewportHeightFromElement = (element: HTMLElement) => {\n const heightAttrValue = element.getAttribute(\"height\");\n const attrViewportHeight = heightAttrValue\n ? parseViewportHeightCss(heightAttrValue)\n : null;\n\n if (attrViewportHeight) {\n return attrViewportHeight;\n }\n\n const styleHeightValue =\n element.getAttribute(\"style\")?.match(/\\bheight\\s*:\\s*([^;]+)/i)?.[1] ||\n null;\n const styleViewportHeight = styleHeightValue\n ? parseViewportHeightCss(styleHeightValue)\n : null;\n\n if (styleViewportHeight) {\n return styleViewportHeight;\n }\n\n return extractViewportHeightFromTailwindClass(\n element.getAttribute(\"class\") || \"\"\n );\n};\n\nconst isFullViewportHeightCss = (value: string | null) =>\n value === \"100vh\" ||\n value === \"100dvh\" ||\n value === \"100svh\" ||\n value === \"100lvh\";\n\nconst inspectSandboxPrimaryHeight = (root: ParentNode): SandboxHeightMeta => {\n const inspectableElements = getInspectableSandboxElementChain(root);\n let viewportHeightCss: string | null = null;\n let hasFullViewportHeight = false;\n\n inspectableElements.forEach((element) => {\n const elementViewportHeight = extractViewportHeightFromElement(element);\n\n if (!viewportHeightCss && elementViewportHeight) {\n viewportHeightCss = elementViewportHeight;\n }\n\n if (isFullViewportHeightCss(elementViewportHeight)) {\n hasFullViewportHeight = true;\n }\n });\n\n return {\n viewportHeightCss,\n hasFullViewportHeight,\n };\n};\n\nconst inspectRootHeightFromHtmlString = (html: string) => {\n const normalized = html.trim();\n\n if (!normalized) {\n return {\n viewportHeightCss: null,\n hasFullViewportHeight: false,\n };\n }\n\n const rootMatch = normalized.match(/^<([a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/);\n const attrs = rootMatch?.[2] || \"\";\n const heightAttrValue = attrs.match(/\\bheight\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleAttrValue = attrs.match(/\\bstyle\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleHeightValue = styleAttrValue?.match(\n /\\bheight\\s*:\\s*([^;]+)/i\n )?.[1];\n const classAttrValue = attrs.match(/\\bclass\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const viewportHeightCss =\n (heightAttrValue ? parseViewportHeightCss(heightAttrValue) : null) ||\n (styleHeightValue ? parseViewportHeightCss(styleHeightValue) : null) ||\n (classAttrValue\n ? extractViewportHeightFromTailwindClass(classAttrValue)\n : null);\n\n return {\n viewportHeightCss,\n hasFullViewportHeight: isFullViewportHeightCss(viewportHeightCss),\n };\n};\n\nconst inspectSandboxPrimaryHeightFromHtml = (html: string) => {\n const normalized = html.trim();\n\n if (!normalized) {\n return EMPTY_SANDBOX_HEIGHT_META;\n }\n\n if (typeof document === \"undefined\") {\n return inspectRootHeightFromHtmlString(normalized);\n }\n\n const template = document.createElement(\"template\");\n template.innerHTML = normalized;\n\n return inspectSandboxPrimaryHeight(template.content);\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 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 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 replaceRootScreenHeightWithFull\n ),\n [htmlContent, replaceRootScreenHeightWithFull]\n );\n const originalHtmlHeightMeta = React.useMemo(\n () => inspectSandboxPrimaryHeightFromHtml(htmlContent),\n [htmlContent]\n );\n const normalizedHtmlHeightMeta = React.useMemo(\n () => inspectSandboxPrimaryHeightFromHtml(normalizedHtmlContent),\n [normalizedHtmlContent]\n );\n const shouldStretchRootHeight = React.useMemo(\n () =>\n replaceRootScreenHeightWithFull &&\n originalHtmlHeightMeta.hasFullViewportHeight,\n [\n originalHtmlHeightMeta.hasFullViewportHeight,\n replaceRootScreenHeightWithFull,\n ]\n );\n const [renderState, setRenderState] = useState<SandboxRenderState>(() => ({\n html: normalizedHtmlContent,\n heightMeta: normalizedHtmlHeightMeta,\n }));\n const prevIncomingHtmlRef = useRef(normalizedHtmlContent);\n const pendingRenderStateRef = useRef<SandboxRenderState>({\n html: normalizedHtmlContent,\n heightMeta: normalizedHtmlHeightMeta,\n });\n const deferRenderTimerRef = useRef<number | null>(null);\n const initialPaintFrameRef = useRef<number | null>(null);\n const renderViewportHeightCssRef = useRef<string | null>(\n normalizedHtmlHeightMeta.viewportHeightCss\n );\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 renderViewportHeightCssRef.current =\n renderState.heightMeta.viewportHeightCss;\n }, [renderState.heightMeta.viewportHeightCss]);\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 const nextRenderState = {\n html: normalizedHtmlContent,\n heightMeta: normalizedHtmlHeightMeta,\n };\n pendingRenderStateRef.current = nextRenderState;\n clearDeferredRenderTimer();\n\n if (!shouldDeferRender) {\n setRenderState(nextRenderState);\n return;\n }\n\n deferRenderTimerRef.current = window.setTimeout(() => {\n setRenderState(pendingRenderStateRef.current);\n deferRenderTimerRef.current = null;\n }, POST_IMAGE_STREAM_DEBOUNCE_MS);\n }, [normalizedHtmlContent, normalizedHtmlHeightMeta]);\n\n const renderHtmlContent = renderState.html;\n const rootViewportHeightCss = renderState.heightMeta.viewportHeightCss;\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%; height: 100%; }\n html, body { margin: 0; padding: 0; overflow: auto; }\n *, *::before, *::after { box-sizing: border-box; }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n\n // 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\n const parseExplicitHeight = (\n value: string,\n parentViewportHeight: number\n ) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const numeric = Number.parseFloat(normalized);\n if (Number.isNaN(numeric)) return null;\n if (/(dvh|svh|lvh|vh)$/i.test(normalized)) {\n return (numeric / 100) * parentViewportHeight;\n }\n if (normalized.endsWith(\"px\") || /^[0-9.]+$/.test(normalized)) {\n return numeric;\n }\n return null;\n };\n const parseTailwindHeightClass = (\n className: string,\n parentViewportHeight: number\n ) => {\n if (!className.trim()) return null;\n const viewportHeightCss =\n extractViewportHeightFromTailwindClass(className);\n if (viewportHeightCss) {\n return parseExplicitHeight(viewportHeightCss, parentViewportHeight);\n }\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n const arbitraryToken = normalizedTokens.find((token) =>\n /^h-\\[[0-9.]+px\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(/^h-\\[([0-9.]+)px\\]$/i);\n if (!matched) return null;\n const numeric = Number.parseFloat(matched[1]);\n if (Number.isNaN(numeric)) return null;\n return numeric;\n };\n\n const resolveExplicitHeight = () => {\n if (!iframeRef.current || !doc.body) return null;\n const 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 { viewportHeightCss } = inspectSandboxPrimaryHeight(doc.body);\n const runtimeParsed = viewportHeightCss\n ? parseExplicitHeight(viewportHeightCss, parentViewportHeight)\n : null;\n\n if (runtimeParsed !== null) {\n return Math.ceil(runtimeParsed);\n }\n\n const wrapper = doc.body.querySelector(\n \".sandbox-wrapper\"\n ) as HTMLElement | null;\n const target = wrapper?.querySelector(\n \".sandbox-container > *\"\n ) as HTMLElement | null;\n\n if (!target) return null;\n\n const heightValue = target.style.height || target.getAttribute(\"height\");\n const explicitPixelHeight = heightValue\n ? parseExplicitHeight(heightValue, parentViewportHeight)\n : null;\n\n if (explicitPixelHeight !== null) {\n return Math.ceil(explicitPixelHeight);\n }\n\n const classHeight = parseTailwindHeightClass(\n target.getAttribute(\"class\") || \"\",\n parentViewportHeight\n );\n\n return classHeight !== null ? Math.ceil(classHeight) : null;\n };\n\n const updateHeight = () => {\n if (!iframeRef.current || !doc.body) return;\n const bodyRect = doc.body.getBoundingClientRect();\n const htmlRect = doc.documentElement?.getBoundingClientRect();\n const bodyHeight = bodyRect.height;\n const htmlHeight = htmlRect?.height || 0;\n const contentHeight = Math.max(bodyHeight, htmlHeight);\n const explicitHeight = resolveExplicitHeight();\n const nextHeight = Math.max(\n 200,\n explicitHeight ?? Math.ceil(contentHeight)\n );\n setHeight(nextHeight);\n };\n const scheduleHeightUpdate = () => {\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n updateHeight();\n });\n };\n updateHeightRef.current = scheduleHeightUpdate;\n\n updateHeight();\n scheduleHeightUpdate();\n\n if (shouldInjectSandboxVendor) {\n // Inject Tailwind/DaisyUI/GSAP before rendering sandbox content to avoid FOUC.\n loadBlackboardVendorOnDemandWithMetrics()\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 return () => {\n isDestroyed = true;\n resizeObserver.disconnect();\n if (shouldBridgeSandboxInteraction) {\n doc.removeEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.removeEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.removeEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n // Defer unmount to avoid React warning when parent is mid-render\n setTimeout(() => {\n root.unmount();\n rootRef.current = null;\n updateHeightRef.current = () => {};\n }, 0);\n };\n }, []);\n\n useEffect(() => {\n const onFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", onFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", onFullscreenChange);\n }, []);\n\n const toggleFullscreen = () => {\n const target = containerRef.current || iframeRef.current;\n if (!target) return;\n if (document.fullscreenElement) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n if (target.requestFullscreen) {\n target.requestFullscreen().catch(() => {});\n }\n };\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n\n root.render(\n <SandboxApp\n html={renderHtmlContent}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n stretchRootHeight={shouldStretchRootHeight}\n />\n );\n\n initialPaintFrameRef.current = window.requestAnimationFrame(() => {\n updateHeightRef.current?.();\n initialPaintFrameRef.current = null;\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 : \"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 : undefined\n }\n >\n {!hideFullScreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className={\n \"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer\"\n }\n >\n {isFullscreen ? \"退出全屏\" : fullScreenButtonText || \"全屏浏览\"}\n </button>\n )}\n {mode === \"blackboard\" && type === \"markdown\" ? (\n <div\n onMouseDown={() => emitSandboxInteraction(\"mousedown\")}\n onPointerDown={() => emitSandboxInteraction(\"pointerdown\")}\n onTouchStart={() => emitSandboxInteraction(\"touchstart\")}\n >\n <ContentRender content={content} />\n </div>\n ) : (\n <iframe\n ref={iframeRef}\n sandbox=\"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\"\n allow=\"fullscreen\"\n allowFullScreen\n className={[className, \"w-full h-full mx-auto my-auto block\"]\n .filter(Boolean)\n .join(\" \")}\n style={{\n height: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n margin: \"auto\",\n visibility: \"visible\",\n }}\n />\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","loadBlackboardVendor","m","loadBlackboardVendorOnDemandWithMetrics","loadStart","startedAt","inject","error","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_THROTTLE_MS","EMPTY_SANDBOX_HEIGHT_META","normalizeTailwindHeightTokens","className","token","parseViewportHeightCss","value","normalized","matched","extractViewportHeightFromTailwindClass","normalizedTokens","arbitraryToken","SANDBOX_IGNORED_TAG_NAMES","isSandboxRenderableElement","element","getFirstRenderableElementChild","root","node","getInspectableSandboxElementChain","chain","current","childElements","extractViewportHeightFromElement","heightAttrValue","attrViewportHeight","styleHeightValue","styleViewportHeight","isFullViewportHeightCss","inspectSandboxPrimaryHeight","inspectableElements","viewportHeightCss","hasFullViewportHeight","elementViewportHeight","inspectRootHeightFromHtmlString","html","attrs","classAttrValue","inspectSandboxPrimaryHeightFromHtml","template","replaceRootScreenHeightToken","segments","replaceRootScreenHeightWithFullClass","enabled","match","tagStart","classMatch","nextClassName","IframeSandbox","content","type","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","replaceRootScreenHeightWithFull","containerRef","useRef","iframeRef","rootRef","updateHeightRef","height","setHeight","useState","lastSandboxInteractionTimeRef","resetToken","setResetToken","isFullscreen","setIsFullscreen","shouldInjectSandboxVendor","isBlackboardMode","prevHtmlRef","htmlContent","React","normalizedHtmlContent","originalHtmlHeightMeta","normalizedHtmlHeightMeta","shouldStretchRootHeight","renderState","setRenderState","prevIncomingHtmlRef","pendingRenderStateRef","deferRenderTimerRef","initialPaintFrameRef","renderViewportHeightCssRef","emitSandboxInteraction","useCallback","eventType","now","SANDBOX_INTERACTION_MESSAGE_SOURCE","SANDBOX_INTERACTION_MESSAGE_TYPE","clearDeferredRenderTimer","clearInitialPaintFrames","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","shouldDeferRender","nextRenderState","renderHtmlContent","rootViewportHeightCss","hasRootVhHeight","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","rootEl","createRoot","isDestroyed","parseExplicitHeight","parentViewportHeight","numeric","parseTailwindHeightClass","resolveExplicitHeight","precomputedViewportHeightCss","parsed","runtimeParsed","target","heightValue","explicitPixelHeight","classHeight","updateHeight","bodyRect","htmlRect","bodyHeight","htmlHeight","contentHeight","explicitHeight","nextHeight","scheduleHeightUpdate","resizeObserver","onFullscreenChange","toggleFullscreen","jsx","SandboxApp","containerClassName","jsxs","ContentRender"],"mappings":"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"}
1
+ {"version":3,"file":"IframeSandbox.cjs.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport SandboxApp from \"./SandboxApp\";\nimport ContentRender from \"./ContentRender\";\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 loadBlackboardVendorOnDemandWithMetrics = () => {\n const loadStart = performance.now();\n const startedAt = new Date().toISOString();\n console.log(\"[IframeSandbox][SandboxLoad] start\", { startedAt });\n\n return loadBlackboardVendor()\n .then((inject) => {\n console.log(\"[IframeSandbox][SandboxLoad] done\", {\n startedAt,\n endedAt: new Date().toISOString(),\n durationMs: Number((performance.now() - loadStart).toFixed(2)),\n });\n return inject;\n })\n .catch((error) => {\n console.error(\"[IframeSandbox][SandboxLoad] failed\", {\n startedAt,\n endedAt: new Date().toISOString(),\n durationMs: Number((performance.now() - loadStart).toFixed(2)),\n error,\n });\n throw error;\n });\n};\n\nconst COMPLETE_IMAGE_TAG_PATTERN = /<img\\b[^>]*>/i;\nconst POST_IMAGE_STREAM_DEBOUNCE_MS = 180;\nconst SANDBOX_INTERACTION_THROTTLE_MS = 240;\nconst EMPTY_ROOT_HEIGHT_META = {\n viewportHeightCss: null,\n hasFullViewportHeight: false,\n} as const;\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 normalizeTailwindHeightTokens = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.split(\":\").pop() || token);\n\nconst parseViewportHeightCss = (value: string) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const matched = normalized.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);\n if (!matched) return null;\n return `${matched[1]}${matched[2].toLowerCase()}`;\n};\n\nconst extractViewportHeightFromTailwindClass = (className: string) => {\n if (!className.trim()) return null;\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n if (\n normalizedTokens.includes(\"h-screen\") ||\n normalizedTokens.includes(\"h-dvh\") ||\n normalizedTokens.includes(\"min-h-screen\") ||\n normalizedTokens.includes(\"min-h-dvh\")\n ) {\n return \"100dvh\";\n }\n if (\n normalizedTokens.includes(\"h-svh\") ||\n normalizedTokens.includes(\"min-h-svh\")\n ) {\n return \"100svh\";\n }\n if (\n normalizedTokens.includes(\"h-lvh\") ||\n normalizedTokens.includes(\"min-h-lvh\")\n ) {\n return \"100lvh\";\n }\n const arbitraryToken = normalizedTokens.find((token) =>\n /^(h|min-h)-\\[[0-9.]+(vh|dvh|svh|lvh)\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(\n /^(h|min-h)-\\[([0-9.]+)(vh|dvh|svh|lvh)\\]$/i\n );\n if (!matched) return null;\n return `${matched[2]}${matched[3].toLowerCase()}`;\n};\n\nconst isFullViewportHeightCss = (value: string | null) =>\n value === \"100vh\" ||\n value === \"100dvh\" ||\n value === \"100svh\" ||\n value === \"100lvh\";\n\nconst inspectRootHeightFromHtmlString = (html: string) => {\n const normalized = html.trim();\n\n if (!normalized) {\n return {\n viewportHeightCss: null,\n hasFullViewportHeight: false,\n };\n }\n\n const rootMatch = normalized.match(/^<([a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/);\n const attrs = rootMatch?.[2] || \"\";\n const heightAttrValue = attrs.match(/\\bheight\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleAttrValue = attrs.match(/\\bstyle\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleHeightValue = styleAttrValue?.match(\n /\\bheight\\s*:\\s*([^;]+)/i\n )?.[1];\n const classAttrValue = attrs.match(/\\bclass\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const viewportHeightCss =\n (heightAttrValue ? parseViewportHeightCss(heightAttrValue) : null) ||\n (styleHeightValue ? parseViewportHeightCss(styleHeightValue) : null) ||\n (classAttrValue\n ? extractViewportHeightFromTailwindClass(classAttrValue)\n : null);\n\n return {\n viewportHeightCss,\n hasFullViewportHeight: isFullViewportHeightCss(viewportHeightCss),\n };\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 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 ? inspectRootHeightFromHtmlString(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 const normalized = renderHtmlContent.trim();\n if (!normalized) return null;\n const rootMatch = normalized.match(/^<([a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/);\n if (!rootMatch) return null;\n const attrs = rootMatch[2] || \"\";\n const heightAttrMatch = attrs.match(/\\bheight\\s*=\\s*[\"']([^\"']+)[\"']/i);\n if (heightAttrMatch) {\n const explicitHeightCss = parseViewportHeightCss(heightAttrMatch[1]);\n if (explicitHeightCss) return explicitHeightCss;\n }\n const styleAttrMatch = attrs.match(/\\bstyle\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleHeightMatch = styleAttrMatch?.match(\n /\\bheight\\s*:\\s*([^;]+)/i\n )?.[1];\n if (styleHeightMatch) {\n const styleHeightCss = parseViewportHeightCss(styleHeightMatch);\n if (styleHeightCss) return styleHeightCss;\n }\n const classAttrMatch = attrs.match(/\\bclass\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n if (!classAttrMatch) return null;\n return extractViewportHeightFromTailwindClass(classAttrMatch);\n }, [renderHtmlContent, 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%; height: 100%; }\n html, body { margin: 0; padding: 0; overflow: auto; }\n *, *::before, *::after { box-sizing: border-box; }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n\n // 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\n const parseExplicitHeight = (\n value: string,\n parentViewportHeight: number\n ) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const numeric = Number.parseFloat(normalized);\n if (Number.isNaN(numeric)) return null;\n if (/(dvh|svh|lvh|vh)$/i.test(normalized)) {\n return (numeric / 100) * parentViewportHeight;\n }\n if (normalized.endsWith(\"px\") || /^[0-9.]+$/.test(normalized)) {\n return numeric;\n }\n return null;\n };\n const parseTailwindHeightClass = (\n className: string,\n parentViewportHeight: number\n ) => {\n if (!className.trim()) return null;\n const viewportHeightCss =\n extractViewportHeightFromTailwindClass(className);\n if (viewportHeightCss) {\n return parseExplicitHeight(viewportHeightCss, parentViewportHeight);\n }\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n const arbitraryToken = normalizedTokens.find((token) =>\n /^h-\\[[0-9.]+px\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(/^h-\\[([0-9.]+)px\\]$/i);\n if (!matched) return null;\n const numeric = Number.parseFloat(matched[1]);\n if (Number.isNaN(numeric)) return null;\n return numeric;\n };\n\n const resolveExplicitHeight = () => {\n if (!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 elements = Array.from(container.children) as HTMLElement[];\n if (elements.length !== 1) return null;\n const target = elements[0];\n\n const heightValue = target.style.height || target.getAttribute(\"height\");\n const explicitPixelHeight = heightValue\n ? parseExplicitHeight(heightValue, parentViewportHeight)\n : null;\n\n if (explicitPixelHeight !== null) {\n return Math.ceil(explicitPixelHeight);\n }\n\n const classHeight = parseTailwindHeightClass(\n target.getAttribute(\"class\") || \"\",\n parentViewportHeight\n );\n\n return classHeight !== null ? Math.ceil(classHeight) : null;\n };\n\n const updateHeight = () => {\n if (!shouldMeasureDynamicHeight) return;\n if (!iframeRef.current || !doc.body) return;\n const bodyRect = doc.body.getBoundingClientRect();\n const htmlRect = doc.documentElement?.getBoundingClientRect();\n const bodyHeight = bodyRect.height;\n const htmlHeight = htmlRect?.height || 0;\n const contentHeight = Math.max(bodyHeight, htmlHeight);\n const explicitHeight = resolveExplicitHeight();\n const nextHeight = Math.max(\n 200,\n explicitHeight ?? Math.ceil(contentHeight)\n );\n setHeight((prevHeight) =>\n prevHeight === nextHeight ? prevHeight : nextHeight\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 loadBlackboardVendorOnDemandWithMetrics()\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 return () => {\n isDestroyed = true;\n resizeObserver.disconnect();\n if (shouldBridgeSandboxInteraction) {\n doc.removeEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.removeEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.removeEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n // Defer unmount to avoid React warning when parent is mid-render\n setTimeout(() => {\n root.unmount();\n rootRef.current = null;\n updateHeightRef.current = () => {};\n }, 0);\n };\n }, []);\n\n useEffect(() => {\n const onFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", onFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", onFullscreenChange);\n }, []);\n\n const toggleFullscreen = () => {\n const target = containerRef.current || iframeRef.current;\n if (!target) return;\n if (document.fullscreenElement) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n if (target.requestFullscreen) {\n target.requestFullscreen().catch(() => {});\n }\n };\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n\n root.render(\n <SandboxApp\n html={renderHtmlContent}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n stretchRootHeight={shouldStretchRootHeight}\n />\n );\n\n initialPaintFrameRef.current = window.requestAnimationFrame(() => {\n updateHeightRef.current?.();\n initialPaintFrameRef.current = null;\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 : \"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 : undefined\n }\n >\n {!hideFullScreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className={\n \"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer\"\n }\n >\n {isFullscreen ? \"退出全屏\" : fullScreenButtonText || \"全屏浏览\"}\n </button>\n )}\n {mode === \"blackboard\" && type === \"markdown\" ? (\n <div\n onMouseDown={() => emitSandboxInteraction(\"mousedown\")}\n onPointerDown={() => emitSandboxInteraction(\"pointerdown\")}\n onTouchStart={() => emitSandboxInteraction(\"touchstart\")}\n >\n <ContentRender content={content} />\n </div>\n ) : (\n <iframe\n ref={iframeRef}\n sandbox=\"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\"\n allow=\"fullscreen\"\n allowFullScreen\n className={[className, \"w-full h-full mx-auto my-auto block\"]\n .filter(Boolean)\n .join(\" \")}\n style={{\n height: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n margin: \"auto\",\n visibility: \"visible\",\n }}\n />\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","loadBlackboardVendor","m","loadBlackboardVendorOnDemandWithMetrics","loadStart","startedAt","inject","error","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_THROTTLE_MS","EMPTY_ROOT_HEIGHT_META","normalizeTailwindHeightTokens","className","token","parseViewportHeightCss","value","normalized","matched","extractViewportHeightFromTailwindClass","normalizedTokens","arbitraryToken","isFullViewportHeightCss","inspectRootHeightFromHtmlString","html","attrs","heightAttrValue","styleHeightValue","classAttrValue","viewportHeightCss","replaceRootScreenHeightToken","segments","replaceRootScreenHeightWithFullClass","enabled","match","tagStart","classMatch","nextClassName","IframeSandbox","content","type","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","replaceRootScreenHeightWithFull","containerRef","useRef","iframeRef","rootRef","updateHeightRef","height","setHeight","useState","lastSandboxInteractionTimeRef","resetToken","setResetToken","isFullscreen","setIsFullscreen","shouldInjectSandboxVendor","isBlackboardMode","shouldMeasureDynamicHeight","shouldProcessRootScreenHeight","prevHtmlRef","htmlContent","React","normalizedHtmlContent","originalRootHeightMeta","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","rootMatch","heightAttrMatch","explicitHeightCss","styleHeightMatch","styleHeightCss","classAttrMatch","hasRootVhHeight","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","rootEl","root","createRoot","isDestroyed","parseExplicitHeight","parentViewportHeight","numeric","parseTailwindHeightClass","resolveExplicitHeight","precomputedViewportHeightCss","parsed","container","elements","target","heightValue","explicitPixelHeight","classHeight","updateHeight","bodyRect","htmlRect","bodyHeight","htmlHeight","contentHeight","explicitHeight","nextHeight","prevHeight","scheduleHeightUpdate","resizeObserver","onFullscreenChange","toggleFullscreen","jsx","SandboxApp","containerClassName","jsxs","ContentRender"],"mappings":"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"}