markdown-flow-ui 0.2.1 → 0.2.3-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/assets/markdown-flow-ui.css +1 -1
  2. package/dist/components/ContentRender/IframeSandbox.cjs.js +7 -7
  3. package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
  4. package/dist/components/ContentRender/IframeSandbox.es.js +283 -252
  5. package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
  6. package/dist/components/ContentRender/SandboxApp.cjs.js +2 -2
  7. package/dist/components/ContentRender/SandboxApp.cjs.js.map +1 -1
  8. package/dist/components/ContentRender/SandboxApp.es.js +106 -95
  9. package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
  10. package/dist/components/ContentRender/blackboard-vendor.cjs.js +1 -1
  11. package/dist/components/ContentRender/blackboard-vendor.cjs.js.map +1 -1
  12. package/dist/components/ContentRender/blackboard-vendor.d.ts +2 -0
  13. package/dist/components/ContentRender/blackboard-vendor.es.js +9 -12
  14. package/dist/components/ContentRender/blackboard-vendor.es.js.map +1 -1
  15. package/dist/components/ContentRender/utils/iframe-scaling.cjs.js +12 -9
  16. package/dist/components/ContentRender/utils/iframe-scaling.cjs.js.map +1 -1
  17. package/dist/components/ContentRender/utils/iframe-scaling.es.js +16 -12
  18. package/dist/components/ContentRender/utils/iframe-scaling.es.js.map +1 -1
  19. package/dist/components/ContentRender/utils/link-targets.cjs.js +2 -0
  20. package/dist/components/ContentRender/utils/link-targets.cjs.js.map +1 -0
  21. package/dist/components/ContentRender/utils/link-targets.d.ts +6 -0
  22. package/dist/components/ContentRender/utils/link-targets.es.js +26 -0
  23. package/dist/components/ContentRender/utils/link-targets.es.js.map +1 -0
  24. package/dist/components/ContentRender/utils/link-targets.test.d.ts +1 -0
  25. package/dist/components/ContentRender/utils/presentation-scaling.cjs.js +2 -0
  26. package/dist/components/ContentRender/utils/presentation-scaling.cjs.js.map +1 -0
  27. package/dist/components/ContentRender/utils/presentation-scaling.d.ts +34 -0
  28. package/dist/components/ContentRender/utils/presentation-scaling.es.js +67 -0
  29. package/dist/components/ContentRender/utils/presentation-scaling.es.js.map +1 -0
  30. package/dist/components/ContentRender/utils/presentation-scaling.test.d.ts +1 -0
  31. package/dist/components/ContentRender/utils/tailwind-runtime.cjs.js +2 -0
  32. package/dist/components/ContentRender/utils/tailwind-runtime.cjs.js.map +1 -0
  33. package/dist/components/ContentRender/utils/tailwind-runtime.d.ts +5 -0
  34. package/dist/components/ContentRender/utils/tailwind-runtime.es.js +11 -0
  35. package/dist/components/ContentRender/utils/tailwind-runtime.es.js.map +1 -0
  36. package/dist/components/ContentRender/utils/tailwind-runtime.test.d.ts +1 -0
  37. package/dist/components/Slide/MarkdownSlideScaling.cjs.js +2 -0
  38. package/dist/components/Slide/MarkdownSlideScaling.cjs.js.map +1 -0
  39. package/dist/components/Slide/MarkdownSlideScaling.d.ts +13 -0
  40. package/dist/components/Slide/MarkdownSlideScaling.es.js +109 -0
  41. package/dist/components/Slide/MarkdownSlideScaling.es.js.map +1 -0
  42. package/dist/components/Slide/Slide.cjs.js +1 -1
  43. package/dist/components/Slide/Slide.cjs.js.map +1 -1
  44. package/dist/components/Slide/Slide.d.ts +7 -0
  45. package/dist/components/Slide/Slide.es.js +803 -708
  46. package/dist/components/Slide/Slide.es.js.map +1 -1
  47. package/dist/components/Slide/Slide.stories.d.ts +2473 -0
  48. package/dist/components/Slide/constants.cjs.js +2 -0
  49. package/dist/components/Slide/constants.cjs.js.map +1 -0
  50. package/dist/components/Slide/constants.d.ts +1 -0
  51. package/dist/components/Slide/constants.es.js +5 -0
  52. package/dist/components/Slide/constants.es.js.map +1 -0
  53. package/dist/components/Slide/utils/imageOnlyStepVisualReady.cjs.js +2 -0
  54. package/dist/components/Slide/utils/imageOnlyStepVisualReady.cjs.js.map +1 -0
  55. package/dist/components/Slide/utils/imageOnlyStepVisualReady.d.ts +13 -0
  56. package/dist/components/Slide/utils/imageOnlyStepVisualReady.es.js +12 -0
  57. package/dist/components/Slide/utils/imageOnlyStepVisualReady.es.js.map +1 -0
  58. package/dist/components/Slide/utils/interactionPlayback.cjs.js +1 -1
  59. package/dist/components/Slide/utils/interactionPlayback.cjs.js.map +1 -1
  60. package/dist/components/Slide/utils/interactionPlayback.d.ts +8 -0
  61. package/dist/components/Slide/utils/interactionPlayback.es.js +9 -2
  62. package/dist/components/Slide/utils/interactionPlayback.es.js.map +1 -1
  63. package/dist/components/Slide/utils/interactionResolution.cjs.js +2 -0
  64. package/dist/components/Slide/utils/interactionResolution.cjs.js.map +1 -0
  65. package/dist/components/Slide/utils/interactionResolution.d.ts +13 -0
  66. package/dist/components/Slide/utils/interactionResolution.es.js +33 -0
  67. package/dist/components/Slide/utils/interactionResolution.es.js.map +1 -0
  68. package/dist/components/Slide/utils/interactionResolution.test.d.ts +1 -0
  69. package/dist/components/Slide/utils/markdownScaling.cjs.js +2 -0
  70. package/dist/components/Slide/utils/markdownScaling.cjs.js.map +1 -0
  71. package/dist/components/Slide/utils/markdownScaling.d.ts +7 -0
  72. package/dist/components/Slide/utils/markdownScaling.es.js +12 -0
  73. package/dist/components/Slide/utils/markdownScaling.es.js.map +1 -0
  74. package/dist/components/Slide/utils/markdownScaling.test.d.ts +1 -0
  75. package/dist/components/Slide/utils/silentStepAutoAdvance.cjs.js +2 -0
  76. package/dist/components/Slide/utils/silentStepAutoAdvance.cjs.js.map +1 -0
  77. package/dist/components/Slide/utils/silentStepAutoAdvance.d.ts +14 -0
  78. package/dist/components/Slide/utils/silentStepAutoAdvance.es.js +37 -0
  79. package/dist/components/Slide/utils/silentStepAutoAdvance.es.js.map +1 -0
  80. package/dist/components/Slide/utils/silentStepAutoAdvance.test.d.ts +1 -0
  81. package/dist/markdown-flow-ui-lib.css +1 -1
  82. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
- const i = `
1
+ import { PRESENTATION_DEFAULT_FONT_SIZE_PX as n, PRESENTATION_MIN_FONT_SIZE_PX as s, PRESENTATION_OVERFLOW_TOLERANCE_PX as i, PRESENTATION_MIN_BASE_FONT_SIZE_PX as r, PRESENTATION_WIDTH_FONT_DIVISOR as a, PRESENTATION_HEIGHT_FONT_RATIO as d } from "./presentation-scaling.es.js";
2
+ const l = `
2
3
  /* Gamma-style scaling base */
3
- :root { --mdf-fs: 16px; }
4
+ :root { --mdf-fs: ${n}px; }
4
5
 
