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

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 (54) 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/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/hast-util-to-jsx-runtime@2.3.6/node_modules/hast-util-to-jsx-runtime/lib/index.cjs.js +1 -1
  7. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/hast-util-to-jsx-runtime@2.3.6/node_modules/hast-util-to-jsx-runtime/lib/index.es.js +1 -1
  8. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-input@1.8.0_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-input/es/BaseInput.cjs.js +1 -1
  9. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-input@1.8.0_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-input/es/BaseInput.es.js +1 -1
  10. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/ResizableTextArea.cjs.js +1 -1
  11. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/ResizableTextArea.es.js +1 -1
  12. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/TextArea.cjs.js +1 -1
  13. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/TextArea.es.js +1 -1
  14. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/index.cjs.js +1 -1
  15. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/index.es.js +1 -1
  16. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.cjs.js +1 -1
  17. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.es.js +1 -1
  18. package/dist/_virtual/index.cjs10.js +1 -1
  19. package/dist/_virtual/index.cjs4.js +1 -1
  20. package/dist/_virtual/index.cjs5.js +1 -1
  21. package/dist/_virtual/index.cjs6.js +1 -1
  22. package/dist/_virtual/index.cjs9.js +1 -1
  23. package/dist/_virtual/index.es10.js +2 -2
  24. package/dist/_virtual/index.es4.js +4 -4
  25. package/dist/_virtual/index.es5.js +4 -4
  26. package/dist/_virtual/index.es6.js +5 -5
  27. package/dist/_virtual/index.es9.js +2 -2
  28. package/dist/components/ContentRender/ContentRender.cjs.js +2 -2
  29. package/dist/components/ContentRender/ContentRender.cjs.js.map +1 -1
  30. package/dist/components/ContentRender/ContentRender.es.js +38 -42
  31. package/dist/components/ContentRender/ContentRender.es.js.map +1 -1
  32. package/dist/components/ContentRender/IframeSandbox.cjs.js +2 -2
  33. package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
  34. package/dist/components/ContentRender/IframeSandbox.es.js +124 -138
  35. package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
  36. package/dist/components/Slide/index.cjs.js +2 -0
  37. package/dist/components/Slide/index.cjs.js.map +1 -0
  38. package/dist/components/Slide/index.es.js +12 -0
  39. package/dist/components/Slide/index.es.js.map +1 -0
  40. package/dist/components/ui/inputGroup/textarea.cjs.js +1 -1
  41. package/dist/components/ui/inputGroup/textarea.es.js +1 -1
  42. package/dist/index.cjs.js +1 -1
  43. package/dist/index.es.js +13 -24
  44. package/dist/index.es.js.map +1 -1
  45. package/dist/renderer.cjs.js +1 -1
  46. package/dist/renderer.d.ts +2 -3
  47. package/dist/renderer.es.js +14 -25
  48. package/dist/renderer.es.js.map +1 -1
  49. package/dist/slide.cjs.js +2 -0
  50. package/dist/slide.cjs.js.map +1 -0
  51. package/dist/slide.d.ts +2 -0
  52. package/dist/slide.es.js +18 -0
  53. package/dist/slide.es.js.map +1 -0
  54. package/package.json +9 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ContentRender.cjs.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport { sanitizeInvalidTagName } from \"./utils/sanitize-invalid-tag-name\";\nimport { stripSvgTextLineBreaks } from \"./utils/strip-svg-text-line-breaks\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport useTypewriterStateMachine from \"./useTypewriterStateMachine\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport {\n splitContentSegments,\n type RenderSegment,\n} from \"./utils/split-content\";\nimport {\n getInteractionDefaultValues,\n type InteractionDefaultValueOptions,\n} from \"../../lib/interaction-defaults\";\n\nconst SANDBOX_TAG_HINT_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)\\b/i;\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n /**\n * Callback invoked when the custom button after content is clicked.\n * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n * @example\n * ```tsx\n * <ContentRender\n * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n * />\n * ```\n */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n userInput?: string;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n onTypeFinished?: () => void;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n const cleanedSvg = stripSvgTextLineBreaks(svg);\n template.innerHTML = cleanedSvg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const isRelativeLength = (value?: string | null) => {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === \"auto\" || normalized.endsWith(\"%\");\n };\n const toNumericLength = (value?: string | null) => {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"auto\" || normalized.endsWith(\"%\")) {\n return null;\n }\n const parsed = Number.parseFloat(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n };\n // Treat percentage/auto sizing as responsive so viewBox drives the layout\n const isWidthRelative = isRelativeLength(widthAttr);\n const isHeightRelative = isRelativeLength(heightAttr);\n const widthMissing = !widthAttr || widthAttr === \"0\";\n const heightMissing = !heightAttr || heightAttr === \"0\";\n const numericWidth = toNumericLength(widthAttr);\n const numericHeight = toNumericLength(heightAttr);\n const matchesViewBox =\n numericWidth === viewBoxWidth && numericHeight === viewBoxHeight;\n\n // Prefer responsive layout when sizing is relative or matches the viewBox\n const shouldUseResponsiveSize =\n isWidthRelative ||\n isHeightRelative ||\n (widthMissing && heightMissing) ||\n matchesViewBox;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (widthMissing && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (heightMissing && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins = [remarkGfm, remarkMath, remarkFlow, remarkBreaks];\n\nconst rehypePlugins = [\n preserveCustomVariableProperties,\n rehypeRaw,\n sanitizeInvalidTagName,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst mergeNonSandboxSegments = (segments: RenderSegment[]) => {\n if (segments.length <= 1) return segments;\n const merged: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type === \"sandbox\") {\n merged.push(segment);\n return;\n }\n\n const last = merged[merged.length - 1];\n if (last && last.type !== \"sandbox\") {\n merged[merged.length - 1] = {\n type: \"markdown\",\n value: `${last.value}${segment.value}`,\n };\n return;\n }\n\n merged.push({ type: \"markdown\", value: segment.value });\n });\n\n return merged;\n};\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n customRenderBar,\n onSend,\n typingSpeed = 30,\n enableTypewriter = false,\n userInput,\n interactionDefaultValueOptions,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n onTypeFinished,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n sandboxFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(content),\n [content]\n );\n\n const interactionDefaults = useMemo(\n () =>\n getInteractionDefaultValues(\n content,\n userInput,\n interactionDefaultValueOptions\n ),\n [content, interactionDefaultValueOptions, userInput]\n );\n\n const resolvedDefaultButtonText =\n defaultButtonText?.trim() || interactionDefaults.buttonText;\n const resolvedDefaultInputText =\n defaultInputText?.trim() || interactionDefaults.inputText;\n const fallbackSelectedValues = useMemo(\n () =>\n userInput\n ? userInput\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined,\n [userInput]\n );\n const resolvedDefaultSelectedValues = defaultSelectedValues?.length\n ? defaultSelectedValues\n : interactionDefaults.selectedValues || fallbackSelectedValues;\n\n // Use custom Hook to handle typewriter effect\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={resolvedDefaultButtonText}\n defaultInputText={resolvedDefaultInputText}\n defaultSelectedValues={resolvedDefaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n confirmButtonText={confirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(content, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n />\n ),\n };\n\n const { displayContent, isComplete } = useTypewriterStateMachine({\n // processMarkdownText will let code block printf(\"You win!\\n\") become printf(\"You win!<br/>\");\n // content: processMarkdownText(content),\n content: normalizedContent,\n typingSpeed,\n disabled: !enableTypewriter,\n });\n\n const hasPotentialSandboxTags = useMemo(\n () => SANDBOX_TAG_HINT_PATTERN.test(content),\n [content]\n );\n\n const renderSegments = useMemo(\n () => (hasPotentialSandboxTags ? splitContentSegments(content, true) : []),\n [content, hasPotentialSandboxTags]\n );\n\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n const mergedRenderSegments = useMemo(\n () => mergeNonSandboxSegments(renderSegments),\n [renderSegments]\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(displayContent),\n [displayContent]\n );\n\n const hasCompleted = useRef(false);\n\n useEffect(() => {\n // Reset completion state on each content update so streaming patches can emit completion again.\n hasCompleted.current = false;\n }, [content]);\n\n useEffect(() => {\n if (hasSandbox) {\n if (!hasCompleted.current) {\n hasCompleted.current = true;\n onTypeFinished?.();\n }\n return;\n }\n\n if (isComplete && !hasCompleted.current) {\n hasCompleted.current = true; // Mark as completed\n onTypeFinished?.(); // Call the passed callback\n }\n }, [hasSandbox, isComplete, onTypeFinished]);\n\n const renderMarkdownSegments = (raw: string, keyPrefix: string) => {\n const normalized = normalizeInlineHtml(raw);\n const parsed = parseMarkdownSegments(normalized);\n\n return parsed.map((seg, index) => {\n const key = `${keyPrefix}-${seg.type}-${index}`;\n\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={key}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart key={key} chart={seg.value} frozen={!seg.complete} />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={key} svg={seg.value} />;\n }\n\n return null;\n });\n };\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {mergedRenderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n type=\"sandbox\"\n content={segment.value}\n className=\"content-render-iframe\"\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n fullScreenButtonText={sandboxFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <React.Fragment key={`md-${idx}`}>\n {renderMarkdownSegments(segment.value, `md-${idx}`)}\n </React.Fragment>\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SANDBOX_TAG_HINT_PATTERN","SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","cleanedSvg","stripSvgTextLineBreaks","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","isRelativeLength","normalized","toNumericLength","parsed","isWidthRelative","isHeightRelative","widthMissing","heightMissing","numericWidth","numericHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","sanitizeInvalidTagName","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","mergeNonSandboxSegments","segments","merged","segment","last","ContentRender","content","customRenderBar","onSend","typingSpeed","enableTypewriter","userInput","interactionDefaultValueOptions","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","onTypeFinished","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","sandboxFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","normalizedContent","useMemo","normalizeInlineHtml","interactionDefaults","getInteractionDefaultValues","resolvedDefaultButtonText","resolvedDefaultInputText","fallbackSelectedValues","resolvedDefaultSelectedValues","children","props","CustomButtonInputVariable","className","rest","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","displayContent","isComplete","useTypewriterStateMachine","hasPotentialSandboxTags","renderSegments","splitContentSegments","hasSandbox","mergedRenderSegments","parseMarkdownSegments","hasCompleted","renderMarkdownSegments","raw","keyPrefix","seg","index","key","idx","IframeSandbox","React","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"ContentRender.cjs.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport { sanitizeInvalidTagName } from \"./utils/sanitize-invalid-tag-name\";\nimport { stripSvgTextLineBreaks } from \"./utils/strip-svg-text-line-breaks\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport useTypewriterStateMachine from \"./useTypewriterStateMachine\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport {\n splitContentSegments,\n type RenderSegment,\n} from \"./utils/split-content\";\nimport {\n getInteractionDefaultValues,\n type InteractionDefaultValueOptions,\n} from \"../../lib/interaction-defaults\";\n\nconst SANDBOX_TAG_HINT_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)\\b/i;\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n /**\n * Callback invoked when the custom button after content is clicked.\n * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n * @example\n * ```tsx\n * <ContentRender\n * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n * />\n * ```\n */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n userInput?: string;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n onTypeFinished?: () => void;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n const cleanedSvg = stripSvgTextLineBreaks(svg);\n template.innerHTML = cleanedSvg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const isRelativeLength = (value?: string | null) => {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === \"auto\" || normalized.endsWith(\"%\");\n };\n const toNumericLength = (value?: string | null) => {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"auto\" || normalized.endsWith(\"%\")) {\n return null;\n }\n const parsed = Number.parseFloat(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n };\n // Treat percentage/auto sizing as responsive so viewBox drives the layout\n const isWidthRelative = isRelativeLength(widthAttr);\n const isHeightRelative = isRelativeLength(heightAttr);\n const widthMissing = !widthAttr || widthAttr === \"0\";\n const heightMissing = !heightAttr || heightAttr === \"0\";\n const numericWidth = toNumericLength(widthAttr);\n const numericHeight = toNumericLength(heightAttr);\n const matchesViewBox =\n numericWidth === viewBoxWidth && numericHeight === viewBoxHeight;\n\n // Prefer responsive layout when sizing is relative or matches the viewBox\n const shouldUseResponsiveSize =\n isWidthRelative ||\n isHeightRelative ||\n (widthMissing && heightMissing) ||\n matchesViewBox;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (widthMissing && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (heightMissing && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins = [remarkGfm, remarkMath, remarkFlow, remarkBreaks];\n\nconst rehypePlugins = [\n preserveCustomVariableProperties,\n rehypeRaw,\n sanitizeInvalidTagName,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst mergeNonSandboxSegments = (segments: RenderSegment[]) => {\n if (segments.length <= 1) return segments;\n const merged: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type === \"sandbox\") {\n merged.push(segment);\n return;\n }\n\n const last = merged[merged.length - 1];\n if (last && last.type !== \"sandbox\") {\n merged[merged.length - 1] = {\n type: \"markdown\",\n value: `${last.value}${segment.value}`,\n };\n return;\n }\n\n merged.push({ type: \"markdown\", value: segment.value });\n });\n\n return merged;\n};\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n customRenderBar,\n onSend,\n typingSpeed = 30,\n enableTypewriter = false,\n userInput,\n interactionDefaultValueOptions,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n onTypeFinished,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n sandboxFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(content),\n [content]\n );\n\n const interactionDefaults = useMemo(\n () =>\n getInteractionDefaultValues(\n content,\n userInput,\n interactionDefaultValueOptions\n ),\n [content, interactionDefaultValueOptions, userInput]\n );\n\n const resolvedDefaultButtonText =\n defaultButtonText?.trim() || interactionDefaults.buttonText;\n const resolvedDefaultInputText =\n defaultInputText?.trim() || interactionDefaults.inputText;\n const fallbackSelectedValues = useMemo(\n () =>\n userInput\n ? userInput\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined,\n [userInput]\n );\n const resolvedDefaultSelectedValues = defaultSelectedValues?.length\n ? defaultSelectedValues\n : interactionDefaults.selectedValues || fallbackSelectedValues;\n\n // Use custom Hook to handle typewriter effect\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={resolvedDefaultButtonText}\n defaultInputText={resolvedDefaultInputText}\n defaultSelectedValues={resolvedDefaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n confirmButtonText={confirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(content, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n />\n ),\n };\n\n const { displayContent, isComplete } = useTypewriterStateMachine({\n // processMarkdownText will let code block printf(\"You win!\\n\") become printf(\"You win!<br/>\");\n // content: processMarkdownText(content),\n content: normalizedContent,\n typingSpeed,\n disabled: !enableTypewriter,\n });\n\n const hasPotentialSandboxTags = useMemo(\n () => SANDBOX_TAG_HINT_PATTERN.test(content),\n [content]\n );\n\n const renderSegments = useMemo(\n () => (hasPotentialSandboxTags ? splitContentSegments(content, true) : []),\n [content, hasPotentialSandboxTags]\n );\n\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n const mergedRenderSegments = useMemo(\n () => mergeNonSandboxSegments(renderSegments),\n [renderSegments]\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(displayContent),\n [displayContent]\n );\n\n const hasCompleted = useRef(false);\n\n useEffect(() => {\n if (hasSandbox) return;\n if (isComplete && !hasCompleted.current) {\n hasCompleted.current = true; // Mark as completed\n onTypeFinished?.(); // Call the passed callback\n }\n }, [hasSandbox, isComplete, onTypeFinished]);\n\n useEffect(() => {\n if (hasSandbox) return;\n hasCompleted.current = false; // Reset completion status when content changes\n }, [hasSandbox, content]);\n\n const renderMarkdownSegments = (raw: string, keyPrefix: string) => {\n const normalized = normalizeInlineHtml(raw);\n const parsed = parseMarkdownSegments(normalized);\n\n return parsed.map((seg, index) => {\n const key = `${keyPrefix}-${seg.type}-${index}`;\n\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={key}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart key={key} chart={seg.value} frozen={!seg.complete} />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={key} svg={seg.value} />;\n }\n\n return null;\n });\n };\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {mergedRenderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n type=\"sandbox\"\n content={segment.value}\n className=\"content-render-iframe\"\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n fullScreenButtonText={sandboxFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <React.Fragment key={`md-${idx}`}>\n {renderMarkdownSegments(segment.value, `md-${idx}`)}\n </React.Fragment>\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SANDBOX_TAG_HINT_PATTERN","SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","cleanedSvg","stripSvgTextLineBreaks","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","isRelativeLength","normalized","toNumericLength","parsed","isWidthRelative","isHeightRelative","widthMissing","heightMissing","numericWidth","numericHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","sanitizeInvalidTagName","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","mergeNonSandboxSegments","segments","merged","segment","last","ContentRender","content","customRenderBar","onSend","typingSpeed","enableTypewriter","userInput","interactionDefaultValueOptions","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","onTypeFinished","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","sandboxFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","normalizedContent","useMemo","normalizeInlineHtml","interactionDefaults","getInteractionDefaultValues","resolvedDefaultButtonText","resolvedDefaultInputText","fallbackSelectedValues","resolvedDefaultSelectedValues","children","props","CustomButtonInputVariable","className","rest","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","displayContent","isComplete","useTypewriterStateMachine","hasPotentialSandboxTags","renderSegments","splitContentSegments","hasSandbox","mergedRenderSegments","parseMarkdownSegments","hasCompleted","renderMarkdownSegments","raw","keyPrefix","seg","index","key","idx","IframeSandbox","React","jsxs"],"mappings":"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"}
