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,8 +1,9 @@
1
1
  import { j as R } from "../../_virtual/jsx-runtime.es.js";
2
2
  import { useRef as f, useState as q, useEffect as N } from "react";
3
- import oe from "../ui/loading-overlay-card.es.js";
4
- import { getContentRenderLocaleTexts as ae } from "./contentRenderI18n.es.js";
5
- const ce = [
3
+ import ie from "../ui/loading-overlay-card.es.js";
4
+ import { getContentRenderLocaleTexts as le } from "./contentRenderI18n.es.js";
5
+ import { isAnchorElement as ue, shouldForceAnchorHrefToNewTab as P, mergeAnchorRelValue as X, resolveClosestAnchor as fe } from "./utils/link-targets.es.js";
6
+ const de = [
6
7
  "src",
7
8
  "srcset",
8
9
  "sizes",
@@ -16,55 +17,55 @@ const ce = [
16
17
  "crossorigin",
17
18
  "referrerpolicy",
18
19
  "fetchpriority"
19
- ], J = (o) => ce.map(
20
+ ], Y = (o) => de.map(
20
21
  (n) => `${n}:${o.getAttribute(n) || ""}`
21
- ).join("|"), ie = (o) => {
22
+ ).join("|"), he = (o) => {
22
23
  const n = /* @__PURE__ */ new Map();
23
24
  return o.querySelectorAll("img").forEach((i) => {
24
- const l = i, r = J(l), c = n.get(r) || [];
25
- c.push(l), n.set(r, c);
25
+ const l = i, s = Y(l), a = n.get(s) || [];
26
+ a.push(l), n.set(s, a);
26
27
  }), n;
27
- }, le = (o, n) => {
28
+ }, me = (o, n) => {
28
29
  const i = Array.from(o.attributes), l = new Set(
29
- i.map((r) => r.name)
30
+ i.map((s) => s.name)
30
31
  );
31
- Array.from(n.attributes).forEach((r) => {
32
- l.has(r.name) || n.removeAttribute(r.name);
33
- }), i.forEach((r) => {
34
- n.setAttribute(r.name, r.value);
32
+ Array.from(n.attributes).forEach((s) => {
33
+ l.has(s.name) || n.removeAttribute(s.name);
34
+ }), i.forEach((s) => {
35
+ n.setAttribute(s.name, s.value);
35
36
  });
36
- }, ue = (o, n) => {
37
+ }, pe = (o, n) => {
37
38
  n.size && o.querySelectorAll("img").forEach((i) => {
38
- const l = i, r = J(l), c = n.get(r), p = c?.shift();
39
- p && (le(l, p), l.replaceWith(p), c && c.length === 0 && n.delete(r));
39
+ const l = i, s = Y(l), a = n.get(s), p = a?.shift();
40
+ p && (me(l, p), l.replaceWith(p), a && a.length === 0 && n.delete(s));
40
41
  });
41
- }, ye = ({
42
+ }, Ae = ({
42
43
  html: o,
43
44
  locale: n,
44
45
  loadingText: i,
45
46
  styleLoadingText: l,
46
- scriptLoadingText: r,
47
- resetToken: c = 0,
47
+ scriptLoadingText: s,
48
+ resetToken: a = 0,
48
49
  mode: p = "content",
49
- hasRootVhHeight: P = !1,
50
- stretchRootHeight: X = !1,
51
- enableScaling: z = !1,
52
- disableLoadingOverlay: j = !1
50
+ hasRootVhHeight: Z = !1,
51
+ stretchRootHeight: ee = !1,
52
+ enableScaling: F = !1,
53
+ disableLoadingOverlay: k = !1
53
54
  }) => {
54
- const T = ae(n), L = f(null), [Y, S] = q(!1), [Z, C] = q(!1), [ee, M] = q(!1), _ = f([]), k = f([]), F = f(0), U = f(0), y = f(null), g = f(null), b = f(!1), x = f(!1), W = f(c), te = 200, d = (t) => {
55
+ const L = le(n), T = f(null), [te, A] = q(!1), [re, S] = q(!1), [ne, j] = q(!1), _ = f([]), H = f([]), z = f(0), U = f(0), y = f(null), g = f(null), b = f(!1), x = f(!1), V = f(a), se = 200, d = (t) => {
55
56
  t.current && (clearTimeout(t.current), t.current = null);
56
- }, B = (t, a, u, D) => {
57
- const m = performance.now() - u.current, I = Math.max(0, te - m);
58
- d(a), a.current = window.setTimeout(() => {
59
- t(!1), D?.(), a.current = null;
57
+ }, W = (t, c, u, D) => {
58
+ const h = performance.now() - u.current, I = Math.max(0, se - h);
59
+ d(c), c.current = window.setTimeout(() => {
60
+ t(!1), D?.(), c.current = null;
60
61
  }, I);
61
62
  };
62
63
  N(() => {
63
- const t = L.current?.ownerDocument;
64
+ const t = T.current?.ownerDocument;
64
65
  if (!t) return;
65
- const a = "sandbox-spinner-style";
66
- let u = t.getElementById(a);
67
- u || (u = t.createElement("style"), u.id = a, t.head?.appendChild(u)), u.textContent = `
66
+ const c = "sandbox-spinner-style";
67
+ let u = t.getElementById(c);
68
+ u || (u = t.createElement("style"), u.id = c, t.head?.appendChild(u)), u.textContent = `
68
69
  .sandbox-wrapper { align-items: center; }
69
70
  .sandbox-container { position: relative; width: 100%; }
70
71
  .sandbox-container svg,
@@ -85,76 +86,86 @@ const ce = [
85
86
  .overflow-y-auto { overflow-y: visible !important; }
86
87
  `;
87
88
  }, []), N(() => {
88
- c !== W.current && (M(!1), W.current = c), d(y), d(g), b.current = !1, x.current = !1;
89
- const t = L.current;
89
+ a !== V.current && (j(!1), V.current = a), d(y), d(g), b.current = !1, x.current = !1;
90
+ const t = T.current;
90
91
  if (!t) return;
91
- const a = t.ownerDocument, u = a?.body;
92
+ const c = t.ownerDocument, u = c?.body;
92
93
  if (!u) return;
93
- const D = ie(t);
94
- _.current.forEach((e) => e.remove()), _.current = [], k.current.forEach((e) => e.remove()), k.current = [], S(!1), C(!1);
95
- const m = a.createElement("div");
96
- m.innerHTML = o;
97
- const I = (o.match(/<script[\s>]/gi) || []).length, se = (o.match(/<\/script>/gi) || []).length, V = I > 0 && I === se, w = [];
98
- Array.from(m.querySelectorAll("style, script")).forEach((e) => {
94
+ const D = he(t);
95
+ _.current.forEach((e) => e.remove()), _.current = [], H.current.forEach((e) => e.remove()), H.current = [], A(!1), S(!1);
96
+ const h = c.createElement("div");
97
+ h.innerHTML = o, h.querySelectorAll("a[href]").forEach((e) => {
98
+ ue(e) && P(e.getAttribute("href")) && (e.setAttribute("target", "_blank"), e.setAttribute("rel", X(e.getAttribute("rel"))));
99
+ });
100
+ const I = (o.match(/<script[\s>]/gi) || []).length, ae = (o.match(/<\/script>/gi) || []).length, B = I > 0 && I === ae, v = [];
101
+ Array.from(h.querySelectorAll("style, script")).forEach((e) => {
99
102
  if (e.tagName.toLowerCase() === "style") {
100
- const s = a.createElement("style");
101
- s.textContent = e.textContent || "", Array.from(e.attributes).forEach((h) => {
102
- s.setAttribute(h.name, h.value);
103
- }), w.push(s);
103
+ const r = c.createElement("style");
104
+ r.textContent = e.textContent || "", Array.from(e.attributes).forEach((m) => {
105
+ r.setAttribute(m.name, m.value);
106
+ }), v.push(r);
104
107
  } else {
105
- const s = a.createElement("script");
106
- Array.from(e.attributes).forEach((h) => {
107
- s.setAttribute(h.name, h.value);
108
- }), s.textContent = e.textContent || "", w.push(s);
108
+ const r = c.createElement("script");
109
+ Array.from(e.attributes).forEach((m) => {
110
+ r.setAttribute(m.name, m.value);
111
+ }), r.textContent = e.textContent || "", v.push(r);
109
112
  }
110
113
  e.remove();
111
- }), ue(m, D);
112
- const O = w.some(
114
+ }), pe(h, D);
115
+ const O = v.some(
113
116
  (e) => e.tagName.toLowerCase() === "style"
114
- ), G = w.some(
117
+ ), G = v.some(
115
118
  (e) => e.tagName.toLowerCase() === "script"
116
119
  );
117
- O && (b.current = !0, F.current = performance.now(), d(y), S(!0)), G && (x.current = !0, U.current = performance.now(), d(g), C(!0));
118
- const $ = Array.from(m.childNodes), K = $.length > 0;
119
- M(K), t.replaceChildren(...$);
120
- let v = null;
121
- const Q = () => t.childNodes.length === 0 ? !1 : (M(!0), v?.disconnect(), v = null, !0);
122
- return !K && G && V && (v = new MutationObserver(() => {
123
- Q();
124
- }), v.observe(t, {
120
+ O && (b.current = !0, z.current = performance.now(), d(y), A(!0)), G && (x.current = !0, U.current = performance.now(), d(g), S(!0));
121
+ const $ = Array.from(h.childNodes), K = $.length > 0;
122
+ j(K), t.replaceChildren(...$);
123
+ const Q = (e) => {
124
+ const r = fe(e.target);
125
+ r && P(r.getAttribute("href")) && (r.setAttribute("target", "_blank"), r.setAttribute(
126
+ "rel",
127
+ X(r.getAttribute("rel"))
128
+ ));
129
+ };
130
+ t.addEventListener("click", Q, !0);
131
+ let w = null;
132
+ const J = () => t.childNodes.length === 0 ? !1 : (j(!0), w?.disconnect(), w = null, !0);
133
+ return !K && G && B && (w = new MutationObserver(() => {
134
+ J();
135
+ }), w.observe(t, {
125
136
  childList: !0,
126
137
  subtree: !0
127
- })), w.forEach((e) => {
138
+ })), v.forEach((e) => {
128
139
  if (e.tagName.toLowerCase() === "style") {
129
- a.head?.appendChild(e), _.current.push(e);
140
+ c.head?.appendChild(e), _.current.push(e);
130
141
  return;
131
142
  }
132
- if (V) {
133
- const s = e, h = s.textContent || "";
134
- if (!s.src)
143
+ if (B) {
144
+ const r = e, m = r.textContent || "";
145
+ if (!r.src)
135
146
  try {
136
- new Function(h);
147
+ new Function(m);
137
148
  } catch {
138
- s.remove();
149
+ r.remove();
139
150
  return;
140
151
  }
141
152
  try {
142
- u.appendChild(s), k.current.push(s);
153
+ u.appendChild(r), H.current.push(r);
143
154
  } catch {
144
- s.remove();
155
+ r.remove();
145
156
  }
146
157
  } else
147
158
  e.remove();
148
- }), Q(), z && t.ownerDocument?.defaultView?.__mdf_triggerFitContent?.(), requestAnimationFrame(() => {
149
- O && B(
150
- S,
159
+ }), J(), F && t.ownerDocument?.defaultView?.__mdf_triggerFitContent?.(), requestAnimationFrame(() => {
160
+ O && W(
161
+ A,
151
162
  y,
152
- F,
163
+ z,
153
164
  () => {
154
165
  b.current = !1;
155
166
  }
156
- ), G && B(
157
- C,
167
+ ), G && W(
168
+ S,
158
169
  g,
159
170
  U,
160
171
  () => {
@@ -162,49 +173,49 @@ const ce = [
162
173
  }
163
174
  );
164
175
  }), () => {
165
- v?.disconnect();
176
+ w?.disconnect(), t.removeEventListener("click", Q, !0);
166
177
  };
167
- }, [o, c, z]), N(
178
+ }, [o, a, F]), N(
168
179
  () => () => {
169
180
  d(y), d(g);
170
181
  },
171
182
  []
172
183
  ), N(() => {
173
- j && (d(y), d(g), b.current = !1, x.current = !1, S(!1), C(!1));
174
- }, [j]);
175
- const E = j ? null : Z || x.current ? r || i || T.sandboxScriptLoadingText : Y || b.current ? l || i || T.sandboxStyleLoadingText : ee ? null : i || T.sandboxLoadingText, H = p === "blackboard", A = H && X, ne = {
184
+ k && (d(y), d(g), b.current = !1, x.current = !1, A(!1), S(!1));
185
+ }, [k]);
186
+ const C = k ? null : re || x.current ? s || i || L.sandboxScriptLoadingText : te || b.current ? l || i || L.sandboxStyleLoadingText : ne ? null : i || L.sandboxLoadingText, M = p === "blackboard", E = M && ee, oe = {
176
187
  position: "relative",
177
188
  width: "100%",
178
189
  height: "100%",
179
190
  display: "flex",
180
191
  flexDirection: "column",
181
192
  // Keep blackboard scroll behavior while centering content in non-blackboard mode
182
- justifyContent: A ? "flex-start" : H ? "space-around" : "flex-start"
183
- }, re = {
184
- pointerEvents: E ? "none" : void 0,
185
- margin: H ? void 0 : "auto 0",
193
+ justifyContent: E ? "flex-start" : M ? "space-around" : "flex-start"
194
+ }, ce = {
195
+ pointerEvents: C ? "none" : void 0,
196
+ margin: M ? void 0 : "auto 0",
186
197
  width: "100%",
187
- height: A ? "100%" : void 0,
188
- minHeight: A ? 0 : void 0,
189
- flex: A ? "1 1 auto" : void 0
198
+ height: E ? "100%" : void 0,
199
+ minHeight: E ? 0 : void 0,
200
+ flex: E ? "1 1 auto" : void 0
190
201
  };
191
202
  return /* @__PURE__ */ R.jsxs(
192
203
  "div",
193
204
  {
194
- "data-root-vh": P ? "true" : "false",
205
+ "data-root-vh": Z ? "true" : "false",
195
206
  className: "sandbox-wrapper",
196
- style: ne,
197
- "aria-busy": !!E,
207
+ style: oe,
208
+ "aria-busy": !!C,
198
209
  children: [
199
210
  /* @__PURE__ */ R.jsx(
200
211
  "div",
201
212
  {
202
- ref: L,
213
+ ref: T,
203
214
  className: "sandbox-container",
204
- style: re
215
+ style: ce
205
216
  }
206
217
  ),
207
- E && /* @__PURE__ */ R.jsx(
218
+ C && /* @__PURE__ */ R.jsx(
208
219
  "div",
209
220
  {
210
221
  style: {
@@ -216,7 +227,7 @@ const ce = [
216
227
  justifyContent: "center",
217
228
  pointerEvents: "none"
218
229
  },
219
- children: /* @__PURE__ */ R.jsx(oe, { message: E })
230
+ children: /* @__PURE__ */ R.jsx(ie, { message: C })
220
231
  }
221
232
  )
222
233
  ]
@@ -224,6 +235,6 @@ const ce = [
224
235
  );
225
236
  };
226
237
  export {
227
- ye as default
238
+ Ae as default
228
239
  };
229
240
  //# 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\";\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\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 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 };\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","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","contentNodes","hasInitialContent","scriptContentObserver","markRenderedContentFromContainer","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","jsx","LoadingOverlayCard"],"mappings":";;;;AAoBA,MAAMA,KAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEMC,IAAmB,CAACC,MACxBF,GAAuB;AAAA,EACrB,CAACG,MAAc,GAAGA,CAAS,IAAID,EAAM,aAAaC,CAAS,KAAK,EAAE;AACpE,EAAE,KAAK,GAAG,GAENC,KAAwB,CAACC,MAAqB;AAClD,QAAMC,wBAAe,IAAA;AACrB,SAAAD,EAAK,iBAAiB,KAAK,EAAE,QAAQ,CAACE,MAAS;AAC7C,UAAML,IAAQK,GACRC,IAAMP,EAAiBC,CAAK,GAC5BO,IAASH,EAAS,IAAIE,CAAG,KAAK,CAAA;AACpC,IAAAC,EAAO,KAAKP,CAAK,GACjBI,EAAS,IAAIE,GAAKC,CAAM;AAAA,EAC1B,CAAC,GACMH;AACT,GAEMI,KAAsB,CAC1BC,GACAC,MACG;AACH,QAAMC,IAAmB,MAAM,KAAKF,EAAY,UAAU,GACpDG,IAAuB,IAAI;AAAA,IAC/BD,EAAiB,IAAI,CAACV,MAAcA,EAAU,IAAI;AAAA,EAAA;AAGpD,QAAM,KAAKS,EAAY,UAAU,EAAE,QAAQ,CAACT,MAAc;AACxD,IAAKW,EAAqB,IAAIX,EAAU,IAAI,KAC1CS,EAAY,gBAAgBT,EAAU,IAAI;AAAA,EAE9C,CAAC,GAEDU,EAAiB,QAAQ,CAACV,MAAc;AACtC,IAAAS,EAAY,aAAaT,EAAU,MAAMA,EAAU,KAAK;AAAA,EAC1D,CAAC;AACH,GAEMY,KAAsB,CAC1BV,GACAC,MACG;AACH,EAAKA,EAAS,QAEdD,EAAK,iBAAiB,KAAK,EAAE,QAAQ,CAACE,MAAS;AAC7C,UAAMS,IAAYT,GACZC,IAAMP,EAAiBe,CAAS,GAChCP,IAASH,EAAS,IAAIE,CAAG,GACzBS,IAAiBR,GAAQ,MAAA;AAC/B,IAAKQ,MAELP,GAAoBM,GAAWC,CAAc,GAC7CD,EAAU,YAAYC,CAAc,GAEhCR,KAAUA,EAAO,WAAW,KAC9BH,EAAS,OAAOE,CAAG;AAAA,EAEvB,CAAC;AACH,GAEMU,KAAwC,CAAC;AAAA,EAC7C,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,aAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,MAAAC,IAAO;AAAA,EACP,iBAAAC,IAAkB;AAAA,EAClB,mBAAAC,IAAoB;AAAA,EACpB,eAAAC,IAAgB;AAAA,EAChB,uBAAAC,IAAwB;AAC1B,MAAM;AACJ,QAAMC,IAAcC,GAA4BX,CAAM,GAChDY,IAAeC,EAAuB,IAAI,GAC1C,CAACC,GAAoBC,CAAqB,IAAIC,EAAS,EAAK,GAC5D,CAACC,GAAqBC,CAAsB,IAAIF,EAAS,EAAK,GAC9D,CAACG,IAAoBC,CAAqB,IAAIJ,EAAS,EAAK,GAC5DK,IAAoBR,EAA2B,EAAE,GACjDS,IAAqBT,EAA4B,EAAE,GACnDU,IAAgBV,EAAO,CAAC,GACxBW,IAAiBX,EAAO,CAAC,GACzBY,IAAgBZ,EAAsB,IAAI,GAC1Ca,IAAiBb,EAAsB,IAAI,GAC3Cc,IAAed,EAAO,EAAK,GAC3Be,IAAgBf,EAAO,EAAK,GAC5BgB,IAAoBhB,EAAOT,CAAU,GACrC0B,KAAiB,KAEjBC,IAAa,CAACC,MAAoD;AACtE,IAAIA,EAAS,YACX,aAAaA,EAAS,OAAO,GAC7BA,EAAS,UAAU;AAAA,EAEvB,GAEMC,IAA8B,CAClCC,GACAF,GACAG,GACAC,MACG;AACH,UAAMC,IAAU,YAAY,IAAA,IAAQF,EAAS,SACvCG,IAAQ,KAAK,IAAI,GAAGR,KAAiBO,CAAO;AAClD,IAAAN,EAAWC,CAAQ,GACnBA,EAAS,UAAU,OAAO,WAAW,MAAM;AACzC,MAAAE,EAAO,EAAK,GACZE,IAAA,GACAJ,EAAS,UAAU;AAAA,IACrB,GAAGM,CAAK;AAAA,EACV;AAEA,EAAAC,EAAU,MAAM;AACd,UAAMC,IAAM5B,EAAa,SAAS;AAClC,QAAI,CAAC4B,EAAK;AACV,UAAMC,IAAU;AAChB,QAAIC,IAAUF,EAAI,eAAeC,CAAO;AACxC,IAAKC,MACHA,IAAUF,EAAI,cAAc,OAAO,GACnCE,EAAQ,KAAKD,GACbD,EAAI,MAAM,YAAYE,CAAO,IAE/BA,EAAQ,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBxB,GAAG,CAAA,CAAE,GAELH,EAAU,MAAM;AACd,IAAInC,MAAeyB,EAAkB,YACnCT,EAAsB,EAAK,GAC3BS,EAAkB,UAAUzB,IAE9B2B,EAAWN,CAAa,GACxBM,EAAWL,CAAc,GACzBC,EAAa,UAAU,IACvBC,EAAc,UAAU;AAExB,UAAMe,IAAY/B,EAAa;AAC/B,QAAI,CAAC+B,EAAW;AAChB,UAAMH,IAAMG,EAAU,eAChBC,IAAOJ,GAAK;AAClB,QAAI,CAACI,EAAM;AACX,UAAMC,IAAiB7D,GAAsB2D,CAAS;AAEtD,IAAAtB,EAAkB,QAAQ,QAAQ,CAAClC,MAASA,EAAK,QAAQ,GACzDkC,EAAkB,UAAU,CAAA,GAC5BC,EAAmB,QAAQ,QAAQ,CAACnC,MAASA,EAAK,QAAQ,GAC1DmC,EAAmB,UAAU,CAAA,GAE7BP,EAAsB,EAAK,GAC3BG,EAAuB,EAAK;AAC5B,UAAM4B,IAAUN,EAAI,cAAc,KAAK;AACvC,IAAAM,EAAQ,YAAY/C;AAEpB,UAAMgD,KAAmBhD,EAAK,MAAM,gBAAgB,KAAK,CAAA,GAAI,QACvDiD,MAAoBjD,EAAK,MAAM,cAAc,KAAK,CAAA,GAAI,QACtDkD,IACJF,IAAkB,KAAKA,MAAoBC,IAEvCE,IAA+B,CAAA;AAErC,UAAM,KAAKJ,EAAQ,iBAAiB,eAAe,CAAC,EAAE,QAAQ,CAAC3D,MAAS;AACtE,UAAIA,EAAK,QAAQ,YAAA,MAAkB,SAAS;AAC1C,cAAMgE,IAASX,EAAI,cAAc,OAAO;AACxC,QAAAW,EAAO,cAAchE,EAAK,eAAe,IACzC,MAAM,KAAKA,EAAK,UAAU,EAAE,QAAQ,CAACiE,MAAS;AAC5C,UAAAD,EAAO,aAAaC,EAAK,MAAMA,EAAK,KAAK;AAAA,QAC3C,CAAC,GACDF,EAAc,KAAKC,CAAM;AAAA,MAC3B,OAAO;AACL,cAAME,IAAcb,EAAI,cAAc,QAAQ;AAC9C,cAAM,KAAKrD,EAAK,UAAU,EAAE,QAAQ,CAACiE,MAAS;AAC5C,UAAAC,EAAY,aAAaD,EAAK,MAAMA,EAAK,KAAK;AAAA,QAChD,CAAC,GACDC,EAAY,cAAclE,EAAK,eAAe,IAC9C+D,EAAc,KAAKG,CAAW;AAAA,MAChC;AACA,MAAAlE,EAAK,OAAA;AAAA,IACP,CAAC,GACDQ,GAAoBmD,GAASD,CAAc;AAE3C,UAAMS,IAAYJ,EAAc;AAAA,MAC9B,CAAC/D,MAASA,EAAK,QAAQ,kBAAkB;AAAA,IAAA,GAErCoE,IAAaL,EAAc;AAAA,MAC/B,CAAC/D,MAASA,EAAK,QAAQ,kBAAkB;AAAA,IAAA;AAE3C,IAAImE,MACF3B,EAAa,UAAU,IACvBJ,EAAc,UAAU,YAAY,IAAA,GACpCQ,EAAWN,CAAa,GACxBV,EAAsB,EAAI,IAExBwC,MACF3B,EAAc,UAAU,IACxBJ,EAAe,UAAU,YAAY,IAAA,GACrCO,EAAWL,CAAc,GACzBR,EAAuB,EAAI;AAG7B,UAAMsC,IAAe,MAAM,KAAKV,EAAQ,UAAU,GAC5CW,IAAoBD,EAAa,SAAS;AAChD,IAAApC,EAAsBqC,CAAiB,GACvCd,EAAU,gBAAgB,GAAGa,CAAY;AAEzC,QAAIE,IAAiD;AACrD,UAAMC,IAAmC,MACnChB,EAAU,WAAW,WAAW,IAC3B,MAGTvB,EAAsB,EAAI,GAC1BsC,GAAuB,WAAA,GACvBA,IAAwB,MACjB;AAET,WAAI,CAACD,KAAqBF,KAAcN,MACtCS,IAAwB,IAAI,iBAAiB,MAAM;AACjD,MAAAC,EAAA;AAAA,IACF,CAAC,GACDD,EAAsB,QAAQf,GAAW;AAAA,MACvC,WAAW;AAAA,MACX,SAAS;AAAA,IAAA,CACV,IAGHO,EAAc,QAAQ,CAAC/D,MAAS;AAC9B,UAAIA,EAAK,QAAQ,YAAA,MAAkB,SAAS;AAC1C,QAAAqD,EAAI,MAAM,YAAYrD,CAAI,GAC1BkC,EAAkB,QAAQ,KAAKlC,CAAwB;AACvD;AAAA,MACF;AAEA,UAAI8D,GAAsB;AACxB,cAAMW,IAAazE,GACb0E,IAAaD,EAAW,eAAe;AAG7C,YAFuB,CAACA,EAAW;AAGjC,cAAI;AAGF,gBAAI,SAASC,CAAU;AAAA,UACzB,QAAQ;AACN,YAAAD,EAAW,OAAA;AACX;AAAA,UACF;AAGF,YAAI;AACF,UAAAhB,EAAK,YAAYgB,CAAU,GAC3BtC,EAAmB,QAAQ,KAAKsC,CAAU;AAAA,QAC5C,QAAQ;AACN,UAAAA,EAAW,OAAA;AAAA,QACb;AAAA,MACF;AAEE,QAAAzE,EAAK,OAAA;AAAA,IAET,CAAC,GACDwE,EAAA,GACInD,KACUmC,EAAU,eAAe,aAChC,0BAAA,GAGP,sBAAsB,MAAM;AAC1B,MAAIW,KACFrB;AAAA,QACElB;AAAA,QACAU;AAAA,QACAF;AAAA,QACA,MAAM;AACJ,UAAAI,EAAa,UAAU;AAAA,QACzB;AAAA,MAAA,GAGA4B,KACFtB;AAAA,QACEf;AAAA,QACAQ;AAAA,QACAF;AAAA,QACA,MAAM;AACJ,UAAAI,EAAc,UAAU;AAAA,QAC1B;AAAA,MAAA;AAAA,IAGN,CAAC,GAEM,MAAM;AACX,MAAA8B,GAAuB,WAAA;AAAA,IACzB;AAAA,EACF,GAAG,CAAC3D,GAAMK,GAAYI,CAAa,CAAC,GAEpC+B;AAAA,IACE,MAAM,MAAM;AACV,MAAAR,EAAWN,CAAa,GACxBM,EAAWL,CAAc;AAAA,IAC3B;AAAA,IACA,CAAA;AAAA,EAAC,GAGHa,EAAU,MAAM;AACd,IAAK9B,MAILsB,EAAWN,CAAa,GACxBM,EAAWL,CAAc,GACzBC,EAAa,UAAU,IACvBC,EAAc,UAAU,IACxBb,EAAsB,EAAK,GAC3BG,EAAuB,EAAK;AAAA,EAC9B,GAAG,CAACT,CAAqB,CAAC;AAE1B,QAAMqD,IACArD,IACK,OAGLQ,KAAuBW,EAAc,UAErCzB,KAAqBF,KAAeS,EAAY,2BAEhDI,KAAsBa,EAAa,UAEnCzB,KAAoBD,KAAeS,EAAY,0BAE9CS,KAEE,OADElB,KAAeS,EAAY,oBAIhCqD,IAAe1D,MAAS,cACxB2D,IAA0BD,KAAgBxD,GAC1C0D,KAA2C;AAAA,IAC/C,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,eAAe;AAAA;AAAA,IAEf,gBAAgBD,IACZ,eACAD,IACE,iBACA;AAAA,EAAA,GAEFG,KAA6C;AAAA,IACjD,eAAeJ,IAAiB,SAAS;AAAA,IACzC,QAAQC,IAAe,SAAY;AAAA,IACnC,OAAO;AAAA,IACP,QAAQC,IAA0B,SAAS;AAAA,IAC3C,WAAWA,IAA0B,IAAI;AAAA,IACzC,MAAMA,IAA0B,aAAa;AAAA,EAAA;AAG/C,SACEG,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,gBAAc7D,IAAkB,SAAS;AAAA,MACzC,WAAU;AAAA,MACV,OAAO2D;AAAA,MACP,aAAW,CAAC,CAACH;AAAA,MAEb,UAAA;AAAA,QAAAM,gBAAAA,EAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAKxD;AAAA,YACL,WAAU;AAAA,YACV,OAAOsD;AAAA,UAAA;AAAA,QAAA;AAAA,QAERJ,KACCM,gBAAAA,EAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,eAAe;AAAA,YAAA;AAAA,YAGjB,UAAAA,gBAAAA,EAAAA,IAACC,IAAA,EAAmB,SAASP,EAAA,CAAgB;AAAA,UAAA;AAAA,QAAA;AAAA,MAC/C;AAAA,IAAA;AAAA,EAAA;AAIR;"}
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,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("./vendor/tailwindcss-v3.min.cjs.js"),r=require("./vendor/daisyui-v4.min.css.cjs.js"),s=require("./vendor/gsap-v3.min.cjs.js"),d=require("./cjkFontFamily.cjs.js");function c(e){const i=e.createElement("script");i.textContent=l.default,e.head.appendChild(i);const t=e.defaultView?.tailwind;t&&(t.config=d.addCjkSafeSansToTailwindConfig(t.config));const n=e.createElement("style");n.textContent=r.default,e.head.appendChild(n);const a=e.createElement("script");a.textContent=s.default,e.head.appendChild(a)}exports.injectBlackboardLibraries=c;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./vendor/tailwindcss-v3.min.cjs.js"),l=require("./vendor/daisyui-v4.min.css.cjs.js"),s=require("./vendor/gsap-v3.min.cjs.js"),a=require("./utils/tailwind-runtime.cjs.js");function d(e){const t=e.createElement("script");t.textContent=r.default,e.head.appendChild(t),a.refreshTailwindRuntime(e);const i=e.createElement("style");i.textContent=l.default,e.head.appendChild(i);const n=e.createElement("script");n.textContent=s.default,e.head.appendChild(n)}exports.refreshTailwindRuntime=a.refreshTailwindRuntime;exports.injectBlackboardLibraries=d;
2
2
  //# sourceMappingURL=blackboard-vendor.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blackboard-vendor.cjs.js","sources":["../../../src/components/ContentRender/blackboard-vendor.ts"],"sourcesContent":["import tailwindScript from \"./vendor/tailwindcss-v3.min.js?raw\";\nimport daisyuiCss from \"./vendor/daisyui-v4.min.css?raw\";\nimport gsapScript from \"./vendor/gsap-v3.min.js?raw\";\nimport { addCjkSafeSansToTailwindConfig } from \"./cjkFontFamily\";\n\ninterface TailwindRuntimeWindow extends Window {\n tailwind?: {\n config?: unknown;\n };\n}\n\n/**\n * Inject blackboard-mode libraries (Tailwind CSS, DaisyUI, GSAP)\n * into an iframe document using DOM API to avoid template-string escaping issues.\n */\nexport function injectBlackboardLibraries(doc: Document): void {\n // 1. Tailwind CSS v3 (JIT compiler, must load first)\n const tailwindEl = doc.createElement(\"script\");\n tailwindEl.textContent = tailwindScript;\n // The Play CDN script replaces window.tailwind with its Proxy during execution,\n // so configure that runtime only after the synchronous append completes.\n doc.head.appendChild(tailwindEl);\n const tailwindRuntime = (doc.defaultView as TailwindRuntimeWindow | null)\n ?.tailwind;\n if (tailwindRuntime) {\n tailwindRuntime.config = addCjkSafeSansToTailwindConfig(\n tailwindRuntime.config\n );\n }\n\n // 2. DaisyUI v4 CSS\n const daisyuiEl = doc.createElement(\"style\");\n daisyuiEl.textContent = daisyuiCss;\n doc.head.appendChild(daisyuiEl);\n\n // 3. GSAP v3\n const gsapEl = doc.createElement(\"script\");\n gsapEl.textContent = gsapScript;\n doc.head.appendChild(gsapEl);\n}\n"],"names":["injectBlackboardLibraries","doc","tailwindEl","tailwindScript","tailwindRuntime","addCjkSafeSansToTailwindConfig","daisyuiEl","daisyuiCss","gsapEl","gsapScript"],"mappings":"mQAeO,SAASA,EAA0BC,EAAqB,CAE7D,MAAMC,EAAaD,EAAI,cAAc,QAAQ,EAC7CC,EAAW,YAAcC,EAAAA,QAGzBF,EAAI,KAAK,YAAYC,CAAU,EAC/B,MAAME,EAAmBH,EAAI,aACzB,SACAG,IACFA,EAAgB,OAASC,EAAAA,+BACvBD,EAAgB,MAAA,GAKpB,MAAME,EAAYL,EAAI,cAAc,OAAO,EAC3CK,EAAU,YAAcC,EAAAA,QACxBN,EAAI,KAAK,YAAYK,CAAS,EAG9B,MAAME,EAASP,EAAI,cAAc,QAAQ,EACzCO,EAAO,YAAcC,EAAAA,QACrBR,EAAI,KAAK,YAAYO,CAAM,CAC7B"}
1
+ {"version":3,"file":"blackboard-vendor.cjs.js","sources":["../../../src/components/ContentRender/blackboard-vendor.ts"],"sourcesContent":["import tailwindScript from \"./vendor/tailwindcss-v3.min.js?raw\";\nimport daisyuiCss from \"./vendor/daisyui-v4.min.css?raw\";\nimport gsapScript from \"./vendor/gsap-v3.min.js?raw\";\nimport { refreshTailwindRuntime } from \"./utils/tailwind-runtime\";\n\nexport { refreshTailwindRuntime };\n\n/**\n * Inject blackboard-mode libraries (Tailwind CSS, DaisyUI, GSAP)\n * into an iframe document using DOM API to avoid template-string escaping issues.\n */\nexport function injectBlackboardLibraries(doc: Document): void {\n // 1. Tailwind CSS v3 (JIT compiler, must load first)\n const tailwindEl = doc.createElement(\"script\");\n tailwindEl.textContent = tailwindScript;\n // The Play CDN script replaces window.tailwind with its Proxy during execution,\n // so configure that runtime only after the synchronous append completes.\n doc.head.appendChild(tailwindEl);\n refreshTailwindRuntime(doc);\n\n // 2. DaisyUI v4 CSS\n const daisyuiEl = doc.createElement(\"style\");\n daisyuiEl.textContent = daisyuiCss;\n doc.head.appendChild(daisyuiEl);\n\n // 3. GSAP v3\n const gsapEl = doc.createElement(\"script\");\n gsapEl.textContent = gsapScript;\n doc.head.appendChild(gsapEl);\n}\n"],"names":["injectBlackboardLibraries","doc","tailwindEl","tailwindScript","refreshTailwindRuntime","daisyuiEl","daisyuiCss","gsapEl","gsapScript"],"mappings":"4QAWO,SAASA,EAA0BC,EAAqB,CAE7D,MAAMC,EAAaD,EAAI,cAAc,QAAQ,EAC7CC,EAAW,YAAcC,EAAAA,QAGzBF,EAAI,KAAK,YAAYC,CAAU,EAC/BE,EAAAA,uBAAuBH,CAAG,EAG1B,MAAMI,EAAYJ,EAAI,cAAc,OAAO,EAC3CI,EAAU,YAAcC,EAAAA,QACxBL,EAAI,KAAK,YAAYI,CAAS,EAG9B,MAAME,EAASN,EAAI,cAAc,QAAQ,EACzCM,EAAO,YAAcC,EAAAA,QACrBP,EAAI,KAAK,YAAYM,CAAM,CAC7B"}
@@ -1,3 +1,5 @@
1
+ import { refreshTailwindRuntime } from './utils/tailwind-runtime';
2
+ export { refreshTailwindRuntime };
1
3
  /**
2
4
  * Inject blackboard-mode libraries (Tailwind CSS, DaisyUI, GSAP)
3
5
  * into an iframe document using DOM API to avoid template-string escaping issues.
@@ -1,20 +1,17 @@
1
1
  import r from "./vendor/tailwindcss-v3.min.es.js";
2
- import l from "./vendor/daisyui-v4.min.css.es.js";
2
+ import a from "./vendor/daisyui-v4.min.css.es.js";
3
3
  import p from "./vendor/gsap-v3.min.es.js";
4
- import { addCjkSafeSansToTailwindConfig as o } from "./cjkFontFamily.es.js";
4
+ import { refreshTailwindRuntime as l } from "./utils/tailwind-runtime.es.js";
5
5
  function c(t) {
6
6
  const e = t.createElement("script");
7
- e.textContent = r, t.head.appendChild(e);
8
- const i = t.defaultView?.tailwind;
9
- i && (i.config = o(
10
- i.config
11
- ));
12
- const n = t.createElement("style");
13
- n.textContent = l, t.head.appendChild(n);
14
- const a = t.createElement("script");
15
- a.textContent = p, t.head.appendChild(a);
7
+ e.textContent = r, t.head.appendChild(e), l(t);
8
+ const i = t.createElement("style");
9
+ i.textContent = a, t.head.appendChild(i);
10
+ const n = t.createElement("script");
11
+ n.textContent = p, t.head.appendChild(n);
16
12
  }
17
13
  export {
18
- c as injectBlackboardLibraries
14
+ c as injectBlackboardLibraries,
15
+ l as refreshTailwindRuntime
19
16
  };
20
17
  //# sourceMappingURL=blackboard-vendor.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blackboard-vendor.es.js","sources":["../../../src/components/ContentRender/blackboard-vendor.ts"],"sourcesContent":["import tailwindScript from \"./vendor/tailwindcss-v3.min.js?raw\";\nimport daisyuiCss from \"./vendor/daisyui-v4.min.css?raw\";\nimport gsapScript from \"./vendor/gsap-v3.min.js?raw\";\nimport { addCjkSafeSansToTailwindConfig } from \"./cjkFontFamily\";\n\ninterface TailwindRuntimeWindow extends Window {\n tailwind?: {\n config?: unknown;\n };\n}\n\n/**\n * Inject blackboard-mode libraries (Tailwind CSS, DaisyUI, GSAP)\n * into an iframe document using DOM API to avoid template-string escaping issues.\n */\nexport function injectBlackboardLibraries(doc: Document): void {\n // 1. Tailwind CSS v3 (JIT compiler, must load first)\n const tailwindEl = doc.createElement(\"script\");\n tailwindEl.textContent = tailwindScript;\n // The Play CDN script replaces window.tailwind with its Proxy during execution,\n // so configure that runtime only after the synchronous append completes.\n doc.head.appendChild(tailwindEl);\n const tailwindRuntime = (doc.defaultView as TailwindRuntimeWindow | null)\n ?.tailwind;\n if (tailwindRuntime) {\n tailwindRuntime.config = addCjkSafeSansToTailwindConfig(\n tailwindRuntime.config\n );\n }\n\n // 2. DaisyUI v4 CSS\n const daisyuiEl = doc.createElement(\"style\");\n daisyuiEl.textContent = daisyuiCss;\n doc.head.appendChild(daisyuiEl);\n\n // 3. GSAP v3\n const gsapEl = doc.createElement(\"script\");\n gsapEl.textContent = gsapScript;\n doc.head.appendChild(gsapEl);\n}\n"],"names":["injectBlackboardLibraries","doc","tailwindEl","tailwindScript","tailwindRuntime","addCjkSafeSansToTailwindConfig","daisyuiEl","daisyuiCss","gsapEl","gsapScript"],"mappings":";;;;AAeO,SAASA,EAA0BC,GAAqB;AAE7D,QAAMC,IAAaD,EAAI,cAAc,QAAQ;AAC7C,EAAAC,EAAW,cAAcC,GAGzBF,EAAI,KAAK,YAAYC,CAAU;AAC/B,QAAME,IAAmBH,EAAI,aACzB;AACJ,EAAIG,MACFA,EAAgB,SAASC;AAAA,IACvBD,EAAgB;AAAA,EAAA;AAKpB,QAAME,IAAYL,EAAI,cAAc,OAAO;AAC3C,EAAAK,EAAU,cAAcC,GACxBN,EAAI,KAAK,YAAYK,CAAS;AAG9B,QAAME,IAASP,EAAI,cAAc,QAAQ;AACzC,EAAAO,EAAO,cAAcC,GACrBR,EAAI,KAAK,YAAYO,CAAM;AAC7B;"}
1
+ {"version":3,"file":"blackboard-vendor.es.js","sources":["../../../src/components/ContentRender/blackboard-vendor.ts"],"sourcesContent":["import tailwindScript from \"./vendor/tailwindcss-v3.min.js?raw\";\nimport daisyuiCss from \"./vendor/daisyui-v4.min.css?raw\";\nimport gsapScript from \"./vendor/gsap-v3.min.js?raw\";\nimport { refreshTailwindRuntime } from \"./utils/tailwind-runtime\";\n\nexport { refreshTailwindRuntime };\n\n/**\n * Inject blackboard-mode libraries (Tailwind CSS, DaisyUI, GSAP)\n * into an iframe document using DOM API to avoid template-string escaping issues.\n */\nexport function injectBlackboardLibraries(doc: Document): void {\n // 1. Tailwind CSS v3 (JIT compiler, must load first)\n const tailwindEl = doc.createElement(\"script\");\n tailwindEl.textContent = tailwindScript;\n // The Play CDN script replaces window.tailwind with its Proxy during execution,\n // so configure that runtime only after the synchronous append completes.\n doc.head.appendChild(tailwindEl);\n refreshTailwindRuntime(doc);\n\n // 2. DaisyUI v4 CSS\n const daisyuiEl = doc.createElement(\"style\");\n daisyuiEl.textContent = daisyuiCss;\n doc.head.appendChild(daisyuiEl);\n\n // 3. GSAP v3\n const gsapEl = doc.createElement(\"script\");\n gsapEl.textContent = gsapScript;\n doc.head.appendChild(gsapEl);\n}\n"],"names":["injectBlackboardLibraries","doc","tailwindEl","tailwindScript","refreshTailwindRuntime","daisyuiEl","daisyuiCss","gsapEl","gsapScript"],"mappings":";;;;AAWO,SAASA,EAA0BC,GAAqB;AAE7D,QAAMC,IAAaD,EAAI,cAAc,QAAQ;AAC7C,EAAAC,EAAW,cAAcC,GAGzBF,EAAI,KAAK,YAAYC,CAAU,GAC/BE,EAAuBH,CAAG;AAG1B,QAAMI,IAAYJ,EAAI,cAAc,OAAO;AAC3C,EAAAI,EAAU,cAAcC,GACxBL,EAAI,KAAK,YAAYI,CAAS;AAG9B,QAAME,IAASN,EAAI,cAAc,QAAQ;AACzC,EAAAM,EAAO,cAAcC,GACrBP,EAAI,KAAK,YAAYM,CAAM;AAC7B;"}
@@ -1,6 +1,6 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./presentation-scaling.cjs.js"),n=`
2
2
  /* Gamma-style scaling base */
3
- :root { --mdf-fs: 16px; }
3
+ :root { --mdf-fs: ${e.PRESENTATION_DEFAULT_FONT_SIZE_PX}px; }
4
4
 
5
5
  *, *::before, *::after {
6
6
  box-sizing: border-box;
@@ -25,13 +25,13 @@ html, body {
25
25
  /* Hide scrollbars inside scaled content — overflow handled by compression */
26
26
  .sandbox-container *::-webkit-scrollbar { display: none; }
27
27
  .sandbox-container * { scrollbar-width: none; -ms-overflow-style: none; }
28
- `,n=`
28
+ `,s=`
29
29
  !function() {
30
30
  var fitTimer = null;
31
- var baseFontSize = 16;
31
+ var baseFontSize = ${e.PRESENTATION_DEFAULT_FONT_SIZE_PX};
32
32
  var compressionRatio = 1;
33
33
  var lastCompressTime = 0;
34
- var MIN_FONT_PX = 8;
34
+ var MIN_FONT_PX = ${e.PRESENTATION_MIN_FONT_SIZE_PX};
35
35
 
36
36
  function applyFs(fs) {
37
37
  document.documentElement.style.setProperty('--mdf-fs', fs + 'px');
@@ -48,8 +48,8 @@ html, body {
48
48
  var naturalH = slide.offsetHeight;
49
49
  var naturalW = slide.scrollWidth;
50
50
 
51
- var overflowH = naturalH > viewH + 4;
52
- var overflowW = naturalW > viewW + 4;
51
+ var overflowH = naturalH > viewH + ${e.PRESENTATION_OVERFLOW_TOLERANCE_PX};
52
+ var overflowW = naturalW > viewW + ${e.PRESENTATION_OVERFLOW_TOLERANCE_PX};
53
53
 
54
54
  if (overflowH || overflowW) {
55
55
  var now = Date.now();
@@ -84,7 +84,10 @@ html, body {
84
84
  function syncFs() {
85
85
  var w = document.documentElement.clientWidth;
86
86
  var h = document.documentElement.clientHeight;
87
- baseFontSize = Math.min(Math.max(12, w / 48), h * 0.03);
87
+ baseFontSize = Math.min(
88
+ Math.max(${e.PRESENTATION_MIN_BASE_FONT_SIZE_PX}, w / ${e.PRESENTATION_WIDTH_FONT_DIVISOR}),
89
+ h * ${e.PRESENTATION_HEIGHT_FONT_RATIO}
90
+ );
88
91
  applyFs(Math.max(baseFontSize * compressionRatio, MIN_FONT_PX));
89
92
  clearTimeout(fitTimer);
90
93
  fitTimer = setTimeout(fitContent, 60);
@@ -157,5 +160,5 @@ html, body {
157
160
  delete window.__mdf_cleanupScaling;
158
161
  };
159
162
  }();
160
- `;function s(e){const t=e.createElement("style");t.id="mdf-scaling-style",t.textContent=i,e.head.appendChild(t);const o=e.createElement("script");o.id="mdf-scaling-script",o.textContent=n,e.head.appendChild(o)}exports.injectScalingSystem=s;
163
+ `;function r(t){const o=t.createElement("style");o.id="mdf-scaling-style",o.textContent=n,t.head.appendChild(o);const i=t.createElement("script");i.id="mdf-scaling-script",i.textContent=s,t.head.appendChild(i)}exports.injectScalingSystem=r;
161
164
  //# sourceMappingURL=iframe-scaling.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"iframe-scaling.cjs.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":"gFAgBA,MAAMA,EAAc;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,EA6BdC,EAAa;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,EA2IZ,SAASC,EAAoBC,EAAqB,CACvD,MAAMC,EAAUD,EAAI,cAAc,OAAO,EACzCC,EAAQ,GAAK,oBACbA,EAAQ,YAAcJ,EACtBG,EAAI,KAAK,YAAYC,CAAO,EAE5B,MAAMC,EAAWF,EAAI,cAAc,QAAQ,EAC3CE,EAAS,GAAK,qBACdA,EAAS,YAAcJ,EACvBE,EAAI,KAAK,YAAYE,CAAQ,CAC/B"}
1
+ {"version":3,"file":"iframe-scaling.cjs.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":"iIAyBMA,EAAc;AAAA;AAAA,oBAEAC,mCAAiC;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,EA2B/CC,EAAa;AAAA;AAAA;AAAA,uBAGID,mCAAiC;AAAA;AAAA;AAAA,sBAGlCE,+BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAiBVC,oCAAkC;AAAA,yCAClCA,oCAAkC;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,EAAAA,kCAAkC,SAASC,iCAA+B;AAAA,YAC/EC,EAAAA,8BAA8B;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,EAiFnC,SAASC,EAAoBC,EAAqB,CACvD,MAAMC,EAAUD,EAAI,cAAc,OAAO,EACzCC,EAAQ,GAAK,oBACbA,EAAQ,YAAcV,EACtBS,EAAI,KAAK,YAAYC,CAAO,EAE5B,MAAMC,EAAWF,EAAI,cAAc,QAAQ,EAC3CE,EAAS,GAAK,qBACdA,EAAS,YAAcT,EACvBO,EAAI,KAAK,YAAYE,CAAQ,CAC/B"}