5
6
  *, *::before, *::after {
6
7
  box-sizing: border-box;
@@ -25,13 +26,13 @@ html, body {
25
26
  /* Hide scrollbars inside scaled content — overflow handled by compression */
26
27
  .sandbox-container *::-webkit-scrollbar { display: none; }
27
28
  .sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }
28
- `, n = `
29
+ `, m = `
29
30
  !function() {
30
31
  var fitTimer = null;
31
- var baseFontSize = 16;
32
+ var baseFontSize = ${n};
32
33
  var compressionRatio = 1;
33
34
  var lastCompressTime = 0;
34
- var MIN_FONT_PX = 8;
35
+ var MIN_FONT_PX = ${s};
35
36
 
36
37
  function applyFs(fs) {
37
38
  document.documentElement.style.setProperty('--mdf-fs', fs + 'px');
@@ -48,8 +49,8 @@ html, body {
48
49
  var naturalH = slide.offsetHeight;
49
50
  var naturalW = slide.scrollWidth;
50
51
 
51
- var overflowH = naturalH > viewH + 4;
52
- var overflowW = naturalW > viewW + 4;
52
+ var overflowH = naturalH > viewH + ${i};
53
+ var overflowW = naturalW > viewW + ${i};
53
54
 
54
55
  if (overflowH || overflowW) {
55
56
  var now = Date.now();
@@ -84,7 +85,10 @@ html, body {
84
85
  function syncFs() {
85
86
  var w = document.documentElement.clientWidth;
86
87
  var h = document.documentElement.clientHeight;
87
- baseFontSize = Math.min(Math.max(12, w / 48), h * 0.03);
88
+ baseFontSize = Math.min(
89
+ Math.max(${r}, w / ${a}),
90
+ h * ${d}
91
+ );
88
92
  applyFs(Math.max(baseFontSize * compressionRatio, MIN_FONT_PX));
89
93
  clearTimeout(fitTimer);
90
94
  fitTimer = setTimeout(fitContent, 60);
@@ -158,13 +162,13 @@ html, body {
158
162
  };
159
163
  }();
160
164
  `;
161
- function s(e) {
165
+ function f(e) {
162
166
  const t = e.createElement("style");
163
- t.id = "mdf-scaling-style", t.textContent = i, e.head.appendChild(t);
167
+ t.id = "mdf-scaling-style", t.textContent = l, e.head.appendChild(t);
164
168
  const o = e.createElement("script");
165
- o.id = "mdf-scaling-script", o.textContent = n, e.head.appendChild(o);
169
+ o.id = "mdf-scaling-script", o.textContent = m, e.head.appendChild(o);
166
170
  }
167
171
  export {
168
- s as injectScalingSystem
172
+ f as injectScalingSystem
169
173
  };
170
174
  //# sourceMappingURL=iframe-scaling.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"iframe-scaling.es.js","sources":["../../../../src/components/ContentRender/utils/iframe-scaling.ts"],"sourcesContent":["/**\n * Gamma-style font-size scaling system for iframe sandbox.\n *\n * Injects CSS + JS into an iframe document so that:\n * 1. A base font-size is computed from the viewport: clamp(12px, width/48, height*3%)\n * 2. The CSS variable --mdf-fs drives html/body font-size; all em children follow.\n * 3. When content overflows the viewport, a compression ratio shrinks font-size.\n * 4. ResizeObserver / MutationObserver keep everything in sync.\n */\n\n/** Window extension for the scaling system injected into the iframe. */\nexport interface ScalingWindow extends Window {\n __mdf_triggerFitContent?: () => void;\n __mdf_cleanupScaling?: () => void;\n}\n\nconst SCALING_CSS = `\n/* Gamma-style scaling base */\n:root { --mdf-fs: 16px; }\n\n*, *::before, *::after {\n box-sizing: border-box;\n overflow-wrap: break-word;\n word-break: break-word;\n}\n\nhtml, body {\n font-size: var(--mdf-fs);\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n/* Force sandbox content children into the em scaling chain */\n.sandbox-container > * {\n height: auto !important;\n min-height: 100vh !important;\n overflow: hidden !important;\n font-size: var(--mdf-fs) !important;\n}\n\n/* Hide scrollbars inside scaled content — overflow handled by compression */\n.sandbox-container *::-webkit-scrollbar { display: none; }\n.sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }\n`;\n\nconst SCALING_JS = `\n!function() {\n var fitTimer = null;\n var baseFontSize = 16;\n var compressionRatio = 1;\n var lastCompressTime = 0;\n var MIN_FONT_PX = 8;\n\n function applyFs(fs) {\n document.documentElement.style.setProperty('--mdf-fs', fs + 'px');\n if (document.body) document.body.style.fontSize = fs + 'px';\n }\n\n function fitContent() {\n var container = document.querySelector('.sandbox-container');\n if (!container || !container.firstElementChild) return;\n\n var slide = container.firstElementChild;\n var viewH = document.documentElement.clientHeight;\n var viewW = document.documentElement.clientWidth;\n var naturalH = slide.offsetHeight;\n var naturalW = slide.scrollWidth;\n\n var overflowH = naturalH > viewH + 4;\n var overflowW = naturalW > viewW + 4;\n\n if (overflowH || overflowW) {\n var now = Date.now();\n if (now - lastCompressTime < 300) return;\n lastCompressTime = now;\n\n var ratioH = overflowH ? (viewH / naturalH) : 1;\n var ratioW = overflowW ? (viewW / naturalW) : 1;\n compressionRatio = compressionRatio * Math.min(ratioH, ratioW);\n compressionRatio = Math.max(compressionRatio, MIN_FONT_PX / baseFontSize);\n applyFs(baseFontSize * compressionRatio);\n\n if (baseFontSize * compressionRatio <= MIN_FONT_PX * 1.1 && viewH < 400) {\n document.documentElement.style.overflowY = 'hidden';\n if (document.body) document.body.style.overflowY = 'hidden';\n }\n } else {\n if (compressionRatio < 1 && naturalH > 0) {\n var maxRatio = viewH * compressionRatio / naturalH;\n if (maxRatio >= 1) {\n compressionRatio = 1;\n } else if (maxRatio > compressionRatio) {\n compressionRatio = maxRatio;\n }\n applyFs(baseFontSize * compressionRatio);\n }\n document.documentElement.style.overflowY = '';\n if (document.body) document.body.style.overflowY = '';\n }\n }\n\n function syncFs() {\n var w = document.documentElement.clientWidth;\n var h = document.documentElement.clientHeight;\n baseFontSize = Math.min(Math.max(12, w / 48), h * 0.03);\n applyFs(Math.max(baseFontSize * compressionRatio, MIN_FONT_PX));\n clearTimeout(fitTimer);\n fitTimer = setTimeout(fitContent, 60);\n }\n\n var rootResizeObs = null;\n if (window.ResizeObserver) {\n rootResizeObs = new ResizeObserver(syncFs);\n rootResizeObs.observe(document.documentElement);\n } else {\n window.addEventListener('resize', syncFs);\n }\n syncFs();\n\n var slideResizeObs = null;\n function observeSlide(slide) {\n if (!window.ResizeObserver) return;\n if (slideResizeObs) slideResizeObs.disconnect();\n slideResizeObs = new ResizeObserver(function() {\n clearTimeout(fitTimer);\n fitTimer = setTimeout(fitContent, 50);\n });\n slideResizeObs.observe(slide);\n }\n\n var mutationObs = null;\n function startFitObserver() {\n var c = document.querySelector('.sandbox-container');\n if (!c) return;\n mutationObs = new MutationObserver(function(mutations) {\n var hasNewContent = false;\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 &&\n node.tagName !== 'STYLE' && node.tagName !== 'SCRIPT') {\n hasNewContent = true;\n observeSlide(node);\n }\n });\n });\n if (hasNewContent) {\n compressionRatio = 1;\n lastCompressTime = 0;\n applyFs(baseFontSize);\n }\n clearTimeout(fitTimer);\n fitTimer = setTimeout(fitContent, 80);\n });\n mutationObs.observe(c, { childList: true });\n }\n\n if (document.readyState !== 'loading') {\n startFitObserver();\n } else {\n document.addEventListener('DOMContentLoaded', startFitObserver);\n }\n\n window.__mdf_triggerFitContent = function() {\n clearTimeout(fitTimer);\n fitTimer = setTimeout(fitContent, 100);\n };\n\n window.__mdf_cleanupScaling = function() {\n clearTimeout(fitTimer);\n if (rootResizeObs) rootResizeObs.disconnect();\n if (slideResizeObs) slideResizeObs.disconnect();\n if (mutationObs) mutationObs.disconnect();\n window.removeEventListener('resize', syncFs);\n delete window.__mdf_triggerFitContent;\n delete window.__mdf_cleanupScaling;\n };\n}();\n`;\n\n/**\n * Inject the Gamma-style font-size scaling system into an iframe document.\n * Must be called AFTER blackboard vendor libraries (Tailwind/DaisyUI/GSAP)\n * so that the scaling CSS rules take precedence.\n */\nexport function injectScalingSystem(doc: Document): void {\n const styleEl = doc.createElement(\"style\");\n styleEl.id = \"mdf-scaling-style\";\n styleEl.textContent = SCALING_CSS;\n doc.head.appendChild(styleEl);\n\n const scriptEl = doc.createElement(\"script\");\n scriptEl.id = \"mdf-scaling-script\";\n scriptEl.textContent = SCALING_JS;\n doc.head.appendChild(scriptEl);\n}\n"],"names":["SCALING_CSS","SCALING_JS","injectScalingSystem","doc","styleEl","scriptEl"],"mappings":"AAgBA,MAAMA,IAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GA6BdC,IAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2IZ,SAASC,EAAoBC,GAAqB;AACvD,QAAMC,IAAUD,EAAI,cAAc,OAAO;AACzC,EAAAC,EAAQ,KAAK,qBACbA,EAAQ,cAAcJ,GACtBG,EAAI,KAAK,YAAYC,CAAO;AAE5B,QAAMC,IAAWF,EAAI,cAAc,QAAQ;AAC3C,EAAAE,EAAS,KAAK,sBACdA,EAAS,cAAcJ,GACvBE,EAAI,KAAK,YAAYE,CAAQ;AAC/B;"}
1
+ {"version":3,"file":"iframe-scaling.es.js","sources":["../../../../src/components/ContentRender/utils/iframe-scaling.ts"],"sourcesContent":["/**\n * Gamma-style font-size scaling system for iframe sandbox.\n *\n * Injects CSS + JS into an iframe document so that:\n * 1. A base font-size is computed from the viewport: clamp(12px, width/48, height*3%)\n * 2. The CSS variable --mdf-fs drives html/body font-size; all em children follow.\n * 3. When content overflows the viewport, a compression ratio shrinks font-size.\n * 4. ResizeObserver / MutationObserver keep everything in sync.\n */\n\nimport {\n PRESENTATION_DEFAULT_FONT_SIZE_PX,\n PRESENTATION_HEIGHT_FONT_RATIO,\n PRESENTATION_MIN_BASE_FONT_SIZE_PX,\n PRESENTATION_MIN_FONT_SIZE_PX,\n PRESENTATION_OVERFLOW_TOLERANCE_PX,\n PRESENTATION_WIDTH_FONT_DIVISOR,\n} from \"./presentation-scaling\";\n\n/** Window extension for the scaling system injected into the iframe. */\nexport interface ScalingWindow extends Window {\n __mdf_triggerFitContent?: () => void;\n __mdf_cleanupScaling?: () => void;\n}\n\nconst SCALING_CSS = `\n/* Gamma-style scaling base */\n:root { --mdf-fs: ${PRESENTATION_DEFAULT_FONT_SIZE_PX}px; }\n\n*, *::before, *::after {\n box-sizing: border-box;\n overflow-wrap: break-word;\n word-break: break-word;\n}\n\nhtml, body {\n font-size: var(--mdf-fs);\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n/* Force sandbox content children into the em scaling chain */\n.sandbox-container > * {\n height: auto !important;\n min-height: 100vh !important;\n overflow: hidden !important;\n font-size: var(--mdf-fs) !important;\n}\n\n/* Hide scrollbars inside scaled content — overflow handled by compression */\n.sandbox-container *::-webkit-scrollbar { display: none; }\n.sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }\n`;\n\nconst SCALING_JS = `\n!function() {\n var fitTimer = null;\n var baseFontSize = ${PRESENTATION_DEFAULT_FONT_SIZE_PX};\n var compressionRatio = 1;\n var lastCompressTime = 0;\n var MIN_FONT_PX = ${PRESENTATION_MIN_FONT_SIZE_PX};\n\n function applyFs(fs) {\n document.documentElement.style.setProperty('--mdf-fs', fs + 'px');\n if (document.body) document.body.style.fontSize = fs + 'px';\n }\n\n function fitContent() {\n var container = document.querySelector('.sandbox-container');\n if (!container || !container.firstElementChild) return;\n\n var slide = container.firstElementChild;\n var viewH = document.documentElement.clientHeight;\n var viewW = document.documentElement.clientWidth;\n var naturalH = slide.offsetHeight;\n var naturalW = slide.scrollWidth;\n\n var overflowH = naturalH > viewH + ${PRESENTATION_OVERFLOW_TOLERANCE_PX};\n var overflowW = naturalW > viewW + ${PRESENTATION_OVERFLOW_TOLERANCE_PX};\n\n if (overflowH || overflowW) {\n var now = Date.now();\n if (now - lastCompressTime < 300) return;\n lastCompressTime = now;\n\n var ratioH = overflowH ? (viewH / naturalH) : 1;\n var ratioW = overflowW ? (viewW / naturalW) : 1;\n compressionRatio = compressionRatio * Math.min(ratioH, ratioW);\n compressionRatio = Math.max(compressionRatio, MIN_FONT_PX / baseFontSize);\n applyFs(baseFontSize * compressionRatio);\n\n if (baseFontSize * compressionRatio <= MIN_FONT_PX * 1.1 && viewH < 400) {\n document.documentElement.style.overflowY = 'hidden';\n if (document.body) document.body.style.overflowY = 'hidden';\n }\n } else {\n if (compressionRatio < 1 && naturalH > 0) {\n var maxRatio = viewH * compressionRatio / naturalH;\n if (maxRatio >= 1) {\n compressionRatio = 1;\n } else if (maxRatio > compressionRatio) {\n compressionRatio = maxRatio;\n }\n applyFs(baseFontSize * compressionRatio);\n }\n document.documentElement.style.overflowY = '';\n if (document.body) document.body.style.overflowY = '';\n }\n }\n\n function syncFs() {\n var w = document.documentElement.clientWidth;\n var h = document.documentElement.clientHeight;\n baseFontSize = Math.min(\n Math.max(${PRESENTATION_MIN_BASE_FONT_SIZE_PX}, w / ${PRESENTATION_WIDTH_FONT_DIVISOR}),\n h * ${PRESENTATION_HEIGHT_FONT_RATIO}\n );\n applyFs(Math.max(baseFontSize * compressionRatio, MIN_FONT_PX));\n clearTimeout(fitTimer);\n fitTimer = setTimeout(fitContent, 60);\n }\n\n var rootResizeObs = null;\n if (window.ResizeObserver) {\n rootResizeObs = new ResizeObserver(syncFs);\n rootResizeObs.observe(document.documentElement);\n } else {\n window.addEventListener('resize', syncFs);\n }\n syncFs();\n\n var slideResizeObs = null;\n function observeSlide(slide) {\n if (!window.ResizeObserver) return;\n if (slideResizeObs) slideResizeObs.disconnect();\n slideResizeObs = new ResizeObserver(function() {\n clearTimeout(fitTimer);\n fitTimer = setTimeout(fitContent, 50);\n });\n slideResizeObs.observe(slide);\n }\n\n var mutationObs = null;\n function startFitObserver() {\n var c = document.querySelector('.sandbox-container');\n if (!c) return;\n mutationObs = new MutationObserver(function(mutations) {\n var hasNewContent = false;\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 &&\n node.tagName !== 'STYLE' && node.tagName !== 'SCRIPT') {\n hasNewContent = true;\n observeSlide(node);\n }\n });\n });\n if (hasNewContent) {\n compressionRatio = 1;\n lastCompressTime = 0;\n applyFs(baseFontSize);\n }\n clearTimeout(fitTimer);\n fitTimer = setTimeout(fitContent, 80);\n });\n mutationObs.observe(c, { childList: true });\n }\n\n if (document.readyState !== 'loading') {\n startFitObserver();\n } else {\n document.addEventListener('DOMContentLoaded', startFitObserver);\n }\n\n window.__mdf_triggerFitContent = function() {\n clearTimeout(fitTimer);\n fitTimer = setTimeout(fitContent, 100);\n };\n\n window.__mdf_cleanupScaling = function() {\n clearTimeout(fitTimer);\n if (rootResizeObs) rootResizeObs.disconnect();\n if (slideResizeObs) slideResizeObs.disconnect();\n if (mutationObs) mutationObs.disconnect();\n window.removeEventListener('resize', syncFs);\n delete window.__mdf_triggerFitContent;\n delete window.__mdf_cleanupScaling;\n };\n}();\n`;\n\n/**\n * Inject the Gamma-style font-size scaling system into an iframe document.\n * Must be called AFTER blackboard vendor libraries (Tailwind/DaisyUI/GSAP)\n * so that the scaling CSS rules take precedence.\n */\nexport function injectScalingSystem(doc: Document): void {\n const styleEl = doc.createElement(\"style\");\n styleEl.id = \"mdf-scaling-style\";\n styleEl.textContent = SCALING_CSS;\n doc.head.appendChild(styleEl);\n\n const scriptEl = doc.createElement(\"script\");\n scriptEl.id = \"mdf-scaling-script\";\n scriptEl.textContent = SCALING_JS;\n doc.head.appendChild(scriptEl);\n}\n"],"names":["SCALING_CSS","PRESENTATION_DEFAULT_FONT_SIZE_PX","SCALING_JS","PRESENTATION_MIN_FONT_SIZE_PX","PRESENTATION_OVERFLOW_TOLERANCE_PX","PRESENTATION_MIN_BASE_FONT_SIZE_PX","PRESENTATION_WIDTH_FONT_DIVISOR","PRESENTATION_HEIGHT_FONT_RATIO","injectScalingSystem","doc","styleEl","scriptEl"],"mappings":";AAyBA,MAAMA,IAAc;AAAA;AAAA,oBAEAC,CAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GA2B/CC,IAAa;AAAA;AAAA;AAAA,uBAGID,CAAiC;AAAA;AAAA;AAAA,sBAGlCE,CAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAiBVC,CAAkC;AAAA,yCAClCA,CAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAoC1DC,CAAkC,SAASC,CAA+B;AAAA,YAC/EC,CAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiFnC,SAASC,EAAoBC,GAAqB;AACvD,QAAMC,IAAUD,EAAI,cAAc,OAAO;AACzC,EAAAC,EAAQ,KAAK,qBACbA,EAAQ,cAAcV,GACtBS,EAAI,KAAK,YAAYC,CAAO;AAE5B,QAAMC,IAAWF,EAAI,cAAc,QAAQ;AAC3C,EAAAE,EAAS,KAAK,sBACdA,EAAS,cAAcT,GACvBO,EAAI,KAAK,YAAYE,CAAQ;AAC/B;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=t=>{const e=t?.trim().toLowerCase()??"";return!(!e||e.startsWith("#")||e.startsWith("javascript:")||e.startsWith("data:")||e.startsWith("mailto:")||e.startsWith("tel:"))},o=t=>t?.tagName?.toLowerCase()==="a",a=t=>{const e=t;if(!e)return null;if(typeof e.closest=="function"){const n=e.closest("a[href]");return o(n)?n:null}const r=e.parentElement?.closest("a[href]");return o(r)?r:null},l=t=>{const e=new Set((t??"").split(/\s+/).map(r=>r.trim()).filter(Boolean));return e.add("noopener"),e.add("noreferrer"),Array.from(e).join(" ")};exports.isAnchorElement=o;exports.mergeAnchorRelValue=l;exports.resolveClosestAnchor=a;exports.shouldForceAnchorHrefToNewTab=s;
2
+ //# sourceMappingURL=link-targets.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-targets.cjs.js","sources":["../../../../src/components/ContentRender/utils/link-targets.ts"],"sourcesContent":["export const shouldForceAnchorHrefToNewTab = (href: string | null) => {\n const normalizedHref = href?.trim().toLowerCase() ?? \"\";\n\n if (!normalizedHref) {\n return false;\n }\n\n if (\n normalizedHref.startsWith(\"#\") ||\n normalizedHref.startsWith(\"javascript:\") ||\n normalizedHref.startsWith(\"data:\") ||\n normalizedHref.startsWith(\"mailto:\") ||\n normalizedHref.startsWith(\"tel:\")\n ) {\n return false;\n }\n\n return true;\n};\n\nexport const isAnchorElement = (\n node: { tagName?: string | null } | null | undefined\n): node is HTMLAnchorElement => node?.tagName?.toLowerCase() === \"a\";\n\nexport const resolveClosestAnchor = (target: EventTarget | null) => {\n const candidate = target as {\n closest?: (selector: string) => Element | null;\n parentElement?: Element | null;\n } | null;\n\n if (!candidate) {\n return null;\n }\n\n if (typeof candidate.closest === \"function\") {\n const anchor = candidate.closest(\"a[href]\");\n return isAnchorElement(anchor) ? anchor : null;\n }\n\n const anchor = candidate.parentElement?.closest(\"a[href]\");\n return isAnchorElement(anchor) ? anchor : null;\n};\n\nexport const mergeAnchorRelValue = (rel: string | null) => {\n const tokens = new Set(\n (rel ?? \"\")\n .split(/\\s+/)\n .map((token) => token.trim())\n .filter(Boolean)\n );\n\n tokens.add(\"noopener\");\n tokens.add(\"noreferrer\");\n\n return Array.from(tokens).join(\" \");\n};\n"],"names":["shouldForceAnchorHrefToNewTab","href","normalizedHref","isAnchorElement","node","resolveClosestAnchor","target","candidate","anchor","mergeAnchorRelValue","rel","tokens","token"],"mappings":"gFAAO,MAAMA,EAAiCC,GAAwB,CACpE,MAAMC,EAAiBD,GAAM,KAAA,EAAO,eAAiB,GAMrD,MAJI,GAACC,GAKHA,EAAe,WAAW,GAAG,GAC7BA,EAAe,WAAW,aAAa,GACvCA,EAAe,WAAW,OAAO,GACjCA,EAAe,WAAW,SAAS,GACnCA,EAAe,WAAW,MAAM,EAMpC,EAEaC,EACXC,GAC8BA,GAAM,SAAS,gBAAkB,IAEpDC,EAAwBC,GAA+B,CAClE,MAAMC,EAAYD,EAKlB,GAAI,CAACC,EACH,OAAO,KAGT,GAAI,OAAOA,EAAU,SAAY,WAAY,CAC3C,MAAMC,EAASD,EAAU,QAAQ,SAAS,EAC1C,OAAOJ,EAAgBK,CAAM,EAAIA,EAAS,IAC5C,CAEA,MAAMA,EAASD,EAAU,eAAe,QAAQ,SAAS,EACzD,OAAOJ,EAAgBK,CAAM,EAAIA,EAAS,IAC5C,EAEaC,EAAuBC,GAAuB,CACzD,MAAMC,EAAS,IAAI,KAChBD,GAAO,IACL,MAAM,KAAK,EACX,IAAKE,GAAUA,EAAM,MAAM,EAC3B,OAAO,OAAO,CAAA,EAGnB,OAAAD,EAAO,IAAI,UAAU,EACrBA,EAAO,IAAI,YAAY,EAEhB,MAAM,KAAKA,CAAM,EAAE,KAAK,GAAG,CACpC"}
@@ -0,0 +1,6 @@
1
+ export declare const shouldForceAnchorHrefToNewTab: (href: string | null) => boolean;
2
+ export declare const isAnchorElement: (node: {
3
+ tagName?: string | null;
4
+ } | null | undefined) => node is HTMLAnchorElement;
5
+ export declare const resolveClosestAnchor: (target: EventTarget | null) => HTMLAnchorElement | null;
6
+ export declare const mergeAnchorRelValue: (rel: string | null) => string;
@@ -0,0 +1,26 @@
1
+ const s = (e) => {
2
+ const t = e?.trim().toLowerCase() ?? "";
3
+ return !(!t || t.startsWith("#") || t.startsWith("javascript:") || t.startsWith("data:") || t.startsWith("mailto:") || t.startsWith("tel:"));
4
+ }, n = (e) => e?.tagName?.toLowerCase() === "a", a = (e) => {
5
+ const t = e;
6
+ if (!t)
7
+ return null;
8
+ if (typeof t.closest == "function") {
9
+ const o = t.closest("a[href]");
10
+ return n(o) ? o : null;
11
+ }
12
+ const r = t.parentElement?.closest("a[href]");
13
+ return n(r) ? r : null;
14
+ }, l = (e) => {
15
+ const t = new Set(
16
+ (e ?? "").split(/\s+/).map((r) => r.trim()).filter(Boolean)
17
+ );
18
+ return t.add("noopener"), t.add("noreferrer"), Array.from(t).join(" ");
19
+ };
20
+ export {
21
+ n as isAnchorElement,
22
+ l as mergeAnchorRelValue,
23
+ a as resolveClosestAnchor,
24
+ s as shouldForceAnchorHrefToNewTab
25
+ };
26
+ //# sourceMappingURL=link-targets.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-targets.es.js","sources":["../../../../src/components/ContentRender/utils/link-targets.ts"],"sourcesContent":["export const shouldForceAnchorHrefToNewTab = (href: string | null) => {\n const normalizedHref = href?.trim().toLowerCase() ?? \"\";\n\n if (!normalizedHref) {\n return false;\n }\n\n if (\n normalizedHref.startsWith(\"#\") ||\n normalizedHref.startsWith(\"javascript:\") ||\n normalizedHref.startsWith(\"data:\") ||\n normalizedHref.startsWith(\"mailto:\") ||\n normalizedHref.startsWith(\"tel:\")\n ) {\n return false;\n }\n\n return true;\n};\n\nexport const isAnchorElement = (\n node: { tagName?: string | null } | null | undefined\n): node is HTMLAnchorElement => node?.tagName?.toLowerCase() === \"a\";\n\nexport const resolveClosestAnchor = (target: EventTarget | null) => {\n const candidate = target as {\n closest?: (selector: string) => Element | null;\n parentElement?: Element | null;\n } | null;\n\n if (!candidate) {\n return null;\n }\n\n if (typeof candidate.closest === \"function\") {\n const anchor = candidate.closest(\"a[href]\");\n return isAnchorElement(anchor) ? anchor : null;\n }\n\n const anchor = candidate.parentElement?.closest(\"a[href]\");\n return isAnchorElement(anchor) ? anchor : null;\n};\n\nexport const mergeAnchorRelValue = (rel: string | null) => {\n const tokens = new Set(\n (rel ?? \"\")\n .split(/\\s+/)\n .map((token) => token.trim())\n .filter(Boolean)\n );\n\n tokens.add(\"noopener\");\n tokens.add(\"noreferrer\");\n\n return Array.from(tokens).join(\" \");\n};\n"],"names":["shouldForceAnchorHrefToNewTab","href","normalizedHref","isAnchorElement","node","resolveClosestAnchor","target","candidate","anchor","mergeAnchorRelValue","rel","tokens","token"],"mappings":"AAAO,MAAMA,IAAgC,CAACC,MAAwB;AACpE,QAAMC,IAAiBD,GAAM,KAAA,EAAO,iBAAiB;AAMrD,SAJI,GAACC,KAKHA,EAAe,WAAW,GAAG,KAC7BA,EAAe,WAAW,aAAa,KACvCA,EAAe,WAAW,OAAO,KACjCA,EAAe,WAAW,SAAS,KACnCA,EAAe,WAAW,MAAM;AAMpC,GAEaC,IAAkB,CAC7BC,MAC8BA,GAAM,SAAS,kBAAkB,KAEpDC,IAAuB,CAACC,MAA+B;AAClE,QAAMC,IAAYD;AAKlB,MAAI,CAACC;AACH,WAAO;AAGT,MAAI,OAAOA,EAAU,WAAY,YAAY;AAC3C,UAAMC,IAASD,EAAU,QAAQ,SAAS;AAC1C,WAAOJ,EAAgBK,CAAM,IAAIA,IAAS;AAAA,EAC5C;AAEA,QAAMA,IAASD,EAAU,eAAe,QAAQ,SAAS;AACzD,SAAOJ,EAAgBK,CAAM,IAAIA,IAAS;AAC5C,GAEaC,IAAsB,CAACC,MAAuB;AACzD,QAAMC,IAAS,IAAI;AAAA,KAChBD,KAAO,IACL,MAAM,KAAK,EACX,IAAI,CAACE,MAAUA,EAAM,MAAM,EAC3B,OAAO,OAAO;AAAA,EAAA;AAGnB,SAAAD,EAAO,IAAI,UAAU,GACrBA,EAAO,IAAI,YAAY,GAEhB,MAAM,KAAKA,CAAM,EAAE,KAAK,GAAG;AACpC;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=16,h=12,N=8,S=48,r=.03,T=4,A=8,c=.05,o=i=>Number.isFinite(i)&&i>0,P=({height:i,width:t})=>!o(t)||!o(i)?a:Math.max(N,Math.min(Math.max(h,t/S),i*r)),R=(i,t)=>t.height<=i.height+T&&t.width<=i.width+T,F=({baseFontSize:i,content:t,currentRatio:s=1,viewport:n})=>{if(!o(i)||!o(n.width)||!o(n.height)||!o(t.width)||!o(t.height))return 1;const e=t.height>n.height+T?n.height/t.height:1,_=t.width>n.width+T?n.width/t.width:1,E=Math.min(1,N/i);return Math.max(E,Math.min(1,s*Math.min(e,_)))},m=({measure:i,viewport:t})=>{const s=P(t);let n=1,e=s;for(let _=0;_<A;_+=1){const E=i(e);if(R(t,E))return e;const O=F({baseFontSize:s,content:E,currentRatio:n,viewport:t}),I=Math.max(N,s*O);if(Math.abs(I-e)<c)return I;n=O,e=I}return e};exports.PRESENTATION_DEFAULT_FONT_SIZE_PX=a;exports.PRESENTATION_HEIGHT_FONT_RATIO=r;exports.PRESENTATION_MIN_BASE_FONT_SIZE_PX=h;exports.PRESENTATION_MIN_FONT_SIZE_PX=N;exports.PRESENTATION_OVERFLOW_TOLERANCE_PX=T;exports.PRESENTATION_WIDTH_FONT_DIVISOR=S;exports.fitPresentationFontSize=m;exports.presentationContentFits=R;exports.resolvePresentationBaseFontSize=P;exports.resolvePresentationCompressionRatio=F;
2
+ //# sourceMappingURL=presentation-scaling.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation-scaling.cjs.js","sources":["../../../../src/components/ContentRender/utils/presentation-scaling.ts"],"sourcesContent":["export const PRESENTATION_DEFAULT_FONT_SIZE_PX = 16;\nexport const PRESENTATION_MIN_BASE_FONT_SIZE_PX = 12;\nexport const PRESENTATION_MIN_FONT_SIZE_PX = 8;\nexport const PRESENTATION_WIDTH_FONT_DIVISOR = 48;\nexport const PRESENTATION_HEIGHT_FONT_RATIO = 0.03;\nexport const PRESENTATION_OVERFLOW_TOLERANCE_PX = 4;\n\nconst MAX_FIT_ITERATIONS = 8;\nconst MIN_FONT_SIZE_DELTA_PX = 0.05;\n\nexport interface PresentationSize {\n height: number;\n width: number;\n}\n\nexport interface FitPresentationFontSizeOptions {\n measure: (fontSize: number) => PresentationSize;\n viewport: PresentationSize;\n}\n\nconst isPositiveFinite = (value: number) => Number.isFinite(value) && value > 0;\n\n/**\n * Matches the viewport-driven base font-size used by HTML presentation slides.\n */\nexport const resolvePresentationBaseFontSize = ({\n height,\n width,\n}: PresentationSize) => {\n if (!isPositiveFinite(width) || !isPositiveFinite(height)) {\n return PRESENTATION_DEFAULT_FONT_SIZE_PX;\n }\n\n return Math.max(\n PRESENTATION_MIN_FONT_SIZE_PX,\n Math.min(\n Math.max(\n PRESENTATION_MIN_BASE_FONT_SIZE_PX,\n width / PRESENTATION_WIDTH_FONT_DIVISOR\n ),\n height * PRESENTATION_HEIGHT_FONT_RATIO\n )\n );\n};\n\nexport const presentationContentFits = (\n viewport: PresentationSize,\n content: PresentationSize\n) =>\n content.height <= viewport.height + PRESENTATION_OVERFLOW_TOLERANCE_PX &&\n content.width <= viewport.width + PRESENTATION_OVERFLOW_TOLERANCE_PX;\n\nexport interface ResolvePresentationCompressionRatioOptions {\n baseFontSize: number;\n content: PresentationSize;\n currentRatio?: number;\n viewport: PresentationSize;\n}\n\n/**\n * Returns the next cumulative compression ratio for content that overflows.\n */\nexport const resolvePresentationCompressionRatio = ({\n baseFontSize,\n content,\n currentRatio = 1,\n viewport,\n}: ResolvePresentationCompressionRatioOptions) => {\n if (\n !isPositiveFinite(baseFontSize) ||\n !isPositiveFinite(viewport.width) ||\n !isPositiveFinite(viewport.height) ||\n !isPositiveFinite(content.width) ||\n !isPositiveFinite(content.height)\n ) {\n return 1;\n }\n\n const heightRatio =\n content.height > viewport.height + PRESENTATION_OVERFLOW_TOLERANCE_PX\n ? viewport.height / content.height\n : 1;\n const widthRatio =\n content.width > viewport.width + PRESENTATION_OVERFLOW_TOLERANCE_PX\n ? viewport.width / content.width\n : 1;\n const minimumRatio = Math.min(\n 1,\n PRESENTATION_MIN_FONT_SIZE_PX / baseFontSize\n );\n\n return Math.max(\n minimumRatio,\n Math.min(1, currentRatio * Math.min(heightRatio, widthRatio))\n );\n};\n\n/**\n * Applies the presentation font-size through `measure` and iteratively shrinks\n * it until the content fits or reaches the shared 8px lower bound.\n */\nexport const fitPresentationFontSize = ({\n measure,\n viewport,\n}: FitPresentationFontSizeOptions) => {\n const baseFontSize = resolvePresentationBaseFontSize(viewport);\n let compressionRatio = 1;\n let fontSize = baseFontSize;\n\n for (let iteration = 0; iteration < MAX_FIT_ITERATIONS; iteration += 1) {\n const content = measure(fontSize);\n\n if (presentationContentFits(viewport, content)) {\n return fontSize;\n }\n\n const nextCompressionRatio = resolvePresentationCompressionRatio({\n baseFontSize,\n content,\n currentRatio: compressionRatio,\n viewport,\n });\n const nextFontSize = Math.max(\n PRESENTATION_MIN_FONT_SIZE_PX,\n baseFontSize * nextCompressionRatio\n );\n\n if (Math.abs(nextFontSize - fontSize) < MIN_FONT_SIZE_DELTA_PX) {\n return nextFontSize;\n }\n\n compressionRatio = nextCompressionRatio;\n fontSize = nextFontSize;\n }\n\n return fontSize;\n};\n"],"names":["PRESENTATION_DEFAULT_FONT_SIZE_PX","PRESENTATION_MIN_BASE_FONT_SIZE_PX","PRESENTATION_MIN_FONT_SIZE_PX","PRESENTATION_WIDTH_FONT_DIVISOR","PRESENTATION_HEIGHT_FONT_RATIO","PRESENTATION_OVERFLOW_TOLERANCE_PX","MAX_FIT_ITERATIONS","MIN_FONT_SIZE_DELTA_PX","isPositiveFinite","value","resolvePresentationBaseFontSize","height","width","presentationContentFits","viewport","content","resolvePresentationCompressionRatio","baseFontSize","currentRatio","heightRatio","widthRatio","minimumRatio","fitPresentationFontSize","measure","compressionRatio","fontSize","iteration","nextCompressionRatio","nextFontSize"],"mappings":"gFAAO,MAAMA,EAAoC,GACpCC,EAAqC,GACrCC,EAAgC,EAChCC,EAAkC,GAClCC,EAAiC,IACjCC,EAAqC,EAE5CC,EAAqB,EACrBC,EAAyB,IAYzBC,EAAoBC,GAAkB,OAAO,SAASA,CAAK,GAAKA,EAAQ,EAKjEC,EAAkC,CAAC,CAC9C,OAAAC,EACA,MAAAC,CACF,IACM,CAACJ,EAAiBI,CAAK,GAAK,CAACJ,EAAiBG,CAAM,EAC/CX,EAGF,KAAK,IACVE,EACA,KAAK,IACH,KAAK,IACHD,EACAW,EAAQT,CAAA,EAEVQ,EAASP,CAAA,CACX,EAISS,EAA0B,CACrCC,EACAC,IAEAA,EAAQ,QAAUD,EAAS,OAAST,GACpCU,EAAQ,OAASD,EAAS,MAAQT,EAYvBW,EAAsC,CAAC,CAClD,aAAAC,EACA,QAAAF,EACA,aAAAG,EAAe,EACf,SAAAJ,CACF,IAAkD,CAChD,GACE,CAACN,EAAiBS,CAAY,GAC9B,CAACT,EAAiBM,EAAS,KAAK,GAChC,CAACN,EAAiBM,EAAS,MAAM,GACjC,CAACN,EAAiBO,EAAQ,KAAK,GAC/B,CAACP,EAAiBO,EAAQ,MAAM,EAEhC,MAAO,GAGT,MAAMI,EACJJ,EAAQ,OAASD,EAAS,OAAST,EAC/BS,EAAS,OAASC,EAAQ,OAC1B,EACAK,EACJL,EAAQ,MAAQD,EAAS,MAAQT,EAC7BS,EAAS,MAAQC,EAAQ,MACzB,EACAM,EAAe,KAAK,IACxB,EACAnB,EAAgCe,CAAA,EAGlC,OAAO,KAAK,IACVI,EACA,KAAK,IAAI,EAAGH,EAAe,KAAK,IAAIC,EAAaC,CAAU,CAAC,CAAA,CAEhE,EAMaE,EAA0B,CAAC,CACtC,QAAAC,EACA,SAAAT,CACF,IAAsC,CACpC,MAAMG,EAAeP,EAAgCI,CAAQ,EAC7D,IAAIU,EAAmB,EACnBC,EAAWR,EAEf,QAASS,EAAY,EAAGA,EAAYpB,EAAoBoB,GAAa,EAAG,CACtE,MAAMX,EAAUQ,EAAQE,CAAQ,EAEhC,GAAIZ,EAAwBC,EAAUC,CAAO,EAC3C,OAAOU,EAGT,MAAME,EAAuBX,EAAoC,CAC/D,aAAAC,EACA,QAAAF,EACA,aAAcS,EACd,SAAAV,CAAA,CACD,EACKc,EAAe,KAAK,IACxB1B,EACAe,EAAeU,CAAA,EAGjB,GAAI,KAAK,IAAIC,EAAeH,CAAQ,EAAIlB,EACtC,OAAOqB,EAGTJ,EAAmBG,EACnBF,EAAWG,CACb,CAEA,OAAOH,CACT"}
@@ -0,0 +1,34 @@
1
+ export declare const PRESENTATION_DEFAULT_FONT_SIZE_PX = 16;
2
+ export declare const PRESENTATION_MIN_BASE_FONT_SIZE_PX = 12;
3
+ export declare const PRESENTATION_MIN_FONT_SIZE_PX = 8;
4
+ export declare const PRESENTATION_WIDTH_FONT_DIVISOR = 48;
5
+ export declare const PRESENTATION_HEIGHT_FONT_RATIO = 0.03;
6
+ export declare const PRESENTATION_OVERFLOW_TOLERANCE_PX = 4;
7
+ export interface PresentationSize {
8
+ height: number;
9
+ width: number;
10
+ }
11
+ export interface FitPresentationFontSizeOptions {
12
+ measure: (fontSize: number) => PresentationSize;
13
+ viewport: PresentationSize;
14
+ }
15
+ /**
16
+ * Matches the viewport-driven base font-size used by HTML presentation slides.
17
+ */
18
+ export declare const resolvePresentationBaseFontSize: ({ height, width, }: PresentationSize) => number;
19
+ export declare const presentationContentFits: (viewport: PresentationSize, content: PresentationSize) => boolean;
20
+ export interface ResolvePresentationCompressionRatioOptions {
21
+ baseFontSize: number;
22
+ content: PresentationSize;
23
+ currentRatio?: number;
24
+ viewport: PresentationSize;
25
+ }
26
+ /**
27
+ * Returns the next cumulative compression ratio for content that overflows.
28
+ */
29
+ export declare const resolvePresentationCompressionRatio: ({ baseFontSize, content, currentRatio, viewport, }: ResolvePresentationCompressionRatioOptions) => number;
30
+ /**
31
+ * Applies the presentation font-size through `measure` and iteratively shrinks
32
+ * it until the content fits or reaches the shared 8px lower bound.
33
+ */
34
+ export declare const fitPresentationFontSize: ({ measure, viewport, }: FitPresentationFontSizeOptions) => number;
@@ -0,0 +1,67 @@
1
+ const o = 16, e = 12, A = 8, h = 48, F = 0.03, a = 4;
2
+ const N = (t) => Number.isFinite(t) && t > 0, s = ({
3
+ height: t,
4
+ width: _
5
+ }) => !N(_) || !N(t) ? 16 : Math.max(
6
+ 8,
7
+ Math.min(
8
+ Math.max(
9
+ 12,
10
+ _ / 48
11
+ ),
12
+ t * 0.03
13
+ )
14
+ ), S = (t, _) => _.height <= t.height + 4 && _.width <= t.width + 4, P = ({
15
+ baseFontSize: t,
16
+ content: _,
17
+ currentRatio: O = 1,
18
+ viewport: E
19
+ }) => {
20
+ if (!N(t) || !N(E.width) || !N(E.height) || !N(_.width) || !N(_.height))
21
+ return 1;
22
+ const T = _.height > E.height + 4 ? E.height / _.height : 1, I = _.width > E.width + 4 ? E.width / _.width : 1, i = Math.min(
23
+ 1,
24
+ 8 / t
25
+ );
26
+ return Math.max(
27
+ i,
28
+ Math.min(1, O * Math.min(T, I))
29
+ );
30
+ }, r = ({
31
+ measure: t,
32
+ viewport: _
33
+ }) => {
34
+ const O = s(_);
35
+ let E = 1, T = O;
36
+ for (let I = 0; I < 8; I += 1) {
37
+ const i = t(T);
38
+ if (S(_, i))
39
+ return T;
40
+ const R = P({
41
+ baseFontSize: O,
42
+ content: i,
43
+ currentRatio: E,
44
+ viewport: _
45
+ }), n = Math.max(
46
+ 8,
47
+ O * R
48
+ );
49
+ if (Math.abs(n - T) < 0.05)
50
+ return n;
51
+ E = R, T = n;
52
+ }
53
+ return T;
54
+ };
55
+ export {
56
+ o as PRESENTATION_DEFAULT_FONT_SIZE_PX,
57
+ F as PRESENTATION_HEIGHT_FONT_RATIO,
58
+ e as PRESENTATION_MIN_BASE_FONT_SIZE_PX,
59
+ A as PRESENTATION_MIN_FONT_SIZE_PX,
60
+ a as PRESENTATION_OVERFLOW_TOLERANCE_PX,
61
+ h as PRESENTATION_WIDTH_FONT_DIVISOR,
62
+ r as fitPresentationFontSize,
63
+ S as presentationContentFits,
64
+ s as resolvePresentationBaseFontSize,
65
+ P as resolvePresentationCompressionRatio
66
+ };
67
+ //# sourceMappingURL=presentation-scaling.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation-scaling.es.js","sources":["../../../../src/components/ContentRender/utils/presentation-scaling.ts"],"sourcesContent":["export const PRESENTATION_DEFAULT_FONT_SIZE_PX = 16;\nexport const PRESENTATION_MIN_BASE_FONT_SIZE_PX = 12;\nexport const PRESENTATION_MIN_FONT_SIZE_PX = 8;\nexport const PRESENTATION_WIDTH_FONT_DIVISOR = 48;\nexport const PRESENTATION_HEIGHT_FONT_RATIO = 0.03;\nexport const PRESENTATION_OVERFLOW_TOLERANCE_PX = 4;\n\nconst MAX_FIT_ITERATIONS = 8;\nconst MIN_FONT_SIZE_DELTA_PX = 0.05;\n\nexport interface PresentationSize {\n height: number;\n width: number;\n}\n\nexport interface FitPresentationFontSizeOptions {\n measure: (fontSize: number) => PresentationSize;\n viewport: PresentationSize;\n}\n\nconst isPositiveFinite = (value: number) => Number.isFinite(value) && value > 0;\n\n/**\n * Matches the viewport-driven base font-size used by HTML presentation slides.\n */\nexport const resolvePresentationBaseFontSize = ({\n height,\n width,\n}: PresentationSize) => {\n if (!isPositiveFinite(width) || !isPositiveFinite(height)) {\n return PRESENTATION_DEFAULT_FONT_SIZE_PX;\n }\n\n return Math.max(\n PRESENTATION_MIN_FONT_SIZE_PX,\n Math.min(\n Math.max(\n PRESENTATION_MIN_BASE_FONT_SIZE_PX,\n width / PRESENTATION_WIDTH_FONT_DIVISOR\n ),\n height * PRESENTATION_HEIGHT_FONT_RATIO\n )\n );\n};\n\nexport const presentationContentFits = (\n viewport: PresentationSize,\n content: PresentationSize\n) =>\n content.height <= viewport.height + PRESENTATION_OVERFLOW_TOLERANCE_PX &&\n content.width <= viewport.width + PRESENTATION_OVERFLOW_TOLERANCE_PX;\n\nexport interface ResolvePresentationCompressionRatioOptions {\n baseFontSize: number;\n content: PresentationSize;\n currentRatio?: number;\n viewport: PresentationSize;\n}\n\n/**\n * Returns the next cumulative compression ratio for content that overflows.\n */\nexport const resolvePresentationCompressionRatio = ({\n baseFontSize,\n content,\n currentRatio = 1,\n viewport,\n}: ResolvePresentationCompressionRatioOptions) => {\n if (\n !isPositiveFinite(baseFontSize) ||\n !isPositiveFinite(viewport.width) ||\n !isPositiveFinite(viewport.height) ||\n !isPositiveFinite(content.width) ||\n !isPositiveFinite(content.height)\n ) {\n return 1;\n }\n\n const heightRatio =\n content.height > viewport.height + PRESENTATION_OVERFLOW_TOLERANCE_PX\n ? viewport.height / content.height\n : 1;\n const widthRatio =\n content.width > viewport.width + PRESENTATION_OVERFLOW_TOLERANCE_PX\n ? viewport.width / content.width\n : 1;\n const minimumRatio = Math.min(\n 1,\n PRESENTATION_MIN_FONT_SIZE_PX / baseFontSize\n );\n\n return Math.max(\n minimumRatio,\n Math.min(1, currentRatio * Math.min(heightRatio, widthRatio))\n );\n};\n\n/**\n * Applies the presentation font-size through `measure` and iteratively shrinks\n * it until the content fits or reaches the shared 8px lower bound.\n */\nexport const fitPresentationFontSize = ({\n measure,\n viewport,\n}: FitPresentationFontSizeOptions) => {\n const baseFontSize = resolvePresentationBaseFontSize(viewport);\n let compressionRatio = 1;\n let fontSize = baseFontSize;\n\n for (let iteration = 0; iteration < MAX_FIT_ITERATIONS; iteration += 1) {\n const content = measure(fontSize);\n\n if (presentationContentFits(viewport, content)) {\n return fontSize;\n }\n\n const nextCompressionRatio = resolvePresentationCompressionRatio({\n baseFontSize,\n content,\n currentRatio: compressionRatio,\n viewport,\n });\n const nextFontSize = Math.max(\n PRESENTATION_MIN_FONT_SIZE_PX,\n baseFontSize * nextCompressionRatio\n );\n\n if (Math.abs(nextFontSize - fontSize) < MIN_FONT_SIZE_DELTA_PX) {\n return nextFontSize;\n }\n\n compressionRatio = nextCompressionRatio;\n fontSize = nextFontSize;\n }\n\n return fontSize;\n};\n"],"names":["PRESENTATION_DEFAULT_FONT_SIZE_PX","PRESENTATION_MIN_BASE_FONT_SIZE_PX","PRESENTATION_MIN_FONT_SIZE_PX","PRESENTATION_WIDTH_FONT_DIVISOR","PRESENTATION_HEIGHT_FONT_RATIO","PRESENTATION_OVERFLOW_TOLERANCE_PX","isPositiveFinite","value","resolvePresentationBaseFontSize","height","width","presentationContentFits","viewport","content","resolvePresentationCompressionRatio","baseFontSize","currentRatio","heightRatio","widthRatio","minimumRatio","fitPresentationFontSize","measure","compressionRatio","fontSize","iteration","nextCompressionRatio","nextFontSize"],"mappings":"AAAO,MAAMA,IAAoC,IACpCC,IAAqC,IACrCC,IAAgC,GAChCC,IAAkC,IAClCC,IAAiC,MACjCC,IAAqC;AAelD,MAAMC,IAAmB,CAACC,MAAkB,OAAO,SAASA,CAAK,KAAKA,IAAQ,GAKjEC,IAAkC,CAAC;AAAA,EAC9C,QAAAC;AAAA,EACA,OAAAC;AACF,MACM,CAACJ,EAAiBI,CAAK,KAAK,CAACJ,EAAiBG,CAAM,IAC/C,KAGF,KAAK;AAAA,EACV;AAAA,EACA,KAAK;AAAA,IACH,KAAK;AAAA,MACH;AAAA,MACAC,IAAQ;AAAA,IAAA;AAAA,IAEVD,IAAS;AAAA,EAAA;AACX,GAISE,IAA0B,CACrCC,GACAC,MAEAA,EAAQ,UAAUD,EAAS,SAAS,KACpCC,EAAQ,SAASD,EAAS,QAAQ,GAYvBE,IAAsC,CAAC;AAAA,EAClD,cAAAC;AAAA,EACA,SAAAF;AAAA,EACA,cAAAG,IAAe;AAAA,EACf,UAAAJ;AACF,MAAkD;AAChD,MACE,CAACN,EAAiBS,CAAY,KAC9B,CAACT,EAAiBM,EAAS,KAAK,KAChC,CAACN,EAAiBM,EAAS,MAAM,KACjC,CAACN,EAAiBO,EAAQ,KAAK,KAC/B,CAACP,EAAiBO,EAAQ,MAAM;AAEhC,WAAO;AAGT,QAAMI,IACJJ,EAAQ,SAASD,EAAS,SAAS,IAC/BA,EAAS,SAASC,EAAQ,SAC1B,GACAK,IACJL,EAAQ,QAAQD,EAAS,QAAQ,IAC7BA,EAAS,QAAQC,EAAQ,QACzB,GACAM,IAAe,KAAK;AAAA,IACxB;AAAA,IACA,IAAgCJ;AAAA,EAAA;AAGlC,SAAO,KAAK;AAAA,IACVI;AAAA,IACA,KAAK,IAAI,GAAGH,IAAe,KAAK,IAAIC,GAAaC,CAAU,CAAC;AAAA,EAAA;AAEhE,GAMaE,IAA0B,CAAC;AAAA,EACtC,SAAAC;AAAA,EACA,UAAAT;AACF,MAAsC;AACpC,QAAMG,IAAeP,EAAgCI,CAAQ;AAC7D,MAAIU,IAAmB,GACnBC,IAAWR;AAEf,WAASS,IAAY,GAAGA,IAAY,GAAoBA,KAAa,GAAG;AACtE,UAAMX,IAAUQ,EAAQE,CAAQ;AAEhC,QAAIZ,EAAwBC,GAAUC,CAAO;AAC3C,aAAOU;AAGT,UAAME,IAAuBX,EAAoC;AAAA,MAC/D,cAAAC;AAAA,MACA,SAAAF;AAAA,MACA,cAAcS;AAAA,MACd,UAAAV;AAAA,IAAA,CACD,GACKc,IAAe,KAAK;AAAA,MACxB;AAAA,MACAX,IAAeU;AAAA,IAAA;AAGjB,QAAI,KAAK,IAAIC,IAAeH,CAAQ,IAAI;AACtC,aAAOG;AAGT,IAAAJ,IAAmBG,GACnBF,IAAWG;AAAA,EACb;AAEA,SAAOH;AACT;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("../cjkFontFamily.cjs.js"),t=i=>{const e=i.defaultView?.tailwind;return e?(e.config=n.addCjkSafeSansToTailwindConfig(e.config),!0):!1};exports.refreshTailwindRuntime=t;
2
+ //# sourceMappingURL=tailwind-runtime.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwind-runtime.cjs.js","sources":["../../../../src/components/ContentRender/utils/tailwind-runtime.ts"],"sourcesContent":["import { addCjkSafeSansToTailwindConfig } from \"../cjkFontFamily\";\n\ninterface TailwindRuntimeWindow extends Window {\n tailwind?: {\n config?: unknown;\n };\n}\n\n/**\n * Reassigns the Tailwind Play config so its JIT runtime rescans the iframe DOM.\n * This is required when a sandbox was initialized under a display:none parent.\n */\nexport const refreshTailwindRuntime = (doc: Document): boolean => {\n const tailwindRuntime = (doc.defaultView as TailwindRuntimeWindow | null)\n ?.tailwind;\n\n if (!tailwindRuntime) {\n return false;\n }\n\n tailwindRuntime.config = addCjkSafeSansToTailwindConfig(\n tailwindRuntime.config\n );\n return true;\n};\n"],"names":["refreshTailwindRuntime","doc","tailwindRuntime","addCjkSafeSansToTailwindConfig"],"mappings":"2HAYaA,EAA0BC,GAA2B,CAChE,MAAMC,EAAmBD,EAAI,aACzB,SAEJ,OAAKC,GAILA,EAAgB,OAASC,EAAAA,+BACvBD,EAAgB,MAAA,EAEX,IANE,EAOX"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Reassigns the Tailwind Play config so its JIT runtime rescans the iframe DOM.
3
+ * This is required when a sandbox was initialized under a display:none parent.
4
+ */
5
+ export declare const refreshTailwindRuntime: (doc: Document) => boolean;
@@ -0,0 +1,11 @@
1
+ import { addCjkSafeSansToTailwindConfig as e } from "../cjkFontFamily.es.js";
2
+ const r = (n) => {
3
+ const i = n.defaultView?.tailwind;
4
+ return i ? (i.config = e(
5
+ i.config
6
+ ), !0) : !1;
7
+ };
8
+ export {
9
+ r as refreshTailwindRuntime
10
+ };
11
+ //# sourceMappingURL=tailwind-runtime.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwind-runtime.es.js","sources":["../../../../src/components/ContentRender/utils/tailwind-runtime.ts"],"sourcesContent":["import { addCjkSafeSansToTailwindConfig } from \"../cjkFontFamily\";\n\ninterface TailwindRuntimeWindow extends Window {\n tailwind?: {\n config?: unknown;\n };\n}\n\n/**\n * Reassigns the Tailwind Play config so its JIT runtime rescans the iframe DOM.\n * This is required when a sandbox was initialized under a display:none parent.\n */\nexport const refreshTailwindRuntime = (doc: Document): boolean => {\n const tailwindRuntime = (doc.defaultView as TailwindRuntimeWindow | null)\n ?.tailwind;\n\n if (!tailwindRuntime) {\n return false;\n }\n\n tailwindRuntime.config = addCjkSafeSansToTailwindConfig(\n tailwindRuntime.config\n );\n return true;\n};\n"],"names":["refreshTailwindRuntime","doc","tailwindRuntime","addCjkSafeSansToTailwindConfig"],"mappings":";AAYO,MAAMA,IAAyB,CAACC,MAA2B;AAChE,QAAMC,IAAmBD,EAAI,aACzB;AAEJ,SAAKC,KAILA,EAAgB,SAASC;AAAA,IACvBD,EAAgB;AAAA,EAAA,GAEX,MANE;AAOX;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const b=require("../../_virtual/jsx-runtime.cjs.js"),i=require("react"),R=require("../../lib/utils.cjs.js"),y=require("../ContentRender/utils/presentation-scaling.cjs.js"),p="--mdf-slide-font-size",m=typeof window>"u"?i.useEffect:i.useLayoutEffect,z=(o,c)=>o.contentHeight===c.contentHeight&&o.contentWidth===c.contentWidth&&o.mode===c.mode&&o.viewportHeight===c.viewportHeight&&o.viewportWidth===c.viewportWidth,H=({children:o,className:c,mode:e,...E})=>{const w=i.useRef(null),d=i.useRef(null),s=i.useRef(null),v=i.useRef(!1),f=i.useRef(null),h=i.useCallback(()=>{const r=w.current,t=d.current;if(e==="disabled"||!r||!t||v.current)return;const n={height:r.clientHeight,width:r.clientWidth};if(n.height<=0||n.width<=0)return;const u={contentHeight:t.scrollHeight,contentWidth:t.scrollWidth,mode:e,viewportHeight:n.height,viewportWidth:n.width},a=f.current;if(!(a&&z(a,u))){v.current=!0;try{const S=e==="fit"?y.fitPresentationFontSize({viewport:n,measure:F=>(t.style.setProperty(p,`${F}px`),{height:t.scrollHeight,width:t.scrollWidth})}):y.resolvePresentationBaseFontSize(n);t.style.setProperty(p,`${S}px`),t.dataset.markdownSlideFontSize=String(S),f.current={contentHeight:t.scrollHeight,contentWidth:t.scrollWidth,mode:e,viewportHeight:n.height,viewportWidth:n.width}}finally{v.current=!1}}},[e]),l=i.useCallback(()=>{e==="disabled"||s.current!==null||(s.current=window.requestAnimationFrame(()=>{s.current=null,h()}))},[h,e]);m(()=>{s.current!==null&&(window.cancelAnimationFrame(s.current),s.current=null);const r=d.current;if(r){if(e==="disabled"){r.style.removeProperty(p),delete r.dataset.markdownSlideFontSize,f.current=null;return}h()}},[h,e]),i.useEffect(()=>{const r=w.current,t=d.current;if(e==="disabled"||!r||!t)return;const n=typeof ResizeObserver>"u"?null:new ResizeObserver(l);n?.observe(r);const u=()=>{f.current=null,l()},a=e==="fit"&&typeof MutationObserver<"u"?new MutationObserver(u):null;return e==="fit"&&(n?.observe(t),a?.observe(t,{childList:!0,characterData:!0,subtree:!0}),t.addEventListener("load",u,!0)),window.addEventListener("resize",l),l(),()=>{n?.disconnect(),a?.disconnect(),e==="fit"&&t.removeEventListener("load",u,!0),window.removeEventListener("resize",l),s.current!==null&&(window.cancelAnimationFrame(s.current),s.current=null)}},[e,l]);const g=e!=="disabled";return b.jsxRuntimeExports.jsx("div",{ref:w,className:R.cn(c,g&&"slide-markdown-scaling"),"data-markdown-slide-scaling":g?e:void 0,...E,children:b.jsxRuntimeExports.jsx("div",{ref:d,className:R.cn("slide-markdown-scaling__content flex w-full flex-col gap-4",e!=="fit"&&"slide-markdown-scaling__content--contents"),children:o})})};exports.default=H;
2
+ //# sourceMappingURL=MarkdownSlideScaling.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownSlideScaling.cjs.js","sources":["../../../src/components/Slide/MarkdownSlideScaling.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useLayoutEffect, useRef } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n fitPresentationFontSize,\n resolvePresentationBaseFontSize,\n} from \"../ContentRender/utils/presentation-scaling\";\nimport type { MarkdownScalingMode } from \"./utils/markdownScaling\";\n\nconst SLIDE_FONT_SIZE_PROPERTY = \"--mdf-slide-font-size\";\nconst useIsomorphicLayoutEffect =\n typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\ninterface MarkdownFitSnapshot {\n contentHeight: number;\n contentWidth: number;\n mode: MarkdownScalingMode;\n viewportHeight: number;\n viewportWidth: number;\n}\n\nconst areFitSnapshotsEqual = (\n left: MarkdownFitSnapshot,\n right: MarkdownFitSnapshot\n) =>\n left.contentHeight === right.contentHeight &&\n left.contentWidth === right.contentWidth &&\n left.mode === right.mode &&\n left.viewportHeight === right.viewportHeight &&\n left.viewportWidth === right.viewportWidth;\n\nexport interface MarkdownSlideScalingProps\n extends React.ComponentPropsWithoutRef<\"div\"> {\n /** Controls whether Markdown content is fitted, base-scaled, or unscaled. */\n mode: MarkdownScalingMode;\n}\n\n/**\n * Fits all Markdown elements in one logical slide with a shared font-size.\n * Keeping this boundary outside ContentRender lets accumulated title, text,\n * table, and code elements participate in the same presentation layout.\n */\nconst MarkdownSlideScaling: React.FC<MarkdownSlideScalingProps> = ({\n children,\n className,\n mode,\n ...props\n}) => {\n const viewportRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const fitFrameRef = useRef<number | null>(null);\n const isFittingRef = useRef(false);\n const lastFitSnapshotRef = useRef<MarkdownFitSnapshot | null>(null);\n\n const fitContent = useCallback(() => {\n const viewport = viewportRef.current;\n const content = contentRef.current;\n\n if (mode === \"disabled\" || !viewport || !content || isFittingRef.current) {\n return;\n }\n\n const viewportSize = {\n height: viewport.clientHeight,\n width: viewport.clientWidth,\n };\n\n if (viewportSize.height <= 0 || viewportSize.width <= 0) {\n return;\n }\n\n const currentSnapshot: MarkdownFitSnapshot = {\n contentHeight: content.scrollHeight,\n contentWidth: content.scrollWidth,\n mode,\n viewportHeight: viewportSize.height,\n viewportWidth: viewportSize.width,\n };\n const lastSnapshot = lastFitSnapshotRef.current;\n\n if (lastSnapshot && areFitSnapshotsEqual(lastSnapshot, currentSnapshot)) {\n return;\n }\n\n isFittingRef.current = true;\n\n try {\n const fontSize =\n mode === \"fit\"\n ? fitPresentationFontSize({\n viewport: viewportSize,\n measure: (candidateFontSize) => {\n content.style.setProperty(\n SLIDE_FONT_SIZE_PROPERTY,\n `${candidateFontSize}px`\n );\n\n // Read after the CSS variable update so wrapping and em-based\n // styles are included in the next compression step.\n return {\n height: content.scrollHeight,\n width: content.scrollWidth,\n };\n },\n })\n : resolvePresentationBaseFontSize(viewportSize);\n\n content.style.setProperty(SLIDE_FONT_SIZE_PROPERTY, `${fontSize}px`);\n content.dataset.markdownSlideFontSize = String(fontSize);\n lastFitSnapshotRef.current = {\n contentHeight: content.scrollHeight,\n contentWidth: content.scrollWidth,\n mode,\n viewportHeight: viewportSize.height,\n viewportWidth: viewportSize.width,\n };\n } finally {\n isFittingRef.current = false;\n }\n }, [mode]);\n\n const scheduleFit = useCallback(() => {\n if (mode === \"disabled\" || fitFrameRef.current !== null) {\n return;\n }\n\n fitFrameRef.current = window.requestAnimationFrame(() => {\n fitFrameRef.current = null;\n fitContent();\n });\n }, [fitContent, mode]);\n\n useIsomorphicLayoutEffect(() => {\n if (fitFrameRef.current !== null) {\n window.cancelAnimationFrame(fitFrameRef.current);\n fitFrameRef.current = null;\n }\n\n const content = contentRef.current;\n\n if (!content) {\n return;\n }\n\n if (mode === \"disabled\") {\n content.style.removeProperty(SLIDE_FONT_SIZE_PROPERTY);\n delete content.dataset.markdownSlideFontSize;\n lastFitSnapshotRef.current = null;\n return;\n }\n\n fitContent();\n }, [fitContent, mode]);\n\n useEffect(() => {\n const viewport = viewportRef.current;\n const content = contentRef.current;\n\n if (mode === \"disabled\" || !viewport || !content) {\n return;\n }\n\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(scheduleFit);\n resizeObserver?.observe(viewport);\n\n const handleContentChange = () => {\n lastFitSnapshotRef.current = null;\n scheduleFit();\n };\n const mutationObserver =\n mode === \"fit\" && typeof MutationObserver !== \"undefined\"\n ? new MutationObserver(handleContentChange)\n : null;\n\n if (mode === \"fit\") {\n resizeObserver?.observe(content);\n mutationObserver?.observe(content, {\n childList: true,\n characterData: true,\n subtree: true,\n });\n content.addEventListener(\"load\", handleContentChange, true);\n }\n\n window.addEventListener(\"resize\", scheduleFit);\n scheduleFit();\n\n return () => {\n resizeObserver?.disconnect();\n mutationObserver?.disconnect();\n\n if (mode === \"fit\") {\n content.removeEventListener(\"load\", handleContentChange, true);\n }\n\n window.removeEventListener(\"resize\", scheduleFit);\n\n if (fitFrameRef.current !== null) {\n window.cancelAnimationFrame(fitFrameRef.current);\n fitFrameRef.current = null;\n }\n };\n }, [mode, scheduleFit]);\n\n const isScaling = mode !== \"disabled\";\n\n return (\n <div\n ref={viewportRef}\n className={cn(className, isScaling && \"slide-markdown-scaling\")}\n data-markdown-slide-scaling={isScaling ? mode : undefined}\n {...props}\n >\n <div\n ref={contentRef}\n className={cn(\n \"slide-markdown-scaling__content flex w-full flex-col gap-4\",\n mode !== \"fit\" && \"slide-markdown-scaling__content--contents\"\n )}\n >\n {children}\n </div>\n </div>\n );\n};\n\nexport default MarkdownSlideScaling;\n"],"names":["SLIDE_FONT_SIZE_PROPERTY","useIsomorphicLayoutEffect","useEffect","useLayoutEffect","areFitSnapshotsEqual","left","right","MarkdownSlideScaling","children","className","mode","props","viewportRef","useRef","contentRef","fitFrameRef","isFittingRef","lastFitSnapshotRef","fitContent","useCallback","viewport","content","viewportSize","currentSnapshot","lastSnapshot","fontSize","fitPresentationFontSize","candidateFontSize","resolvePresentationBaseFontSize","scheduleFit","resizeObserver","handleContentChange","mutationObserver","isScaling","jsx","cn"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { MarkdownScalingMode } from './utils/markdownScaling';
3
+ export interface MarkdownSlideScalingProps extends React.ComponentPropsWithoutRef<"div"> {
4
+ /** Controls whether Markdown content is fitted, base-scaled, or unscaled. */
5
+ mode: MarkdownScalingMode;
6
+ }
7
+ /**
8
+ * Fits all Markdown elements in one logical slide with a shared font-size.
9
+ * Keeping this boundary outside ContentRender lets accumulated title, text,
10
+ * table, and code elements participate in the same presentation layout.
11
+ */
12
+ declare const MarkdownSlideScaling: React.FC<MarkdownSlideScalingProps>;
13
+ export default MarkdownSlideScaling;
@@ -0,0 +1,109 @@
1
+ import { j as m } from "../../_virtual/jsx-runtime.es.js";
2
+ import { useRef as u, useCallback as b, useEffect as F, useLayoutEffect as H } from "react";
3
+ import { cn as y } from "../../lib/utils.es.js";
4
+ import { fitPresentationFontSize as W, resolvePresentationBaseFontSize as R } from "../ContentRender/utils/presentation-scaling.es.js";
5
+ const v = "--mdf-slide-font-size", x = typeof window > "u" ? F : H, k = (o, s) => o.contentHeight === s.contentHeight && o.contentWidth === s.contentWidth && o.mode === s.mode && o.viewportHeight === s.viewportHeight && o.viewportWidth === s.viewportWidth, j = ({
6
+ children: o,
7
+ className: s,
8
+ mode: t,
9
+ ...z
10
+ }) => {
11
+ const w = u(null), d = u(null), i = u(null), p = u(!1), f = u(null), h = b(() => {
12
+ const r = w.current, e = d.current;
13
+ if (t === "disabled" || !r || !e || p.current)
14
+ return;
15
+ const n = {
16
+ height: r.clientHeight,
17
+ width: r.clientWidth
18
+ };
19
+ if (n.height <= 0 || n.width <= 0)
20
+ return;
21
+ const l = {
22
+ contentHeight: e.scrollHeight,
23
+ contentWidth: e.scrollWidth,
24
+ mode: t,
25
+ viewportHeight: n.height,
26
+ viewportWidth: n.width
27
+ }, a = f.current;
28
+ if (!(a && k(a, l))) {
29
+ p.current = !0;
30
+ try {
31
+ const S = t === "fit" ? W({
32
+ viewport: n,
33
+ measure: (E) => (e.style.setProperty(
34
+ v,
35
+ `${E}px`
36
+ ), {
37
+ height: e.scrollHeight,
38
+ width: e.scrollWidth
39
+ })
40
+ }) : R(n);
41
+ e.style.setProperty(v, `${S}px`), e.dataset.markdownSlideFontSize = String(S), f.current = {
42
+ contentHeight: e.scrollHeight,
43
+ contentWidth: e.scrollWidth,
44
+ mode: t,
45
+ viewportHeight: n.height,
46
+ viewportWidth: n.width
47
+ };
48
+ } finally {
49
+ p.current = !1;
50
+ }
51
+ }
52
+ }, [t]), c = b(() => {
53
+ t === "disabled" || i.current !== null || (i.current = window.requestAnimationFrame(() => {
54
+ i.current = null, h();
55
+ }));
56
+ }, [h, t]);
57
+ x(() => {
58
+ i.current !== null && (window.cancelAnimationFrame(i.current), i.current = null);
59
+ const r = d.current;
60
+ if (r) {
61
+ if (t === "disabled") {
62
+ r.style.removeProperty(v), delete r.dataset.markdownSlideFontSize, f.current = null;
63
+ return;
64
+ }
65
+ h();
66
+ }
67
+ }, [h, t]), F(() => {
68
+ const r = w.current, e = d.current;
69
+ if (t === "disabled" || !r || !e)
70
+ return;
71
+ const n = typeof ResizeObserver > "u" ? null : new ResizeObserver(c);
72
+ n?.observe(r);
73
+ const l = () => {
74
+ f.current = null, c();
75
+ }, a = t === "fit" && typeof MutationObserver < "u" ? new MutationObserver(l) : null;
76
+ return t === "fit" && (n?.observe(e), a?.observe(e, {
77
+ childList: !0,
78
+ characterData: !0,
79
+ subtree: !0
80
+ }), e.addEventListener("load", l, !0)), window.addEventListener("resize", c), c(), () => {
81
+ n?.disconnect(), a?.disconnect(), t === "fit" && e.removeEventListener("load", l, !0), window.removeEventListener("resize", c), i.current !== null && (window.cancelAnimationFrame(i.current), i.current = null);
82
+ };
83
+ }, [t, c]);
84
+ const g = t !== "disabled";
85
+ return /* @__PURE__ */ m.jsx(
86
+ "div",
87
+ {
88
+ ref: w,
89
+ className: y(s, g && "slide-markdown-scaling"),
90
+ "data-markdown-slide-scaling": g ? t : void 0,
91
+ ...z,
92
+ children: /* @__PURE__ */ m.jsx(
93
+ "div",
94
+ {
95
+ ref: d,
96
+ className: y(
97
+ "slide-markdown-scaling__content flex w-full flex-col gap-4",
98
+ t !== "fit" && "slide-markdown-scaling__content--contents"
99
+ ),
100
+ children: o
101
+ }
102
+ )
103
+ }
104
+ );
105
+ };
106
+ export {
107
+ j as default
108
+ };
109
+ //# sourceMappingURL=MarkdownSlideScaling.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownSlideScaling.es.js","sources":["../../../src/components/Slide/MarkdownSlideScaling.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useLayoutEffect, useRef } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n fitPresentationFontSize,\n resolvePresentationBaseFontSize,\n} from \"../ContentRender/utils/presentation-scaling\";\nimport type { MarkdownScalingMode } from \"./utils/markdownScaling\";\n\nconst SLIDE_FONT_SIZE_PROPERTY = \"--mdf-slide-font-size\";\nconst useIsomorphicLayoutEffect =\n typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\ninterface MarkdownFitSnapshot {\n contentHeight: number;\n contentWidth: number;\n mode: MarkdownScalingMode;\n viewportHeight: number;\n viewportWidth: number;\n}\n\nconst areFitSnapshotsEqual = (\n left: MarkdownFitSnapshot,\n right: MarkdownFitSnapshot\n) =>\n left.contentHeight === right.contentHeight &&\n left.contentWidth === right.contentWidth &&\n left.mode === right.mode &&\n left.viewportHeight === right.viewportHeight &&\n left.viewportWidth === right.viewportWidth;\n\nexport interface MarkdownSlideScalingProps\n extends React.ComponentPropsWithoutRef<\"div\"> {\n /** Controls whether Markdown content is fitted, base-scaled, or unscaled. */\n mode: MarkdownScalingMode;\n}\n\n/**\n * Fits all Markdown elements in one logical slide with a shared font-size.\n * Keeping this boundary outside ContentRender lets accumulated title, text,\n * table, and code elements participate in the same presentation layout.\n */\nconst MarkdownSlideScaling: React.FC<MarkdownSlideScalingProps> = ({\n children,\n className,\n mode,\n ...props\n}) => {\n const viewportRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const fitFrameRef = useRef<number | null>(null);\n const isFittingRef = useRef(false);\n const lastFitSnapshotRef = useRef<MarkdownFitSnapshot | null>(null);\n\n const fitContent = useCallback(() => {\n const viewport = viewportRef.current;\n const content = contentRef.current;\n\n if (mode === \"disabled\" || !viewport || !content || isFittingRef.current) {\n return;\n }\n\n const viewportSize = {\n height: viewport.clientHeight,\n width: viewport.clientWidth,\n };\n\n if (viewportSize.height <= 0 || viewportSize.width <= 0) {\n return;\n }\n\n const currentSnapshot: MarkdownFitSnapshot = {\n contentHeight: content.scrollHeight,\n contentWidth: content.scrollWidth,\n mode,\n viewportHeight: viewportSize.height,\n viewportWidth: viewportSize.width,\n };\n const lastSnapshot = lastFitSnapshotRef.current;\n\n if (lastSnapshot && areFitSnapshotsEqual(lastSnapshot, currentSnapshot)) {\n return;\n }\n\n isFittingRef.current = true;\n\n try {\n const fontSize =\n mode === \"fit\"\n ? fitPresentationFontSize({\n viewport: viewportSize,\n measure: (candidateFontSize) => {\n content.style.setProperty(\n SLIDE_FONT_SIZE_PROPERTY,\n `${candidateFontSize}px`\n );\n\n // Read after the CSS variable update so wrapping and em-based\n // styles are included in the next compression step.\n return {\n height: content.scrollHeight,\n width: content.scrollWidth,\n };\n },\n })\n : resolvePresentationBaseFontSize(viewportSize);\n\n content.style.setProperty(SLIDE_FONT_SIZE_PROPERTY, `${fontSize}px`);\n content.dataset.markdownSlideFontSize = String(fontSize);\n lastFitSnapshotRef.current = {\n contentHeight: content.scrollHeight,\n contentWidth: content.scrollWidth,\n mode,\n viewportHeight: viewportSize.height,\n viewportWidth: viewportSize.width,\n };\n } finally {\n isFittingRef.current = false;\n }\n }, [mode]);\n\n const scheduleFit = useCallback(() => {\n if (mode === \"disabled\" || fitFrameRef.current !== null) {\n return;\n }\n\n fitFrameRef.current = window.requestAnimationFrame(() => {\n fitFrameRef.current = null;\n fitContent();\n });\n }, [fitContent, mode]);\n\n useIsomorphicLayoutEffect(() => {\n if (fitFrameRef.current !== null) {\n window.cancelAnimationFrame(fitFrameRef.current);\n fitFrameRef.current = null;\n }\n\n const content = contentRef.current;\n\n if (!content) {\n return;\n }\n\n if (mode === \"disabled\") {\n content.style.removeProperty(SLIDE_FONT_SIZE_PROPERTY);\n delete content.dataset.markdownSlideFontSize;\n lastFitSnapshotRef.current = null;\n return;\n }\n\n fitContent();\n }, [fitContent, mode]);\n\n useEffect(() => {\n const viewport = viewportRef.current;\n const content = contentRef.current;\n\n if (mode === \"disabled\" || !viewport || !content) {\n return;\n }\n\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(scheduleFit);\n resizeObserver?.observe(viewport);\n\n const handleContentChange = () => {\n lastFitSnapshotRef.current = null;\n scheduleFit();\n };\n const mutationObserver =\n mode === \"fit\" && typeof MutationObserver !== \"undefined\"\n ? new MutationObserver(handleContentChange)\n : null;\n\n if (mode === \"fit\") {\n resizeObserver?.observe(content);\n mutationObserver?.observe(content, {\n childList: true,\n characterData: true,\n subtree: true,\n });\n content.addEventListener(\"load\", handleContentChange, true);\n }\n\n window.addEventListener(\"resize\", scheduleFit);\n scheduleFit();\n\n return () => {\n resizeObserver?.disconnect();\n mutationObserver?.disconnect();\n\n if (mode === \"fit\") {\n content.removeEventListener(\"load\", handleContentChange, true);\n }\n\n window.removeEventListener(\"resize\", scheduleFit);\n\n if (fitFrameRef.current !== null) {\n window.cancelAnimationFrame(fitFrameRef.current);\n fitFrameRef.current = null;\n }\n };\n }, [mode, scheduleFit]);\n\n const isScaling = mode !== \"disabled\";\n\n return (\n <div\n ref={viewportRef}\n className={cn(className, isScaling && \"slide-markdown-scaling\")}\n data-markdown-slide-scaling={isScaling ? mode : undefined}\n {...props}\n >\n <div\n ref={contentRef}\n className={cn(\n \"slide-markdown-scaling__content flex w-full flex-col gap-4\",\n mode !== \"fit\" && \"slide-markdown-scaling__content--contents\"\n )}\n >\n {children}\n </div>\n </div>\n );\n};\n\nexport default MarkdownSlideScaling;\n"],"names":["SLIDE_FONT_SIZE_PROPERTY","useIsomorphicLayoutEffect","useEffect","useLayoutEffect","areFitSnapshotsEqual","left","right","MarkdownSlideScaling","children","className","mode","props","viewportRef","useRef","contentRef","fitFrameRef","isFittingRef","lastFitSnapshotRef","fitContent","useCallback","viewport","content","viewportSize","currentSnapshot","lastSnapshot","fontSize","fitPresentationFontSize","candidateFontSize","resolvePresentationBaseFontSize","scheduleFit","resizeObserver","handleContentChange","mutationObserver","isScaling","jsx","cn"],"mappings":"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"}