@files-preview-app/preview-file 1.3.5 → 1.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -579,6 +579,7 @@ var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" str
579
579
  var ICON_FAST_FORWARD = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 19 22 12 13 5 13 19"></polygon><polygon points="2 19 11 12 2 5 2 19"></polygon></svg>`;
580
580
  var ICON_REWIND = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 19 2 12 11 5 11 19"></polygon><polygon points="22 19 13 12 22 5 22 19"></polygon></svg>`;
581
581
  var ICON_EXTERNAL_WINDOW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><line x1="3" y1="8" x2="21" y2="8"></line><circle cx="6" cy="5.5" r="0.75" fill="currentColor"></circle><circle cx="8.5" cy="5.5" r="0.75" fill="currentColor"></circle><polyline points="14 13 18 13 18 17"></polyline><line x1="11" y1="20" x2="18" y2="13"></line></svg>`;
582
+ var ICON_RESET_ZOOM = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><path d="M13 11a3 3 0 1 0-3 3"></path><path d="M10 11v3h3"></path></svg>`;
582
583
  var ICON_MAP = {
583
584
  "zoom-in": ICON_ZOOM_IN,
584
585
  "zoom-out": ICON_ZOOM_OUT,
@@ -608,7 +609,10 @@ var ICON_MAP = {
608
609
  "open-window": ICON_EXTERNAL_WINDOW,
609
610
  "external-window": ICON_EXTERNAL_WINDOW,
610
611
  "openWindow": ICON_EXTERNAL_WINDOW,
611
- "openSeparateWindow": ICON_EXTERNAL_WINDOW
612
+ "openSeparateWindow": ICON_EXTERNAL_WINDOW,
613
+ "reset-zoom": ICON_RESET_ZOOM,
614
+ "zoom-reset": ICON_RESET_ZOOM,
615
+ "resetZoom": ICON_RESET_ZOOM
612
616
  };
613
617
  var ToolbarController = class {
614
618
  el;
@@ -641,6 +645,10 @@ var ToolbarController = class {
641
645
  this.config.fitToPage = false;
642
646
  this.config.fitWidth = false;
643
647
  }
648
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
649
+ this.config.resetZoom = false;
650
+ this.config.zoomReset = false;
651
+ }
644
652
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = false;
645
653
  if (actionId === "fullscreen") this.config.fullscreen = false;
646
654
  if (actionId === "download") this.config.download = false;
@@ -665,6 +673,10 @@ var ToolbarController = class {
665
673
  this.config.fitToPage = true;
666
674
  this.config.fitWidth = true;
667
675
  }
676
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
677
+ this.config.resetZoom = true;
678
+ this.config.zoomReset = true;
679
+ }
668
680
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = true;
669
681
  if (actionId === "fullscreen") this.config.fullscreen = true;
670
682
  if (actionId === "download") this.config.download = true;
