markdown-flow-ui 0.2.13 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/_virtual/index.es3.js +5 -4
- package/dist/_virtual/index.es3.js.map +1 -1
- package/dist/_virtual/index.es4.js +4 -5
- package/dist/_virtual/index.es4.js.map +1 -1
- package/dist/_virtual/index3.cjs +1 -1
- package/dist/_virtual/index4.cjs +1 -1
- package/dist/assets/markdown-flow-ui.css +10 -1
- package/dist/components/ContentRender/CodeBlock.cjs +1 -1
- package/dist/components/ContentRender/CodeBlock.cjs.map +1 -1
- package/dist/components/ContentRender/CodeBlock.d.ts +5 -0
- package/dist/components/ContentRender/CodeBlock.es.js +41 -38
- package/dist/components/ContentRender/CodeBlock.es.js.map +1 -1
- package/dist/components/ContentRender/ContentRender.cjs +2 -2
- package/dist/components/ContentRender/ContentRender.cjs.map +1 -1
- package/dist/components/ContentRender/ContentRender.d.ts +9 -4
- package/dist/components/ContentRender/ContentRender.es.js +389 -298
- package/dist/components/ContentRender/ContentRender.es.js.map +1 -1
- package/dist/components/ContentRender/IframeSandbox.cjs +7 -7
- package/dist/components/ContentRender/IframeSandbox.cjs.map +1 -1
- package/dist/components/ContentRender/IframeSandbox.d.ts +5 -1
- package/dist/components/ContentRender/IframeSandbox.es.js +311 -266
- package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
- package/dist/components/ContentRender/MarkdownFlowInput.cjs +1 -1
- package/dist/components/ContentRender/MarkdownFlowInput.cjs.map +1 -1
- package/dist/components/ContentRender/MarkdownFlowInput.d.ts +5 -1
- package/dist/components/ContentRender/MarkdownFlowInput.es.js +37 -32
- package/dist/components/ContentRender/MarkdownFlowInput.es.js.map +1 -1
- package/dist/components/ContentRender/SandboxApp.cjs +2 -2
- package/dist/components/ContentRender/SandboxApp.cjs.map +1 -1
- package/dist/components/ContentRender/SandboxApp.d.ts +5 -1
- package/dist/components/ContentRender/SandboxApp.es.js +108 -103
- package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
- package/dist/components/ContentRender/blackboard-vendor.d.ts +1 -1
- package/dist/components/ContentRender/contentRenderI18n.cjs +1 -1
- package/dist/components/ContentRender/contentRenderI18n.cjs.map +1 -1
- package/dist/components/ContentRender/contentRenderI18n.d.ts +6 -1
- package/dist/components/ContentRender/contentRenderI18n.es.js +5 -56
- package/dist/components/ContentRender/contentRenderI18n.es.js.map +1 -1
- package/dist/components/ContentRender/contentRenderI18n.test.d.ts +1 -0
- package/dist/components/ContentRender/index.cjs +1 -1
- package/dist/components/ContentRender/index.d.ts +11 -11
- package/dist/components/ContentRender/index.es.js +1 -2
- package/dist/components/ContentRender/index.es.js.map +1 -1
- package/dist/components/ContentRender/locales/contentRender.json.cjs +2 -0
- package/dist/components/ContentRender/locales/contentRender.json.cjs.map +1 -0
- package/dist/components/ContentRender/locales/contentRender.json.d.ts +90 -0
- package/dist/components/ContentRender/locales/contentRender.json.es.js +11 -0
- package/dist/components/ContentRender/locales/contentRender.json.es.js.map +1 -0
- package/dist/components/ContentRender/plugins/CustomVariable.cjs +1 -1
- package/dist/components/ContentRender/plugins/CustomVariable.cjs.map +1 -1
- package/dist/components/ContentRender/plugins/CustomVariable.d.ts +7 -3
- package/dist/components/ContentRender/plugins/CustomVariable.es.js +165 -151
- package/dist/components/ContentRender/plugins/CustomVariable.es.js.map +1 -1
- package/dist/components/ContentRender/plugins/MermaidChart.cjs +1 -1
- package/dist/components/ContentRender/plugins/MermaidChart.cjs.map +1 -1
- package/dist/components/ContentRender/plugins/MermaidChart.d.ts +1 -0
- package/dist/components/ContentRender/plugins/MermaidChart.es.js +68 -44
- package/dist/components/ContentRender/plugins/MermaidChart.es.js.map +1 -1
- package/dist/components/MarkdownFlow/MarkdownFlow.cjs +1 -1
- package/dist/components/MarkdownFlow/MarkdownFlow.cjs.map +1 -1
- package/dist/components/MarkdownFlow/MarkdownFlow.d.ts +12 -4
- package/dist/components/MarkdownFlow/MarkdownFlow.es.js +51 -39
- package/dist/components/MarkdownFlow/MarkdownFlow.es.js.map +1 -1
- package/dist/components/MarkdownFlow/ScrollToBottomButton.cjs +1 -1
- package/dist/components/MarkdownFlow/ScrollToBottomButton.cjs.map +1 -1
- package/dist/components/MarkdownFlow/ScrollToBottomButton.d.ts +31 -1
- package/dist/components/MarkdownFlow/ScrollToBottomButton.es.js +46 -17
- package/dist/components/MarkdownFlow/ScrollToBottomButton.es.js.map +1 -1
- package/dist/components/MarkdownFlow/ScrollToBottomControl.cjs +2 -0
- package/dist/components/MarkdownFlow/ScrollToBottomControl.cjs.map +1 -0
- package/dist/components/MarkdownFlow/ScrollToBottomControl.d.ts +18 -0
- package/dist/components/MarkdownFlow/ScrollToBottomControl.es.js +47 -0
- package/dist/components/MarkdownFlow/ScrollToBottomControl.es.js.map +1 -0
- package/dist/components/MarkdownFlow/ScrollableMarkdownFlow.cjs +1 -1
- package/dist/components/MarkdownFlow/ScrollableMarkdownFlow.cjs.map +1 -1
- package/dist/components/MarkdownFlow/ScrollableMarkdownFlow.d.ts +1 -1
- package/dist/components/MarkdownFlow/ScrollableMarkdownFlow.es.js +33 -52
- package/dist/components/MarkdownFlow/ScrollableMarkdownFlow.es.js.map +1 -1
- package/dist/components/MarkdownFlow/index.cjs +1 -1
- package/dist/components/MarkdownFlow/index.d.ts +9 -6
- package/dist/components/MarkdownFlow/index.es.js +6 -6
- package/dist/components/MarkdownFlow/index.es.js.map +1 -1
- package/dist/components/MarkdownFlow/useScrollToBottom.cjs +1 -1
- package/dist/components/MarkdownFlow/useScrollToBottom.cjs.map +1 -1
- package/dist/components/MarkdownFlow/useScrollToBottom.d.ts +40 -8
- package/dist/components/MarkdownFlow/useScrollToBottom.es.js +352 -83
- package/dist/components/MarkdownFlow/useScrollToBottom.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/MarkdownFlowEditor.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/MarkdownFlowEditor.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/MarkdownFlowEditor.d.ts +5 -3
- package/dist/components/MarkdownFlowEditor/MarkdownFlowEditor.es.js +371 -324
- package/dist/components/MarkdownFlowEditor/MarkdownFlowEditor.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/CustomDialog.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/CustomDialog.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/CustomDialog.d.ts +10 -0
- package/dist/components/MarkdownFlowEditor/components/CustomDialog.es.js +22 -19
- package/dist/components/MarkdownFlowEditor/components/CustomDialog.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/CustomPopover.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/CustomPopover.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/CustomPopover.d.ts +8 -0
- package/dist/components/MarkdownFlowEditor/components/CustomPopover.es.js +19 -15
- package/dist/components/MarkdownFlowEditor/components/CustomPopover.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/EditorToolbar.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/EditorToolbar.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/EditorToolbar.d.ts +4 -1
- package/dist/components/MarkdownFlowEditor/components/EditorToolbar.es.js +99 -93
- package/dist/components/MarkdownFlowEditor/components/EditorToolbar.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/ImageInject.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/ImageInject.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/ImageInject.d.ts +1 -1
- package/dist/components/MarkdownFlowEditor/components/ImageInject.es.js +183 -182
- package/dist/components/MarkdownFlowEditor/components/ImageInject.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/VariableSearchDropdown.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/VariableSearchDropdown.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/VariableSearchDropdown.d.ts +1 -1
- package/dist/components/MarkdownFlowEditor/components/VariableSearchDropdown.es.js +107 -103
- package/dist/components/MarkdownFlowEditor/components/VariableSearchDropdown.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/VariableSelect.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/VariableSelect.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/VariableSelect.d.ts +1 -1
- package/dist/components/MarkdownFlowEditor/components/VariableSelect.es.js +106 -106
- package/dist/components/MarkdownFlowEditor/components/VariableSelect.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/VideoInject.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/VideoInject.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/VideoInject.es.js +64 -63
- package/dist/components/MarkdownFlowEditor/components/VideoInject.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/icons/ButtonIcon.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/icons/ButtonIcon.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/icons/ButtonIcon.es.js +13 -13
- package/dist/components/MarkdownFlowEditor/components/icons/ButtonIcon.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/icons/SearchBracesIcon.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/components/icons/SearchBracesIcon.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/components/icons/SearchBracesIcon.es.js +12 -12
- package/dist/components/MarkdownFlowEditor/components/icons/SearchBracesIcon.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/editor-context.d.ts +1 -1
- package/dist/components/MarkdownFlowEditor/editorI18n.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/editorI18n.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/editorI18n.d.ts +290 -0
- package/dist/components/MarkdownFlowEditor/editorI18n.es.js +12 -8
- package/dist/components/MarkdownFlowEditor/editorI18n.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/editorI18n.test.d.ts +1 -0
- package/dist/components/MarkdownFlowEditor/index.d.ts +6 -6
- package/dist/components/MarkdownFlowEditor/locales/ar-SA.json.cjs +2 -0
- package/dist/components/MarkdownFlowEditor/locales/ar-SA.json.cjs.map +1 -0
- package/dist/components/MarkdownFlowEditor/locales/ar-SA.json.d.ts +72 -0
- package/dist/components/MarkdownFlowEditor/locales/ar-SA.json.es.js +140 -0
- package/dist/components/MarkdownFlowEditor/locales/ar-SA.json.es.js.map +1 -0
- package/dist/components/MarkdownFlowEditor/locales/en-US.json.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/locales/en-US.json.d.ts +2 -0
- package/dist/components/MarkdownFlowEditor/locales/en-US.json.es.js +118 -114
- package/dist/components/MarkdownFlowEditor/locales/en-US.json.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/locales/fr-FR.json.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/locales/fr-FR.json.d.ts +2 -0
- package/dist/components/MarkdownFlowEditor/locales/fr-FR.json.es.js +118 -114
- package/dist/components/MarkdownFlowEditor/locales/fr-FR.json.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/locales/th-TH.json.cjs +2 -0
- package/dist/components/MarkdownFlowEditor/locales/th-TH.json.cjs.map +1 -0
- package/dist/components/MarkdownFlowEditor/locales/th-TH.json.d.ts +72 -0
- package/dist/components/MarkdownFlowEditor/locales/th-TH.json.es.js +140 -0
- package/dist/components/MarkdownFlowEditor/locales/th-TH.json.es.js.map +1 -0
- package/dist/components/MarkdownFlowEditor/locales/zh-CN.json.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/locales/zh-CN.json.d.ts +2 -0
- package/dist/components/MarkdownFlowEditor/locales/zh-CN.json.es.js +70 -66
- package/dist/components/MarkdownFlowEditor/locales/zh-CN.json.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/plugins/ImgPlaceholder.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/plugins/ImgPlaceholder.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/plugins/ImgPlaceholder.es.js +40 -35
- package/dist/components/MarkdownFlowEditor/plugins/ImgPlaceholder.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/plugins/PlaceholderWidget.d.ts +1 -1
- package/dist/components/MarkdownFlowEditor/plugins/VideoPlaceholder.cjs +1 -1
- package/dist/components/MarkdownFlowEditor/plugins/VideoPlaceholder.cjs.map +1 -1
- package/dist/components/MarkdownFlowEditor/plugins/VideoPlaceholder.es.js +27 -23
- package/dist/components/MarkdownFlowEditor/plugins/VideoPlaceholder.es.js.map +1 -1
- package/dist/components/MarkdownFlowEditor/plugins/mediaPlaceholderLabels.cjs +2 -0
- package/dist/components/MarkdownFlowEditor/plugins/mediaPlaceholderLabels.cjs.map +1 -0
- package/dist/components/MarkdownFlowEditor/plugins/mediaPlaceholderLabels.d.ts +7 -0
- package/dist/components/MarkdownFlowEditor/plugins/mediaPlaceholderLabels.es.js +12 -0
- package/dist/components/MarkdownFlowEditor/plugins/mediaPlaceholderLabels.es.js.map +1 -0
- package/dist/components/MarkdownFlowEditor/utils.d.ts +1 -1
- package/dist/components/Slide/MarkdownSlideScaling.cjs +1 -1
- package/dist/components/Slide/MarkdownSlideScaling.cjs.map +1 -1
- package/dist/components/Slide/MarkdownSlideScaling.d.ts +1 -1
- package/dist/components/Slide/MarkdownSlideScaling.es.js +20 -20
- package/dist/components/Slide/MarkdownSlideScaling.es.js.map +1 -1
- package/dist/components/Slide/MobilePlayerSettingsSheet.cjs +1 -1
- package/dist/components/Slide/MobilePlayerSettingsSheet.cjs.map +1 -1
- package/dist/components/Slide/MobilePlayerSettingsSheet.d.ts +7 -2
- package/dist/components/Slide/MobilePlayerSettingsSheet.es.js +61 -57
- package/dist/components/Slide/MobilePlayerSettingsSheet.es.js.map +1 -1
- package/dist/components/Slide/Player.cjs +1 -1
- package/dist/components/Slide/Player.cjs.map +1 -1
- package/dist/components/Slide/Player.d.ts +6 -6
- package/dist/components/Slide/Player.es.js +547 -541
- package/dist/components/Slide/Player.es.js.map +1 -1
- package/dist/components/Slide/Slide.cjs +1 -1
- package/dist/components/Slide/Slide.cjs.map +1 -1
- package/dist/components/Slide/Slide.d.ts +14 -12
- package/dist/components/Slide/Slide.es.js +745 -726
- package/dist/components/Slide/Slide.es.js.map +1 -1
- package/dist/components/Slide/SubtitleOverlay.cjs +1 -1
- package/dist/components/Slide/SubtitleOverlay.cjs.map +1 -1
- package/dist/components/Slide/SubtitleOverlay.d.ts +2 -2
- package/dist/components/Slide/SubtitleOverlay.es.js +17 -17
- package/dist/components/Slide/SubtitleOverlay.es.js.map +1 -1
- package/dist/components/Slide/diff-utils.d.ts +1 -1
- package/dist/components/Slide/index.d.ts +12 -12
- package/dist/components/Slide/locales/slide.json.cjs +2 -0
- package/dist/components/Slide/locales/slide.json.cjs.map +1 -0
- package/dist/components/Slide/locales/slide.json.d.ts +205 -0
- package/dist/components/Slide/locales/slide.json.es.js +11 -0
- package/dist/components/Slide/locales/slide.json.es.js.map +1 -0
- package/dist/components/Slide/slideI18n.cjs +1 -1
- package/dist/components/Slide/slideI18n.cjs.map +1 -1
- package/dist/components/Slide/slideI18n.d.ts +6 -3
- package/dist/components/Slide/slideI18n.es.js +10 -155
- package/dist/components/Slide/slideI18n.es.js.map +1 -1
- package/dist/components/Slide/useSlide.d.ts +1 -1
- package/dist/components/Slide/utils/appendedMarkerAdvance.d.ts +1 -1
- package/dist/components/Slide/utils/audioSegments.d.ts +1 -1
- package/dist/components/Slide/utils/interactionResolution.d.ts +2 -2
- package/dist/components/Slide/utils/listenModeElementList.d.ts +2 -2
- package/dist/components/Slide/utils/markdownScaling.d.ts +1 -1
- package/dist/components/Slide/utils/playerCustomActions.d.ts +2 -2
- package/dist/components/Slide/utils/playerKeyboardShortcuts.cjs +1 -1
- package/dist/components/Slide/utils/playerKeyboardShortcuts.cjs.map +1 -1
- package/dist/components/Slide/utils/playerKeyboardShortcuts.d.ts +1 -1
- package/dist/components/Slide/utils/playerKeyboardShortcuts.es.js +20 -20
- package/dist/components/Slide/utils/playerKeyboardShortcuts.es.js.map +1 -1
- package/dist/components/Slide/utils/runStreamFixture.d.ts +1 -1
- package/dist/components/Slide/utils/segmentSeek.d.ts +1 -1
- package/dist/components/Slide/utils/silentStepAutoAdvance.d.ts +1 -1
- package/dist/components/Slide/utils/streamingNavigation.d.ts +1 -1
- package/dist/components/Slide/utils/subtitleCue.d.ts +1 -1
- package/dist/components/Slide/utils/subtitleJumpNavigation.d.ts +1 -1
- package/dist/components/index.d.ts +22 -18
- package/dist/components/ui/button.cjs +1 -1
- package/dist/components/ui/button.cjs.map +1 -1
- package/dist/components/ui/button.es.js +12 -13
- package/dist/components/ui/button.es.js.map +1 -1
- package/dist/components/ui/checkbox.cjs +1 -1
- package/dist/components/ui/checkbox.cjs.map +1 -1
- package/dist/components/ui/checkbox.es.js +35 -35
- package/dist/components/ui/checkbox.es.js.map +1 -1
- package/dist/components/ui/dialog.cjs +1 -1
- package/dist/components/ui/dialog.cjs.map +1 -1
- package/dist/components/ui/dialog.d.ts +5 -1
- package/dist/components/ui/dialog.es.js +37 -37
- package/dist/components/ui/dialog.es.js.map +1 -1
- package/dist/components/ui/input.cjs +1 -1
- package/dist/components/ui/input.cjs.map +1 -1
- package/dist/components/ui/input.es.js +4 -4
- package/dist/components/ui/input.es.js.map +1 -1
- package/dist/components/ui/inputGroup/button.cjs +1 -1
- package/dist/components/ui/inputGroup/button.cjs.map +1 -1
- package/dist/components/ui/inputGroup/button.es.js +9 -10
- package/dist/components/ui/inputGroup/button.es.js.map +1 -1
- package/dist/components/ui/inputGroup/input-group.cjs +1 -1
- package/dist/components/ui/inputGroup/input-group.cjs.map +1 -1
- package/dist/components/ui/inputGroup/input-group.d.ts +1 -1
- package/dist/components/ui/inputGroup/input-group.es.js +10 -10
- package/dist/components/ui/inputGroup/input-group.es.js.map +1 -1
- package/dist/components/ui/inputGroup/textarea.cjs +1 -1
- package/dist/components/ui/inputGroup/textarea.cjs.map +1 -1
- package/dist/components/ui/inputGroup/textarea.es.js +3 -3
- package/dist/components/ui/inputGroup/textarea.es.js.map +1 -1
- package/dist/components/ui/loading-overlay-card.cjs +2 -2
- package/dist/components/ui/loading-overlay-card.cjs.map +1 -1
- package/dist/components/ui/loading-overlay-card.es.js +11 -11
- package/dist/components/ui/loading-overlay-card.es.js.map +1 -1
- package/dist/components/ui/popover.cjs +1 -1
- package/dist/components/ui/popover.cjs.map +1 -1
- package/dist/components/ui/popover.es.js +6 -6
- package/dist/components/ui/popover.es.js.map +1 -1
- package/dist/components/ui/tooltip.cjs +1 -1
- package/dist/components/ui/tooltip.cjs.map +1 -1
- package/dist/components/ui/tooltip.es.js +16 -16
- package/dist/components/ui/tooltip.es.js.map +1 -1
- package/dist/editor.d.ts +2 -2
- package/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.es.js +22 -19
- package/dist/index.es.js.map +1 -1
- package/dist/lib/locale.cjs +1 -1
- package/dist/lib/locale.cjs.map +1 -1
- package/dist/lib/locale.d.ts +5 -1
- package/dist/lib/locale.es.js +26 -13
- package/dist/lib/locale.es.js.map +1 -1
- package/dist/lib/locale.test.d.ts +1 -0
- package/dist/lib/useDetachedLanguage.cjs +2 -0
- package/dist/lib/useDetachedLanguage.cjs.map +1 -0
- package/dist/lib/useDetachedLanguage.d.ts +3 -0
- package/dist/lib/useDetachedLanguage.es.js +25 -0
- package/dist/lib/useDetachedLanguage.es.js.map +1 -0
- package/dist/lib/useResolvedDirection.cjs +2 -0
- package/dist/lib/useResolvedDirection.cjs.map +1 -0
- package/dist/lib/useResolvedDirection.d.ts +6 -0
- package/dist/lib/useResolvedDirection.es.js +37 -0
- package/dist/lib/useResolvedDirection.es.js.map +1 -0
- package/dist/markdown-flow-ui-lib.css +1 -1
- package/dist/node_modules/@radix-ui/react-arrow/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-arrow/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-arrow/dist/index.es.js +6 -6
- package/dist/node_modules/@radix-ui/react-arrow/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-context/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-context/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-context/dist/index.es.js +21 -21
- package/dist/node_modules/@radix-ui/react-context/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-dialog/dist/index.cjs +2 -2
- package/dist/node_modules/@radix-ui/react-dialog/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-dialog/dist/index.es.js +100 -100
- package/dist/node_modules/@radix-ui/react-dialog/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-dismissable-layer/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-dismissable-layer/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-dismissable-layer/dist/index.es.js +38 -38
- package/dist/node_modules/@radix-ui/react-dismissable-layer/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-focus-scope/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-focus-scope/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-focus-scope/dist/index.es.js +9 -9
- package/dist/node_modules/@radix-ui/react-focus-scope/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-popover/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-popover/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-popover/dist/index.es.js +95 -95
- package/dist/node_modules/@radix-ui/react-popover/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-popper/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-popper/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-popper/dist/index.es.js +48 -48
- package/dist/node_modules/@radix-ui/react-popper/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-portal/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-portal/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-portal/dist/index.es.js +6 -6
- package/dist/node_modules/@radix-ui/react-portal/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-primitive/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-primitive/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-primitive/dist/index.es.js +9 -9
- package/dist/node_modules/@radix-ui/react-primitive/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-slot/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-slot/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-slot/dist/index.es.js +17 -17
- package/dist/node_modules/@radix-ui/react-slot/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-tooltip/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-tooltip/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-tooltip/dist/index.es.js +100 -100
- package/dist/node_modules/@radix-ui/react-tooltip/dist/index.es.js.map +1 -1
- package/dist/node_modules/@radix-ui/react-visually-hidden/dist/index.cjs +1 -1
- package/dist/node_modules/@radix-ui/react-visually-hidden/dist/index.cjs.map +1 -1
- package/dist/node_modules/@radix-ui/react-visually-hidden/dist/index.es.js +6 -6
- package/dist/node_modules/@radix-ui/react-visually-hidden/dist/index.es.js.map +1 -1
- package/dist/node_modules/@uiw/react-codemirror/esm/index.cjs +1 -1
- package/dist/node_modules/@uiw/react-codemirror/esm/index.cjs.map +1 -1
- package/dist/node_modules/@uiw/react-codemirror/esm/index.es.js +27 -27
- package/dist/node_modules/@uiw/react-codemirror/esm/index.es.js.map +1 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/{chevron-down.cjs → chevrons-down.cjs} +2 -2
- package/dist/node_modules/lucide-react/dist/esm/icons/chevrons-down.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/{chevron-down.es.js → chevrons-down.es.js} +6 -3
- package/dist/node_modules/lucide-react/dist/esm/icons/chevrons-down.es.js.map +1 -0
- package/dist/node_modules/rc-input/es/BaseInput.cjs +1 -1
- package/dist/node_modules/rc-input/es/BaseInput.es.js +1 -1
- package/dist/node_modules/rc-textarea/es/ResizableTextArea.cjs +1 -1
- package/dist/node_modules/rc-textarea/es/ResizableTextArea.es.js +1 -1
- package/dist/node_modules/rc-textarea/es/TextArea.cjs +1 -1
- package/dist/node_modules/rc-textarea/es/TextArea.es.js +1 -1
- package/dist/node_modules/rc-textarea/es/index.cjs +1 -1
- package/dist/node_modules/rc-textarea/es/index.es.js +1 -1
- package/dist/node_modules/react-markdown/lib/index.cjs +1 -1
- package/dist/node_modules/react-markdown/lib/index.cjs.map +1 -1
- package/dist/node_modules/react-markdown/lib/index.es.js +39 -39
- package/dist/node_modules/react-markdown/lib/index.es.js.map +1 -1
- package/dist/node_modules/remark-flow/dist/interaction-plugin-core.cjs +1 -1
- package/dist/node_modules/remark-flow/dist/interaction-plugin-core.es.js +1 -1
- package/dist/renderer.cjs +1 -1
- package/dist/renderer.d.ts +18 -17
- package/dist/renderer.es.js +20 -17
- package/dist/renderer.es.js.map +1 -1
- package/dist/scroll.cjs +2 -0
- package/dist/scroll.cjs.map +1 -0
- package/dist/scroll.d.ts +6 -0
- package/dist/scroll.es.js +9 -0
- package/dist/scroll.es.js.map +1 -0
- package/dist/slide.d.ts +3 -3
- package/package.json +13 -2
- package/dist/_virtual/jsx-runtime.cjs +0 -2
- package/dist/_virtual/jsx-runtime.cjs.map +0 -1
- package/dist/_virtual/jsx-runtime.es.js +0 -6
- package/dist/_virtual/jsx-runtime.es.js.map +0 -1
- package/dist/_virtual/jsx-runtime.es2.js +0 -5
- package/dist/_virtual/jsx-runtime.es2.js.map +0 -1
- package/dist/_virtual/jsx-runtime2.cjs +0 -2
- package/dist/_virtual/jsx-runtime2.cjs.map +0 -1
- package/dist/_virtual/react-jsx-runtime.development.cjs +0 -2
- package/dist/_virtual/react-jsx-runtime.development.cjs.map +0 -1
- package/dist/_virtual/react-jsx-runtime.development.es.js +0 -5
- package/dist/_virtual/react-jsx-runtime.development.es.js.map +0 -1
- package/dist/_virtual/react-jsx-runtime.production.cjs +0 -2
- package/dist/_virtual/react-jsx-runtime.production.cjs.map +0 -1
- package/dist/_virtual/react-jsx-runtime.production.es.js +0 -5
- package/dist/_virtual/react-jsx-runtime.production.es.js.map +0 -1
- package/dist/lib/localeTextMap.cjs +0 -2
- package/dist/lib/localeTextMap.cjs.map +0 -1
- package/dist/lib/localeTextMap.es.js +0 -5
- package/dist/lib/localeTextMap.es.js.map +0 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/chevron-down.cjs.map +0 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/chevron-down.es.js.map +0 -1
- package/dist/node_modules/react/cjs/react-jsx-runtime.development.cjs +0 -24
- package/dist/node_modules/react/cjs/react-jsx-runtime.development.cjs.map +0 -1
- package/dist/node_modules/react/cjs/react-jsx-runtime.development.es.js +0 -409
- package/dist/node_modules/react/cjs/react-jsx-runtime.development.es.js.map +0 -1
- package/dist/node_modules/react/cjs/react-jsx-runtime.production.cjs +0 -10
- package/dist/node_modules/react/cjs/react-jsx-runtime.production.cjs.map +0 -1
- package/dist/node_modules/react/cjs/react-jsx-runtime.production.es.js +0 -36
- package/dist/node_modules/react/cjs/react-jsx-runtime.production.es.js.map +0 -1
- package/dist/node_modules/react/jsx-runtime.cjs +0 -2
- package/dist/node_modules/react/jsx-runtime.cjs.map +0 -1
- package/dist/node_modules/react/jsx-runtime.es.js +0 -11
- package/dist/node_modules/react/jsx-runtime.es.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxApp.cjs","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport type { MarkdownFlowLocale } from \"../../lib/locale\";\nimport { getContentRenderLocaleTexts } from \"./contentRenderI18n\";\nimport type { ScalingWindow } from \"./utils/iframe-scaling\";\nimport {\n isAnchorElement,\n mergeAnchorRelValue,\n resolveClosestAnchor,\n shouldForceAnchorHrefToNewTab,\n} from \"./utils/link-targets\";\n\nexport interface SandboxAppProps {\n html: string;\n locale?: MarkdownFlowLocale;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n hasRootVhHeight?: boolean;\n stretchRootHeight?: boolean;\n enableScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nconst IMAGE_REUSE_ATTRIBUTES = [\n \"src\",\n \"srcset\",\n \"sizes\",\n \"alt\",\n \"class\",\n \"width\",\n \"height\",\n \"style\",\n \"loading\",\n \"decoding\",\n \"crossorigin\",\n \"referrerpolicy\",\n \"fetchpriority\",\n];\n\nconst getImageReuseKey = (image: HTMLImageElement) =>\n IMAGE_REUSE_ATTRIBUTES.map(\n (attribute) => `${attribute}:${image.getAttribute(attribute) || \"\"}`\n ).join(\"|\");\n\nconst collectReusableImages = (root: ParentNode) => {\n const imageMap = new Map<string, HTMLImageElement[]>();\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n const key = getImageReuseKey(image);\n const bucket = imageMap.get(key) || [];\n bucket.push(image);\n imageMap.set(key, bucket);\n });\n return imageMap;\n};\n\nconst syncImageAttributes = (\n sourceImage: HTMLImageElement,\n targetImage: HTMLImageElement\n) => {\n const sourceAttributes = Array.from(sourceImage.attributes);\n const sourceAttributeNames = new Set(\n sourceAttributes.map((attribute) => attribute.name)\n );\n\n Array.from(targetImage.attributes).forEach((attribute) => {\n if (!sourceAttributeNames.has(attribute.name)) {\n targetImage.removeAttribute(attribute.name);\n }\n });\n\n sourceAttributes.forEach((attribute) => {\n targetImage.setAttribute(attribute.name, attribute.value);\n });\n};\n\nconst reuseRenderedImages = (\n root: ParentNode,\n imageMap: Map<string, HTMLImageElement[]>\n) => {\n if (!imageMap.size) return;\n\n root.querySelectorAll(\"img\").forEach((node) => {\n const nextImage = node as HTMLImageElement;\n const key = getImageReuseKey(nextImage);\n const bucket = imageMap.get(key);\n const preservedImage = bucket?.shift();\n if (!preservedImage) return;\n\n syncImageAttributes(nextImage, preservedImage);\n nextImage.replaceWith(preservedImage);\n\n if (bucket && bucket.length === 0) {\n imageMap.delete(key);\n }\n });\n};\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n locale,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n hasRootVhHeight = false,\n stretchRootHeight = false,\n enableScaling = false,\n disableLoadingOverlay = false,\n}) => {\n const localeTexts = getContentRenderLocaleTexts(locale);\n const containerRef = useRef<HTMLDivElement>(null);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const [hasRenderedContent, setHasRenderedContent] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n .sandbox-wrapper { align-items: center; }\n .sandbox-container { position: relative; width: 100%; }\n .sandbox-container svg,\n .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }\n /* Hide scroll UI without removing scroll semantics. Content roots with\n inline style=\"height:100vh; overflow-y:auto\" are the signal that\n IframeSandbox.getInnerScrollableHeight relies on to grow the iframe\n when content exceeds the viewport. We must not change overflow-y,\n but sub-pixel rounding (1px below the +1 detection threshold) can\n still surface a phantom scrollbar on content that visually fits.\n Hide the scrollbar UI globally; when content truly overflows the\n iframe is resized and no scrollbar would render anyway. */\n .sandbox-container *::-webkit-scrollbar { display: none; }\n .sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }\n .justify-\\\\[safe_center\\\\]{\n justify-content: safe center;\n }\n .overflow-y-auto { overflow-y: visible !important; }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n setHasRenderedContent(false);\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n const reusableImages = collectReusableImages(container);\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n const wrapper = doc.createElement(\"div\");\n wrapper.innerHTML = html;\n wrapper.querySelectorAll(\"a[href]\").forEach((node) => {\n if (!isAnchorElement(node)) {\n return;\n }\n\n if (!shouldForceAnchorHrefToNewTab(node.getAttribute(\"href\"))) {\n return;\n }\n\n node.setAttribute(\"target\", \"_blank\");\n node.setAttribute(\"rel\", mergeAnchorRelValue(node.getAttribute(\"rel\")));\n });\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n reuseRenderedImages(wrapper, reusableImages);\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n const hasInitialContent = contentNodes.length > 0;\n setHasRenderedContent(hasInitialContent);\n container.replaceChildren(...contentNodes);\n\n const handleLinkClick = (event: MouseEvent) => {\n const anchor = resolveClosestAnchor(event.target);\n if (!anchor) {\n return;\n }\n\n if (!shouldForceAnchorHrefToNewTab(anchor.getAttribute(\"href\"))) {\n return;\n }\n\n anchor.setAttribute(\"target\", \"_blank\");\n anchor.setAttribute(\n \"rel\",\n mergeAnchorRelValue(anchor.getAttribute(\"rel\"))\n );\n };\n container.addEventListener(\"click\", handleLinkClick, true);\n\n let scriptContentObserver: MutationObserver | null = null;\n const markRenderedContentFromContainer = () => {\n if (container.childNodes.length === 0) {\n return false;\n }\n\n setHasRenderedContent(true);\n scriptContentObserver?.disconnect();\n scriptContentObserver = null;\n return true;\n };\n if (!hasInitialContent && hasScripts && shouldExecuteScripts) {\n scriptContentObserver = new MutationObserver(() => {\n markRenderedContentFromContainer();\n });\n scriptContentObserver.observe(container, {\n childList: true,\n subtree: true,\n });\n }\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n markRenderedContentFromContainer();\n if (enableScaling) {\n const win = container.ownerDocument?.defaultView as ScalingWindow | null;\n win?.__mdf_triggerFitContent?.();\n }\n\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n\n return () => {\n scriptContentObserver?.disconnect();\n container.removeEventListener(\"click\", handleLinkClick, true);\n };\n }, [html, resetToken, enableScaling]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n }, [disableLoadingOverlay]);\n\n const overlayMessage = (() => {\n if (disableLoadingOverlay) {\n return null;\n }\n\n if (isGeneratingScripts || hasScriptsRef.current)\n return (\n scriptLoadingText || loadingText || localeTexts.sandboxScriptLoadingText\n );\n if (isGeneratingStyles || hasStylesRef.current)\n return (\n styleLoadingText || loadingText || localeTexts.sandboxStyleLoadingText\n );\n if (!hasRenderedContent)\n return loadingText || localeTexts.sandboxLoadingText;\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n const shouldStretchRootHeight = isBlackboard && stretchRootHeight;\n const sandboxWrapperStyle: React.CSSProperties = {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n // Keep blackboard scroll behavior while centering content in non-blackboard mode\n justifyContent: shouldStretchRootHeight\n ? \"flex-start\"\n : isBlackboard\n ? \"space-around\"\n : \"flex-start\",\n };\n const sandboxContainerStyle: React.CSSProperties = {\n pointerEvents: overlayMessage ? \"none\" : undefined,\n margin: isBlackboard ? undefined : \"auto 0\",\n width: \"100%\",\n height: shouldStretchRootHeight ? \"100%\" : undefined,\n minHeight: shouldStretchRootHeight ? 0 : undefined,\n flex: shouldStretchRootHeight ? \"1 1 auto\" : undefined,\n };\n\n return (\n <div\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className=\"sandbox-wrapper\"\n style={sandboxWrapperStyle}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n className=\"sandbox-container\"\n style={sandboxContainerStyle}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 20,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n }}\n >\n <LoadingOverlayCard message={overlayMessage} />\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["IMAGE_REUSE_ATTRIBUTES","getImageReuseKey","image","attribute","collectReusableImages","root","imageMap","node","key","bucket","syncImageAttributes","sourceImage","targetImage","sourceAttributes","sourceAttributeNames","reuseRenderedImages","nextImage","preservedImage","SandboxApp","html","locale","loadingText","styleLoadingText","scriptLoadingText","resetToken","mode","hasRootVhHeight","stretchRootHeight","enableScaling","disableLoadingOverlay","localeTexts","getContentRenderLocaleTexts","containerRef","useRef","isGeneratingStyles","setIsGeneratingStyles","useState","isGeneratingScripts","setIsGeneratingScripts","hasRenderedContent","setHasRenderedContent","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","reusableImages","wrapper","isAnchorElement","shouldForceAnchorHrefToNewTab","mergeAnchorRelValue","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","contentNodes","hasInitialContent","handleLinkClick","event","anchor","resolveClosestAnchor","scriptContentObserver","markRenderedContentFromContainer","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","jsx","LoadingOverlayCard"],"mappings":"0SA0BMA,GAAyB,CAC7B,MACA,SACA,QACA,MACA,QACA,QACA,SACA,QACA,UACA,WACA,cACA,iBACA,eACF,EAEMC,EAAoBC,GACxBF,GAAuB,IACpBG,GAAc,GAAGA,CAAS,IAAID,EAAM,aAAaC,CAAS,GAAK,EAAE,EACpE,EAAE,KAAK,GAAG,EAENC,GAAyBC,GAAqB,CAClD,MAAMC,MAAe,IACrB,OAAAD,EAAK,iBAAiB,KAAK,EAAE,QAASE,GAAS,CAC7C,MAAML,EAAQK,EACRC,EAAMP,EAAiBC,CAAK,EAC5BO,EAASH,EAAS,IAAIE,CAAG,GAAK,CAAA,EACpCC,EAAO,KAAKP,CAAK,EACjBI,EAAS,IAAIE,EAAKC,CAAM,CAC1B,CAAC,EACMH,CACT,EAEMI,GAAsB,CAC1BC,EACAC,IACG,CACH,MAAMC,EAAmB,MAAM,KAAKF,EAAY,UAAU,EACpDG,EAAuB,IAAI,IAC/BD,EAAiB,IAAKV,GAAcA,EAAU,IAAI,CAAA,EAGpD,MAAM,KAAKS,EAAY,UAAU,EAAE,QAAST,GAAc,CACnDW,EAAqB,IAAIX,EAAU,IAAI,GAC1CS,EAAY,gBAAgBT,EAAU,IAAI,CAE9C,CAAC,EAEDU,EAAiB,QAASV,GAAc,CACtCS,EAAY,aAAaT,EAAU,KAAMA,EAAU,KAAK,CAC1D,CAAC,CACH,EAEMY,GAAsB,CAC1BV,EACAC,IACG,CACEA,EAAS,MAEdD,EAAK,iBAAiB,KAAK,EAAE,QAASE,GAAS,CAC7C,MAAMS,EAAYT,EACZC,EAAMP,EAAiBe,CAAS,EAChCP,EAASH,EAAS,IAAIE,CAAG,EACzBS,EAAiBR,GAAQ,MAAA,EAC1BQ,IAELP,GAAoBM,EAAWC,CAAc,EAC7CD,EAAU,YAAYC,CAAc,EAEhCR,GAAUA,EAAO,SAAW,GAC9BH,EAAS,OAAOE,CAAG,EAEvB,CAAC,CACH,EAEMU,GAAwC,CAAC,CAC7C,KAAAC,EACA,OAAAC,EACA,YAAAC,EACA,iBAAAC,EACA,kBAAAC,EACA,WAAAC,EAAa,EACb,KAAAC,EAAO,UACP,gBAAAC,EAAkB,GAClB,kBAAAC,EAAoB,GACpB,cAAAC,EAAgB,GAChB,sBAAAC,EAAwB,EAC1B,IAAM,CACJ,MAAMC,EAAcC,GAAAA,4BAA4BX,CAAM,EAChDY,EAAeC,EAAAA,OAAuB,IAAI,EAC1C,CAACC,EAAoBC,CAAqB,EAAIC,EAAAA,SAAS,EAAK,EAC5D,CAACC,EAAqBC,CAAsB,EAAIF,EAAAA,SAAS,EAAK,EAC9D,CAACG,GAAoBC,CAAqB,EAAIJ,EAAAA,SAAS,EAAK,EAC5DK,EAAoBR,EAAAA,OAA2B,EAAE,EACjDS,EAAqBT,EAAAA,OAA4B,EAAE,EACnDU,EAAgBV,EAAAA,OAAO,CAAC,EACxBW,EAAiBX,EAAAA,OAAO,CAAC,EACzBY,EAAgBZ,EAAAA,OAAsB,IAAI,EAC1Ca,EAAiBb,EAAAA,OAAsB,IAAI,EAC3Cc,EAAed,EAAAA,OAAO,EAAK,EAC3Be,EAAgBf,EAAAA,OAAO,EAAK,EAC5BgB,EAAoBhB,EAAAA,OAAOT,CAAU,EACrC0B,GAAiB,IAEjBC,EAAcC,GAAoD,CAClEA,EAAS,UACX,aAAaA,EAAS,OAAO,EAC7BA,EAAS,QAAU,KAEvB,EAEMC,EAA8B,CAClCC,EACAF,EACAG,EACAC,IACG,CACH,MAAMC,EAAU,YAAY,IAAA,EAAQF,EAAS,QACvCG,EAAQ,KAAK,IAAI,EAAGR,GAAiBO,CAAO,EAClDN,EAAWC,CAAQ,EACnBA,EAAS,QAAU,OAAO,WAAW,IAAM,CACzCE,EAAO,EAAK,EACZE,IAAA,EACAJ,EAAS,QAAU,IACrB,EAAGM,CAAK,CACV,EAEAC,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAM5B,EAAa,SAAS,cAClC,GAAI,CAAC4B,EAAK,OACV,MAAMC,EAAU,wBAChB,IAAIC,EAAUF,EAAI,eAAeC,CAAO,EACnCC,IACHA,EAAUF,EAAI,cAAc,OAAO,EACnCE,EAAQ,GAAKD,EACbD,EAAI,MAAM,YAAYE,CAAO,GAE/BA,EAAQ,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAoBxB,EAAG,CAAA,CAAE,EAELH,EAAAA,UAAU,IAAM,CACVnC,IAAeyB,EAAkB,UACnCT,EAAsB,EAAK,EAC3BS,EAAkB,QAAUzB,GAE9B2B,EAAWN,CAAa,EACxBM,EAAWL,CAAc,EACzBC,EAAa,QAAU,GACvBC,EAAc,QAAU,GAExB,MAAMe,EAAY/B,EAAa,QAC/B,GAAI,CAAC+B,EAAW,OAChB,MAAMH,EAAMG,EAAU,cAChBC,EAAOJ,GAAK,KAClB,GAAI,CAACI,EAAM,OACX,MAAMC,EAAiB7D,GAAsB2D,CAAS,EAEtDtB,EAAkB,QAAQ,QAASlC,GAASA,EAAK,QAAQ,EACzDkC,EAAkB,QAAU,CAAA,EAC5BC,EAAmB,QAAQ,QAASnC,GAASA,EAAK,QAAQ,EAC1DmC,EAAmB,QAAU,CAAA,EAE7BP,EAAsB,EAAK,EAC3BG,EAAuB,EAAK,EAC5B,MAAM4B,EAAUN,EAAI,cAAc,KAAK,EACvCM,EAAQ,UAAY/C,EACpB+C,EAAQ,iBAAiB,SAAS,EAAE,QAAS3D,GAAS,CAC/C4D,EAAAA,gBAAgB5D,CAAI,GAIpB6D,EAAAA,8BAA8B7D,EAAK,aAAa,MAAM,CAAC,IAI5DA,EAAK,aAAa,SAAU,QAAQ,EACpCA,EAAK,aAAa,MAAO8D,EAAAA,oBAAoB9D,EAAK,aAAa,KAAK,CAAC,CAAC,EACxE,CAAC,EAED,MAAM+D,GAAmBnD,EAAK,MAAM,gBAAgB,GAAK,CAAA,GAAI,OACvDoD,IAAoBpD,EAAK,MAAM,cAAc,GAAK,CAAA,GAAI,OACtDqD,EACJF,EAAkB,GAAKA,IAAoBC,GAEvCE,EAA+B,CAAA,EAErC,MAAM,KAAKP,EAAQ,iBAAiB,eAAe,CAAC,EAAE,QAAS3D,GAAS,CACtE,GAAIA,EAAK,QAAQ,YAAA,IAAkB,QAAS,CAC1C,MAAMmE,EAASd,EAAI,cAAc,OAAO,EACxCc,EAAO,YAAcnE,EAAK,aAAe,GACzC,MAAM,KAAKA,EAAK,UAAU,EAAE,QAASoE,GAAS,CAC5CD,EAAO,aAAaC,EAAK,KAAMA,EAAK,KAAK,CAC3C,CAAC,EACDF,EAAc,KAAKC,CAAM,CAC3B,KAAO,CACL,MAAME,EAAchB,EAAI,cAAc,QAAQ,EAC9C,MAAM,KAAKrD,EAAK,UAAU,EAAE,QAASoE,GAAS,CAC5CC,EAAY,aAAaD,EAAK,KAAMA,EAAK,KAAK,CAChD,CAAC,EACDC,EAAY,YAAcrE,EAAK,aAAe,GAC9CkE,EAAc,KAAKG,CAAW,CAChC,CACArE,EAAK,OAAA,CACP,CAAC,EACDQ,GAAoBmD,EAASD,CAAc,EAE3C,MAAMY,EAAYJ,EAAc,KAC7BlE,GAASA,EAAK,QAAQ,gBAAkB,OAAA,EAErCuE,EAAaL,EAAc,KAC9BlE,GAASA,EAAK,QAAQ,gBAAkB,QAAA,EAEvCsE,IACF9B,EAAa,QAAU,GACvBJ,EAAc,QAAU,YAAY,IAAA,EACpCQ,EAAWN,CAAa,EACxBV,EAAsB,EAAI,GAExB2C,IACF9B,EAAc,QAAU,GACxBJ,EAAe,QAAU,YAAY,IAAA,EACrCO,EAAWL,CAAc,EACzBR,EAAuB,EAAI,GAG7B,MAAMyC,EAAe,MAAM,KAAKb,EAAQ,UAAU,EAC5Cc,EAAoBD,EAAa,OAAS,EAChDvC,EAAsBwC,CAAiB,EACvCjB,EAAU,gBAAgB,GAAGgB,CAAY,EAEzC,MAAME,EAAmBC,GAAsB,CAC7C,MAAMC,EAASC,EAAAA,qBAAqBF,EAAM,MAAM,EAC3CC,GAIAf,EAAAA,8BAA8Be,EAAO,aAAa,MAAM,CAAC,IAI9DA,EAAO,aAAa,SAAU,QAAQ,EACtCA,EAAO,aACL,MACAd,sBAAoBc,EAAO,aAAa,KAAK,CAAC,CAAA,EAElD,EACApB,EAAU,iBAAiB,QAASkB,EAAiB,EAAI,EAEzD,IAAII,EAAiD,KACrD,MAAMC,EAAmC,IACnCvB,EAAU,WAAW,SAAW,EAC3B,IAGTvB,EAAsB,EAAI,EAC1B6C,GAAuB,WAAA,EACvBA,EAAwB,KACjB,IAET,MAAI,CAACL,GAAqBF,GAAcN,IACtCa,EAAwB,IAAI,iBAAiB,IAAM,CACjDC,EAAA,CACF,CAAC,EACDD,EAAsB,QAAQtB,EAAW,CACvC,UAAW,GACX,QAAS,EAAA,CACV,GAGHU,EAAc,QAASlE,GAAS,CAC9B,GAAIA,EAAK,QAAQ,YAAA,IAAkB,QAAS,CAC1CqD,EAAI,MAAM,YAAYrD,CAAI,EAC1BkC,EAAkB,QAAQ,KAAKlC,CAAwB,EACvD,MACF,CAEA,GAAIiE,EAAsB,CACxB,MAAMe,EAAahF,EACbiF,EAAaD,EAAW,aAAe,GAG7C,GAFuB,CAACA,EAAW,IAGjC,GAAI,CAGF,IAAI,SAASC,CAAU,CACzB,MAAQ,CACND,EAAW,OAAA,EACX,MACF,CAGF,GAAI,CACFvB,EAAK,YAAYuB,CAAU,EAC3B7C,EAAmB,QAAQ,KAAK6C,CAAU,CAC5C,MAAQ,CACNA,EAAW,OAAA,CACb,CACF,MAEEhF,EAAK,OAAA,CAET,CAAC,EACD+E,EAAA,EACI1D,GACUmC,EAAU,eAAe,aAChC,0BAAA,EAGP,sBAAsB,IAAM,CACtBc,GACFxB,EACElB,EACAU,EACAF,EACA,IAAM,CACJI,EAAa,QAAU,EACzB,CAAA,EAGA+B,GACFzB,EACEf,EACAQ,EACAF,EACA,IAAM,CACJI,EAAc,QAAU,EAC1B,CAAA,CAGN,CAAC,EAEM,IAAM,CACXqC,GAAuB,WAAA,EACvBtB,EAAU,oBAAoB,QAASkB,EAAiB,EAAI,CAC9D,CACF,EAAG,CAAC9D,EAAMK,EAAYI,CAAa,CAAC,EAEpC+B,EAAAA,UACE,IAAM,IAAM,CACVR,EAAWN,CAAa,EACxBM,EAAWL,CAAc,CAC3B,EACA,CAAA,CAAC,EAGHa,EAAAA,UAAU,IAAM,CACT9B,IAILsB,EAAWN,CAAa,EACxBM,EAAWL,CAAc,EACzBC,EAAa,QAAU,GACvBC,EAAc,QAAU,GACxBb,EAAsB,EAAK,EAC3BG,EAAuB,EAAK,EAC9B,EAAG,CAACT,CAAqB,CAAC,EAE1B,MAAM4D,EACA5D,EACK,KAGLQ,GAAuBW,EAAc,QAErCzB,GAAqBF,GAAeS,EAAY,yBAEhDI,GAAsBa,EAAa,QAEnCzB,GAAoBD,GAAeS,EAAY,wBAE9CS,GAEE,KADElB,GAAeS,EAAY,mBAIhC4D,EAAejE,IAAS,aACxBkE,EAA0BD,GAAgB/D,EAC1CiE,GAA2C,CAC/C,SAAU,WACV,MAAO,OACP,OAAQ,OACR,QAAS,OACT,cAAe,SAEf,eAAgBD,EACZ,aACAD,EACE,eACA,YAAA,EAEFG,GAA6C,CACjD,cAAeJ,EAAiB,OAAS,OACzC,OAAQC,EAAe,OAAY,SACnC,MAAO,OACP,OAAQC,EAA0B,OAAS,OAC3C,UAAWA,EAA0B,EAAI,OACzC,KAAMA,EAA0B,WAAa,MAAA,EAG/C,OACEG,EAAAA,kBAAAA,KAAC,MAAA,CACC,eAAcpE,EAAkB,OAAS,QACzC,UAAU,kBACV,MAAOkE,GACP,YAAW,CAAC,CAACH,EAEb,SAAA,CAAAM,EAAAA,kBAAAA,IAAC,MAAA,CACC,IAAK/D,EACL,UAAU,oBACV,MAAO6D,EAAA,CAAA,EAERJ,GACCM,EAAAA,kBAAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,MAAO,EACP,OAAQ,GACR,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,cAAe,MAAA,EAGjB,SAAAA,EAAAA,kBAAAA,IAACC,GAAAA,QAAA,CAAmB,QAASP,CAAA,CAAgB,CAAA,CAAA,CAC/C,CAAA,CAAA,CAIR"}
|
|
1
|
+
{"version":3,"file":"SandboxApp.cjs","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport {\n getMarkdownFlowDirection,\n getMarkdownFlowLanguage,\n type MarkdownFlowLocale,\n} from \"../../lib/locale\";\nimport { getContentRenderLocaleTexts } from \"./contentRenderI18n\";\nimport type { ScalingWindow } from \"./utils/iframe-scaling\";\nimport {\n isAnchorElement,\n mergeAnchorRelValue,\n resolveClosestAnchor,\n shouldForceAnchorHrefToNewTab,\n} from \"./utils/link-targets\";\n\nexport interface SandboxAppProps {\n html: string;\n locale?: MarkdownFlowLocale;\n /** Overrides the wrapper language without changing authored HTML language. */\n lang?: string;\n /** Overrides the wrapper direction while preserving explicit direction in authored HTML. */\n dir?: React.HTMLAttributes<HTMLDivElement>[\"dir\"];\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n hasRootVhHeight?: boolean;\n stretchRootHeight?: boolean;\n enableScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nconst IMAGE_REUSE_ATTRIBUTES = [\n \"src\",\n \"srcset\",\n \"sizes\",\n \"alt\",\n \"class\",\n \"width\",\n \"height\",\n \"style\",\n \"loading\",\n \"decoding\",\n \"crossorigin\",\n \"referrerpolicy\",\n \"fetchpriority\",\n];\n\nconst getImageReuseKey = (image: HTMLImageElement) =>\n IMAGE_REUSE_ATTRIBUTES.map(\n (attribute) => `${attribute}:${image.getAttribute(attribute) || \"\"}`\n ).join(\"|\");\n\nconst collectReusableImages = (root: ParentNode) => {\n const imageMap = new Map<string, HTMLImageElement[]>();\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n const key = getImageReuseKey(image);\n const bucket = imageMap.get(key) || [];\n bucket.push(image);\n imageMap.set(key, bucket);\n });\n return imageMap;\n};\n\nconst syncImageAttributes = (\n sourceImage: HTMLImageElement,\n targetImage: HTMLImageElement\n) => {\n const sourceAttributes = Array.from(sourceImage.attributes);\n const sourceAttributeNames = new Set(\n sourceAttributes.map((attribute) => attribute.name)\n );\n\n Array.from(targetImage.attributes).forEach((attribute) => {\n if (!sourceAttributeNames.has(attribute.name)) {\n targetImage.removeAttribute(attribute.name);\n }\n });\n\n sourceAttributes.forEach((attribute) => {\n targetImage.setAttribute(attribute.name, attribute.value);\n });\n};\n\nconst reuseRenderedImages = (\n root: ParentNode,\n imageMap: Map<string, HTMLImageElement[]>\n) => {\n if (!imageMap.size) return;\n\n root.querySelectorAll(\"img\").forEach((node) => {\n const nextImage = node as HTMLImageElement;\n const key = getImageReuseKey(nextImage);\n const bucket = imageMap.get(key);\n const preservedImage = bucket?.shift();\n if (!preservedImage) return;\n\n syncImageAttributes(nextImage, preservedImage);\n nextImage.replaceWith(preservedImage);\n\n if (bucket && bucket.length === 0) {\n imageMap.delete(key);\n }\n });\n};\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n locale,\n dir,\n lang,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n hasRootVhHeight = false,\n stretchRootHeight = false,\n enableScaling = false,\n disableLoadingOverlay = false,\n}) => {\n const localeTexts = getContentRenderLocaleTexts(locale);\n const containerRef = useRef<HTMLDivElement>(null);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const [hasRenderedContent, setHasRenderedContent] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n .sandbox-wrapper { align-items: center; }\n .sandbox-container { position: relative; width: 100%; }\n .sandbox-container svg,\n .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }\n /* Hide scroll UI without removing scroll semantics. Content roots with\n inline style=\"height:100vh; overflow-y:auto\" are the signal that\n IframeSandbox.getInnerScrollableHeight relies on to grow the iframe\n when content exceeds the viewport. We must not change overflow-y,\n but sub-pixel rounding (1px below the +1 detection threshold) can\n still surface a phantom scrollbar on content that visually fits.\n Hide the scrollbar UI globally; when content truly overflows the\n iframe is resized and no scrollbar would render anyway. */\n .sandbox-container *::-webkit-scrollbar { display: none; }\n .sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }\n .justify-\\\\[safe_center\\\\]{\n justify-content: safe center;\n }\n .overflow-y-auto { overflow-y: visible !important; }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n setHasRenderedContent(false);\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n const reusableImages = collectReusableImages(container);\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n const wrapper = doc.createElement(\"div\");\n wrapper.innerHTML = html;\n wrapper.querySelectorAll(\"a[href]\").forEach((node) => {\n if (!isAnchorElement(node)) {\n return;\n }\n\n if (!shouldForceAnchorHrefToNewTab(node.getAttribute(\"href\"))) {\n return;\n }\n\n node.setAttribute(\"target\", \"_blank\");\n node.setAttribute(\"rel\", mergeAnchorRelValue(node.getAttribute(\"rel\")));\n });\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n reuseRenderedImages(wrapper, reusableImages);\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n const hasInitialContent = contentNodes.length > 0;\n setHasRenderedContent(hasInitialContent);\n container.replaceChildren(...contentNodes);\n\n const handleLinkClick = (event: MouseEvent) => {\n const anchor = resolveClosestAnchor(event.target);\n if (!anchor) {\n return;\n }\n\n if (!shouldForceAnchorHrefToNewTab(anchor.getAttribute(\"href\"))) {\n return;\n }\n\n anchor.setAttribute(\"target\", \"_blank\");\n anchor.setAttribute(\n \"rel\",\n mergeAnchorRelValue(anchor.getAttribute(\"rel\"))\n );\n };\n container.addEventListener(\"click\", handleLinkClick, true);\n\n let scriptContentObserver: MutationObserver | null = null;\n const markRenderedContentFromContainer = () => {\n if (container.childNodes.length === 0) {\n return false;\n }\n\n setHasRenderedContent(true);\n scriptContentObserver?.disconnect();\n scriptContentObserver = null;\n return true;\n };\n if (!hasInitialContent && hasScripts && shouldExecuteScripts) {\n scriptContentObserver = new MutationObserver(() => {\n markRenderedContentFromContainer();\n });\n scriptContentObserver.observe(container, {\n childList: true,\n subtree: true,\n });\n }\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n markRenderedContentFromContainer();\n if (enableScaling) {\n const win = container.ownerDocument?.defaultView as ScalingWindow | null;\n win?.__mdf_triggerFitContent?.();\n }\n\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n\n return () => {\n scriptContentObserver?.disconnect();\n container.removeEventListener(\"click\", handleLinkClick, true);\n };\n }, [html, resetToken, enableScaling]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n }, [disableLoadingOverlay]);\n\n const overlayMessage = (() => {\n if (disableLoadingOverlay) {\n return null;\n }\n\n if (isGeneratingScripts || hasScriptsRef.current)\n return (\n scriptLoadingText || loadingText || localeTexts.sandboxScriptLoadingText\n );\n if (isGeneratingStyles || hasStylesRef.current)\n return (\n styleLoadingText || loadingText || localeTexts.sandboxStyleLoadingText\n );\n if (!hasRenderedContent)\n return loadingText || localeTexts.sandboxLoadingText;\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n const shouldStretchRootHeight = isBlackboard && stretchRootHeight;\n const sandboxWrapperStyle: React.CSSProperties = {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n // Keep blackboard scroll behavior while centering content in non-blackboard mode\n justifyContent: shouldStretchRootHeight\n ? \"flex-start\"\n : isBlackboard\n ? \"space-around\"\n : \"flex-start\",\n };\n const sandboxContainerStyle: React.CSSProperties = {\n pointerEvents: overlayMessage ? \"none\" : undefined,\n margin: isBlackboard ? undefined : \"auto 0\",\n width: \"100%\",\n height: shouldStretchRootHeight ? \"100%\" : undefined,\n minHeight: shouldStretchRootHeight ? 0 : undefined,\n flex: shouldStretchRootHeight ? \"1 1 auto\" : undefined,\n };\n\n return (\n <div\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className=\"sandbox-wrapper\"\n dir={dir ?? getMarkdownFlowDirection(locale)}\n lang={lang ?? getMarkdownFlowLanguage(locale)}\n style={sandboxWrapperStyle}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n className=\"sandbox-container\"\n style={sandboxContainerStyle}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 20,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n }}\n >\n <LoadingOverlayCard message={overlayMessage} />\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["IMAGE_REUSE_ATTRIBUTES","getImageReuseKey","image","attribute","collectReusableImages","root","imageMap","node","key","bucket","syncImageAttributes","sourceImage","targetImage","sourceAttributes","sourceAttributeNames","reuseRenderedImages","nextImage","preservedImage","SandboxApp","html","locale","dir","lang","loadingText","styleLoadingText","scriptLoadingText","resetToken","mode","hasRootVhHeight","stretchRootHeight","enableScaling","disableLoadingOverlay","localeTexts","getContentRenderLocaleTexts","containerRef","useRef","isGeneratingStyles","setIsGeneratingStyles","useState","isGeneratingScripts","setIsGeneratingScripts","hasRenderedContent","setHasRenderedContent","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","reusableImages","wrapper","isAnchorElement","shouldForceAnchorHrefToNewTab","mergeAnchorRelValue","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","contentNodes","hasInitialContent","handleLinkClick","event","anchor","resolveClosestAnchor","scriptContentObserver","markRenderedContentFromContainer","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","getMarkdownFlowDirection","getMarkdownFlowLanguage","jsx","LoadingOverlayCard"],"mappings":"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"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { MarkdownFlowLocale } from '../../lib/locale';
|
|
2
|
+
import { MarkdownFlowLocale } from '../../lib/locale.js';
|
|
3
3
|
export interface SandboxAppProps {
|
|
4
4
|
html: string;
|
|
5
5
|
locale?: MarkdownFlowLocale;
|
|
6
|
+
/** Overrides the wrapper language without changing authored HTML language. */
|
|
7
|
+
lang?: string;
|
|
8
|
+
/** Overrides the wrapper direction while preserving explicit direction in authored HTML. */
|
|
9
|
+
dir?: React.HTMLAttributes<HTMLDivElement>["dir"];
|
|
6
10
|
loadingText?: string;
|
|
7
11
|
styleLoadingText?: string;
|
|
8
12
|
scriptLoadingText?: string;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useRef as
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
1
|
+
import { jsxs as ue, jsx as G } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as l, useState as q, useEffect as k } from "react";
|
|
3
|
+
import fe from "../ui/loading-overlay-card.es.js";
|
|
4
|
+
import { getMarkdownFlowLanguage as de, getMarkdownFlowDirection as he } from "../../lib/locale.es.js";
|
|
5
|
+
import { getContentRenderLocaleTexts as me } from "./contentRenderI18n.es.js";
|
|
6
|
+
import { isAnchorElement as pe, shouldForceAnchorHrefToNewTab as X, mergeAnchorRelValue as Y, resolveClosestAnchor as ge } from "./utils/link-targets.es.js";
|
|
7
|
+
const ye = [
|
|
7
8
|
"src",
|
|
8
9
|
"srcset",
|
|
9
10
|
"sizes",
|
|
@@ -17,55 +18,57 @@ const de = [
|
|
|
17
18
|
"crossorigin",
|
|
18
19
|
"referrerpolicy",
|
|
19
20
|
"fetchpriority"
|
|
20
|
-
],
|
|
21
|
+
], Z = (o) => ye.map(
|
|
21
22
|
(n) => `${n}:${o.getAttribute(n) || ""}`
|
|
22
|
-
).join("|"),
|
|
23
|
+
).join("|"), be = (o) => {
|
|
23
24
|
const n = /* @__PURE__ */ new Map();
|
|
24
|
-
return o.querySelectorAll("img").forEach((
|
|
25
|
-
const
|
|
26
|
-
|
|
25
|
+
return o.querySelectorAll("img").forEach((f) => {
|
|
26
|
+
const c = f, s = Z(c), d = n.get(s) || [];
|
|
27
|
+
d.push(c), n.set(s, d);
|
|
27
28
|
}), n;
|
|
28
|
-
},
|
|
29
|
-
const
|
|
30
|
-
|
|
29
|
+
}, we = (o, n) => {
|
|
30
|
+
const f = Array.from(o.attributes), c = new Set(
|
|
31
|
+
f.map((s) => s.name)
|
|
31
32
|
);
|
|
32
33
|
Array.from(n.attributes).forEach((s) => {
|
|
33
|
-
|
|
34
|
-
}),
|
|
34
|
+
c.has(s.name) || n.removeAttribute(s.name);
|
|
35
|
+
}), f.forEach((s) => {
|
|
35
36
|
n.setAttribute(s.name, s.value);
|
|
36
37
|
});
|
|
37
|
-
},
|
|
38
|
-
n.size && o.querySelectorAll("img").forEach((
|
|
39
|
-
const
|
|
40
|
-
p && (
|
|
38
|
+
}, ve = (o, n) => {
|
|
39
|
+
n.size && o.querySelectorAll("img").forEach((f) => {
|
|
40
|
+
const c = f, s = Z(c), d = n.get(s), p = d?.shift();
|
|
41
|
+
p && (we(c, p), c.replaceWith(p), d && d.length === 0 && n.delete(s));
|
|
41
42
|
});
|
|
42
|
-
},
|
|
43
|
+
}, ke = ({
|
|
43
44
|
html: o,
|
|
44
45
|
locale: n,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
dir: f,
|
|
47
|
+
lang: c,
|
|
48
|
+
loadingText: s,
|
|
49
|
+
styleLoadingText: d,
|
|
50
|
+
scriptLoadingText: p,
|
|
51
|
+
resetToken: A = 0,
|
|
52
|
+
mode: ee = "content",
|
|
53
|
+
hasRootVhHeight: te = !1,
|
|
54
|
+
stretchRootHeight: re = !1,
|
|
55
|
+
enableScaling: z = !1,
|
|
56
|
+
disableLoadingOverlay: L = !1
|
|
54
57
|
}) => {
|
|
55
|
-
const
|
|
58
|
+
const N = me(n), T = l(null), [ne, S] = q(!1), [se, C] = q(!1), [oe, M] = q(!1), _ = l([]), H = l([]), U = l(0), V = l(0), g = l(null), y = l(null), b = l(!1), w = l(!1), W = l(A), ae = 200, u = (t) => {
|
|
56
59
|
t.current && (clearTimeout(t.current), t.current = null);
|
|
57
|
-
},
|
|
58
|
-
const h = performance.now() -
|
|
59
|
-
|
|
60
|
-
t(!1), D?.(),
|
|
61
|
-
},
|
|
60
|
+
}, B = (t, a, i, D) => {
|
|
61
|
+
const h = performance.now() - i.current, R = Math.max(0, ae - h);
|
|
62
|
+
u(a), a.current = window.setTimeout(() => {
|
|
63
|
+
t(!1), D?.(), a.current = null;
|
|
64
|
+
}, R);
|
|
62
65
|
};
|
|
63
|
-
|
|
66
|
+
k(() => {
|
|
64
67
|
const t = T.current?.ownerDocument;
|
|
65
68
|
if (!t) return;
|
|
66
|
-
const
|
|
67
|
-
let
|
|
68
|
-
|
|
69
|
+
const a = "sandbox-spinner-style";
|
|
70
|
+
let i = t.getElementById(a);
|
|
71
|
+
i || (i = t.createElement("style"), i.id = a, t.head?.appendChild(i)), i.textContent = `
|
|
69
72
|
.sandbox-wrapper { align-items: center; }
|
|
70
73
|
.sandbox-container { position: relative; width: 100%; }
|
|
71
74
|
.sandbox-container svg,
|
|
@@ -85,62 +88,62 @@ const de = [
|
|
|
85
88
|
}
|
|
86
89
|
.overflow-y-auto { overflow-y: visible !important; }
|
|
87
90
|
`;
|
|
88
|
-
}, []),
|
|
89
|
-
|
|
91
|
+
}, []), k(() => {
|
|
92
|
+
A !== W.current && (M(!1), W.current = A), u(g), u(y), b.current = !1, w.current = !1;
|
|
90
93
|
const t = T.current;
|
|
91
94
|
if (!t) return;
|
|
92
|
-
const
|
|
93
|
-
if (!
|
|
94
|
-
const D =
|
|
95
|
-
_.current.forEach((e) => e.remove()), _.current = [], H.current.forEach((e) => e.remove()), H.current = [],
|
|
96
|
-
const h =
|
|
95
|
+
const a = t.ownerDocument, i = a?.body;
|
|
96
|
+
if (!i) return;
|
|
97
|
+
const D = be(t);
|
|
98
|
+
_.current.forEach((e) => e.remove()), _.current = [], H.current.forEach((e) => e.remove()), H.current = [], S(!1), C(!1);
|
|
99
|
+
const h = a.createElement("div");
|
|
97
100
|
h.innerHTML = o, h.querySelectorAll("a[href]").forEach((e) => {
|
|
98
|
-
|
|
101
|
+
pe(e) && X(e.getAttribute("href")) && (e.setAttribute("target", "_blank"), e.setAttribute("rel", Y(e.getAttribute("rel"))));
|
|
99
102
|
});
|
|
100
|
-
const
|
|
103
|
+
const R = (o.match(/<script[\s>]/gi) || []).length, le = (o.match(/<\/script>/gi) || []).length, O = R > 0 && R === le, v = [];
|
|
101
104
|
Array.from(h.querySelectorAll("style, script")).forEach((e) => {
|
|
102
105
|
if (e.tagName.toLowerCase() === "style") {
|
|
103
|
-
const r =
|
|
106
|
+
const r = a.createElement("style");
|
|
104
107
|
r.textContent = e.textContent || "", Array.from(e.attributes).forEach((m) => {
|
|
105
108
|
r.setAttribute(m.name, m.value);
|
|
106
109
|
}), v.push(r);
|
|
107
110
|
} else {
|
|
108
|
-
const r =
|
|
111
|
+
const r = a.createElement("script");
|
|
109
112
|
Array.from(e.attributes).forEach((m) => {
|
|
110
113
|
r.setAttribute(m.name, m.value);
|
|
111
114
|
}), r.textContent = e.textContent || "", v.push(r);
|
|
112
115
|
}
|
|
113
116
|
e.remove();
|
|
114
|
-
}),
|
|
115
|
-
const
|
|
117
|
+
}), ve(h, D);
|
|
118
|
+
const $ = v.some(
|
|
116
119
|
(e) => e.tagName.toLowerCase() === "style"
|
|
117
|
-
),
|
|
120
|
+
), F = v.some(
|
|
118
121
|
(e) => e.tagName.toLowerCase() === "script"
|
|
119
122
|
);
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
const r =
|
|
125
|
-
r &&
|
|
123
|
+
$ && (b.current = !0, U.current = performance.now(), u(g), S(!0)), F && (w.current = !0, V.current = performance.now(), u(y), C(!0));
|
|
124
|
+
const K = Array.from(h.childNodes), Q = K.length > 0;
|
|
125
|
+
M(Q), t.replaceChildren(...K);
|
|
126
|
+
const J = (e) => {
|
|
127
|
+
const r = ge(e.target);
|
|
128
|
+
r && X(r.getAttribute("href")) && (r.setAttribute("target", "_blank"), r.setAttribute(
|
|
126
129
|
"rel",
|
|
127
|
-
|
|
130
|
+
Y(r.getAttribute("rel"))
|
|
128
131
|
));
|
|
129
132
|
};
|
|
130
|
-
t.addEventListener("click",
|
|
131
|
-
let
|
|
132
|
-
const
|
|
133
|
-
return !
|
|
134
|
-
|
|
135
|
-
}),
|
|
133
|
+
t.addEventListener("click", J, !0);
|
|
134
|
+
let x = null;
|
|
135
|
+
const P = () => t.childNodes.length === 0 ? !1 : (M(!0), x?.disconnect(), x = null, !0);
|
|
136
|
+
return !Q && F && O && (x = new MutationObserver(() => {
|
|
137
|
+
P();
|
|
138
|
+
}), x.observe(t, {
|
|
136
139
|
childList: !0,
|
|
137
140
|
subtree: !0
|
|
138
141
|
})), v.forEach((e) => {
|
|
139
142
|
if (e.tagName.toLowerCase() === "style") {
|
|
140
|
-
|
|
143
|
+
a.head?.appendChild(e), _.current.push(e);
|
|
141
144
|
return;
|
|
142
145
|
}
|
|
143
|
-
if (
|
|
146
|
+
if (O) {
|
|
144
147
|
const r = e, m = r.textContent || "";
|
|
145
148
|
if (!r.src)
|
|
146
149
|
try {
|
|
@@ -150,72 +153,74 @@ const de = [
|
|
|
150
153
|
return;
|
|
151
154
|
}
|
|
152
155
|
try {
|
|
153
|
-
|
|
156
|
+
i.appendChild(r), H.current.push(r);
|
|
154
157
|
} catch {
|
|
155
158
|
r.remove();
|
|
156
159
|
}
|
|
157
160
|
} else
|
|
158
161
|
e.remove();
|
|
159
|
-
}),
|
|
160
|
-
|
|
161
|
-
A,
|
|
162
|
-
y,
|
|
163
|
-
z,
|
|
164
|
-
() => {
|
|
165
|
-
b.current = !1;
|
|
166
|
-
}
|
|
167
|
-
), G && W(
|
|
162
|
+
}), P(), z && t.ownerDocument?.defaultView?.__mdf_triggerFitContent?.(), requestAnimationFrame(() => {
|
|
163
|
+
$ && B(
|
|
168
164
|
S,
|
|
169
165
|
g,
|
|
170
166
|
U,
|
|
171
167
|
() => {
|
|
172
|
-
|
|
168
|
+
b.current = !1;
|
|
169
|
+
}
|
|
170
|
+
), F && B(
|
|
171
|
+
C,
|
|
172
|
+
y,
|
|
173
|
+
V,
|
|
174
|
+
() => {
|
|
175
|
+
w.current = !1;
|
|
173
176
|
}
|
|
174
177
|
);
|
|
175
178
|
}), () => {
|
|
176
|
-
|
|
179
|
+
x?.disconnect(), t.removeEventListener("click", J, !0);
|
|
177
180
|
};
|
|
178
|
-
}, [o,
|
|
181
|
+
}, [o, A, z]), k(
|
|
179
182
|
() => () => {
|
|
180
|
-
|
|
183
|
+
u(g), u(y);
|
|
181
184
|
},
|
|
182
185
|
[]
|
|
183
|
-
),
|
|
184
|
-
|
|
185
|
-
}, [
|
|
186
|
-
const
|
|
186
|
+
), k(() => {
|
|
187
|
+
L && (u(g), u(y), b.current = !1, w.current = !1, S(!1), C(!1));
|
|
188
|
+
}, [L]);
|
|
189
|
+
const E = L ? null : se || w.current ? p || s || N.sandboxScriptLoadingText : ne || b.current ? d || s || N.sandboxStyleLoadingText : oe ? null : s || N.sandboxLoadingText, j = ee === "blackboard", I = j && re, ce = {
|
|
187
190
|
position: "relative",
|
|
188
191
|
width: "100%",
|
|
189
192
|
height: "100%",
|
|
190
193
|
display: "flex",
|
|
191
194
|
flexDirection: "column",
|
|
192
195
|
// Keep blackboard scroll behavior while centering content in non-blackboard mode
|
|
193
|
-
justifyContent:
|
|
194
|
-
},
|
|
195
|
-
pointerEvents:
|
|
196
|
-
margin:
|
|
196
|
+
justifyContent: I ? "flex-start" : j ? "space-around" : "flex-start"
|
|
197
|
+
}, ie = {
|
|
198
|
+
pointerEvents: E ? "none" : void 0,
|
|
199
|
+
margin: j ? void 0 : "auto 0",
|
|
197
200
|
width: "100%",
|
|
198
|
-
height:
|
|
199
|
-
minHeight:
|
|
200
|
-
flex:
|
|
201
|
+
height: I ? "100%" : void 0,
|
|
202
|
+
minHeight: I ? 0 : void 0,
|
|
203
|
+
flex: I ? "1 1 auto" : void 0
|
|
201
204
|
};
|
|
202
|
-
return /* @__PURE__ */
|
|
205
|
+
return /* @__PURE__ */ ue(
|
|
203
206
|
"div",
|
|
204
207
|
{
|
|
205
|
-
"data-root-vh":
|
|
208
|
+
"data-root-vh": te ? "true" : "false",
|
|
206
209
|
className: "sandbox-wrapper",
|
|
207
|
-
|
|
208
|
-
|
|
210
|
+
dir: f ?? he(n),
|
|
211
|
+
lang: c ?? de(n),
|
|
212
|
+
style: ce,
|
|
213
|
+
"aria-busy": !!E,
|
|
209
214
|
children: [
|
|
210
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ G(
|
|
211
216
|
"div",
|
|
212
217
|
{
|
|
213
218
|
ref: T,
|
|
214
219
|
className: "sandbox-container",
|
|
215
|
-
style:
|
|
220
|
+
style: ie
|
|
216
221
|
}
|
|
217
222
|
),
|
|
218
|
-
|
|
223
|
+
E && /* @__PURE__ */ G(
|
|
219
224
|
"div",
|
|
220
225
|
{
|
|
221
226
|
style: {
|
|
@@ -227,7 +232,7 @@ const de = [
|
|
|
227
232
|
justifyContent: "center",
|
|
228
233
|
pointerEvents: "none"
|
|
229
234
|
},
|
|
230
|
-
children: /* @__PURE__ */
|
|
235
|
+
children: /* @__PURE__ */ G(fe, { message: E })
|
|
231
236
|
}
|
|
232
237
|
)
|
|
233
238
|
]
|
|
@@ -235,6 +240,6 @@ const de = [
|
|
|
235
240
|
);
|
|
236
241
|
};
|
|
237
242
|
export {
|
|
238
|
-
|
|
243
|
+
ke as default
|
|
239
244
|
};
|
|
240
245
|
//# sourceMappingURL=SandboxApp.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxApp.es.js","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport type { MarkdownFlowLocale } from \"../../lib/locale\";\nimport { getContentRenderLocaleTexts } from \"./contentRenderI18n\";\nimport type { ScalingWindow } from \"./utils/iframe-scaling\";\nimport {\n isAnchorElement,\n mergeAnchorRelValue,\n resolveClosestAnchor,\n shouldForceAnchorHrefToNewTab,\n} from \"./utils/link-targets\";\n\nexport interface SandboxAppProps {\n html: string;\n locale?: MarkdownFlowLocale;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n hasRootVhHeight?: boolean;\n stretchRootHeight?: boolean;\n enableScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nconst IMAGE_REUSE_ATTRIBUTES = [\n \"src\",\n \"srcset\",\n \"sizes\",\n \"alt\",\n \"class\",\n \"width\",\n \"height\",\n \"style\",\n \"loading\",\n \"decoding\",\n \"crossorigin\",\n \"referrerpolicy\",\n \"fetchpriority\",\n];\n\nconst getImageReuseKey = (image: HTMLImageElement) =>\n IMAGE_REUSE_ATTRIBUTES.map(\n (attribute) => `${attribute}:${image.getAttribute(attribute) || \"\"}`\n ).join(\"|\");\n\nconst collectReusableImages = (root: ParentNode) => {\n const imageMap = new Map<string, HTMLImageElement[]>();\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n const key = getImageReuseKey(image);\n const bucket = imageMap.get(key) || [];\n bucket.push(image);\n imageMap.set(key, bucket);\n });\n return imageMap;\n};\n\nconst syncImageAttributes = (\n sourceImage: HTMLImageElement,\n targetImage: HTMLImageElement\n) => {\n const sourceAttributes = Array.from(sourceImage.attributes);\n const sourceAttributeNames = new Set(\n sourceAttributes.map((attribute) => attribute.name)\n );\n\n Array.from(targetImage.attributes).forEach((attribute) => {\n if (!sourceAttributeNames.has(attribute.name)) {\n targetImage.removeAttribute(attribute.name);\n }\n });\n\n sourceAttributes.forEach((attribute) => {\n targetImage.setAttribute(attribute.name, attribute.value);\n });\n};\n\nconst reuseRenderedImages = (\n root: ParentNode,\n imageMap: Map<string, HTMLImageElement[]>\n) => {\n if (!imageMap.size) return;\n\n root.querySelectorAll(\"img\").forEach((node) => {\n const nextImage = node as HTMLImageElement;\n const key = getImageReuseKey(nextImage);\n const bucket = imageMap.get(key);\n const preservedImage = bucket?.shift();\n if (!preservedImage) return;\n\n syncImageAttributes(nextImage, preservedImage);\n nextImage.replaceWith(preservedImage);\n\n if (bucket && bucket.length === 0) {\n imageMap.delete(key);\n }\n });\n};\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n locale,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n hasRootVhHeight = false,\n stretchRootHeight = false,\n enableScaling = false,\n disableLoadingOverlay = false,\n}) => {\n const localeTexts = getContentRenderLocaleTexts(locale);\n const containerRef = useRef<HTMLDivElement>(null);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const [hasRenderedContent, setHasRenderedContent] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n .sandbox-wrapper { align-items: center; }\n .sandbox-container { position: relative; width: 100%; }\n .sandbox-container svg,\n .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }\n /* Hide scroll UI without removing scroll semantics. Content roots with\n inline style=\"height:100vh; overflow-y:auto\" are the signal that\n IframeSandbox.getInnerScrollableHeight relies on to grow the iframe\n when content exceeds the viewport. We must not change overflow-y,\n but sub-pixel rounding (1px below the +1 detection threshold) can\n still surface a phantom scrollbar on content that visually fits.\n Hide the scrollbar UI globally; when content truly overflows the\n iframe is resized and no scrollbar would render anyway. */\n .sandbox-container *::-webkit-scrollbar { display: none; }\n .sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }\n .justify-\\\\[safe_center\\\\]{\n justify-content: safe center;\n }\n .overflow-y-auto { overflow-y: visible !important; }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n setHasRenderedContent(false);\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n const reusableImages = collectReusableImages(container);\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n const wrapper = doc.createElement(\"div\");\n wrapper.innerHTML = html;\n wrapper.querySelectorAll(\"a[href]\").forEach((node) => {\n if (!isAnchorElement(node)) {\n return;\n }\n\n if (!shouldForceAnchorHrefToNewTab(node.getAttribute(\"href\"))) {\n return;\n }\n\n node.setAttribute(\"target\", \"_blank\");\n node.setAttribute(\"rel\", mergeAnchorRelValue(node.getAttribute(\"rel\")));\n });\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n reuseRenderedImages(wrapper, reusableImages);\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n const hasInitialContent = contentNodes.length > 0;\n setHasRenderedContent(hasInitialContent);\n container.replaceChildren(...contentNodes);\n\n const handleLinkClick = (event: MouseEvent) => {\n const anchor = resolveClosestAnchor(event.target);\n if (!anchor) {\n return;\n }\n\n if (!shouldForceAnchorHrefToNewTab(anchor.getAttribute(\"href\"))) {\n return;\n }\n\n anchor.setAttribute(\"target\", \"_blank\");\n anchor.setAttribute(\n \"rel\",\n mergeAnchorRelValue(anchor.getAttribute(\"rel\"))\n );\n };\n container.addEventListener(\"click\", handleLinkClick, true);\n\n let scriptContentObserver: MutationObserver | null = null;\n const markRenderedContentFromContainer = () => {\n if (container.childNodes.length === 0) {\n return false;\n }\n\n setHasRenderedContent(true);\n scriptContentObserver?.disconnect();\n scriptContentObserver = null;\n return true;\n };\n if (!hasInitialContent && hasScripts && shouldExecuteScripts) {\n scriptContentObserver = new MutationObserver(() => {\n markRenderedContentFromContainer();\n });\n scriptContentObserver.observe(container, {\n childList: true,\n subtree: true,\n });\n }\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n markRenderedContentFromContainer();\n if (enableScaling) {\n const win = container.ownerDocument?.defaultView as ScalingWindow | null;\n win?.__mdf_triggerFitContent?.();\n }\n\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n\n return () => {\n scriptContentObserver?.disconnect();\n container.removeEventListener(\"click\", handleLinkClick, true);\n };\n }, [html, resetToken, enableScaling]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n }, [disableLoadingOverlay]);\n\n const overlayMessage = (() => {\n if (disableLoadingOverlay) {\n return null;\n }\n\n if (isGeneratingScripts || hasScriptsRef.current)\n return (\n scriptLoadingText || loadingText || localeTexts.sandboxScriptLoadingText\n );\n if (isGeneratingStyles || hasStylesRef.current)\n return (\n styleLoadingText || loadingText || localeTexts.sandboxStyleLoadingText\n );\n if (!hasRenderedContent)\n return loadingText || localeTexts.sandboxLoadingText;\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n const shouldStretchRootHeight = isBlackboard && stretchRootHeight;\n const sandboxWrapperStyle: React.CSSProperties = {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n // Keep blackboard scroll behavior while centering content in non-blackboard mode\n justifyContent: shouldStretchRootHeight\n ? \"flex-start\"\n : isBlackboard\n ? \"space-around\"\n : \"flex-start\",\n };\n const sandboxContainerStyle: React.CSSProperties = {\n pointerEvents: overlayMessage ? \"none\" : undefined,\n margin: isBlackboard ? undefined : \"auto 0\",\n width: \"100%\",\n height: shouldStretchRootHeight ? \"100%\" : undefined,\n minHeight: shouldStretchRootHeight ? 0 : undefined,\n flex: shouldStretchRootHeight ? \"1 1 auto\" : undefined,\n };\n\n return (\n <div\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className=\"sandbox-wrapper\"\n style={sandboxWrapperStyle}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n className=\"sandbox-container\"\n style={sandboxContainerStyle}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 20,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n }}\n >\n <LoadingOverlayCard message={overlayMessage} />\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["IMAGE_REUSE_ATTRIBUTES","getImageReuseKey","image","attribute","collectReusableImages","root","imageMap","node","key","bucket","syncImageAttributes","sourceImage","targetImage","sourceAttributes","sourceAttributeNames","reuseRenderedImages","nextImage","preservedImage","SandboxApp","html","locale","loadingText","styleLoadingText","scriptLoadingText","resetToken","mode","hasRootVhHeight","stretchRootHeight","enableScaling","disableLoadingOverlay","localeTexts","getContentRenderLocaleTexts","containerRef","useRef","isGeneratingStyles","setIsGeneratingStyles","useState","isGeneratingScripts","setIsGeneratingScripts","hasRenderedContent","setHasRenderedContent","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","reusableImages","wrapper","isAnchorElement","shouldForceAnchorHrefToNewTab","mergeAnchorRelValue","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","contentNodes","hasInitialContent","handleLinkClick","event","anchor","resolveClosestAnchor","scriptContentObserver","markRenderedContentFromContainer","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","jsx","LoadingOverlayCard"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SandboxApp.es.js","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport {\n getMarkdownFlowDirection,\n getMarkdownFlowLanguage,\n type MarkdownFlowLocale,\n} from \"../../lib/locale\";\nimport { getContentRenderLocaleTexts } from \"./contentRenderI18n\";\nimport type { ScalingWindow } from \"./utils/iframe-scaling\";\nimport {\n isAnchorElement,\n mergeAnchorRelValue,\n resolveClosestAnchor,\n shouldForceAnchorHrefToNewTab,\n} from \"./utils/link-targets\";\n\nexport interface SandboxAppProps {\n html: string;\n locale?: MarkdownFlowLocale;\n /** Overrides the wrapper language without changing authored HTML language. */\n lang?: string;\n /** Overrides the wrapper direction while preserving explicit direction in authored HTML. */\n dir?: React.HTMLAttributes<HTMLDivElement>[\"dir\"];\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n hasRootVhHeight?: boolean;\n stretchRootHeight?: boolean;\n enableScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nconst IMAGE_REUSE_ATTRIBUTES = [\n \"src\",\n \"srcset\",\n \"sizes\",\n \"alt\",\n \"class\",\n \"width\",\n \"height\",\n \"style\",\n \"loading\",\n \"decoding\",\n \"crossorigin\",\n \"referrerpolicy\",\n \"fetchpriority\",\n];\n\nconst getImageReuseKey = (image: HTMLImageElement) =>\n IMAGE_REUSE_ATTRIBUTES.map(\n (attribute) => `${attribute}:${image.getAttribute(attribute) || \"\"}`\n ).join(\"|\");\n\nconst collectReusableImages = (root: ParentNode) => {\n const imageMap = new Map<string, HTMLImageElement[]>();\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n const key = getImageReuseKey(image);\n const bucket = imageMap.get(key) || [];\n bucket.push(image);\n imageMap.set(key, bucket);\n });\n return imageMap;\n};\n\nconst syncImageAttributes = (\n sourceImage: HTMLImageElement,\n targetImage: HTMLImageElement\n) => {\n const sourceAttributes = Array.from(sourceImage.attributes);\n const sourceAttributeNames = new Set(\n sourceAttributes.map((attribute) => attribute.name)\n );\n\n Array.from(targetImage.attributes).forEach((attribute) => {\n if (!sourceAttributeNames.has(attribute.name)) {\n targetImage.removeAttribute(attribute.name);\n }\n });\n\n sourceAttributes.forEach((attribute) => {\n targetImage.setAttribute(attribute.name, attribute.value);\n });\n};\n\nconst reuseRenderedImages = (\n root: ParentNode,\n imageMap: Map<string, HTMLImageElement[]>\n) => {\n if (!imageMap.size) return;\n\n root.querySelectorAll(\"img\").forEach((node) => {\n const nextImage = node as HTMLImageElement;\n const key = getImageReuseKey(nextImage);\n const bucket = imageMap.get(key);\n const preservedImage = bucket?.shift();\n if (!preservedImage) return;\n\n syncImageAttributes(nextImage, preservedImage);\n nextImage.replaceWith(preservedImage);\n\n if (bucket && bucket.length === 0) {\n imageMap.delete(key);\n }\n });\n};\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n locale,\n dir,\n lang,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n hasRootVhHeight = false,\n stretchRootHeight = false,\n enableScaling = false,\n disableLoadingOverlay = false,\n}) => {\n const localeTexts = getContentRenderLocaleTexts(locale);\n const containerRef = useRef<HTMLDivElement>(null);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const [hasRenderedContent, setHasRenderedContent] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n .sandbox-wrapper { align-items: center; }\n .sandbox-container { position: relative; width: 100%; }\n .sandbox-container svg,\n .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }\n /* Hide scroll UI without removing scroll semantics. Content roots with\n inline style=\"height:100vh; overflow-y:auto\" are the signal that\n IframeSandbox.getInnerScrollableHeight relies on to grow the iframe\n when content exceeds the viewport. We must not change overflow-y,\n but sub-pixel rounding (1px below the +1 detection threshold) can\n still surface a phantom scrollbar on content that visually fits.\n Hide the scrollbar UI globally; when content truly overflows the\n iframe is resized and no scrollbar would render anyway. */\n .sandbox-container *::-webkit-scrollbar { display: none; }\n .sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }\n .justify-\\\\[safe_center\\\\]{\n justify-content: safe center;\n }\n .overflow-y-auto { overflow-y: visible !important; }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n setHasRenderedContent(false);\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n const reusableImages = collectReusableImages(container);\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n const wrapper = doc.createElement(\"div\");\n wrapper.innerHTML = html;\n wrapper.querySelectorAll(\"a[href]\").forEach((node) => {\n if (!isAnchorElement(node)) {\n return;\n }\n\n if (!shouldForceAnchorHrefToNewTab(node.getAttribute(\"href\"))) {\n return;\n }\n\n node.setAttribute(\"target\", \"_blank\");\n node.setAttribute(\"rel\", mergeAnchorRelValue(node.getAttribute(\"rel\")));\n });\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n reuseRenderedImages(wrapper, reusableImages);\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n const hasInitialContent = contentNodes.length > 0;\n setHasRenderedContent(hasInitialContent);\n container.replaceChildren(...contentNodes);\n\n const handleLinkClick = (event: MouseEvent) => {\n const anchor = resolveClosestAnchor(event.target);\n if (!anchor) {\n return;\n }\n\n if (!shouldForceAnchorHrefToNewTab(anchor.getAttribute(\"href\"))) {\n return;\n }\n\n anchor.setAttribute(\"target\", \"_blank\");\n anchor.setAttribute(\n \"rel\",\n mergeAnchorRelValue(anchor.getAttribute(\"rel\"))\n );\n };\n container.addEventListener(\"click\", handleLinkClick, true);\n\n let scriptContentObserver: MutationObserver | null = null;\n const markRenderedContentFromContainer = () => {\n if (container.childNodes.length === 0) {\n return false;\n }\n\n setHasRenderedContent(true);\n scriptContentObserver?.disconnect();\n scriptContentObserver = null;\n return true;\n };\n if (!hasInitialContent && hasScripts && shouldExecuteScripts) {\n scriptContentObserver = new MutationObserver(() => {\n markRenderedContentFromContainer();\n });\n scriptContentObserver.observe(container, {\n childList: true,\n subtree: true,\n });\n }\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n markRenderedContentFromContainer();\n if (enableScaling) {\n const win = container.ownerDocument?.defaultView as ScalingWindow | null;\n win?.__mdf_triggerFitContent?.();\n }\n\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n\n return () => {\n scriptContentObserver?.disconnect();\n container.removeEventListener(\"click\", handleLinkClick, true);\n };\n }, [html, resetToken, enableScaling]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n }, [disableLoadingOverlay]);\n\n const overlayMessage = (() => {\n if (disableLoadingOverlay) {\n return null;\n }\n\n if (isGeneratingScripts || hasScriptsRef.current)\n return (\n scriptLoadingText || loadingText || localeTexts.sandboxScriptLoadingText\n );\n if (isGeneratingStyles || hasStylesRef.current)\n return (\n styleLoadingText || loadingText || localeTexts.sandboxStyleLoadingText\n );\n if (!hasRenderedContent)\n return loadingText || localeTexts.sandboxLoadingText;\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n const shouldStretchRootHeight = isBlackboard && stretchRootHeight;\n const sandboxWrapperStyle: React.CSSProperties = {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n // Keep blackboard scroll behavior while centering content in non-blackboard mode\n justifyContent: shouldStretchRootHeight\n ? \"flex-start\"\n : isBlackboard\n ? \"space-around\"\n : \"flex-start\",\n };\n const sandboxContainerStyle: React.CSSProperties = {\n pointerEvents: overlayMessage ? \"none\" : undefined,\n margin: isBlackboard ? undefined : \"auto 0\",\n width: \"100%\",\n height: shouldStretchRootHeight ? \"100%\" : undefined,\n minHeight: shouldStretchRootHeight ? 0 : undefined,\n flex: shouldStretchRootHeight ? \"1 1 auto\" : undefined,\n };\n\n return (\n <div\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className=\"sandbox-wrapper\"\n dir={dir ?? getMarkdownFlowDirection(locale)}\n lang={lang ?? getMarkdownFlowLanguage(locale)}\n style={sandboxWrapperStyle}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n className=\"sandbox-container\"\n style={sandboxContainerStyle}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 20,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n }}\n >\n <LoadingOverlayCard message={overlayMessage} />\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["IMAGE_REUSE_ATTRIBUTES","getImageReuseKey","image","attribute","collectReusableImages","root","imageMap","node","key","bucket","syncImageAttributes","sourceImage","targetImage","sourceAttributes","sourceAttributeNames","reuseRenderedImages","nextImage","preservedImage","SandboxApp","html","locale","dir","lang","loadingText","styleLoadingText","scriptLoadingText","resetToken","mode","hasRootVhHeight","stretchRootHeight","enableScaling","disableLoadingOverlay","localeTexts","getContentRenderLocaleTexts","containerRef","useRef","isGeneratingStyles","setIsGeneratingStyles","useState","isGeneratingScripts","setIsGeneratingScripts","hasRenderedContent","setHasRenderedContent","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","reusableImages","wrapper","isAnchorElement","shouldForceAnchorHrefToNewTab","mergeAnchorRelValue","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","contentNodes","hasInitialContent","handleLinkClick","event","anchor","resolveClosestAnchor","scriptContentObserver","markRenderedContentFromContainer","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","getMarkdownFlowDirection","getMarkdownFlowLanguage","jsx","LoadingOverlayCard"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("../../lib/locale.cjs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("../../lib/locale.cjs"),n=require("./locales/contentRender.json.cjs"),e=n.default,r=t=>e[o.normalizeMarkdownFlowLocale(t)];exports.CONTENT_RENDER_LOCALE_TEXTS=e;exports.getContentRenderLocaleTexts=r;
|
|
2
2
|
//# sourceMappingURL=contentRenderI18n.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contentRenderI18n.cjs","sources":["../../../src/components/ContentRender/contentRenderI18n.ts"],"sourcesContent":["import {\n normalizeMarkdownFlowLocale,\n type MarkdownFlowLocale,\n} from \"../../lib/locale\";\nimport
|
|
1
|
+
{"version":3,"file":"contentRenderI18n.cjs","sources":["../../../src/components/ContentRender/contentRenderI18n.ts"],"sourcesContent":["import {\n normalizeMarkdownFlowLocale,\n type MarkdownFlowLocale,\n} from \"../../lib/locale\";\nimport localeTexts from \"./locales/contentRender.json\";\n\nexport interface ContentRenderLocaleTexts {\n confirmButtonText: string;\n copyButtonText: string;\n copiedButtonText: string;\n sandboxLoadingText: string;\n sandboxStyleLoadingText: string;\n sandboxScriptLoadingText: string;\n sandboxFullscreenButtonText: string;\n sandboxExitFullscreenButtonText: string;\n sendButtonLabel: string;\n scrollToBottomLabel: string;\n mermaidLoadingText: string;\n mermaidEmptyChartText: string;\n mermaidErrorText: string;\n footnoteLabel: string;\n footnoteBackLabel: string;\n}\n\nexport const CONTENT_RENDER_LOCALE_TEXTS: Record<\n MarkdownFlowLocale,\n ContentRenderLocaleTexts\n> = localeTexts;\n\nexport const getContentRenderLocaleTexts = (\n locale?: string | null\n): ContentRenderLocaleTexts =>\n CONTENT_RENDER_LOCALE_TEXTS[normalizeMarkdownFlowLocale(locale)];\n"],"names":["CONTENT_RENDER_LOCALE_TEXTS","localeTexts","getContentRenderLocaleTexts","locale","normalizeMarkdownFlowLocale"],"mappings":"sKAwBaA,EAGTC,EAAAA,QAESC,EACXC,GAEAH,EAA4BI,EAAAA,4BAA4BD,CAAM,CAAC"}
|