@@ -39,15 +39,15 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
39
39
  `, i.appendChild(l)), Array.from(i.childNodes).filter(
40
40
  (n) => n !== l
41
41
  ).forEach((n) => i.removeChild(n));
42
- const R = document.createElement("template"), z = se(r);
43
- R.innerHTML = z, i.append(R.content.cloneNode(!0));
44
- let N = !1, T = !1;
42
+ const T = document.createElement("template"), z = se(r);
43
+ T.innerHTML = z, i.append(T.content.cloneNode(!0));
44
+ let y = !1, R = !1;
45
45
  i.querySelectorAll("svg").forEach((n) => {
46
46
  const C = n.getAttribute("viewBox");
47
47
  if (!C) return;
48
48
  const j = C.trim().split(/[\s,]+/).map((c) => Number(c));
49
49
  if (j.length !== 4 || j.some(Number.isNaN)) return;
50
- const [, , x, p] = j, v = n.getAttribute("width"), g = n.getAttribute("height"), L = (c) => {
50
+ const [, , f, p] = j, x = n.getAttribute("width"), v = n.getAttribute("height"), L = (c) => {
51
51
  if (!c) return !1;
52
52
  const m = c.trim().toLowerCase();
53
53
  return m === "auto" || m.endsWith("%");
@@ -58,15 +58,15 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
58
58
  return null;
59
59
  const k = Number.parseFloat(m);
60
60
  return Number.isNaN(k) ? null : k;
61
- }, M = L(v), I = L(g), b = !v || v === "0", A = !g || g === "0", V = B(v), H = B(g);
62
- if (M || I || b && A || V === x && H === p) {
63
- N = !0, n.classList.add("content-render-svg-el--responsive"), n.classList.remove("content-render-svg-el--fixed"), n.style.width = "100%", n.style.height = "auto", !n.style.aspectRatio && p > 0 && (n.style.aspectRatio = `${x} / ${p}`);
61
+ }, M = L(x), I = L(v), g = !x || x === "0", A = !v || v === "0", V = B(x), H = B(v);
62
+ if (M || I || g && A || V === f && H === p) {
63
+ y = !0, n.classList.add("content-render-svg-el--responsive"), n.classList.remove("content-render-svg-el--fixed"), n.style.width = "100%", n.style.height = "auto", !n.style.aspectRatio && p > 0 && (n.style.aspectRatio = `${f} / ${p}`);
64
64
  return;
65
65
  }
66
- T = !0, n.classList.add("content-render-svg-el--fixed"), n.classList.remove("content-render-svg-el--responsive"), b && x > 0 && n.setAttribute("width", `${x}`), A && p > 0 && n.setAttribute("height", `${p}`);
66
+ R = !0, n.classList.add("content-render-svg-el--fixed"), n.classList.remove("content-render-svg-el--responsive"), g && f > 0 && n.setAttribute("width", `${f}`), A && p > 0 && n.setAttribute("height", `${p}`);
67
67
  });
68
- const f = N && !T;
69
- a.classList.toggle("content-render-svg--responsive", f), a.classList.toggle("content-render-svg--fixed", !f);
68
+ const N = y && !R;
69
+ a.classList.toggle("content-render-svg--responsive", N), a.classList.toggle("content-render-svg--fixed", !N);
70
70
  }, [r]), /* @__PURE__ */ t.jsx("div", { className: "content-render-svg-scroll", children: /* @__PURE__ */ t.jsx("div", { className: "content-render-svg", ref: o }) });
71
71
  }, we = [ye, Ne, re, je], Se = [
72
72
  le,
@@ -83,7 +83,7 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
83
83
  components: o,
84
84
  children: r
85
85
  }
86
- ) }), Re = (r) => {
86
+ ) }), Te = (r) => {
87
87
  if (r.length <= 1) return r;
88
88
  const o = [];
89
89
  return r.forEach((a) => {
@@ -109,18 +109,18 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
109
109
  enableTypewriter: S = !1,
110
110
  userInput: l,
111
111
  interactionDefaultValueOptions: $,
112
- defaultButtonText: R,
112
+ defaultButtonText: T,
113
113
  defaultInputText: z,
114
- defaultSelectedValues: N,
115
- readonly: T = !1,
116
- onTypeFinished: f,
114
+ defaultSelectedValues: y,
115
+ readonly: R = !1,
116
+ onTypeFinished: N,
117
117
  confirmButtonText: n,
118
118
  copyButtonText: C,
119
119
  copiedButtonText: j,
120
- sandboxLoadingText: x,
120
+ sandboxLoadingText: f,
121
121
  sandboxStyleLoadingText: p,
122
- sandboxScriptLoadingText: v,
123
- sandboxFullscreenButtonText: g,
122
+ sandboxScriptLoadingText: x,
123
+ sandboxFullscreenButtonText: v,
124
124
  sandboxMode: L = "content",
125
125
  onClickCustomButtonAfterContent: B,
126
126
  beforeSend: M
@@ -129,17 +129,17 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
129
129
  const I = h(
130
130
  () => J(r),
131
131
  [r]
132
- ), b = h(
132
+ ), g = h(
133
133
  () => fe(
134
134
  r,
135
135
  l,
136
136
  $
137
137
  ),
138
138
  [r, $, l]
139
- ), A = R?.trim() || b.buttonText, V = z?.trim() || b.inputText, H = h(
139
+ ), A = T?.trim() || g.buttonText, V = z?.trim() || g.inputText, H = h(
140
140
  () => l ? l.split(",").map((e) => e.trim()).filter(Boolean) : void 0,
141
141
  [l]
142
- ), U = N?.length ? N : b.selectedValues || H, P = {
142
+ ), U = y?.length ? y : g.selectedValues || H, P = {
143
143
  "custom-button-after-content": ({
144
144
  children: e
145
145
  }) => /* @__PURE__ */ t.jsx(
@@ -154,7 +154,7 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
154
154
  ae,
155
155
  {
156
156
  ...e,
157
- readonly: T,
157
+ readonly: R,
158
158
  defaultButtonText: A,
159
159
  defaultInputText: V,
160
160
  defaultSelectedValues: U,
@@ -166,8 +166,8 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
166
166
  code: (e) => {
167
167
  const { className: s, children: d, ...W } = e;
168
168
  if (/language-(\w+)/.exec(s || "")?.[1] === "mermaid") {
169
- const y = d?.toString().replace(/\n$/, "") || "", te = ue(r, y);
170
- return /* @__PURE__ */ t.jsx(F, { chart: y, frozen: te });
169
+ const b = d?.toString().replace(/\n$/, "") || "", te = ue(r, b);
170
+ return /* @__PURE__ */ t.jsx(F, { chart: b, frozen: te });
171
171
  }
172
172
  return /* @__PURE__ */ t.jsx("code", { className: s, ...W, children: d });
173
173
  },
@@ -211,39 +211,35 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
211
211
  ), _ = h(
212
212
  () => k ? he(r, !0) : [],
213
213
  [r, k]
214
- ), D = _.some(
214
+ ), w = _.some(
215
215
  (e) => e.type === "sandbox"
216
216
  ), Z = h(
217
- () => Re(_),
217
+ () => Te(_),
218
218
  [_]
219
219
  ), E = h(
220
220
  () => X(c),
221
221
  [c]
222
- ), w = Y(!1);
222
+ ), D = Y(!1);
223
223
  G(() => {
224
- w.current = !1;
225
- }, [r]), G(() => {
226
- if (D) {
227
- w.current || (w.current = !0, f?.());
228
- return;
229
- }
230
- m && !w.current && (w.current = !0, f?.());
231
- }, [D, m, f]);
224
+ w || m && !D.current && (D.current = !0, N?.());
225
+ }, [w, m, N]), G(() => {
226
+ w || (D.current = !1);
227
+ }, [w, r]);
232
228
  const ee = (e, s) => {
233
229
  const d = J(e);
234
230
  return X(d).map((u, q) => {
235
- const y = `${s}-${u.type}-${q}`;
231
+ const b = `${s}-${u.type}-${q}`;
236
232
  return u.type === "text" ? /* @__PURE__ */ t.jsx(
237
233
  Q,
238
234
  {
239
235
  components: P,
240
236
  content: u.value
241
237
  },
242
- y
243
- ) : u.type === "mermaid" ? /* @__PURE__ */ t.jsx(F, { chart: u.value, frozen: !u.complete }, y) : u.type === "svg" ? /* @__PURE__ */ t.jsx(O, { svg: u.value }, y) : null;
238
+ b
239
+ ) : u.type === "mermaid" ? /* @__PURE__ */ t.jsx(F, { chart: u.value, frozen: !u.complete }, b) : u.type === "svg" ? /* @__PURE__ */ t.jsx(O, { svg: u.value }, b) : null;
244
240
  });
245
241
  };
246
- return D ? /* @__PURE__ */ t.jsx("div", { className: "content-render markdown-body", children: Z.map(
242
+ return w ? /* @__PURE__ */ t.jsx("div", { className: "content-render markdown-body", children: Z.map(
247
243
  (e, s) => e.type === "sandbox" ? /* @__PURE__ */ t.jsx(
248
244
  pe,
249
245
  {
@@ -251,10 +247,10 @@ const ke = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
251
247
  type: "sandbox",
252
248
  content: e.value,
253
249
  className: "content-render-iframe",
254
- loadingText: x,
250
+ loadingText: f,
255
251
  styleLoadingText: p,
256
- scriptLoadingText: v,
257
- fullScreenButtonText: g,
252
+ scriptLoadingText: x,
253
+ fullScreenButtonText: v,
258
254
  mode: L
259
255
  },
260
256
  `sandbox-${s}`
@@ -1 +1 @@
1
- {"version":3,"file":"ContentRender.es.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport { sanitizeInvalidTagName } from \"./utils/sanitize-invalid-tag-name\";\nimport { stripSvgTextLineBreaks } from \"./utils/strip-svg-text-line-breaks\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport useTypewriterStateMachine from \"./useTypewriterStateMachine\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport {\n splitContentSegments,\n type RenderSegment,\n} from \"./utils/split-content\";\nimport {\n getInteractionDefaultValues,\n type InteractionDefaultValueOptions,\n} from \"../../lib/interaction-defaults\";\n\nconst SANDBOX_TAG_HINT_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)\\b/i;\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n /**\n * Callback invoked when the custom button after content is clicked.\n * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n * @example\n * ```tsx\n * <ContentRender\n * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n * />\n * ```\n */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n userInput?: string;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n onTypeFinished?: () => void;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n const cleanedSvg = stripSvgTextLineBreaks(svg);\n template.innerHTML = cleanedSvg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const isRelativeLength = (value?: string | null) => {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === \"auto\" || normalized.endsWith(\"%\");\n };\n const toNumericLength = (value?: string | null) => {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"auto\" || normalized.endsWith(\"%\")) {\n return null;\n }\n const parsed = Number.parseFloat(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n };\n // Treat percentage/auto sizing as responsive so viewBox drives the layout\n const isWidthRelative = isRelativeLength(widthAttr);\n const isHeightRelative = isRelativeLength(heightAttr);\n const widthMissing = !widthAttr || widthAttr === \"0\";\n const heightMissing = !heightAttr || heightAttr === \"0\";\n const numericWidth = toNumericLength(widthAttr);\n const numericHeight = toNumericLength(heightAttr);\n const matchesViewBox =\n numericWidth === viewBoxWidth && numericHeight === viewBoxHeight;\n\n // Prefer responsive layout when sizing is relative or matches the viewBox\n const shouldUseResponsiveSize =\n isWidthRelative ||\n isHeightRelative ||\n (widthMissing && heightMissing) ||\n matchesViewBox;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (widthMissing && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (heightMissing && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins = [remarkGfm, remarkMath, remarkFlow, remarkBreaks];\n\nconst rehypePlugins = [\n preserveCustomVariableProperties,\n rehypeRaw,\n sanitizeInvalidTagName,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst mergeNonSandboxSegments = (segments: RenderSegment[]) => {\n if (segments.length <= 1) return segments;\n const merged: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type === \"sandbox\") {\n merged.push(segment);\n return;\n }\n\n const last = merged[merged.length - 1];\n if (last && last.type !== \"sandbox\") {\n merged[merged.length - 1] = {\n type: \"markdown\",\n value: `${last.value}${segment.value}`,\n };\n return;\n }\n\n merged.push({ type: \"markdown\", value: segment.value });\n });\n\n return merged;\n};\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n customRenderBar,\n onSend,\n typingSpeed = 30,\n enableTypewriter = false,\n userInput,\n interactionDefaultValueOptions,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n onTypeFinished,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n sandboxFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(content),\n [content]\n );\n\n const interactionDefaults = useMemo(\n () =>\n getInteractionDefaultValues(\n content,\n userInput,\n interactionDefaultValueOptions\n ),\n [content, interactionDefaultValueOptions, userInput]\n );\n\n const resolvedDefaultButtonText =\n defaultButtonText?.trim() || interactionDefaults.buttonText;\n const resolvedDefaultInputText =\n defaultInputText?.trim() || interactionDefaults.inputText;\n const fallbackSelectedValues = useMemo(\n () =>\n userInput\n ? userInput\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined,\n [userInput]\n );\n const resolvedDefaultSelectedValues = defaultSelectedValues?.length\n ? defaultSelectedValues\n : interactionDefaults.selectedValues || fallbackSelectedValues;\n\n // Use custom Hook to handle typewriter effect\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={resolvedDefaultButtonText}\n defaultInputText={resolvedDefaultInputText}\n defaultSelectedValues={resolvedDefaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n confirmButtonText={confirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(content, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n />\n ),\n };\n\n const { displayContent, isComplete } = useTypewriterStateMachine({\n // processMarkdownText will let code block printf(\"You win!\\n\") become printf(\"You win!<br/>\");\n // content: processMarkdownText(content),\n content: normalizedContent,\n typingSpeed,\n disabled: !enableTypewriter,\n });\n\n const hasPotentialSandboxTags = useMemo(\n () => SANDBOX_TAG_HINT_PATTERN.test(content),\n [content]\n );\n\n const renderSegments = useMemo(\n () => (hasPotentialSandboxTags ? splitContentSegments(content, true) : []),\n [content, hasPotentialSandboxTags]\n );\n\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n const mergedRenderSegments = useMemo(\n () => mergeNonSandboxSegments(renderSegments),\n [renderSegments]\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(displayContent),\n [displayContent]\n );\n\n const hasCompleted = useRef(false);\n\n useEffect(() => {\n // Reset completion state on each content update so streaming patches can emit completion again.\n hasCompleted.current = false;\n }, [content]);\n\n useEffect(() => {\n if (hasSandbox) {\n if (!hasCompleted.current) {\n hasCompleted.current = true;\n onTypeFinished?.();\n }\n return;\n }\n\n if (isComplete && !hasCompleted.current) {\n hasCompleted.current = true; // Mark as completed\n onTypeFinished?.(); // Call the passed callback\n }\n }, [hasSandbox, isComplete, onTypeFinished]);\n\n const renderMarkdownSegments = (raw: string, keyPrefix: string) => {\n const normalized = normalizeInlineHtml(raw);\n const parsed = parseMarkdownSegments(normalized);\n\n return parsed.map((seg, index) => {\n const key = `${keyPrefix}-${seg.type}-${index}`;\n\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={key}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart key={key} chart={seg.value} frozen={!seg.complete} />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={key} svg={seg.value} />;\n }\n\n return null;\n });\n };\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {mergedRenderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n type=\"sandbox\"\n content={segment.value}\n className=\"content-render-iframe\"\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n fullScreenButtonText={sandboxFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <React.Fragment key={`md-${idx}`}>\n {renderMarkdownSegments(segment.value, `md-${idx}`)}\n </React.Fragment>\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SANDBOX_TAG_HINT_PATTERN","SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","cleanedSvg","stripSvgTextLineBreaks","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","isRelativeLength","normalized","toNumericLength","parsed","isWidthRelative","isHeightRelative","widthMissing","heightMissing","numericWidth","numericHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","sanitizeInvalidTagName","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","mergeNonSandboxSegments","segments","merged","segment","last","ContentRender","content","customRenderBar","onSend","typingSpeed","enableTypewriter","userInput","interactionDefaultValueOptions","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","onTypeFinished","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","sandboxFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","normalizedContent","useMemo","normalizeInlineHtml","interactionDefaults","getInteractionDefaultValues","resolvedDefaultButtonText","resolvedDefaultInputText","fallbackSelectedValues","resolvedDefaultSelectedValues","children","props","CustomButtonInputVariable","className","rest","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","displayContent","isComplete","useTypewriterStateMachine","hasPotentialSandboxTags","renderSegments","splitContentSegments","hasSandbox","mergedRenderSegments","parseMarkdownSegments","hasCompleted","renderMarkdownSegments","raw","keyPrefix","seg","index","key","idx","IframeSandbox","React","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"ContentRender.es.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport { sanitizeInvalidTagName } from \"./utils/sanitize-invalid-tag-name\";\nimport { stripSvgTextLineBreaks } from \"./utils/strip-svg-text-line-breaks\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport useTypewriterStateMachine from \"./useTypewriterStateMachine\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport {\n splitContentSegments,\n type RenderSegment,\n} from \"./utils/split-content\";\nimport {\n getInteractionDefaultValues,\n type InteractionDefaultValueOptions,\n} from \"../../lib/interaction-defaults\";\n\nconst SANDBOX_TAG_HINT_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)\\b/i;\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n /**\n * Callback invoked when the custom button after content is clicked.\n * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n * @example\n * ```tsx\n * <ContentRender\n * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n * />\n * ```\n */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n userInput?: string;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n onTypeFinished?: () => void;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n const cleanedSvg = stripSvgTextLineBreaks(svg);\n template.innerHTML = cleanedSvg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const isRelativeLength = (value?: string | null) => {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === \"auto\" || normalized.endsWith(\"%\");\n };\n const toNumericLength = (value?: string | null) => {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"auto\" || normalized.endsWith(\"%\")) {\n return null;\n }\n const parsed = Number.parseFloat(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n };\n // Treat percentage/auto sizing as responsive so viewBox drives the layout\n const isWidthRelative = isRelativeLength(widthAttr);\n const isHeightRelative = isRelativeLength(heightAttr);\n const widthMissing = !widthAttr || widthAttr === \"0\";\n const heightMissing = !heightAttr || heightAttr === \"0\";\n const numericWidth = toNumericLength(widthAttr);\n const numericHeight = toNumericLength(heightAttr);\n const matchesViewBox =\n numericWidth === viewBoxWidth && numericHeight === viewBoxHeight;\n\n // Prefer responsive layout when sizing is relative or matches the viewBox\n const shouldUseResponsiveSize =\n isWidthRelative ||\n isHeightRelative ||\n (widthMissing && heightMissing) ||\n matchesViewBox;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (widthMissing && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (heightMissing && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins = [remarkGfm, remarkMath, remarkFlow, remarkBreaks];\n\nconst rehypePlugins = [\n preserveCustomVariableProperties,\n rehypeRaw,\n sanitizeInvalidTagName,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst mergeNonSandboxSegments = (segments: RenderSegment[]) => {\n if (segments.length <= 1) return segments;\n const merged: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type === \"sandbox\") {\n merged.push(segment);\n return;\n }\n\n const last = merged[merged.length - 1];\n if (last && last.type !== \"sandbox\") {\n merged[merged.length - 1] = {\n type: \"markdown\",\n value: `${last.value}${segment.value}`,\n };\n return;\n }\n\n merged.push({ type: \"markdown\", value: segment.value });\n });\n\n return merged;\n};\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n customRenderBar,\n onSend,\n typingSpeed = 30,\n enableTypewriter = false,\n userInput,\n interactionDefaultValueOptions,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n onTypeFinished,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n sandboxFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(content),\n [content]\n );\n\n const interactionDefaults = useMemo(\n () =>\n getInteractionDefaultValues(\n content,\n userInput,\n interactionDefaultValueOptions\n ),\n [content, interactionDefaultValueOptions, userInput]\n );\n\n const resolvedDefaultButtonText =\n defaultButtonText?.trim() || interactionDefaults.buttonText;\n const resolvedDefaultInputText =\n defaultInputText?.trim() || interactionDefaults.inputText;\n const fallbackSelectedValues = useMemo(\n () =>\n userInput\n ? userInput\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined,\n [userInput]\n );\n const resolvedDefaultSelectedValues = defaultSelectedValues?.length\n ? defaultSelectedValues\n : interactionDefaults.selectedValues || fallbackSelectedValues;\n\n // Use custom Hook to handle typewriter effect\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={resolvedDefaultButtonText}\n defaultInputText={resolvedDefaultInputText}\n defaultSelectedValues={resolvedDefaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n confirmButtonText={confirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(content, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n />\n ),\n };\n\n const { displayContent, isComplete } = useTypewriterStateMachine({\n // processMarkdownText will let code block printf(\"You win!\\n\") become printf(\"You win!<br/>\");\n // content: processMarkdownText(content),\n content: normalizedContent,\n typingSpeed,\n disabled: !enableTypewriter,\n });\n\n const hasPotentialSandboxTags = useMemo(\n () => SANDBOX_TAG_HINT_PATTERN.test(content),\n [content]\n );\n\n const renderSegments = useMemo(\n () => (hasPotentialSandboxTags ? splitContentSegments(content, true) : []),\n [content, hasPotentialSandboxTags]\n );\n\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n const mergedRenderSegments = useMemo(\n () => mergeNonSandboxSegments(renderSegments),\n [renderSegments]\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(displayContent),\n [displayContent]\n );\n\n const hasCompleted = useRef(false);\n\n useEffect(() => {\n if (hasSandbox) return;\n if (isComplete && !hasCompleted.current) {\n hasCompleted.current = true; // Mark as completed\n onTypeFinished?.(); // Call the passed callback\n }\n }, [hasSandbox, isComplete, onTypeFinished]);\n\n useEffect(() => {\n if (hasSandbox) return;\n hasCompleted.current = false; // Reset completion status when content changes\n }, [hasSandbox, content]);\n\n const renderMarkdownSegments = (raw: string, keyPrefix: string) => {\n const normalized = normalizeInlineHtml(raw);\n const parsed = parseMarkdownSegments(normalized);\n\n return parsed.map((seg, index) => {\n const key = `${keyPrefix}-${seg.type}-${index}`;\n\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={key}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart key={key} chart={seg.value} frozen={!seg.complete} />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={key} svg={seg.value} />;\n }\n\n return null;\n });\n };\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {mergedRenderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n type=\"sandbox\"\n content={segment.value}\n className=\"content-render-iframe\"\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n fullScreenButtonText={sandboxFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <React.Fragment key={`md-${idx}`}>\n {renderMarkdownSegments(segment.value, `md-${idx}`)}\n </React.Fragment>\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SANDBOX_TAG_HINT_PATTERN","SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","cleanedSvg","stripSvgTextLineBreaks","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","isRelativeLength","normalized","toNumericLength","parsed","isWidthRelative","isHeightRelative","widthMissing","heightMissing","numericWidth","numericHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","sanitizeInvalidTagName","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","mergeNonSandboxSegments","segments","merged","segment","last","ContentRender","content","customRenderBar","onSend","typingSpeed","enableTypewriter","userInput","interactionDefaultValueOptions","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","onTypeFinished","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","sandboxFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","normalizedContent","useMemo","normalizeInlineHtml","interactionDefaults","getInteractionDefaultValues","resolvedDefaultButtonText","resolvedDefaultInputText","fallbackSelectedValues","resolvedDefaultSelectedValues","children","props","CustomButtonInputVariable","className","rest","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","displayContent","isComplete","useTypewriterStateMachine","hasPotentialSandboxTags","renderSegments","splitContentSegments","hasSandbox","mergedRenderSegments","parseMarkdownSegments","hasCompleted","renderMarkdownSegments","raw","keyPrefix","seg","index","key","idx","IframeSandbox","React","jsxs"],"mappings":"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"}
@@ -1,4 +1,4 @@
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>
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const M=require("../../_virtual/jsx-runtime.cjs.js"),n=require("react"),Re=require("react-dom/client"),Ee=require("./SandboxApp.cjs.js"),Ce=require("./ContentRender.cjs.js"),ue=require("../../lib/sandboxInteraction.cjs.js");let Z=null;const Te=()=>(Z||(Z=Promise.resolve().then(()=>require("./blackboard-vendor.cjs.js")).then(r=>r.injectBlackboardLibraries)),Z),ye=/<img\b[^>]*>/i,Me=180,Se=240,Ae={viewportHeightCss:null,hasFullViewportHeight:!1},ae=r=>r.split(/\s+/).filter(Boolean).map(e=>e.split(":").pop()||e),D=r=>{const e=r.trim().toLowerCase();if(!e)return null;const s=e.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);return s?`${s[1]}${s[2].toLowerCase()}`:null},J=r=>{if(!r.trim())return null;const e=ae(r);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 s=e.find(a=>/^(h|min-h)-\[[0-9.]+(vh|dvh|svh|lvh)\]$/i.test(a));if(!s)return null;const u=s.match(/^(h|min-h)-\[([0-9.]+)(vh|dvh|svh|lvh)\]$/i);return u?`${u[2]}${u[3].toLowerCase()}`:null},Fe=r=>r==="100vh"||r==="100dvh"||r==="100svh"||r==="100lvh",Ve=r=>{const e=r.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],b=u.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(/\bheight\s*:\s*([^;]+)/i)?.[1],h=u.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1],N=(a?D(a):null)||(b?D(b):null)||(h?J(h):null);return{viewportHeightCss:N,hasFullViewportHeight:Fe(N)}},je=r=>r.split(/\s+/).filter(Boolean).map(e=>{const s=e.split(":");return s[s.length-1]!=="h-screen"&&s[s.length-1]!=="min-h-screen"?e:(s[s.length-1]="h-full",s.join(":"))}).join(" "),Ie=(r,e)=>!e||!r.trim()?r:r.replace(/^(\s*<[a-zA-Z][\w:-]*)(\s[^>]*?)?>/,(s,u,a="")=>{const m=a.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);if(!m)return s;const b=je(m[2]);return b===m[2]?s:`${u}${a.replace(m[0],`class=${m[1]}${b}${m[1]}`)}>`}),Ne=({content:r,type:e,className:s,styleLoadingText:u,scriptLoadingText:a,fullScreenButtonText:m,hideFullScreen:b=!1,mode:h="content",replaceRootScreenHeightWithFull:N=!1})=>{const K=n.useRef(null),E=n.useRef(null),z=n.useRef(null),P=n.useRef(()=>{}),[he,de]=n.useState(480),Q=n.useRef(0),[ee,me]=n.useState(0),[fe,ge]=n.useState(!1),pe=e==="sandbox",_=h==="blackboard",S=_&&e==="sandbox",C=S&&N,q=n.useRef(""),k=n.useMemo(()=>e==="sandbox"?r:"",[r,e]),i=n.useMemo(()=>Ie(k,C),[k,C]),te=n.useMemo(()=>C?Ve(k):Ae,[k,C]),ne=n.useMemo(()=>C&&te.hasFullViewportHeight,[te.hasFullViewportHeight,C]),[O,re]=n.useState(i),oe=n.useRef(i),L=n.useRef(i),A=n.useRef(null),F=n.useRef(null),se=n.useRef(null),T=n.useCallback(o=>{if(typeof window>"u")return;const t=Date.now();t-Q.current<Se||(Q.current=t,window.postMessage({source:ue.SANDBOX_INTERACTION_MESSAGE_SOURCE,type:ue.SANDBOX_INTERACTION_MESSAGE_TYPE,eventType:o},window.location.origin))},[]),G=()=>{A.current!==null&&(window.clearTimeout(A.current),A.current=null)},be=()=>{F.current!==null&&(window.cancelAnimationFrame(F.current),F.current=null)};n.useEffect(()=>()=>{G(),be()},[]),n.useEffect(()=>{const o=oe.current;oe.current=i;const t=!!o&&i.length>o.length&&i.startsWith(o),d=ye.test(i);if(!(t&&d)){G(),L.current=i,re(i);return}L.current=i,G(),A.current=window.setTimeout(()=>{re(L.current),A.current=null},Me)},[i]);const $=n.useMemo(()=>{if(!S)return null;const o=O.trim();if(!o)return null;const t=o.match(/^<([a-zA-Z][\w:-]*)(\s[^>]*?)?>/);if(!t)return null;const d=t[2]||"",y=d.match(/\bheight\s*=\s*["']([^"']+)["']/i);if(y){const g=D(y[1]);if(g)return g}const j=d.match(/\bstyle\s*=\s*["']([^"']+)["']/i)?.[1]?.match(/\bheight\s*:\s*([^;]+)/i)?.[1];if(j){const g=D(j);if(g)return g}const w=d.match(/\bclass\s*=\s*["']([^"']+)["']/i)?.[1];return w?J(w):null},[O,S]);n.useEffect(()=>{se.current=$},[$]);const ie=!!$,V=_&&e==="sandbox"?ne?"100%":$??`${he}px`:void 0;n.useEffect(()=>{if(h!=="blackboard"){q.current=i;return}const o=q.current;!(o&&i.startsWith(o))&&o&&me(d=>d+1),q.current=i},[h,i]),n.useEffect(()=>{const o=E.current;if(!o)return;const t=o.contentDocument;if(!t)return;t.open(),t.write(`<!DOCTYPE html>
2
2
  <html${h==="blackboard"?' style="height: 100%;"':""}>