@@ -684,6 +696,7 @@ var ToolbarController = class {
684
696
  if (actionId === "zoomIn") return "zoom-in";
685
697
  if (actionId === "zoomOut") return "zoom-out";
686
698
  if (actionId === "fitPage" || actionId === "fitToPage" || actionId === "fitWidth") return "fit-page";
699
+ if (actionId === "resetZoom" || actionId === "zoomReset") return "reset-zoom";
687
700
  if (actionId === "rotateCW") return "rotate-cw";
688
701
  if (actionId === "rotateCCW") return "rotate-ccw";
689
702
  if (actionId === "openWindow" || actionId === "openSeparateWindow") return "open-window";
@@ -726,6 +739,9 @@ var ToolbarController = class {
726
739
  if ((id === "fit-page" || id === "fit-width" || id === "fit-slide") && (c.fitPage === false || c.fitToPage === false || c.fitWidth === false || c["fit-page"] === false || c["fit-width"] === false)) {
727
740
  return false;
728
741
  }
742
+ if ((id === "reset-zoom" || id === "zoom-reset") && (c.resetZoom === false || c.zoomReset === false || c["reset-zoom"] === false || c["zoom-reset"] === false)) {
743
+ return false;
744
+ }
729
745
  if ((id === "rotate-cw" || id === "rotate-ccw" || id === "rotate") && (c.rotate === false || c.rotateCW === false || c.rotateCCW === false || c["rotate-cw"] === false)) {
730
746
  return false;
731
747
  }
@@ -1172,6 +1188,9 @@ var FilePreviewViewer = class _FilePreviewViewer {
1172
1188
  this.activeInstance = instance;
1173
1189
  instance.openInSeparateWindow = () => this.openInSeparateWindow();
1174
1190
  instance.toggleThumbnails = () => this.toggleThumbnails();
1191
+ if (!instance.resetZoom && instance.fitToPage) {
1192
+ instance.resetZoom = () => instance.fitToPage?.();
1193
+ }
1175
1194
  this.hideLoading();
1176
1195
  this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
1177
1196
  const isToolbarVisible = options.showToolbar !== false && options.toolbar !== false;
@@ -1455,6 +1474,16 @@ var FilePreviewViewer = class _FilePreviewViewer {
1455
1474
  fitToPage() {
1456
1475
  this.activeInstance?.fitToPage?.();
1457
1476
  }
1477
+ /**
1478
+ * Reset zoom level to initial/default fit state.
1479
+ */
1480
+ resetZoom() {
1481
+ if (this.activeInstance?.resetZoom) {
1482
+ this.activeInstance.resetZoom();
1483
+ } else if (this.activeInstance?.fitToPage) {
1484
+ this.activeInstance.fitToPage();
1485
+ }
1486
+ }
1458
1487
  /**
1459
1488
  * Zoom in.
1460
1489
  */
@@ -2076,6 +2105,14 @@ var PdfPlugin = class {
2076
2105
  group: "zoom",
2077
2106
  execute: () => instance.fitToPage?.()
2078
2107
  },
2108
+ {
2109
+ id: "reset-zoom",
2110
+ icon: "reset-zoom",
2111
+ label: "Reset Zoom",
2112
+ type: "button",
2113
+ group: "zoom",
2114
+ execute: () => instance.resetZoom?.()
2115
+ },
2079
2116
  {
2080
2117
  id: "fit-width",
2081
2118
  icon: "fit-width",
@@ -2131,16 +2168,22 @@ var PdfPlugin = class {
2131
2168
  container.className = "fp-pdf-container";
2132
2169
  container.style.width = "100%";
2133
2170
  container.style.height = "100%";
2134
- container.style.overflowX = "hidden";
2135
- container.style.overflowY = "auto";
2136
- container.style.display = "flex";
2137
- container.style.flexDirection = "column";
2138
- container.style.alignItems = "center";
2139
- container.style.justifyContent = "flex-start";
2140
- container.style.padding = "16px 8px";
2171
+ container.style.overflow = "auto";
2141
2172
  container.style.backgroundColor = "#0f172a";
2142
2173
  container.style.boxSizing = "border-box";
2143
2174
  container.style.position = "relative";
2175
+ const scrollWrapper = document.createElement("div");
2176
+ scrollWrapper.className = "fp-pdf-scroll-wrapper";
2177
+ scrollWrapper.style.minWidth = "100%";
2178
+ scrollWrapper.style.minHeight = "100%";
2179
+ scrollWrapper.style.width = "max-content";
2180
+ scrollWrapper.style.height = "max-content";
2181
+ scrollWrapper.style.display = "flex";
2182
+ scrollWrapper.style.flexDirection = "column";
2183
+ scrollWrapper.style.alignItems = "center";
2184
+ scrollWrapper.style.justifyContent = "flex-start";
2185
+ scrollWrapper.style.padding = "16px 8px";
2186
+ scrollWrapper.style.boxSizing = "border-box";
2144
2187
  const pageCard = document.createElement("div");
2145
2188
  pageCard.className = "fp-pdf-page-card";
2146
2189
  pageCard.style.boxShadow = "0 10px 35px rgba(0, 0, 0, 0.5)";
@@ -2153,7 +2196,8 @@ var PdfPlugin = class {
2153
2196
  pageCard.style.transition = "box-shadow 0.2s ease";
2154
2197
  let canvas = document.createElement("canvas");
2155
2198
  pageCard.appendChild(canvas);
2156
- container.appendChild(pageCard);
2199
+ scrollWrapper.appendChild(pageCard);
2200
+ container.appendChild(scrollWrapper);
2157
2201
  ctx.container.appendChild(container);
2158
2202
  const standardFontsUrl = typeof window !== "undefined" && window.__PDF_STANDARD_FONTS_URL__ || "./standard_fonts/";
2159
2203
  const cmapsUrl = typeof window !== "undefined" && window.__PDF_CMAPS_URL__ || "./cmaps/";
@@ -2338,6 +2382,14 @@ var PdfPlugin = class {
2338
2382
  zoomScale = 1;
2339
2383
  renderPage(currentPage);
2340
2384
  },
2385
+ resetZoom: () => {
2386
+ fitMode = "page";
2387
+ zoomScale = 1;
2388
+ rotation = 0;
2389
+ container.scrollTop = 0;
2390
+ container.scrollLeft = 0;
2391
+ renderPage(currentPage);
2392
+ },
2341
2393
  fitToWidth: () => {
2342
2394
  fitMode = "width";
2343
2395
  zoomScale = 1;
@@ -2505,6 +2557,16 @@ var MediaPlugin = class {
2505
2557
  instance.fitToPage?.();
2506
2558
  }
2507
2559
  },
2560
+ {
2561
+ id: "reset-zoom",
2562
+ icon: "reset-zoom",
2563
+ label: "Reset Zoom",
2564
+ type: "button",
2565
+ group: "zoom",
2566
+ execute: () => {
2567
+ instance.resetZoom?.();
2568
+ }
2569
+ },
2508
2570
  {
2509
2571
  id: "rotate-cw",
2510
2572
  icon: "rotate-cw",
@@ -2644,17 +2706,86 @@ var MediaPlugin = class {
2644
2706
  element = document.createElement("div");
2645
2707
  element.textContent = "Unsupported media type";
2646
2708
  }
2647
- ctx.container.style.display = "flex";
2648
- ctx.container.style.alignItems = "center";
2649
- ctx.container.style.justifyContent = "center";
2650
- ctx.container.style.overflow = "hidden";
2651
- ctx.container.appendChild(element);
2709
+ const scrollWrapper = document.createElement("div");
2710
+ scrollWrapper.className = "fp-media-scroll-wrapper";
2711
+ scrollWrapper.style.minWidth = "100%";
2712
+ scrollWrapper.style.minHeight = "100%";
2713
+ scrollWrapper.style.width = "max-content";
2714
+ scrollWrapper.style.height = "max-content";
2715
+ scrollWrapper.style.display = "flex";
2716
+ scrollWrapper.style.justifyContent = "center";
2717
+ scrollWrapper.style.alignItems = "center";
2718
+ scrollWrapper.style.padding = "16px";
2719
+ scrollWrapper.style.boxSizing = "border-box";
2720
+ const sizer = document.createElement("div");
2721
+ sizer.className = "fp-media-sizer";
2722
+ sizer.style.position = "relative";
2723
+ sizer.style.flexShrink = "0";
2724
+ sizer.style.display = "flex";
2725
+ sizer.style.justifyContent = "center";
2726
+ sizer.style.alignItems = "center";
2727
+ sizer.appendChild(element);
2728
+ scrollWrapper.appendChild(sizer);
2729
+ ctx.container.style.overflow = "auto";
2730
+ ctx.container.style.padding = "0";
2731
+ ctx.container.innerHTML = "";
2732
+ ctx.container.appendChild(scrollWrapper);
2733
+ let naturalW = 800;
2734
+ let naturalH = 600;
2735
+ let baseW = 800;
2736
+ let baseH = 600;
2737
+ const updateBaseDimensions = () => {
2738
+ if (!isImage) return;
2739
+ const img = element;
2740
+ naturalW = img.naturalWidth || naturalW;
2741
+ naturalH = img.naturalHeight || naturalH;
2742
+ const availW = Math.max(100, ctx.container.clientWidth - 48);
2743
+ const availH = Math.max(100, ctx.container.clientHeight - 48);
2744
+ const fitRatio = Math.min(1, availW / naturalW, availH / naturalH);
2745
+ baseW = Math.max(1, Math.round(naturalW * fitRatio));
2746
+ baseH = Math.max(1, Math.round(naturalH * fitRatio));
2747
+ };
2652
2748
  const applyTransform = () => {
2653
- element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2749
+ if (isImage) {
2750
+ updateBaseDimensions();
2751
+ const isRotated90 = rotation % 180 !== 0;
2752
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * currentZoom);
2753
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * currentZoom);
2754
+ sizer.style.width = `${boxW}px`;
2755
+ sizer.style.height = `${boxH}px`;
2756
+ element.style.width = `${baseW}px`;
2757
+ element.style.height = `${baseH}px`;
2758
+ element.style.maxWidth = "none";
2759
+ element.style.maxHeight = "none";
2760
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2761
+ element.style.transformOrigin = "center center";
2762
+ element.style.flexShrink = "0";
2763
+ } else {
2764
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2765
+ }
2654
2766
  };
2767
+ if (isImage) {
2768
+ const img = element;
2769
+ if (img.complete && img.naturalWidth > 0) {
2770
+ updateBaseDimensions();
2771
+ applyTransform();
2772
+ } else {
2773
+ img.onload = () => {
2774
+ updateBaseDimensions();
2775
+ applyTransform();
2776
+ };
2777
+ }
2778
+ }
2779
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
2780
+ if (currentZoom === 1) {
2781
+ applyTransform();
2782
+ }
2783
+ }) : null;
2784
+ ro?.observe(ctx.container);
2655
2785
  const cleanup = () => {
2786
+ ro?.disconnect();
2656
2787
  if (url) URL.revokeObjectURL(url);
2657
- element.remove();
2788
+ scrollWrapper.remove();
2658
2789
  ctx.container.innerHTML = "";
2659
2790
  };
2660
2791
  ctx.signal.addEventListener("abort", cleanup);
@@ -2678,6 +2809,13 @@ var MediaPlugin = class {
2678
2809
  rotation = 0;
2679
2810
  applyTransform();
2680
2811
  } : void 0,
2812
+ resetZoom: isImage ? () => {
2813
+ currentZoom = 1;
2814
+ rotation = 0;
2815
+ ctx.container.scrollTop = 0;
2816
+ ctx.container.scrollLeft = 0;
2817
+ applyTransform();
2818
+ } : void 0,
2681
2819
  rotateCW: isImage || isVideo ? () => {
2682
2820
  rotation = (rotation + 90) % 360;
2683
2821
  applyTransform();
@@ -2794,6 +2932,14 @@ var DocxPlugin = class {
2794
2932
  group: "zoom",
2795
2933
  execute: () => instance.fitToPage?.()
2796
2934
  },
2935
+ {
2936
+ id: "reset-zoom",
2937
+ icon: "reset-zoom",
2938
+ label: "Reset Zoom",
2939
+ type: "button",
2940
+ group: "zoom",
2941
+ execute: () => instance.resetZoom?.()
2942
+ },
2797
2943
  {
2798
2944
  id: "rotate-cw",
2799
2945
  icon: "rotate-cw",
@@ -2832,7 +2978,7 @@ var DocxPlugin = class {
2832
2978
  async render(ctx) {
2833
2979
  const wrapper = document.createElement("div");
2834
2980
  wrapper.className = "fp-docx-wrapper";
2835
- wrapper.style.transformOrigin = "top center";
2981
+ wrapper.style.transformOrigin = "center center";
2836
2982
  wrapper.style.transition = "transform 0.2s ease";
2837
2983
  wrapper.style.padding = "0";
2838
2984
  wrapper.style.maxWidth = "none";
@@ -2842,11 +2988,31 @@ var DocxPlugin = class {
2842
2988
  wrapper.style.flexDirection = "column";
2843
2989
  wrapper.style.alignItems = "center";
2844
2990
  wrapper.style.boxSizing = "border-box";
2845
- ctx.container.style.overflowX = "hidden";
2846
- ctx.container.style.overflowY = "auto";
2847
- ctx.container.style.padding = "16px 8px";
2991
+ wrapper.style.flexShrink = "0";
2992
+ const sizer = document.createElement("div");
2993
+ sizer.className = "fp-docx-sizer";
2994
+ sizer.style.position = "relative";
2995
+ sizer.style.flexShrink = "0";
2996
+ sizer.style.display = "flex";
2997
+ sizer.style.justifyContent = "center";
2998
+ sizer.style.alignItems = "center";
2999
+ const scrollWrapper = document.createElement("div");
3000
+ scrollWrapper.className = "fp-docx-scroll-wrapper";
3001
+ scrollWrapper.style.minWidth = "100%";
3002
+ scrollWrapper.style.minHeight = "100%";
3003
+ scrollWrapper.style.width = "max-content";
3004
+ scrollWrapper.style.height = "max-content";
3005
+ scrollWrapper.style.display = "flex";
3006
+ scrollWrapper.style.justifyContent = "center";
3007
+ scrollWrapper.style.alignItems = "flex-start";
3008
+ scrollWrapper.style.padding = "16px 8px";
3009
+ scrollWrapper.style.boxSizing = "border-box";
3010
+ sizer.appendChild(wrapper);
3011
+ scrollWrapper.appendChild(sizer);
3012
+ ctx.container.style.overflow = "auto";
3013
+ ctx.container.style.padding = "0";
2848
3014
  ctx.container.style.backgroundColor = "#f1f5f9";
2849
- ctx.container.appendChild(wrapper);
3015
+ ctx.container.appendChild(scrollWrapper);
2850
3016
  const styleOverride = document.createElement("style");
2851
3017
  styleOverride.textContent = `
2852
3018
  .fp-docx-wrapper .docx-wrapper {
@@ -2885,8 +3051,8 @@ var DocxPlugin = class {
2885
3051
  renderEndnotes: true,
2886
3052
  useBase64URL: true
2887
3053
  });
2888
- if (!ctx.container.contains(wrapper)) {
2889
- ctx.container.appendChild(wrapper);
3054
+ if (!sizer.contains(wrapper)) {
3055
+ sizer.appendChild(wrapper);
2890
3056
  }
2891
3057
  if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
2892
3058
  renderedSuccessfully = true;
@@ -2923,8 +3089,8 @@ var DocxPlugin = class {
2923
3089
  try {
2924
3090
  wrapper.innerHTML = "";
2925
3091
  this.renderXmlFallback(ctx, wrapper, createdBlobUrls);
2926
- if (!ctx.container.contains(wrapper)) {
2927
- ctx.container.appendChild(wrapper);
3092
+ if (!sizer.contains(wrapper)) {
3093
+ sizer.appendChild(wrapper);
2928
3094
  }
2929
3095
  renderedSuccessfully = true;
2930
3096
  } catch (fallbackErr) {
@@ -2939,8 +3105,8 @@ var DocxPlugin = class {
2939
3105
  </p>
2940
3106
  </div>
2941
3107
  `;
2942
- if (!ctx.container.contains(wrapper)) {
2943
- ctx.container.appendChild(wrapper);
3108
+ if (!sizer.contains(wrapper)) {
3109
+ sizer.appendChild(wrapper);
2944
3110
  }
2945
3111
  }
2946
3112
  }
@@ -3043,15 +3209,18 @@ var DocxPlugin = class {
3043
3209
  return Math.max(0.35, Math.min(3, sW));
3044
3210
  };
3045
3211
  const applyTransform = () => {
3046
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
3047
- wrapper.style.transformOrigin = "top center";
3048
3212
  const activeEl = pageElements[currentPage - 1] || wrapper.querySelector("section.docx") || wrapper;
3213
+ const elW = activeEl.offsetWidth || 816;
3049
3214
  const elH = activeEl.offsetHeight || 1056;
3050
- if (scale > 1) {
3051
- wrapper.style.marginBottom = `${Math.round(elH * scale - elH + 32)}px`;
3052
- } else {
3053
- wrapper.style.marginBottom = "32px";
3054
- }
3215
+ const isRotated90 = rotation % 180 !== 0;
3216
+ const boxW = Math.round((isRotated90 ? elH : elW) * scale);
3217
+ const boxH = Math.round((isRotated90 ? elW : elH) * scale);
3218
+ sizer.style.width = `${boxW}px`;
3219
+ sizer.style.height = `${boxH}px`;
3220
+ wrapper.style.width = `${elW}px`;
3221
+ wrapper.style.height = `${elH}px`;
3222
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
3223
+ wrapper.style.transformOrigin = "center center";
3055
3224
  };
3056
3225
  let resizeObserver = null;
3057
3226
  if (typeof ResizeObserver !== "undefined") {
@@ -3076,7 +3245,7 @@ var DocxPlugin = class {
3076
3245
  for (const url of createdBlobUrls) {
3077
3246
  URL.revokeObjectURL(url);
3078
3247
  }
3079
- wrapper.remove();
3248
+ scrollWrapper.remove();
3080
3249
  styleOverride.remove();
3081
3250
  ctx.container.innerHTML = "";
3082
3251
  };
@@ -3110,6 +3279,14 @@ var DocxPlugin = class {
3110
3279
  rotation = 0;
3111
3280
  applyTransform();
3112
3281
  },
3282
+ resetZoom: () => {
3283
+ isUserZoomed = false;
3284
+ scale = calculateFitScale("page");
3285
+ rotation = 0;
3286
+ ctx.container.scrollTop = 0;
3287
+ ctx.container.scrollLeft = 0;
3288
+ applyTransform();
3289
+ },
3113
3290
  rotateCW: () => {
3114
3291
  rotation = (rotation + 90) % 360;
3115
3292
  applyTransform();
@@ -3559,6 +3736,16 @@ var ExcelPlugin = class {
3559
3736
  instance.zoomIn?.();
3560
3737
  }
3561
3738
  },
3739
+ {
3740
+ id: "reset-zoom",
3741
+ icon: "reset-zoom",
3742
+ label: "Reset Zoom",
3743
+ type: "button",
3744
+ group: "zoom",
3745
+ execute: () => {
3746
+ instance.resetZoom?.();
3747
+ }
3748
+ },
3562
3749
  {
3563
3750
  id: "download",
3564
3751
  icon: "download",
@@ -3605,7 +3792,7 @@ var ExcelPlugin = class {
3605
3792
  contentArea.style.flex = "1";
3606
3793
  contentArea.style.overflow = "auto";
3607
3794
  contentArea.style.padding = "16px";
3608
- contentArea.style.transformOrigin = "top left";
3795
+ contentArea.style.boxSizing = "border-box";
3609
3796
  const tabsArea = document.createElement("div");
3610
3797
  tabsArea.className = "fp-excel-tabs";
3611
3798
  tabsArea.style.display = "flex";
@@ -3619,18 +3806,35 @@ var ExcelPlugin = class {
3619
3806
  container.appendChild(tabsArea);
3620
3807
  ctx.container.appendChild(container);
3621
3808
  let scale = 1;
3809
+ let isUserZoomed = false;
3622
3810
  let currentSheetIndex = 1;
3623
3811
  let sheetNames = [];
3624
3812
  let wb = null;
3625
3813
  const applyTransform = () => {
3626
- contentArea.style.transform = `scale(${scale})`;
3627
- contentArea.style.transformOrigin = "top left";
3814
+ const sizer = contentArea.querySelector(".fp-excel-sizer");
3815
+ const table = contentArea.querySelector("table");
3816
+ if (!sizer || !table) return;
3817
+ if (!table._baseWidth && table.offsetWidth > 0) {
3818
+ table._baseWidth = table.offsetWidth;
3819
+ table._baseHeight = table.offsetHeight;
3820
+ }
3821
+ const baseW = table._baseWidth || table.offsetWidth || 800;
3822
+ const baseH = table._baseHeight || table.offsetHeight || 600;
3823
+ const scaledW = Math.round(baseW * scale);
3824
+ const scaledH = Math.round(baseH * scale);
3825
+ sizer.style.width = `${scaledW}px`;
3826
+ sizer.style.height = `${scaledH}px`;
3827
+ table.style.position = "absolute";
3828
+ table.style.top = "0";
3829
+ table.style.left = "0";
3830
+ table.style.transform = `scale(${scale})`;
3831
+ table.style.transformOrigin = "top left";
3628
3832
  };
3629
3833
  const calculateFitScale = () => {
3630
3834
  const table = contentArea.querySelector("table");
3631
3835
  if (!table) return 1;
3632
3836
  const availW = Math.max(280, container.clientWidth - 48);
3633
- const tW = table.offsetWidth || 800;
3837
+ const tW = table._baseWidth || table.offsetWidth || 800;
3634
3838
  return Math.max(0.4, Math.min(1, availW / tW));
3635
3839
  };
3636
3840
  try {
@@ -3650,9 +3854,13 @@ var ExcelPlugin = class {
3650
3854
  contentArea.innerHTML = '<div style="padding: 24px; color: #888;">Empty sheet</div>';
3651
3855
  return;
3652
3856
  }
3857
+ const sizer = document.createElement("div");
3858
+ sizer.className = "fp-excel-sizer";
3859
+ sizer.style.position = "relative";
3653
3860
  const html = XLSX.utils.sheet_to_html(ws, { id: "fp-sheet-table", editable: false });
3654
- contentArea.innerHTML = html;
3655
- const table = contentArea.querySelector("table");
3861
+ sizer.innerHTML = html;
3862
+ contentArea.appendChild(sizer);
3863
+ const table = sizer.querySelector("table");
3656
3864
  if (table) {
3657
3865
  table.style.borderCollapse = "collapse";
3658
3866
  table.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
@@ -3687,13 +3895,17 @@ var ExcelPlugin = class {
3687
3895
  });
3688
3896
  ctx.emit("page-change", { page: currentSheetIndex, total: sheetNames.length });
3689
3897
  requestAnimationFrame(() => {
3690
- scale = calculateFitScale();
3898
+ if (!isUserZoomed) {
3899
+ scale = calculateFitScale();
3900
+ }
3691
3901
  applyTransform();
3692
3902
  });
3693
3903
  };
3694
3904
  const ro = new ResizeObserver(() => {
3695
- scale = calculateFitScale();
3696
- applyTransform();
3905
+ if (!isUserZoomed) {
3906
+ scale = calculateFitScale();
3907
+ applyTransform();
3908
+ }
3697
3909
  });
3698
3910
  ro.observe(container);
3699
3911
  if (sheetNames.length > 0) {
@@ -3730,20 +3942,31 @@ var ExcelPlugin = class {
3730
3942
  return {
3731
3943
  destroy: cleanup,
3732
3944
  zoomIn: () => {
3945
+ isUserZoomed = true;
3733
3946
  scale += 0.15;
3734
3947
  applyTransform();
3735
3948
  },
3736
3949
  zoomOut: () => {
3950
+ isUserZoomed = true;
3737
3951
  scale = Math.max(0.2, scale - 0.15);
3738
3952
  applyTransform();
3739
3953
  },
3740
3954
  getZoom: () => scale,
3741
3955
  setZoom: (level) => {
3956
+ isUserZoomed = true;
3742
3957
  scale = level;
3743
3958
  applyTransform();
3744
3959
  },
3745
3960
  fitToPage: () => {
3961
+ isUserZoomed = false;
3962
+ scale = calculateFitScale();
3963
+ applyTransform();
3964
+ },
3965
+ resetZoom: () => {
3966
+ isUserZoomed = false;
3746
3967
  scale = calculateFitScale();
3968
+ contentArea.scrollTop = 0;
3969
+ contentArea.scrollLeft = 0;
3747
3970
  applyTransform();
3748
3971
  },
3749
3972
  rotateCW: () => {
@@ -3876,6 +4099,16 @@ var CsvPlugin = class {
3876
4099
  instance.zoomIn?.();
3877
4100
  }
3878
4101
  },
4102
+ {
4103
+ id: "reset-zoom",
4104
+ icon: "reset-zoom",
4105
+ label: "Reset Zoom",
4106
+ type: "button",
4107
+ group: "zoom",
4108
+ execute: () => {
4109
+ instance.resetZoom?.();
4110
+ }
4111
+ },
3879
4112
  {
3880
4113
  id: "download",
3881
4114
  icon: "download",
@@ -3962,21 +4195,41 @@ var CsvPlugin = class {
3962
4195
  container.appendChild(tableWrapper);
3963
4196
  ctx.container.appendChild(container);
3964
4197
  let scale = 1;
4198
+ let isUserZoomed = false;
3965
4199
  const calculateFitScale = () => {
3966
4200
  const availW = Math.max(280, container.clientWidth - 48);
3967
- const tW = table.offsetWidth || 800;
4201
+ const tW = table._baseWidth || table.offsetWidth || 800;
3968
4202
  return Math.max(0.4, Math.min(1, availW / tW));
3969
4203
  };
3970
4204
  const applyScale = () => {
3971
- tableWrapper.style.transform = `scale(${scale})`;
4205
+ if (!table._baseWidth && table.offsetWidth > 0) {
4206
+ table._baseWidth = table.offsetWidth;
4207
+ table._baseHeight = table.offsetHeight;
4208
+ }
4209
+ const baseW = table._baseWidth || table.offsetWidth || 800;
4210
+ const baseH = table._baseHeight || table.offsetHeight || 600;
4211
+ const scaledW = Math.round(baseW * scale);
4212
+ const scaledH = Math.round(baseH * scale);
4213
+ tableWrapper.style.position = "relative";
4214
+ tableWrapper.style.width = `${scaledW}px`;
4215
+ tableWrapper.style.height = `${scaledH}px`;
4216
+ table.style.position = "absolute";
4217
+ table.style.top = "0";
4218
+ table.style.left = "0";
4219
+ table.style.transform = `scale(${scale})`;
4220
+ table.style.transformOrigin = "top left";
3972
4221
  };
3973
4222
  requestAnimationFrame(() => {
3974
- scale = calculateFitScale();
4223
+ if (!isUserZoomed) {
4224
+ scale = calculateFitScale();
4225
+ }
3975
4226
  applyScale();
3976
4227
  });
3977
4228
  const ro = new ResizeObserver(() => {
3978
- scale = calculateFitScale();
3979
- applyScale();
4229
+ if (!isUserZoomed) {
4230
+ scale = calculateFitScale();
4231
+ applyScale();
4232
+ }
3980
4233
  });
3981
4234
  ro.observe(container);
3982
4235
  const cleanup = () => {
@@ -4049,20 +4302,31 @@ var CsvPlugin = class {
4049
4302
  }];
4050
4303
  },
4051
4304
  zoomIn: () => {
4305
+ isUserZoomed = true;
4052
4306
  scale += 0.1;
4053
4307
  applyScale();
4054
4308
  },
4055
4309
  zoomOut: () => {
4310
+ isUserZoomed = true;
4056
4311
  scale = Math.max(0.2, scale - 0.1);
4057
4312
  applyScale();
4058
4313
  },
4059
4314
  getZoom: () => scale,
4060
4315
  setZoom: (level) => {
4316
+ isUserZoomed = true;
4061
4317
  scale = level;
4062
4318
  applyScale();
4063
4319
  },
4064
4320
  fitToPage: () => {
4321
+ isUserZoomed = false;
4322
+ scale = calculateFitScale();
4323
+ applyScale();
4324
+ },
4325
+ resetZoom: () => {
4326
+ isUserZoomed = false;
4065
4327
  scale = calculateFitScale();
4328
+ container.scrollTop = 0;
4329
+ container.scrollLeft = 0;
4066
4330
  applyScale();
4067
4331
  },
4068
4332
  rotateCW: () => {
@@ -4180,6 +4444,16 @@ var CodePlugin = class {
4180
4444
  instance.zoomIn?.();
4181
4445
  }
4182
4446
  },
4447
+ {
4448
+ id: "reset-zoom",
4449
+ icon: "reset-zoom",
4450
+ label: "Reset Zoom",
4451
+ type: "button",
4452
+ group: "zoom",
4453
+ execute: () => {
4454
+ instance.resetZoom?.();
4455
+ }
4456
+ },
4183
4457
  {
4184
4458
  id: "copy",
4185
4459
  icon: "copy",
@@ -4285,15 +4559,27 @@ var CodePlugin = class {
4285
4559
  let isUserZoomed = false;
4286
4560
  const pre = document.createElement("pre");
4287
4561
  const code = document.createElement("code");
4562
+ const sizer = document.createElement("div");
4563
+ const scrollWrapper = document.createElement("div");
4288
4564
  if (isTxt) {
4289
- container.style.overflowX = "hidden";
4290
- container.style.overflowY = "auto";
4565
+ container.style.overflow = "auto";
4291
4566
  container.style.backgroundColor = "#f1f5f9";
4292
- container.style.padding = "16px 8px";
4293
- container.style.boxSizing = "border-box";
4294
- container.style.display = "flex";
4295
- container.style.flexDirection = "column";
4296
- container.style.alignItems = "center";
4567
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4568
+ scrollWrapper.style.minWidth = "100%";
4569
+ scrollWrapper.style.minHeight = "100%";
4570
+ scrollWrapper.style.width = "max-content";
4571
+ scrollWrapper.style.height = "max-content";
4572
+ scrollWrapper.style.display = "flex";
4573
+ scrollWrapper.style.justifyContent = "center";
4574
+ scrollWrapper.style.alignItems = "flex-start";
4575
+ scrollWrapper.style.padding = "16px 8px";
4576
+ scrollWrapper.style.boxSizing = "border-box";
4577
+ sizer.className = "fp-code-sizer";
4578
+ sizer.style.position = "relative";
4579
+ sizer.style.flexShrink = "0";
4580
+ sizer.style.display = "flex";
4581
+ sizer.style.justifyContent = "center";
4582
+ sizer.style.alignItems = "center";
4297
4583
  pre.style.margin = "0 auto";
4298
4584
  pre.style.fontFamily = "Consolas, 'Courier New', monospace";
4299
4585
  pre.style.fontSize = "13px";
@@ -4308,8 +4594,9 @@ var CodePlugin = class {
4308
4594
  pre.style.boxSizing = "border-box";
4309
4595
  pre.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4310
4596
  pre.style.borderRadius = "4px";
4311
- pre.style.transformOrigin = "top center";
4597
+ pre.style.transformOrigin = "center center";
4312
4598
  pre.style.transition = "transform 0.15s ease";
4599
+ pre.style.flexShrink = "0";
4313
4600
  } else {
4314
4601
  container.style.overflow = "auto";
4315
4602
  container.style.backgroundColor = "#1e1e1e";
@@ -4342,7 +4629,13 @@ var CodePlugin = class {
4342
4629
  };
4343
4630
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4344
4631
  pre.appendChild(code);
4345
- container.appendChild(pre);
4632
+ if (isTxt) {
4633
+ sizer.appendChild(pre);
4634
+ scrollWrapper.appendChild(sizer);
4635
+ container.appendChild(scrollWrapper);
4636
+ } else {
4637
+ container.appendChild(pre);
4638
+ }
4346
4639
  const showPage = (pageNum) => {
4347
4640
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4348
4641
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
@@ -4359,10 +4652,16 @@ var CodePlugin = class {
4359
4652
  };
4360
4653
  const updateTransform = () => {
4361
4654
  if (isTxt) {
4655
+ const elW = 816;
4656
+ const baseH = pre.offsetHeight || 1056;
4657
+ const isRotated90 = rotation % 180 !== 0;
4658
+ const boxW = Math.round((isRotated90 ? baseH : elW) * zoomLevel);
4659
+ const boxH = Math.round((isRotated90 ? elW : baseH) * zoomLevel);
4660
+ sizer.style.width = `${boxW}px`;
4661
+ sizer.style.height = `${boxH}px`;
4662
+ pre.style.width = `${elW}px`;
4362
4663
  pre.style.transform = `scale(${zoomLevel}) rotate(${rotation}deg)`;
4363
- const scaledH = 1056 * zoomLevel;
4364
- const extraH = Math.max(0, scaledH - 1056);
4365
- pre.style.marginBottom = `${extraH + 32}px`;
4664
+ pre.style.transformOrigin = "center center";
4366
4665
  } else {
4367
4666
  pre.style.transform = `rotate(${rotation}deg)`;
4368
4667
  pre.style.fontSize = `${fontSize}px`;
@@ -4459,6 +4758,15 @@ var CodePlugin = class {
4459
4758
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4460
4759
  updateTransform();
4461
4760
  },
4761
+ resetZoom: () => {
4762
+ isUserZoomed = false;
4763
+ fontSize = 13;
4764
+ rotation = 0;
4765
+ zoomLevel = isTxt ? calculateTxtFit() : 1;
4766
+ container.scrollTop = 0;
4767
+ container.scrollLeft = 0;
4768
+ updateTransform();
4769
+ },
4462
4770
  rotateCW: () => {
4463
4771
  rotation = (rotation + 90) % 360;
4464
4772
  updateTransform();
@@ -4521,11 +4829,19 @@ var ArchivePlugin = class {
4521
4829
  {
4522
4830
  id: "fit-page",
4523
4831
  icon: "fit-page",
4524
- label: "Reset Zoom",
4832
+ label: "Fit to Page",
4525
4833
  type: "button",
4526
4834
  group: "zoom",
4527
4835
  execute: () => instance.fitToPage?.()
4528
4836
  },
4837
+ {
4838
+ id: "reset-zoom",
4839
+ icon: "reset-zoom",
4840
+ label: "Reset Zoom",
4841
+ type: "button",
4842
+ group: "zoom",
4843
+ execute: () => instance.resetZoom?.()
4844
+ },
4529
4845
  {
4530
4846
  id: "download",
4531
4847
  icon: "download",
@@ -4551,16 +4867,56 @@ var ArchivePlugin = class {
4551
4867
  width: 100%;
4552
4868
  height: 100%;
4553
4869
  overflow: auto;
4554
- padding: 24px;
4555
4870
  box-sizing: border-box;
4556
4871
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
4557
- transform-origin: top left;
4558
- transition: transform 0.2s ease;
4559
4872
  `;
4873
+ const scrollWrapper = document.createElement("div");
4874
+ scrollWrapper.className = "fp-archive-scroll-wrapper";
4875
+ scrollWrapper.style.cssText = `
4876
+ min-width: 100%;
4877
+ min-height: 100%;
4878
+ width: max-content;
4879
+ height: max-content;
4880
+ display: flex;
4881
+ justify-content: center;
4882
+ align-items: flex-start;
4883
+ padding: 24px;
4884
+ box-sizing: border-box;
4885
+ `;
4886
+ const sizer = document.createElement("div");
4887
+ sizer.className = "fp-archive-sizer";
4888
+ sizer.style.cssText = `
4889
+ position: relative;
4890
+ flex-shrink: 0;
4891
+ display: flex;
4892
+ justify-content: center;
4893
+ align-items: flex-start;
4894
+ `;
4895
+ const card = document.createElement("div");
4896
+ card.className = "fp-archive-card";
4897
+ card.style.cssText = `
4898
+ width: 900px;
4899
+ box-sizing: border-box;
4900
+ transform-origin: top center;
4901
+ transition: transform 0.15s ease;
4902
+ flex-shrink: 0;
4903
+ `;
4904
+ sizer.appendChild(card);
4905
+ scrollWrapper.appendChild(sizer);
4906
+ wrapper.appendChild(scrollWrapper);
4560
4907
  ctx.container.innerHTML = "";
4561
4908
  ctx.container.style.overflow = "auto";
4562
4909
  ctx.container.appendChild(wrapper);
4563
4910
  let scale = 1;
4911
+ const applyTransform = () => {
4912
+ const boxW = Math.round(900 * scale);
4913
+ const cardH = card.offsetHeight || 600;
4914
+ const boxH = Math.round(cardH * scale);
4915
+ sizer.style.width = `${boxW}px`;
4916
+ sizer.style.height = `${boxH}px`;
4917
+ card.style.transform = `scale(${scale})`;
4918
+ card.style.transformOrigin = "top center";
4919
+ };
4564
4920
  const entries = await new Promise((resolve, reject) => {
4565
4921
  unzip(new Uint8Array(ctx.buffer), (err, unzipped) => {
4566
4922
  if (err) {
@@ -4584,7 +4940,7 @@ var ArchivePlugin = class {
4584
4940
  });
4585
4941
  const totalUncompressedSize = entries.reduce((acc, e) => acc + e.size, 0);
4586
4942
  const renderUI = (filteredEntries) => {
4587
- wrapper.innerHTML = `
4943
+ card.innerHTML = `
4588
4944
  <div style="max-width: 900px; margin: 0 auto; background: var(--fp-bg, #ffffff); border: 1px solid var(--fp-border, #e5e7eb); border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); overflow: hidden;">
4589
4945
  <div style="padding: 16px 20px; background: var(--fp-toolbar-bg, #f9fafb); border-bottom: 1px solid var(--fp-border, #e5e7eb); display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px;">
4590
4946
  <div>
@@ -4614,7 +4970,7 @@ var ArchivePlugin = class {
4614
4970
  </div>
4615
4971
  </div>
4616
4972
  `;
4617
- const tbody = wrapper.querySelector("#fp-archive-body");
4973
+ const tbody = card.querySelector("#fp-archive-body");
4618
4974
  if (filteredEntries.length === 0) {
4619
4975
  tbody.innerHTML = `<tr><td colspan="3" style="padding: 24px; text-align: center; color: #9ca3af;">No matching files found</td></tr>`;
4620
4976
  } else {
@@ -4643,19 +4999,20 @@ var ArchivePlugin = class {
4643
4999
  }
4644
5000
  });
4645
5001
  });
4646
- const searchInput = wrapper.querySelector("#fp-archive-search");
5002
+ const searchInput = card.querySelector("#fp-archive-search");
4647
5003
  if (searchInput) {
4648
5004
  searchInput.addEventListener("input", () => {
4649
5005
  const q = searchInput.value.toLowerCase().trim();
4650
5006
  const filtered = q ? entries.filter((e) => e.path.toLowerCase().includes(q)) : entries;
4651
5007
  renderUI(filtered);
4652
- const newSearch = wrapper.querySelector("#fp-archive-search");
5008
+ const newSearch = card.querySelector("#fp-archive-search");
4653
5009
  if (newSearch) {
4654
5010
  newSearch.value = q;
4655
5011
  newSearch.focus();
4656
5012
  }
4657
5013
  });
4658
5014
  }
5015
+ applyTransform();
4659
5016
  };
4660
5017
  renderUI(entries);
4661
5018
  const cleanup = () => {
@@ -4667,20 +5024,26 @@ var ArchivePlugin = class {
4667
5024
  destroy: cleanup,
4668
5025
  zoomIn: () => {
4669
5026
  scale += 0.1;
4670
- wrapper.style.transform = `scale(${scale})`;
5027
+ applyTransform();
4671
5028
  },
4672
5029
  zoomOut: () => {
4673
5030
  scale = Math.max(0.3, scale - 0.1);
4674
- wrapper.style.transform = `scale(${scale})`;
5031
+ applyTransform();
4675
5032
  },
4676
5033
  getZoom: () => scale,
4677
5034
  setZoom: (level) => {
4678
5035
  scale = level;
4679
- wrapper.style.transform = `scale(${scale})`;
5036
+ applyTransform();
4680
5037
  },
4681
5038
  fitToPage: () => {
4682
5039
  scale = 1;
4683
- wrapper.style.transform = `scale(1)`;
5040
+ applyTransform();
5041
+ },
5042
+ resetZoom: () => {
5043
+ scale = 1;
5044
+ wrapper.scrollTop = 0;
5045
+ wrapper.scrollLeft = 0;
5046
+ applyTransform();
4684
5047
  },
4685
5048
  download: () => {
4686
5049
  downloadFile(ctx.buffer, ctx.metadata.name || "archive.zip", "application/zip");
@@ -4732,6 +5095,14 @@ var MarkdownPlugin = class {
4732
5095
  group: "zoom",
4733
5096
  execute: () => instance.fitToPage?.()
4734
5097
  },
5098
+ {
5099
+ id: "reset-zoom",
5100
+ icon: "reset-zoom",
5101
+ label: "Reset Zoom",
5102
+ type: "button",
5103
+ group: "zoom",
5104
+ execute: () => instance.resetZoom?.()
5105
+ },
4735
5106
  {
4736
5107
  id: "copy",
4737
5108
  icon: "copy",
@@ -4885,6 +5256,12 @@ var MarkdownPlugin = class {
4885
5256
  fontSize = 15;
4886
5257
  wrapper.style.fontSize = "15px";
4887
5258
  },
5259
+ resetZoom: () => {
5260
+ fontSize = 15;
5261
+ wrapper.style.fontSize = "15px";
5262
+ ctx.container.scrollTop = 0;
5263
+ ctx.container.scrollLeft = 0;
5264
+ },
4888
5265
  download: () => {
4889
5266
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
4890
5267
  },
@@ -4978,6 +5355,14 @@ var PptxPlugin = class {
4978
5355
  group: "zoom",
4979
5356
  execute: () => instance.fitToPage?.()
4980
5357
  },
5358
+ {
5359
+ id: "reset-zoom",
5360
+ icon: "reset-zoom",
5361
+ label: "Reset Zoom",
5362
+ type: "button",
5363
+ group: "zoom",
5364
+ execute: () => instance.resetZoom?.()
5365
+ },
4981
5366
  {
4982
5367
  id: "rotate-cw",
4983
5368
  icon: "rotate-cw",
@@ -5017,12 +5402,30 @@ var PptxPlugin = class {
5017
5402
  width: 100%;
5018
5403
  height: 100%;
5019
5404
  overflow: auto;
5405
+ box-sizing: border-box;
5406
+ background: var(--fp-bg-canvas, #525659);
5407
+ `;
5408
+ const scrollWrapper = document.createElement("div");
5409
+ scrollWrapper.className = "fp-pptx-scroll-wrapper";
5410
+ scrollWrapper.style.cssText = `
5411
+ min-width: 100%;
5412
+ min-height: 100%;
5413
+ width: max-content;
5414
+ height: max-content;
5020
5415
  display: flex;
5021
5416
  justify-content: center;
5022
- align-items: flex-start;
5417
+ align-items: center;
5023
5418
  padding: 24px;
5024
5419
  box-sizing: border-box;
5025
- background: var(--fp-bg-canvas, #525659);
5420
+ `;
5421
+ const sizer = document.createElement("div");
5422
+ sizer.className = "fp-pptx-sizer";
5423
+ sizer.style.cssText = `
5424
+ position: relative;
5425
+ flex-shrink: 0;
5426
+ display: flex;
5427
+ justify-content: center;
5428
+ align-items: center;
5026
5429
  `;
5027
5430
  const slideContainer = document.createElement("div");
5028
5431
  slideContainer.className = "fp-slide-container";
@@ -5031,14 +5434,15 @@ var PptxPlugin = class {
5031
5434
  border-radius: 4px;
5032
5435
  overflow: hidden;
5033
5436
  background: #ffffff;
5034
- transform-origin: top center;
5437
+ transform-origin: center center;
5035
5438
  transition: transform 0.2s ease;
5036
- max-width: calc(100% - 32px);
5037
- max-height: calc(100% - 48px);
5439
+ flex-shrink: 0;
5038
5440
  `;
5039
5441
  const canvas = document.createElement("canvas");
5040
5442
  slideContainer.appendChild(canvas);
5041
- wrapper.appendChild(slideContainer);
5443
+ sizer.appendChild(slideContainer);
5444
+ scrollWrapper.appendChild(sizer);
5445
+ wrapper.appendChild(scrollWrapper);
5042
5446
  ctx.container.innerHTML = "";
5043
5447
  ctx.container.style.overflow = "auto";
5044
5448
  ctx.container.appendChild(wrapper);
@@ -5050,7 +5454,17 @@ var PptxPlugin = class {
5050
5454
  return Math.min(1, Math.min(availW / cW, availH / cH));
5051
5455
  };
5052
5456
  const applyTransform = () => {
5457
+ const cW = canvas.offsetWidth || 1280;
5458
+ const cH = canvas.offsetHeight || 720;
5459
+ const isRotated90 = rotation % 180 !== 0;
5460
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
5461
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
5462
+ sizer.style.width = `${boxW}px`;
5463
+ sizer.style.height = `${boxH}px`;
5464
+ slideContainer.style.width = `${cW}px`;
5465
+ slideContainer.style.height = `${cH}px`;
5053
5466
  slideContainer.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5467
+ slideContainer.style.transformOrigin = "center center";
5054
5468
  };
5055
5469
  const renderCurrentSlide = async () => {
5056
5470
  try {
@@ -5097,6 +5511,13 @@ var PptxPlugin = class {
5097
5511
  rotation = 0;
5098
5512
  applyTransform();
5099
5513
  },
5514
+ resetZoom: () => {
5515
+ scale = calculateFitScale();
5516
+ rotation = 0;
5517
+ wrapper.scrollTop = 0;
5518
+ wrapper.scrollLeft = 0;
5519
+ applyTransform();
5520
+ },
5100
5521
  rotateCW: () => {
5101
5522
  rotation = (rotation + 90) % 360;
5102
5523
  applyTransform();
@@ -5172,6 +5593,14 @@ var ThreeDPlugin = class {
5172
5593
  group: "zoom",
5173
5594
  execute: () => instance.fitToPage?.()
5174
5595
  },
5596
+ {
5597
+ id: "reset-zoom",
5598
+ icon: "reset-zoom",
5599
+ label: "Reset Zoom",
5600
+ type: "button",
5601
+ group: "zoom",
5602
+ execute: () => instance.resetZoom?.()
5603
+ },
5175
5604
  {
5176
5605
  id: "rotate-cw",
5177
5606
  icon: "rotate-cw",
@@ -5308,6 +5737,7 @@ var ThreeDPlugin = class {
5308
5737
  controls.update();
5309
5738
  },
5310
5739
  fitToPage: fitCamera,
5740
+ resetZoom: fitCamera,
5311
5741
  rotateCW: () => {
5312
5742
  isWireframe = !isWireframe;
5313
5743
  materials.forEach((m) => {
@@ -5522,6 +5952,14 @@ var RtfPlugin = class {
5522
5952
  group: "zoom",
5523
5953
  execute: () => instance.fitToPage?.()
5524
5954
  },
5955
+ {
5956
+ id: "reset-zoom",
5957
+ icon: "reset-zoom",
5958
+ label: "Reset Zoom",
5959
+ type: "button",
5960
+ group: "zoom",
5961
+ execute: () => instance.resetZoom?.()
5962
+ },
5525
5963
  {
5526
5964
  id: "rotate-cw",
5527
5965
  icon: "rotate-cw",
@@ -5632,13 +6070,33 @@ var RtfPlugin = class {
5632
6070
  wrapper.style.flexDirection = "column";
5633
6071
  wrapper.style.alignItems = "center";
5634
6072
  wrapper.style.backgroundColor = "transparent";
5635
- wrapper.style.transformOrigin = "top center";
6073
+ wrapper.style.transformOrigin = "center center";
5636
6074
  wrapper.style.transition = "transform 0.15s ease";
5637
- ctx.container.style.overflowX = "hidden";
5638
- ctx.container.style.overflowY = "auto";
5639
- ctx.container.style.padding = "16px 8px";
6075
+ wrapper.style.flexShrink = "0";
6076
+ const sizer = document.createElement("div");
6077
+ sizer.className = "fp-rtf-sizer";
6078
+ sizer.style.position = "relative";
6079
+ sizer.style.flexShrink = "0";
6080
+ sizer.style.display = "flex";
6081
+ sizer.style.justifyContent = "center";
6082
+ sizer.style.alignItems = "center";
6083
+ const scrollWrapper = document.createElement("div");
6084
+ scrollWrapper.className = "fp-rtf-scroll-wrapper";
6085
+ scrollWrapper.style.minWidth = "100%";
6086
+ scrollWrapper.style.minHeight = "100%";
6087
+ scrollWrapper.style.width = "max-content";
6088
+ scrollWrapper.style.height = "max-content";
6089
+ scrollWrapper.style.display = "flex";
6090
+ scrollWrapper.style.justifyContent = "center";
6091
+ scrollWrapper.style.alignItems = "flex-start";
6092
+ scrollWrapper.style.padding = "16px 8px";
6093
+ scrollWrapper.style.boxSizing = "border-box";
6094
+ sizer.appendChild(wrapper);
6095
+ scrollWrapper.appendChild(sizer);
6096
+ ctx.container.style.overflow = "auto";
6097
+ ctx.container.style.padding = "0";
5640
6098
  ctx.container.style.backgroundColor = "#f1f5f9";
5641
- ctx.container.appendChild(wrapper);
6099
+ ctx.container.appendChild(scrollWrapper);
5642
6100
  let scale = 1;
5643
6101
  let rotation = 0;
5644
6102
  let pageElements = [];
@@ -5657,12 +6115,17 @@ var RtfPlugin = class {
5657
6115
  return Math.max(0.4, Math.min(3, sW));
5658
6116
  };
5659
6117
  const applyTransform = () => {
5660
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5661
- wrapper.style.transformOrigin = "top center";
6118
+ const elW = pageWidth;
5662
6119
  const baseH = pageHeight;
5663
- const scaledH = baseH * scale;
5664
- const extraH = Math.max(0, scaledH - baseH);
5665
- wrapper.style.marginBottom = `${extraH + 32}px`;
6120
+ const isRotated90 = rotation % 180 !== 0;
6121
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6122
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6123
+ sizer.style.width = `${boxW}px`;
6124
+ sizer.style.height = `${boxH}px`;
6125
+ wrapper.style.width = `${elW}px`;
6126
+ wrapper.style.height = `${baseH}px`;
6127
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6128
+ wrapper.style.transformOrigin = "center center";
5666
6129
  };
5667
6130
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5668
6131
  if (!isUserZoomed) {
@@ -5933,7 +6396,7 @@ var RtfPlugin = class {
5933
6396
  }
5934
6397
  const cleanup = () => {
5935
6398
  resizeObserver?.disconnect();
5936
- wrapper.remove();
6399
+ scrollWrapper.remove();
5937
6400
  ctx.container.innerHTML = "";
5938
6401
  };
5939
6402
  ctx.signal.addEventListener("abort", cleanup);
@@ -5991,6 +6454,15 @@ var RtfPlugin = class {
5991
6454
  rotation = 0;
5992
6455
  applyTransform();
5993
6456
  },
6457
+ resetZoom: () => {
6458
+ isUserZoomed = false;
6459
+ fitMode = "width";
6460
+ scale = calculateFitScale("width");
6461
+ rotation = 0;
6462
+ ctx.container.scrollTop = 0;
6463
+ ctx.container.scrollLeft = 0;
6464
+ applyTransform();
6465
+ },
5994
6466
  rotateCW: () => {
5995
6467
  rotation = (rotation + 90) % 360;
5996
6468
  applyTransform();
@@ -6058,6 +6530,14 @@ var HtmlPreviewPlugin = class {
6058
6530
  group: "zoom",
6059
6531
  execute: () => instance.fitToPage?.()
6060
6532
  },
6533
+ {
6534
+ id: "reset-zoom",
6535
+ icon: "reset-zoom",
6536
+ label: "Reset Zoom",
6537
+ type: "button",
6538
+ group: "zoom",
6539
+ execute: () => instance.resetZoom?.()
6540
+ },
6061
6541
  {
6062
6542
  id: "copy",
6063
6543
  icon: "copy",
@@ -6091,23 +6571,44 @@ var HtmlPreviewPlugin = class {
6091
6571
  ADD_TAGS: ["style", "link"],
6092
6572
  ADD_ATTR: ["target", "rel"]
6093
6573
  });
6574
+ const sizer = document.createElement("div");
6575
+ sizer.className = "fp-html-sizer";
6576
+ sizer.style.position = "relative";
6094
6577
  const iframe = document.createElement("iframe");
6095
6578
  iframe.className = "fp-html-iframe";
6096
- iframe.style.width = "100%";
6097
- iframe.style.height = "100%";
6098
6579
  iframe.style.border = "none";
6099
6580
  iframe.style.backgroundColor = "#ffffff";
6100
6581
  iframe.style.transformOrigin = "top left";
6101
6582
  iframe.style.transition = "transform 0.2s ease";
6102
6583
  iframe.sandbox.add("allow-same-origin");
6584
+ sizer.appendChild(iframe);
6103
6585
  ctx.container.style.overflow = "auto";
6104
6586
  ctx.container.style.width = "100%";
6105
6587
  ctx.container.style.height = "100%";
6106
- ctx.container.appendChild(iframe);
6588
+ ctx.container.innerHTML = "";
6589
+ ctx.container.appendChild(sizer);
6107
6590
  iframe.srcdoc = sanitized;
6108
6591
  let scale = 1;
6592
+ const applyTransform = () => {
6593
+ const baseW = Math.max(600, ctx.container.clientWidth || 800);
6594
+ const baseH = Math.max(400, ctx.container.clientHeight || 600);
6595
+ const scaledW = Math.round(baseW * scale);
6596
+ const scaledH = Math.round(baseH * scale);
6597
+ sizer.style.width = `${scaledW}px`;
6598
+ sizer.style.height = `${scaledH}px`;
6599
+ iframe.style.position = "absolute";
6600
+ iframe.style.top = "0";
6601
+ iframe.style.left = "0";
6602
+ iframe.style.width = `${baseW}px`;
6603
+ iframe.style.height = `${baseH}px`;
6604
+ iframe.style.transform = `scale(${scale})`;
6605
+ iframe.style.transformOrigin = "top left";
6606
+ };
6607
+ requestAnimationFrame(() => {
6608
+ applyTransform();
6609
+ });
6109
6610
  const cleanup = () => {
6110
- iframe.remove();
6611
+ sizer.remove();
6111
6612
  ctx.container.innerHTML = "";
6112
6613
  };
6113
6614
  ctx.signal.addEventListener("abort", cleanup);
@@ -6115,20 +6616,26 @@ var HtmlPreviewPlugin = class {
6115
6616
  destroy: cleanup,
6116
6617
  zoomIn: () => {
6117
6618
  scale += 0.1;
6118
- iframe.style.transform = `scale(${scale})`;
6619
+ applyTransform();
6119
6620
  },
6120
6621
  zoomOut: () => {
6121
6622
  scale = Math.max(0.2, scale - 0.1);
6122
- iframe.style.transform = `scale(${scale})`;
6623
+ applyTransform();
6123
6624
  },
6124
6625
  getZoom: () => scale,
6125
6626
  setZoom: (level) => {
6126
6627
  scale = level;
6127
- iframe.style.transform = `scale(${scale})`;
6628
+ applyTransform();
6128
6629
  },
6129
6630
  fitToPage: () => {
6130
6631
  scale = 1;
6131
- iframe.style.transform = "scale(1)";
6632
+ applyTransform();
6633
+ },
6634
+ resetZoom: () => {
6635
+ scale = 1;
6636
+ ctx.container.scrollTop = 0;
6637
+ ctx.container.scrollLeft = 0;
6638
+ applyTransform();
6132
6639
  },
6133
6640
  copy: () => {
6134
6641
  navigator.clipboard.writeText(rawHtml);
@@ -6230,6 +6737,14 @@ var OpenDocumentPlugin = class {
6230
6737
  group: "zoom",
6231
6738
  execute: () => instance.fitToPage?.()
6232
6739
  },
6740
+ {
6741
+ id: "reset-zoom",
6742
+ icon: "reset-zoom",
6743
+ label: "Reset Zoom",
6744
+ type: "button",
6745
+ group: "zoom",
6746
+ execute: () => instance.resetZoom?.()
6747
+ },
6233
6748
  {
6234
6749
  id: "rotate-cw",
6235
6750
  icon: "rotate-cw",
@@ -6295,10 +6810,26 @@ var OpenDocumentPlugin = class {
6295
6810
  container.className = "fp-odf-container";
6296
6811
  container.style.width = "100%";
6297
6812
  container.style.height = "100%";
6298
- container.style.overflowX = "hidden";
6299
- container.style.overflowY = "auto";
6300
- container.style.padding = "16px 8px";
6813
+ container.style.overflow = "auto";
6301
6814
  container.style.backgroundColor = "#f1f5f9";
6815
+ const scrollWrapper = document.createElement("div");
6816
+ scrollWrapper.className = "fp-odf-scroll-wrapper";
6817
+ scrollWrapper.style.minWidth = "100%";
6818
+ scrollWrapper.style.minHeight = "100%";
6819
+ scrollWrapper.style.width = "max-content";
6820
+ scrollWrapper.style.height = "max-content";
6821
+ scrollWrapper.style.display = "flex";
6822
+ scrollWrapper.style.justifyContent = "center";
6823
+ scrollWrapper.style.alignItems = "flex-start";
6824
+ scrollWrapper.style.padding = "16px 8px";
6825
+ scrollWrapper.style.boxSizing = "border-box";
6826
+ const sizer = document.createElement("div");
6827
+ sizer.className = "fp-odf-sizer";
6828
+ sizer.style.position = "relative";
6829
+ sizer.style.flexShrink = "0";
6830
+ sizer.style.display = "flex";
6831
+ sizer.style.justifyContent = "center";
6832
+ sizer.style.alignItems = "center";
6302
6833
  const wrapper = document.createElement("div");
6303
6834
  wrapper.className = "fp-odf-wrapper";
6304
6835
  wrapper.style.margin = "0 auto";
@@ -6307,9 +6838,12 @@ var OpenDocumentPlugin = class {
6307
6838
  wrapper.style.backgroundColor = "#ffffff";
6308
6839
  wrapper.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
6309
6840
  wrapper.style.borderRadius = "4px";
6310
- wrapper.style.transformOrigin = "top center";
6841
+ wrapper.style.transformOrigin = "center center";
6311
6842
  wrapper.style.transition = "transform 0.15s ease";
6312
- container.appendChild(wrapper);
6843
+ wrapper.style.flexShrink = "0";
6844
+ sizer.appendChild(wrapper);
6845
+ scrollWrapper.appendChild(sizer);
6846
+ container.appendChild(scrollWrapper);
6313
6847
  ctx.container.appendChild(container);
6314
6848
  let scale = 1;
6315
6849
  let rotation = 0;
@@ -6335,13 +6869,18 @@ var OpenDocumentPlugin = class {
6335
6869
  return Math.max(0.4, Math.min(3, sW));
6336
6870
  };
6337
6871
  const applyTransform = () => {
6338
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6339
- wrapper.style.transformOrigin = "top center";
6340
6872
  const activeSlide = slides[currentPage - 1];
6873
+ const elW = isPresentation ? 960 : 816;
6341
6874
  const baseH = activeSlide?.offsetHeight || wrapper.offsetHeight || 1056;
6342
- const scaledH = baseH * scale;
6343
- const extraH = Math.max(0, scaledH - baseH);
6344
- wrapper.style.marginBottom = `${extraH + 32}px`;
6875
+ const isRotated90 = rotation % 180 !== 0;
6876
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6877
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6878
+ sizer.style.width = `${boxW}px`;
6879
+ sizer.style.height = `${boxH}px`;
6880
+ wrapper.style.width = `${elW}px`;
6881
+ wrapper.style.height = `${baseH}px`;
6882
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6883
+ wrapper.style.transformOrigin = "center center";
6345
6884
  };
6346
6885
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
6347
6886
  if (!isUserZoomed) {
@@ -6497,6 +7036,15 @@ var OpenDocumentPlugin = class {
6497
7036
  rotation = 0;
6498
7037
  applyTransform();
6499
7038
  },
7039
+ resetZoom: () => {
7040
+ isUserZoomed = false;
7041
+ fitMode = "width";
7042
+ scale = calculateFitScale("width");
7043
+ rotation = 0;
7044
+ container.scrollTop = 0;
7045
+ container.scrollLeft = 0;
7046
+ applyTransform();
7047
+ },
6500
7048
  rotateCW: () => {
6501
7049
  rotation = (rotation + 90) % 360;
6502
7050
  applyTransform();
@@ -6840,6 +7388,14 @@ var DocPlugin = class {
6840
7388
  group: "zoom",
6841
7389
  execute: () => instance.fitToPage?.()
6842
7390
  },
7391
+ {
7392
+ id: "reset-zoom",
7393
+ icon: "reset-zoom",
7394
+ label: "Reset Zoom",
7395
+ type: "button",
7396
+ group: "zoom",
7397
+ execute: () => instance.resetZoom?.()
7398
+ },
6843
7399
  {
6844
7400
  id: "rotate-cw",
6845
7401
  icon: "rotate-cw",
@@ -6888,13 +7444,28 @@ var DocPlugin = class {
6888
7444
  container.className = "fp-doc-container";
6889
7445
  container.style.width = "100%";
6890
7446
  container.style.height = "100%";
6891
- container.style.overflowX = "hidden";
6892
- container.style.overflowY = "auto";
6893
- container.style.padding = "16px 8px";
7447
+ container.style.overflow = "auto";
6894
7448
  container.style.backgroundColor = "#f1f5f9";
6895
- container.style.display = "flex";
6896
- container.style.justifyContent = "center";
6897
- container.style.alignItems = "flex-start";
7449
+ const scrollWrapper = document.createElement("div");
7450
+ scrollWrapper.className = "fp-doc-scroll-wrapper";
7451
+ scrollWrapper.style.minWidth = "100%";
7452
+ scrollWrapper.style.minHeight = "100%";
7453
+ scrollWrapper.style.width = "max-content";
7454
+ scrollWrapper.style.height = "max-content";
7455
+ scrollWrapper.style.display = "flex";
7456
+ scrollWrapper.style.justifyContent = "center";
7457
+ scrollWrapper.style.alignItems = "flex-start";
7458
+ scrollWrapper.style.padding = "16px 8px";
7459
+ scrollWrapper.style.boxSizing = "border-box";
7460
+ const sizer = document.createElement("div");
7461
+ sizer.className = "fp-doc-sizer";
7462
+ sizer.style.position = "relative";
7463
+ sizer.style.flexShrink = "0";
7464
+ sizer.style.display = "flex";
7465
+ sizer.style.justifyContent = "center";
7466
+ sizer.style.alignItems = "center";
7467
+ scrollWrapper.appendChild(sizer);
7468
+ container.appendChild(scrollWrapper);
6898
7469
  ctx.container.appendChild(container);
6899
7470
  let scale = 1;
6900
7471
  let extractedRawText = "";
@@ -6942,10 +7513,11 @@ var DocPlugin = class {
6942
7513
  pageCard.style.padding = "72px 56px";
6943
7514
  pageCard.style.boxSizing = "border-box";
6944
7515
  pageCard.style.display = i === 0 ? "block" : "none";
6945
- pageCard.style.transformOrigin = "top center";
7516
+ pageCard.style.transformOrigin = "center center";
6946
7517
  pageCard.style.transition = "transform 0.15s ease";
6947
7518
  pageCard.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
6948
7519
  pageCard.style.color = "#1e293b";
7520
+ pageCard.style.flexShrink = "0";
6949
7521
  if (isFallback && i === 0) {
6950
7522
  pageCard.innerHTML = `
6951
7523
  <div style="border-bottom: 1px solid #e2e8f0; padding-bottom: 12px; margin-bottom: 24px;">
@@ -6957,18 +7529,23 @@ var DocPlugin = class {
6957
7529
  } else {
6958
7530
  pageCard.innerHTML = this.formatDocToHtml(rawPages[i], ctx.metadata.name || "Document");
6959
7531
  }
6960
- container.appendChild(pageCard);
7532
+ sizer.appendChild(pageCard);
6961
7533
  pageCards.push(pageCard);
6962
7534
  }
6963
7535
  let rotation = 0;
6964
7536
  const applyTransform = () => {
6965
7537
  const activeCard = pageCards[currentPage - 1];
6966
7538
  if (activeCard) {
6967
- activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7539
+ const baseW = 816;
6968
7540
  const baseH = activeCard.offsetHeight || 1056;
6969
- const scaledH = baseH * scale;
6970
- const extraH = Math.max(0, scaledH - baseH);
6971
- activeCard.style.marginBottom = `${extraH + 32}px`;
7541
+ const isRotated90 = rotation % 180 !== 0;
7542
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * scale);
7543
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * scale);
7544
+ sizer.style.width = `${boxW}px`;
7545
+ sizer.style.height = `${boxH}px`;
7546
+ activeCard.style.width = `${baseW}px`;
7547
+ activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7548
+ activeCard.style.transformOrigin = "center center";
6972
7549
  }
6973
7550
  };
6974
7551
  const showPage = (pageNum) => {
@@ -6976,11 +7553,11 @@ var DocPlugin = class {
6976
7553
  pageCards.forEach((card, idx) => {
6977
7554
  if (idx + 1 === currentPage) {
6978
7555
  card.style.display = "block";
6979
- card.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6980
7556
  } else {
6981
7557
  card.style.display = "none";
6982
7558
  }
6983
7559
  });
7560
+ applyTransform();
6984
7561
  container.scrollTop = 0;
6985
7562
  ctx.emit("page-change", { page: currentPage, total: totalPages });
6986
7563
  };
@@ -7046,6 +7623,17 @@ var DocPlugin = class {
7046
7623
  rotation = 0;
7047
7624
  applyTransform();
7048
7625
  },
7626
+ resetZoom: () => {
7627
+ isUserZoomed = false;
7628
+ fitMode = "width";
7629
+ scale = calculateFitScale("width");
7630
+ rotation = 0;
7631
+ container.scrollTop = 0;
7632
+ container.scrollLeft = 0;
7633
+ ctx.container.scrollTop = 0;
7634
+ ctx.container.scrollLeft = 0;
7635
+ applyTransform();
7636
+ },
7049
7637
  rotateCW: () => {
7050
7638
  rotation = (rotation + 90) % 360;
7051
7639
  applyTransform();
@@ -7526,6 +8114,14 @@ var PptPlugin = class {
7526
8114
  group: "zoom",
7527
8115
  execute: () => instance.fitToPage?.()
7528
8116
  },
8117
+ {
8118
+ id: "reset-zoom",
8119
+ icon: "reset-zoom",
8120
+ label: "Reset Zoom",
8121
+ type: "button",
8122
+ group: "zoom",
8123
+ execute: () => instance.resetZoom?.()
8124
+ },
7529
8125
  {
7530
8126
  id: "rotate-cw",
7531
8127
  icon: "rotate-cw",
@@ -7558,17 +8154,30 @@ var PptPlugin = class {
7558
8154
  container.style.width = "100%";
7559
8155
  container.style.height = "100%";
7560
8156
  container.style.overflow = "auto";
7561
- container.style.display = "flex";
7562
- container.style.justifyContent = "center";
7563
- container.style.alignItems = "center";
7564
- container.style.padding = "32px 16px";
7565
8157
  container.style.backgroundColor = "#0f172a";
7566
8158
  container.style.boxSizing = "border-box";
8159
+ const scrollWrapper = document.createElement("div");
8160
+ scrollWrapper.className = "fp-ppt-scroll-wrapper";
8161
+ scrollWrapper.style.minWidth = "100%";
8162
+ scrollWrapper.style.minHeight = "100%";
8163
+ scrollWrapper.style.width = "max-content";
8164
+ scrollWrapper.style.height = "max-content";
8165
+ scrollWrapper.style.display = "flex";
8166
+ scrollWrapper.style.justifyContent = "center";
8167
+ scrollWrapper.style.alignItems = "center";
8168
+ scrollWrapper.style.padding = "32px 16px";
8169
+ scrollWrapper.style.boxSizing = "border-box";
8170
+ const sizer = document.createElement("div");
8171
+ sizer.className = "fp-ppt-sizer";
8172
+ sizer.style.position = "relative";
8173
+ sizer.style.flexShrink = "0";
8174
+ sizer.style.display = "flex";
8175
+ sizer.style.justifyContent = "center";
8176
+ sizer.style.alignItems = "center";
7567
8177
  const slideCard = document.createElement("div");
7568
8178
  slideCard.className = "fp-ppt-slide-card";
7569
8179
  slideCard.style.width = "960px";
7570
- slideCard.style.maxWidth = "calc(100% - 32px)";
7571
- slideCard.style.maxHeight = "calc(100% - 48px)";
8180
+ slideCard.style.height = "540px";
7572
8181
  slideCard.style.aspectRatio = "16 / 9";
7573
8182
  slideCard.style.backgroundColor = "#ffffff";
7574
8183
  slideCard.style.boxShadow = "0 12px 40px rgba(0,0,0,0.35)";
@@ -7578,7 +8187,9 @@ var PptPlugin = class {
7578
8187
  slideCard.style.transition = "transform 0.2s ease";
7579
8188
  slideCard.style.transformOrigin = "center center";
7580
8189
  slideCard.style.flexShrink = "0";
7581
- container.appendChild(slideCard);
8190
+ sizer.appendChild(slideCard);
8191
+ scrollWrapper.appendChild(sizer);
8192
+ container.appendChild(scrollWrapper);
7582
8193
  ctx.container.appendChild(container);
7583
8194
  let scale = 1;
7584
8195
  let rotation = 0;
@@ -7591,7 +8202,17 @@ var PptPlugin = class {
7591
8202
  return Math.min(1, Math.min(availW / 960, availH / 540));
7592
8203
  };
7593
8204
  const applyTransform = () => {
8205
+ const cW = 960;
8206
+ const cH = 540;
8207
+ const isRotated90 = rotation % 180 !== 0;
8208
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
8209
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
8210
+ sizer.style.width = `${boxW}px`;
8211
+ sizer.style.height = `${boxH}px`;
8212
+ slideCard.style.width = `${cW}px`;
8213
+ slideCard.style.height = `${cH}px`;
7594
8214
  slideCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
8215
+ slideCard.style.transformOrigin = "center center";
7595
8216
  };
7596
8217
  setTimeout(() => {
7597
8218
  scale = calculateFitScale();
@@ -7714,6 +8335,13 @@ var PptPlugin = class {
7714
8335
  rotation = 0;
7715
8336
  applyTransform();
7716
8337
  },
8338
+ resetZoom: () => {
8339
+ scale = calculateFitScale();
8340
+ rotation = 0;
8341
+ container.scrollTop = 0;
8342
+ container.scrollLeft = 0;
8343
+ applyTransform();
8344
+ },
7717
8345
  rotateCW: () => {
7718
8346
  rotation = (rotation + 90) % 360;
7719
8347
  applyTransform();