3
3
  <head>
4
4
  <meta charset="utf-8" />
@@ -13,5 +13,5 @@
13
13
  <body>
14
14
  <div id="root"></div>
15
15
  </body>
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;
16
+ </html>`),t.close(),t.documentElement.setAttribute("data-theme","light"),t.documentElement.style.colorScheme="light",t.body?.style.setProperty("color-scheme","light");const d=_&&e==="sandbox",y=()=>T("pointerdown"),W=()=>T("mousedown"),j=()=>T("touchstart");d&&(t.addEventListener("pointerdown",y,!0),t.addEventListener("mousedown",W,!0),t.addEventListener("touchstart",j,!0));const w=t.getElementById("root");if(!w)return;const g=Re.createRoot(w);z.current=g;let I=!1;const U=(l,p)=>{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*p:c.endsWith("px")||/^[0-9.]+$/.test(c)?v:null},xe=(l,p)=>{if(!l.trim())return null;const c=J(l);if(c)return U(c,p);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(!S||!E.current||!t.body)return null;const l=E.current.ownerDocument?.documentElement?.clientHeight||window.innerHeight,p=se.current,c=p?U(p,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(!S||!E.current||!t.body)return;const l=t.body.getBoundingClientRect(),p=t.documentElement?.getBoundingClientRect(),c=l.height,v=p?.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(()=>{I||X()})};P.current=B,X(),B(),pe&&Te().then(l=>{I||(l(t),requestAnimationFrame(()=>{I||B()}))}).catch(()=>{I||B()});const Y=new ResizeObserver(()=>X());return Y.observe(t.body),w&&Y.observe(w),()=>{I=!0,Y.disconnect(),d&&(t.removeEventListener("pointerdown",y,!0),t.removeEventListener("mousedown",W,!0),t.removeEventListener("touchstart",j,!0)),setTimeout(()=>{g.unmount(),z.current=null,P.current=()=>{}},0)}},[]),n.useEffect(()=>{const o=()=>{ge(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",o),()=>document.removeEventListener("fullscreenchange",o)},[]);const we=()=>{const o=K.current||E.current;if(o){if(document.fullscreenElement){document.exitFullscreen().catch(()=>{});return}o.requestFullscreen&&o.requestFullscreen().catch(()=>{})}};n.useEffect(()=>{const o=z.current;o&&(o.render(M.jsxRuntimeExports.jsx(Ee.default,{html:O,styleLoadingText:u,scriptLoadingText:a,resetToken:ee,hasRootVhHeight:ie,mode:h,stretchRootHeight:ne})),F.current=window.requestAnimationFrame(()=>{P.current?.(),F.current=null}))},[O,u,a,ee,h]);const ve=["w-full relative content-render-iframe-sandbox",_?"h-full overflow-auto flex flex-col":"aspect-[16/9] overflow-hidden flex items-center justify-center"].filter(Boolean).join(" ");return M.jsxRuntimeExports.jsxs("div",{ref:K,"data-root-vh":ie?"true":"false",className:ve,style:V?{height:V,minHeight:V}:void 0,children:[!b&&M.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"?M.jsxRuntimeExports.jsx("div",{onMouseDown:()=>T("mousedown"),onPointerDown:()=>T("pointerdown"),onTouchStart:()=>T("touchstart"),children:M.jsxRuntimeExports.jsx(Ce.default,{content:r})}):M.jsxRuntimeExports.jsx("iframe",{ref:E,sandbox:"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",allow:"fullscreen",allowFullScreen:!0,className:[s,"w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),style:{height:V??"100%",minHeight:V,margin:"auto",visibility:"visible"}})]})};exports.default=Ne;
17
17
  //# sourceMappingURL=IframeSandbox.cjs.js.map