@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/angular.cjs CHANGED
@@ -576,6 +576,7 @@ var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" str
576
576
  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>`;
577
577
  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>`;
578
578
  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>`;
579
+ 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>`;
579
580
  var ICON_MAP = {
580
581
  "zoom-in": ICON_ZOOM_IN,
581
582
  "zoom-out": ICON_ZOOM_OUT,
@@ -605,7 +606,10 @@ var ICON_MAP = {
605
606
  "open-window": ICON_EXTERNAL_WINDOW,
606
607
  "external-window": ICON_EXTERNAL_WINDOW,
607
608
  "openWindow": ICON_EXTERNAL_WINDOW,
608
- "openSeparateWindow": ICON_EXTERNAL_WINDOW
609
+ "openSeparateWindow": ICON_EXTERNAL_WINDOW,
610
+ "reset-zoom": ICON_RESET_ZOOM,
611
+ "zoom-reset": ICON_RESET_ZOOM,
612
+ "resetZoom": ICON_RESET_ZOOM
609
613
  };
610
614
  var ToolbarController = class {
611
615
  el;
@@ -638,6 +642,10 @@ var ToolbarController = class {
638
642
  this.config.fitToPage = false;
639
643
  this.config.fitWidth = false;
640
644
  }
645
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
646
+ this.config.resetZoom = false;
647
+ this.config.zoomReset = false;
648
+ }
641
649
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = false;
642
650
  if (actionId === "fullscreen") this.config.fullscreen = false;
643
651
  if (actionId === "download") this.config.download = false;
@@ -662,6 +670,10 @@ var ToolbarController = class {
662
670
  this.config.fitToPage = true;
663
671
  this.config.fitWidth = true;
664
672
  }
673
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
674
+ this.config.resetZoom = true;
675
+ this.config.zoomReset = true;
676
+ }
665
677
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = true;
666
678
  if (actionId === "fullscreen") this.config.fullscreen = true;
667
679
  if (actionId === "download") this.config.download = true;
@@ -681,6 +693,7 @@ var ToolbarController = class {
681
693
  if (actionId === "zoomIn") return "zoom-in";
682
694
  if (actionId === "zoomOut") return "zoom-out";
683
695
  if (actionId === "fitPage" || actionId === "fitToPage" || actionId === "fitWidth") return "fit-page";
696
+ if (actionId === "resetZoom" || actionId === "zoomReset") return "reset-zoom";
684
697
  if (actionId === "rotateCW") return "rotate-cw";
685
698
  if (actionId === "rotateCCW") return "rotate-ccw";
686
699
  if (actionId === "openWindow" || actionId === "openSeparateWindow") return "open-window";
@@ -723,6 +736,9 @@ var ToolbarController = class {
723
736
  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)) {
724
737
  return false;
725
738
  }
739
+ if ((id === "reset-zoom" || id === "zoom-reset") && (c.resetZoom === false || c.zoomReset === false || c["reset-zoom"] === false || c["zoom-reset"] === false)) {
740
+ return false;
741
+ }
726
742
  if ((id === "rotate-cw" || id === "rotate-ccw" || id === "rotate") && (c.rotate === false || c.rotateCW === false || c.rotateCCW === false || c["rotate-cw"] === false)) {
727
743
  return false;
728
744
  }
@@ -1169,6 +1185,9 @@ var FilePreviewViewer = class _FilePreviewViewer {
1169
1185
  this.activeInstance = instance;
1170
1186
  instance.openInSeparateWindow = () => this.openInSeparateWindow();
1171
1187
  instance.toggleThumbnails = () => this.toggleThumbnails();
1188
+ if (!instance.resetZoom && instance.fitToPage) {
1189
+ instance.resetZoom = () => instance.fitToPage?.();
1190
+ }
1172
1191
  this.hideLoading();
1173
1192
  this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
1174
1193
  const isToolbarVisible = options.showToolbar !== false && options.toolbar !== false;
@@ -1452,6 +1471,16 @@ var FilePreviewViewer = class _FilePreviewViewer {
1452
1471
  fitToPage() {
1453
1472
  this.activeInstance?.fitToPage?.();
1454
1473
  }
1474
+ /**
1475
+ * Reset zoom level to initial/default fit state.
1476
+ */
1477
+ resetZoom() {
1478
+ if (this.activeInstance?.resetZoom) {
1479
+ this.activeInstance.resetZoom();
1480
+ } else if (this.activeInstance?.fitToPage) {
1481
+ this.activeInstance.fitToPage();
1482
+ }
1483
+ }
1455
1484
  /**
1456
1485
  * Zoom in.
1457
1486
  */
@@ -2073,6 +2102,14 @@ var PdfPlugin = class {
2073
2102
  group: "zoom",
2074
2103
  execute: () => instance.fitToPage?.()
2075
2104
  },
2105
+ {
2106
+ id: "reset-zoom",
2107
+ icon: "reset-zoom",
2108
+ label: "Reset Zoom",
2109
+ type: "button",
2110
+ group: "zoom",
2111
+ execute: () => instance.resetZoom?.()
2112
+ },
2076
2113
  {
2077
2114
  id: "fit-width",
2078
2115
  icon: "fit-width",
@@ -2128,16 +2165,22 @@ var PdfPlugin = class {
2128
2165
  container.className = "fp-pdf-container";
2129
2166
  container.style.width = "100%";
2130
2167
  container.style.height = "100%";
2131
- container.style.overflowX = "hidden";
2132
- container.style.overflowY = "auto";
2133
- container.style.display = "flex";
2134
- container.style.flexDirection = "column";
2135
- container.style.alignItems = "center";
2136
- container.style.justifyContent = "flex-start";
2137
- container.style.padding = "16px 8px";
2168
+ container.style.overflow = "auto";
2138
2169
  container.style.backgroundColor = "#0f172a";
2139
2170
  container.style.boxSizing = "border-box";
2140
2171
  container.style.position = "relative";
2172
+ const scrollWrapper = document.createElement("div");
2173
+ scrollWrapper.className = "fp-pdf-scroll-wrapper";
2174
+ scrollWrapper.style.minWidth = "100%";
2175
+ scrollWrapper.style.minHeight = "100%";
2176
+ scrollWrapper.style.width = "max-content";
2177
+ scrollWrapper.style.height = "max-content";
2178
+ scrollWrapper.style.display = "flex";
2179
+ scrollWrapper.style.flexDirection = "column";
2180
+ scrollWrapper.style.alignItems = "center";
2181
+ scrollWrapper.style.justifyContent = "flex-start";
2182
+ scrollWrapper.style.padding = "16px 8px";
2183
+ scrollWrapper.style.boxSizing = "border-box";
2141
2184
  const pageCard = document.createElement("div");
2142
2185
  pageCard.className = "fp-pdf-page-card";
2143
2186
  pageCard.style.boxShadow = "0 10px 35px rgba(0, 0, 0, 0.5)";
@@ -2150,7 +2193,8 @@ var PdfPlugin = class {
2150
2193
  pageCard.style.transition = "box-shadow 0.2s ease";
2151
2194
  let canvas = document.createElement("canvas");
2152
2195
  pageCard.appendChild(canvas);
2153
- container.appendChild(pageCard);
2196
+ scrollWrapper.appendChild(pageCard);
2197
+ container.appendChild(scrollWrapper);
2154
2198
  ctx.container.appendChild(container);
2155
2199
  const standardFontsUrl = typeof window !== "undefined" && window.__PDF_STANDARD_FONTS_URL__ || "./standard_fonts/";
2156
2200
  const cmapsUrl = typeof window !== "undefined" && window.__PDF_CMAPS_URL__ || "./cmaps/";
@@ -2335,6 +2379,14 @@ var PdfPlugin = class {
2335
2379
  zoomScale = 1;
2336
2380
  renderPage(currentPage);
2337
2381
  },
2382
+ resetZoom: () => {
2383
+ fitMode = "page";
2384
+ zoomScale = 1;
2385
+ rotation = 0;
2386
+ container.scrollTop = 0;
2387
+ container.scrollLeft = 0;
2388
+ renderPage(currentPage);
2389
+ },
2338
2390
  fitToWidth: () => {
2339
2391
  fitMode = "width";
2340
2392
  zoomScale = 1;
@@ -2502,6 +2554,16 @@ var MediaPlugin = class {
2502
2554
  instance.fitToPage?.();
2503
2555
  }
2504
2556
  },
2557
+ {
2558
+ id: "reset-zoom",
2559
+ icon: "reset-zoom",
2560
+ label: "Reset Zoom",
2561
+ type: "button",
2562
+ group: "zoom",
2563
+ execute: () => {
2564
+ instance.resetZoom?.();
2565
+ }
2566
+ },
2505
2567
  {
2506
2568
  id: "rotate-cw",
2507
2569
  icon: "rotate-cw",
@@ -2641,17 +2703,86 @@ var MediaPlugin = class {
2641
2703
  element = document.createElement("div");
2642
2704
  element.textContent = "Unsupported media type";
2643
2705
  }
2644
- ctx.container.style.display = "flex";
2645
- ctx.container.style.alignItems = "center";
2646
- ctx.container.style.justifyContent = "center";
2647
- ctx.container.style.overflow = "hidden";
2648
- ctx.container.appendChild(element);
2706
+ const scrollWrapper = document.createElement("div");
2707
+ scrollWrapper.className = "fp-media-scroll-wrapper";
2708
+ scrollWrapper.style.minWidth = "100%";
2709
+ scrollWrapper.style.minHeight = "100%";
2710
+ scrollWrapper.style.width = "max-content";
2711
+ scrollWrapper.style.height = "max-content";
2712
+ scrollWrapper.style.display = "flex";
2713
+ scrollWrapper.style.justifyContent = "center";
2714
+ scrollWrapper.style.alignItems = "center";
2715
+ scrollWrapper.style.padding = "16px";
2716
+ scrollWrapper.style.boxSizing = "border-box";
2717
+ const sizer = document.createElement("div");
2718
+ sizer.className = "fp-media-sizer";
2719
+ sizer.style.position = "relative";
2720
+ sizer.style.flexShrink = "0";
2721
+ sizer.style.display = "flex";
2722
+ sizer.style.justifyContent = "center";
2723
+ sizer.style.alignItems = "center";
2724
+ sizer.appendChild(element);
2725
+ scrollWrapper.appendChild(sizer);
2726
+ ctx.container.style.overflow = "auto";
2727
+ ctx.container.style.padding = "0";
2728
+ ctx.container.innerHTML = "";
2729
+ ctx.container.appendChild(scrollWrapper);
2730
+ let naturalW = 800;
2731
+ let naturalH = 600;
2732
+ let baseW = 800;
2733
+ let baseH = 600;
2734
+ const updateBaseDimensions = () => {
2735
+ if (!isImage) return;
2736
+ const img = element;
2737
+ naturalW = img.naturalWidth || naturalW;
2738
+ naturalH = img.naturalHeight || naturalH;
2739
+ const availW = Math.max(100, ctx.container.clientWidth - 48);
2740
+ const availH = Math.max(100, ctx.container.clientHeight - 48);
2741
+ const fitRatio = Math.min(1, availW / naturalW, availH / naturalH);
2742
+ baseW = Math.max(1, Math.round(naturalW * fitRatio));
2743
+ baseH = Math.max(1, Math.round(naturalH * fitRatio));
2744
+ };
2649
2745
  const applyTransform = () => {
2650
- element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2746
+ if (isImage) {
2747
+ updateBaseDimensions();
2748
+ const isRotated90 = rotation % 180 !== 0;
2749
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * currentZoom);
2750
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * currentZoom);
2751
+ sizer.style.width = `${boxW}px`;
2752
+ sizer.style.height = `${boxH}px`;
2753
+ element.style.width = `${baseW}px`;
2754
+ element.style.height = `${baseH}px`;
2755
+ element.style.maxWidth = "none";
2756
+ element.style.maxHeight = "none";
2757
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2758
+ element.style.transformOrigin = "center center";
2759
+ element.style.flexShrink = "0";
2760
+ } else {
2761
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2762
+ }
2651
2763
  };
2764
+ if (isImage) {
2765
+ const img = element;
2766
+ if (img.complete && img.naturalWidth > 0) {
2767
+ updateBaseDimensions();
2768
+ applyTransform();
2769
+ } else {
2770
+ img.onload = () => {
2771
+ updateBaseDimensions();
2772
+ applyTransform();
2773
+ };
2774
+ }
2775
+ }
2776
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
2777
+ if (currentZoom === 1) {
2778
+ applyTransform();
2779
+ }
2780
+ }) : null;
2781
+ ro?.observe(ctx.container);
2652
2782
  const cleanup = () => {
2783
+ ro?.disconnect();
2653
2784
  if (url) URL.revokeObjectURL(url);
2654
- element.remove();
2785
+ scrollWrapper.remove();
2655
2786
  ctx.container.innerHTML = "";
2656
2787
  };
2657
2788
  ctx.signal.addEventListener("abort", cleanup);
@@ -2675,6 +2806,13 @@ var MediaPlugin = class {
2675
2806
  rotation = 0;
2676
2807
  applyTransform();
2677
2808
  } : void 0,
2809
+ resetZoom: isImage ? () => {
2810
+ currentZoom = 1;
2811
+ rotation = 0;
2812
+ ctx.container.scrollTop = 0;
2813
+ ctx.container.scrollLeft = 0;
2814
+ applyTransform();
2815
+ } : void 0,
2678
2816
  rotateCW: isImage || isVideo ? () => {
2679
2817
  rotation = (rotation + 90) % 360;
2680
2818
  applyTransform();
@@ -2791,6 +2929,14 @@ var DocxPlugin = class {
2791
2929
  group: "zoom",
2792
2930
  execute: () => instance.fitToPage?.()
2793
2931
  },
2932
+ {
2933
+ id: "reset-zoom",
2934
+ icon: "reset-zoom",
2935
+ label: "Reset Zoom",
2936
+ type: "button",
2937
+ group: "zoom",
2938
+ execute: () => instance.resetZoom?.()
2939
+ },
2794
2940
  {
2795
2941
  id: "rotate-cw",
2796
2942
  icon: "rotate-cw",
@@ -2829,7 +2975,7 @@ var DocxPlugin = class {
2829
2975
  async render(ctx) {
2830
2976
  const wrapper = document.createElement("div");
2831
2977
  wrapper.className = "fp-docx-wrapper";
2832
- wrapper.style.transformOrigin = "top center";
2978
+ wrapper.style.transformOrigin = "center center";
2833
2979
  wrapper.style.transition = "transform 0.2s ease";
2834
2980
  wrapper.style.padding = "0";
2835
2981
  wrapper.style.maxWidth = "none";
@@ -2839,11 +2985,31 @@ var DocxPlugin = class {
2839
2985
  wrapper.style.flexDirection = "column";
2840
2986
  wrapper.style.alignItems = "center";
2841
2987
  wrapper.style.boxSizing = "border-box";
2842
- ctx.container.style.overflowX = "hidden";
2843
- ctx.container.style.overflowY = "auto";
2844
- ctx.container.style.padding = "16px 8px";
2988
+ wrapper.style.flexShrink = "0";
2989
+ const sizer = document.createElement("div");
2990
+ sizer.className = "fp-docx-sizer";
2991
+ sizer.style.position = "relative";
2992
+ sizer.style.flexShrink = "0";
2993
+ sizer.style.display = "flex";
2994
+ sizer.style.justifyContent = "center";
2995
+ sizer.style.alignItems = "center";
2996
+ const scrollWrapper = document.createElement("div");
2997
+ scrollWrapper.className = "fp-docx-scroll-wrapper";
2998
+ scrollWrapper.style.minWidth = "100%";
2999
+ scrollWrapper.style.minHeight = "100%";
3000
+ scrollWrapper.style.width = "max-content";
3001
+ scrollWrapper.style.height = "max-content";
3002
+ scrollWrapper.style.display = "flex";
3003
+ scrollWrapper.style.justifyContent = "center";
3004
+ scrollWrapper.style.alignItems = "flex-start";
3005
+ scrollWrapper.style.padding = "16px 8px";
3006
+ scrollWrapper.style.boxSizing = "border-box";
3007
+ sizer.appendChild(wrapper);
3008
+ scrollWrapper.appendChild(sizer);
3009
+ ctx.container.style.overflow = "auto";
3010
+ ctx.container.style.padding = "0";
2845
3011
  ctx.container.style.backgroundColor = "#f1f5f9";
2846
- ctx.container.appendChild(wrapper);
3012
+ ctx.container.appendChild(scrollWrapper);
2847
3013
  const styleOverride = document.createElement("style");
2848
3014
  styleOverride.textContent = `
2849
3015
  .fp-docx-wrapper .docx-wrapper {
@@ -2882,8 +3048,8 @@ var DocxPlugin = class {
2882
3048
  renderEndnotes: true,
2883
3049
  useBase64URL: true
2884
3050
  });
2885
- if (!ctx.container.contains(wrapper)) {
2886
- ctx.container.appendChild(wrapper);
3051
+ if (!sizer.contains(wrapper)) {
3052
+ sizer.appendChild(wrapper);
2887
3053
  }
2888
3054
  if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
2889
3055
  renderedSuccessfully = true;
@@ -2920,8 +3086,8 @@ var DocxPlugin = class {
2920
3086
  try {
2921
3087
  wrapper.innerHTML = "";
2922
3088
  this.renderXmlFallback(ctx, wrapper, createdBlobUrls);
2923
- if (!ctx.container.contains(wrapper)) {
2924
- ctx.container.appendChild(wrapper);
3089
+ if (!sizer.contains(wrapper)) {
3090
+ sizer.appendChild(wrapper);
2925
3091
  }
2926
3092
  renderedSuccessfully = true;
2927
3093
  } catch (fallbackErr) {
@@ -2936,8 +3102,8 @@ var DocxPlugin = class {
2936
3102
  </p>
2937
3103
  </div>
2938
3104
  `;
2939
- if (!ctx.container.contains(wrapper)) {
2940
- ctx.container.appendChild(wrapper);
3105
+ if (!sizer.contains(wrapper)) {
3106
+ sizer.appendChild(wrapper);
2941
3107
  }
2942
3108
  }
2943
3109
  }
@@ -3040,15 +3206,18 @@ var DocxPlugin = class {
3040
3206
  return Math.max(0.35, Math.min(3, sW));
3041
3207
  };
3042
3208
  const applyTransform = () => {
3043
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
3044
- wrapper.style.transformOrigin = "top center";
3045
3209
  const activeEl = pageElements[currentPage - 1] || wrapper.querySelector("section.docx") || wrapper;
3210
+ const elW = activeEl.offsetWidth || 816;
3046
3211
  const elH = activeEl.offsetHeight || 1056;
3047
- if (scale > 1) {
3048
- wrapper.style.marginBottom = `${Math.round(elH * scale - elH + 32)}px`;
3049
- } else {
3050
- wrapper.style.marginBottom = "32px";
3051
- }
3212
+ const isRotated90 = rotation % 180 !== 0;
3213
+ const boxW = Math.round((isRotated90 ? elH : elW) * scale);
3214
+ const boxH = Math.round((isRotated90 ? elW : elH) * scale);
3215
+ sizer.style.width = `${boxW}px`;
3216
+ sizer.style.height = `${boxH}px`;
3217
+ wrapper.style.width = `${elW}px`;
3218
+ wrapper.style.height = `${elH}px`;
3219
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
3220
+ wrapper.style.transformOrigin = "center center";
3052
3221
  };
3053
3222
  let resizeObserver = null;
3054
3223
  if (typeof ResizeObserver !== "undefined") {
@@ -3073,7 +3242,7 @@ var DocxPlugin = class {
3073
3242
  for (const url of createdBlobUrls) {
3074
3243
  URL.revokeObjectURL(url);
3075
3244
  }
3076
- wrapper.remove();
3245
+ scrollWrapper.remove();
3077
3246
  styleOverride.remove();
3078
3247
  ctx.container.innerHTML = "";
3079
3248
  };
@@ -3107,6 +3276,14 @@ var DocxPlugin = class {
3107
3276
  rotation = 0;
3108
3277
  applyTransform();
3109
3278
  },
3279
+ resetZoom: () => {
3280
+ isUserZoomed = false;
3281
+ scale = calculateFitScale("page");
3282
+ rotation = 0;
3283
+ ctx.container.scrollTop = 0;
3284
+ ctx.container.scrollLeft = 0;
3285
+ applyTransform();
3286
+ },
3110
3287
  rotateCW: () => {
3111
3288
  rotation = (rotation + 90) % 360;
3112
3289
  applyTransform();
@@ -3556,6 +3733,16 @@ var ExcelPlugin = class {
3556
3733
  instance.zoomIn?.();
3557
3734
  }
3558
3735
  },
3736
+ {
3737
+ id: "reset-zoom",
3738
+ icon: "reset-zoom",
3739
+ label: "Reset Zoom",
3740
+ type: "button",
3741
+ group: "zoom",
3742
+ execute: () => {
3743
+ instance.resetZoom?.();
3744
+ }
3745
+ },
3559
3746
  {
3560
3747
  id: "download",
3561
3748
  icon: "download",
@@ -3602,7 +3789,7 @@ var ExcelPlugin = class {
3602
3789
  contentArea.style.flex = "1";
3603
3790
  contentArea.style.overflow = "auto";
3604
3791
  contentArea.style.padding = "16px";
3605
- contentArea.style.transformOrigin = "top left";
3792
+ contentArea.style.boxSizing = "border-box";
3606
3793
  const tabsArea = document.createElement("div");
3607
3794
  tabsArea.className = "fp-excel-tabs";
3608
3795
  tabsArea.style.display = "flex";
@@ -3616,18 +3803,35 @@ var ExcelPlugin = class {
3616
3803
  container.appendChild(tabsArea);
3617
3804
  ctx.container.appendChild(container);
3618
3805
  let scale = 1;
3806
+ let isUserZoomed = false;
3619
3807
  let currentSheetIndex = 1;
3620
3808
  let sheetNames = [];
3621
3809
  let wb = null;
3622
3810
  const applyTransform = () => {
3623
- contentArea.style.transform = `scale(${scale})`;
3624
- contentArea.style.transformOrigin = "top left";
3811
+ const sizer = contentArea.querySelector(".fp-excel-sizer");
3812
+ const table = contentArea.querySelector("table");
3813
+ if (!sizer || !table) return;
3814
+ if (!table._baseWidth && table.offsetWidth > 0) {
3815
+ table._baseWidth = table.offsetWidth;
3816
+ table._baseHeight = table.offsetHeight;
3817
+ }
3818
+ const baseW = table._baseWidth || table.offsetWidth || 800;
3819
+ const baseH = table._baseHeight || table.offsetHeight || 600;
3820
+ const scaledW = Math.round(baseW * scale);
3821
+ const scaledH = Math.round(baseH * scale);
3822
+ sizer.style.width = `${scaledW}px`;
3823
+ sizer.style.height = `${scaledH}px`;
3824
+ table.style.position = "absolute";
3825
+ table.style.top = "0";
3826
+ table.style.left = "0";
3827
+ table.style.transform = `scale(${scale})`;
3828
+ table.style.transformOrigin = "top left";
3625
3829
  };
3626
3830
  const calculateFitScale = () => {
3627
3831
  const table = contentArea.querySelector("table");
3628
3832
  if (!table) return 1;
3629
3833
  const availW = Math.max(280, container.clientWidth - 48);
3630
- const tW = table.offsetWidth || 800;
3834
+ const tW = table._baseWidth || table.offsetWidth || 800;
3631
3835
  return Math.max(0.4, Math.min(1, availW / tW));
3632
3836
  };
3633
3837
  try {
@@ -3647,9 +3851,13 @@ var ExcelPlugin = class {
3647
3851
  contentArea.innerHTML = '<div style="padding: 24px; color: #888;">Empty sheet</div>';
3648
3852
  return;
3649
3853
  }
3854
+ const sizer = document.createElement("div");
3855
+ sizer.className = "fp-excel-sizer";
3856
+ sizer.style.position = "relative";
3650
3857
  const html = XLSX__namespace.utils.sheet_to_html(ws, { id: "fp-sheet-table", editable: false });
3651
- contentArea.innerHTML = html;
3652
- const table = contentArea.querySelector("table");
3858
+ sizer.innerHTML = html;
3859
+ contentArea.appendChild(sizer);
3860
+ const table = sizer.querySelector("table");
3653
3861
  if (table) {
3654
3862
  table.style.borderCollapse = "collapse";
3655
3863
  table.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
@@ -3684,13 +3892,17 @@ var ExcelPlugin = class {
3684
3892
  });
3685
3893
  ctx.emit("page-change", { page: currentSheetIndex, total: sheetNames.length });
3686
3894
  requestAnimationFrame(() => {
3687
- scale = calculateFitScale();
3895
+ if (!isUserZoomed) {
3896
+ scale = calculateFitScale();
3897
+ }
3688
3898
  applyTransform();
3689
3899
  });
3690
3900
  };
3691
3901
  const ro = new ResizeObserver(() => {
3692
- scale = calculateFitScale();
3693
- applyTransform();
3902
+ if (!isUserZoomed) {
3903
+ scale = calculateFitScale();
3904
+ applyTransform();
3905
+ }
3694
3906
  });
3695
3907
  ro.observe(container);
3696
3908
  if (sheetNames.length > 0) {
@@ -3727,20 +3939,31 @@ var ExcelPlugin = class {
3727
3939
  return {
3728
3940
  destroy: cleanup,
3729
3941
  zoomIn: () => {
3942
+ isUserZoomed = true;
3730
3943
  scale += 0.15;
3731
3944
  applyTransform();
3732
3945
  },
3733
3946
  zoomOut: () => {
3947
+ isUserZoomed = true;
3734
3948
  scale = Math.max(0.2, scale - 0.15);
3735
3949
  applyTransform();
3736
3950
  },
3737
3951
  getZoom: () => scale,
3738
3952
  setZoom: (level) => {
3953
+ isUserZoomed = true;
3739
3954
  scale = level;
3740
3955
  applyTransform();
3741
3956
  },
3742
3957
  fitToPage: () => {
3958
+ isUserZoomed = false;
3959
+ scale = calculateFitScale();
3960
+ applyTransform();
3961
+ },
3962
+ resetZoom: () => {
3963
+ isUserZoomed = false;
3743
3964
  scale = calculateFitScale();
3965
+ contentArea.scrollTop = 0;
3966
+ contentArea.scrollLeft = 0;
3744
3967
  applyTransform();
3745
3968
  },
3746
3969
  rotateCW: () => {
@@ -3873,6 +4096,16 @@ var CsvPlugin = class {
3873
4096
  instance.zoomIn?.();
3874
4097
  }
3875
4098
  },
4099
+ {
4100
+ id: "reset-zoom",
4101
+ icon: "reset-zoom",
4102
+ label: "Reset Zoom",
4103
+ type: "button",
4104
+ group: "zoom",
4105
+ execute: () => {
4106
+ instance.resetZoom?.();
4107
+ }
4108
+ },
3876
4109
  {
3877
4110
  id: "download",
3878
4111
  icon: "download",
@@ -3959,21 +4192,41 @@ var CsvPlugin = class {
3959
4192
  container.appendChild(tableWrapper);
3960
4193
  ctx.container.appendChild(container);
3961
4194
  let scale = 1;
4195
+ let isUserZoomed = false;
3962
4196
  const calculateFitScale = () => {
3963
4197
  const availW = Math.max(280, container.clientWidth - 48);
3964
- const tW = table.offsetWidth || 800;
4198
+ const tW = table._baseWidth || table.offsetWidth || 800;
3965
4199
  return Math.max(0.4, Math.min(1, availW / tW));
3966
4200
  };
3967
4201
  const applyScale = () => {
3968
- tableWrapper.style.transform = `scale(${scale})`;
4202
+ if (!table._baseWidth && table.offsetWidth > 0) {
4203
+ table._baseWidth = table.offsetWidth;
4204
+ table._baseHeight = table.offsetHeight;
4205
+ }
4206
+ const baseW = table._baseWidth || table.offsetWidth || 800;
4207
+ const baseH = table._baseHeight || table.offsetHeight || 600;
4208
+ const scaledW = Math.round(baseW * scale);
4209
+ const scaledH = Math.round(baseH * scale);
4210
+ tableWrapper.style.position = "relative";
4211
+ tableWrapper.style.width = `${scaledW}px`;
4212
+ tableWrapper.style.height = `${scaledH}px`;
4213
+ table.style.position = "absolute";
4214
+ table.style.top = "0";
4215
+ table.style.left = "0";
4216
+ table.style.transform = `scale(${scale})`;
4217
+ table.style.transformOrigin = "top left";
3969
4218
  };
3970
4219
  requestAnimationFrame(() => {
3971
- scale = calculateFitScale();
4220
+ if (!isUserZoomed) {
4221
+ scale = calculateFitScale();
4222
+ }
3972
4223
  applyScale();
3973
4224
  });
3974
4225
  const ro = new ResizeObserver(() => {
3975
- scale = calculateFitScale();
3976
- applyScale();
4226
+ if (!isUserZoomed) {
4227
+ scale = calculateFitScale();
4228
+ applyScale();
4229
+ }
3977
4230
  });
3978
4231
  ro.observe(container);
3979
4232
  const cleanup = () => {
@@ -4046,20 +4299,31 @@ var CsvPlugin = class {
4046
4299
  }];
4047
4300
  },
4048
4301
  zoomIn: () => {
4302
+ isUserZoomed = true;
4049
4303
  scale += 0.1;
4050
4304
  applyScale();
4051
4305
  },
4052
4306
  zoomOut: () => {
4307
+ isUserZoomed = true;
4053
4308
  scale = Math.max(0.2, scale - 0.1);
4054
4309
  applyScale();
4055
4310
  },
4056
4311
  getZoom: () => scale,
4057
4312
  setZoom: (level) => {
4313
+ isUserZoomed = true;
4058
4314
  scale = level;
4059
4315
  applyScale();
4060
4316
  },
4061
4317
  fitToPage: () => {
4318
+ isUserZoomed = false;
4319
+ scale = calculateFitScale();
4320
+ applyScale();
4321
+ },
4322
+ resetZoom: () => {
4323
+ isUserZoomed = false;
4062
4324
  scale = calculateFitScale();
4325
+ container.scrollTop = 0;
4326
+ container.scrollLeft = 0;
4063
4327
  applyScale();
4064
4328
  },
4065
4329
  rotateCW: () => {
@@ -4177,6 +4441,16 @@ var CodePlugin = class {
4177
4441
  instance.zoomIn?.();
4178
4442
  }
4179
4443
  },
4444
+ {
4445
+ id: "reset-zoom",
4446
+ icon: "reset-zoom",
4447
+ label: "Reset Zoom",
4448
+ type: "button",
4449
+ group: "zoom",
4450
+ execute: () => {
4451
+ instance.resetZoom?.();
4452
+ }
4453
+ },
4180
4454
  {
4181
4455
  id: "copy",
4182
4456
  icon: "copy",
@@ -4282,15 +4556,27 @@ var CodePlugin = class {
4282
4556
  let isUserZoomed = false;
4283
4557
  const pre = document.createElement("pre");
4284
4558
  const code = document.createElement("code");
4559
+ const sizer = document.createElement("div");
4560
+ const scrollWrapper = document.createElement("div");
4285
4561
  if (isTxt) {
4286
- container.style.overflowX = "hidden";
4287
- container.style.overflowY = "auto";
4562
+ container.style.overflow = "auto";
4288
4563
  container.style.backgroundColor = "#f1f5f9";
4289
- container.style.padding = "16px 8px";
4290
- container.style.boxSizing = "border-box";
4291
- container.style.display = "flex";
4292
- container.style.flexDirection = "column";
4293
- container.style.alignItems = "center";
4564
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4565
+ scrollWrapper.style.minWidth = "100%";
4566
+ scrollWrapper.style.minHeight = "100%";
4567
+ scrollWrapper.style.width = "max-content";
4568
+ scrollWrapper.style.height = "max-content";
4569
+ scrollWrapper.style.display = "flex";
4570
+ scrollWrapper.style.justifyContent = "center";
4571
+ scrollWrapper.style.alignItems = "flex-start";
4572
+ scrollWrapper.style.padding = "16px 8px";
4573
+ scrollWrapper.style.boxSizing = "border-box";
4574
+ sizer.className = "fp-code-sizer";
4575
+ sizer.style.position = "relative";
4576
+ sizer.style.flexShrink = "0";
4577
+ sizer.style.display = "flex";
4578
+ sizer.style.justifyContent = "center";
4579
+ sizer.style.alignItems = "center";
4294
4580
  pre.style.margin = "0 auto";
4295
4581
  pre.style.fontFamily = "Consolas, 'Courier New', monospace";
4296
4582
  pre.style.fontSize = "13px";
@@ -4305,8 +4591,9 @@ var CodePlugin = class {
4305
4591
  pre.style.boxSizing = "border-box";
4306
4592
  pre.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4307
4593
  pre.style.borderRadius = "4px";
4308
- pre.style.transformOrigin = "top center";
4594
+ pre.style.transformOrigin = "center center";
4309
4595
  pre.style.transition = "transform 0.15s ease";
4596
+ pre.style.flexShrink = "0";
4310
4597
  } else {
4311
4598
  container.style.overflow = "auto";
4312
4599
  container.style.backgroundColor = "#1e1e1e";
@@ -4339,7 +4626,13 @@ var CodePlugin = class {
4339
4626
  };
4340
4627
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4341
4628
  pre.appendChild(code);
4342
- container.appendChild(pre);
4629
+ if (isTxt) {
4630
+ sizer.appendChild(pre);
4631
+ scrollWrapper.appendChild(sizer);
4632
+ container.appendChild(scrollWrapper);
4633
+ } else {
4634
+ container.appendChild(pre);
4635
+ }
4343
4636
  const showPage = (pageNum) => {
4344
4637
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4345
4638
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
@@ -4356,10 +4649,16 @@ var CodePlugin = class {
4356
4649
  };
4357
4650
  const updateTransform = () => {
4358
4651
  if (isTxt) {
4652
+ const elW = 816;
4653
+ const baseH = pre.offsetHeight || 1056;
4654
+ const isRotated90 = rotation % 180 !== 0;
4655
+ const boxW = Math.round((isRotated90 ? baseH : elW) * zoomLevel);
4656
+ const boxH = Math.round((isRotated90 ? elW : baseH) * zoomLevel);
4657
+ sizer.style.width = `${boxW}px`;
4658
+ sizer.style.height = `${boxH}px`;
4659
+ pre.style.width = `${elW}px`;
4359
4660
  pre.style.transform = `scale(${zoomLevel}) rotate(${rotation}deg)`;
4360
- const scaledH = 1056 * zoomLevel;
4361
- const extraH = Math.max(0, scaledH - 1056);
4362
- pre.style.marginBottom = `${extraH + 32}px`;
4661
+ pre.style.transformOrigin = "center center";
4363
4662
  } else {
4364
4663
  pre.style.transform = `rotate(${rotation}deg)`;
4365
4664
  pre.style.fontSize = `${fontSize}px`;
@@ -4456,6 +4755,15 @@ var CodePlugin = class {
4456
4755
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4457
4756
  updateTransform();
4458
4757
  },
4758
+ resetZoom: () => {
4759
+ isUserZoomed = false;
4760
+ fontSize = 13;
4761
+ rotation = 0;
4762
+ zoomLevel = isTxt ? calculateTxtFit() : 1;
4763
+ container.scrollTop = 0;
4764
+ container.scrollLeft = 0;
4765
+ updateTransform();
4766
+ },
4459
4767
  rotateCW: () => {
4460
4768
  rotation = (rotation + 90) % 360;
4461
4769
  updateTransform();
@@ -4518,11 +4826,19 @@ var ArchivePlugin = class {
4518
4826
  {
4519
4827
  id: "fit-page",
4520
4828
  icon: "fit-page",
4521
- label: "Reset Zoom",
4829
+ label: "Fit to Page",
4522
4830
  type: "button",
4523
4831
  group: "zoom",
4524
4832
  execute: () => instance.fitToPage?.()
4525
4833
  },
4834
+ {
4835
+ id: "reset-zoom",
4836
+ icon: "reset-zoom",
4837
+ label: "Reset Zoom",
4838
+ type: "button",
4839
+ group: "zoom",
4840
+ execute: () => instance.resetZoom?.()
4841
+ },
4526
4842
  {
4527
4843
  id: "download",
4528
4844
  icon: "download",
@@ -4548,16 +4864,56 @@ var ArchivePlugin = class {
4548
4864
  width: 100%;
4549
4865
  height: 100%;
4550
4866
  overflow: auto;
4551
- padding: 24px;
4552
4867
  box-sizing: border-box;
4553
4868
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
4554
- transform-origin: top left;
4555
- transition: transform 0.2s ease;
4556
4869
  `;
4870
+ const scrollWrapper = document.createElement("div");
4871
+ scrollWrapper.className = "fp-archive-scroll-wrapper";
4872
+ scrollWrapper.style.cssText = `
4873
+ min-width: 100%;
4874
+ min-height: 100%;
4875
+ width: max-content;
4876
+ height: max-content;
4877
+ display: flex;
4878
+ justify-content: center;
4879
+ align-items: flex-start;
4880
+ padding: 24px;
4881
+ box-sizing: border-box;
4882
+ `;
4883
+ const sizer = document.createElement("div");
4884
+ sizer.className = "fp-archive-sizer";
4885
+ sizer.style.cssText = `
4886
+ position: relative;
4887
+ flex-shrink: 0;
4888
+ display: flex;
4889
+ justify-content: center;
4890
+ align-items: flex-start;
4891
+ `;
4892
+ const card = document.createElement("div");
4893
+ card.className = "fp-archive-card";
4894
+ card.style.cssText = `
4895
+ width: 900px;
4896
+ box-sizing: border-box;
4897
+ transform-origin: top center;
4898
+ transition: transform 0.15s ease;
4899
+ flex-shrink: 0;
4900
+ `;
4901
+ sizer.appendChild(card);
4902
+ scrollWrapper.appendChild(sizer);
4903
+ wrapper.appendChild(scrollWrapper);
4557
4904
  ctx.container.innerHTML = "";
4558
4905
  ctx.container.style.overflow = "auto";
4559
4906
  ctx.container.appendChild(wrapper);
4560
4907
  let scale = 1;
4908
+ const applyTransform = () => {
4909
+ const boxW = Math.round(900 * scale);
4910
+ const cardH = card.offsetHeight || 600;
4911
+ const boxH = Math.round(cardH * scale);
4912
+ sizer.style.width = `${boxW}px`;
4913
+ sizer.style.height = `${boxH}px`;
4914
+ card.style.transform = `scale(${scale})`;
4915
+ card.style.transformOrigin = "top center";
4916
+ };
4561
4917
  const entries = await new Promise((resolve, reject) => {
4562
4918
  fflate.unzip(new Uint8Array(ctx.buffer), (err, unzipped) => {
4563
4919
  if (err) {
@@ -4581,7 +4937,7 @@ var ArchivePlugin = class {
4581
4937
  });
4582
4938
  const totalUncompressedSize = entries.reduce((acc, e) => acc + e.size, 0);
4583
4939
  const renderUI = (filteredEntries) => {
4584
- wrapper.innerHTML = `
4940
+ card.innerHTML = `
4585
4941
  <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;">
4586
4942
  <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;">
4587
4943
  <div>
@@ -4611,7 +4967,7 @@ var ArchivePlugin = class {
4611
4967
  </div>
4612
4968
  </div>
4613
4969
  `;
4614
- const tbody = wrapper.querySelector("#fp-archive-body");
4970
+ const tbody = card.querySelector("#fp-archive-body");
4615
4971
  if (filteredEntries.length === 0) {
4616
4972
  tbody.innerHTML = `<tr><td colspan="3" style="padding: 24px; text-align: center; color: #9ca3af;">No matching files found</td></tr>`;
4617
4973
  } else {
@@ -4640,19 +4996,20 @@ var ArchivePlugin = class {
4640
4996
  }
4641
4997
  });
4642
4998
  });
4643
- const searchInput = wrapper.querySelector("#fp-archive-search");
4999
+ const searchInput = card.querySelector("#fp-archive-search");
4644
5000
  if (searchInput) {
4645
5001
  searchInput.addEventListener("input", () => {
4646
5002
  const q = searchInput.value.toLowerCase().trim();
4647
5003
  const filtered = q ? entries.filter((e) => e.path.toLowerCase().includes(q)) : entries;
4648
5004
  renderUI(filtered);
4649
- const newSearch = wrapper.querySelector("#fp-archive-search");
5005
+ const newSearch = card.querySelector("#fp-archive-search");
4650
5006
  if (newSearch) {
4651
5007
  newSearch.value = q;
4652
5008
  newSearch.focus();
4653
5009
  }
4654
5010
  });
4655
5011
  }
5012
+ applyTransform();
4656
5013
  };
4657
5014
  renderUI(entries);
4658
5015
  const cleanup = () => {
@@ -4664,20 +5021,26 @@ var ArchivePlugin = class {
4664
5021
  destroy: cleanup,
4665
5022
  zoomIn: () => {
4666
5023
  scale += 0.1;
4667
- wrapper.style.transform = `scale(${scale})`;
5024
+ applyTransform();
4668
5025
  },
4669
5026
  zoomOut: () => {
4670
5027
  scale = Math.max(0.3, scale - 0.1);
4671
- wrapper.style.transform = `scale(${scale})`;
5028
+ applyTransform();
4672
5029
  },
4673
5030
  getZoom: () => scale,
4674
5031
  setZoom: (level) => {
4675
5032
  scale = level;
4676
- wrapper.style.transform = `scale(${scale})`;
5033
+ applyTransform();
4677
5034
  },
4678
5035
  fitToPage: () => {
4679
5036
  scale = 1;
4680
- wrapper.style.transform = `scale(1)`;
5037
+ applyTransform();
5038
+ },
5039
+ resetZoom: () => {
5040
+ scale = 1;
5041
+ wrapper.scrollTop = 0;
5042
+ wrapper.scrollLeft = 0;
5043
+ applyTransform();
4681
5044
  },
4682
5045
  download: () => {
4683
5046
  downloadFile(ctx.buffer, ctx.metadata.name || "archive.zip", "application/zip");
@@ -4729,6 +5092,14 @@ var MarkdownPlugin = class {
4729
5092
  group: "zoom",
4730
5093
  execute: () => instance.fitToPage?.()
4731
5094
  },
5095
+ {
5096
+ id: "reset-zoom",
5097
+ icon: "reset-zoom",
5098
+ label: "Reset Zoom",
5099
+ type: "button",
5100
+ group: "zoom",
5101
+ execute: () => instance.resetZoom?.()
5102
+ },
4732
5103
  {
4733
5104
  id: "copy",
4734
5105
  icon: "copy",
@@ -4882,6 +5253,12 @@ var MarkdownPlugin = class {
4882
5253
  fontSize = 15;
4883
5254
  wrapper.style.fontSize = "15px";
4884
5255
  },
5256
+ resetZoom: () => {
5257
+ fontSize = 15;
5258
+ wrapper.style.fontSize = "15px";
5259
+ ctx.container.scrollTop = 0;
5260
+ ctx.container.scrollLeft = 0;
5261
+ },
4885
5262
  download: () => {
4886
5263
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
4887
5264
  },
@@ -4975,6 +5352,14 @@ var PptxPlugin = class {
4975
5352
  group: "zoom",
4976
5353
  execute: () => instance.fitToPage?.()
4977
5354
  },
5355
+ {
5356
+ id: "reset-zoom",
5357
+ icon: "reset-zoom",
5358
+ label: "Reset Zoom",
5359
+ type: "button",
5360
+ group: "zoom",
5361
+ execute: () => instance.resetZoom?.()
5362
+ },
4978
5363
  {
4979
5364
  id: "rotate-cw",
4980
5365
  icon: "rotate-cw",
@@ -5014,12 +5399,30 @@ var PptxPlugin = class {
5014
5399
  width: 100%;
5015
5400
  height: 100%;
5016
5401
  overflow: auto;
5402
+ box-sizing: border-box;
5403
+ background: var(--fp-bg-canvas, #525659);
5404
+ `;
5405
+ const scrollWrapper = document.createElement("div");
5406
+ scrollWrapper.className = "fp-pptx-scroll-wrapper";
5407
+ scrollWrapper.style.cssText = `
5408
+ min-width: 100%;
5409
+ min-height: 100%;
5410
+ width: max-content;
5411
+ height: max-content;
5017
5412
  display: flex;
5018
5413
  justify-content: center;
5019
- align-items: flex-start;
5414
+ align-items: center;
5020
5415
  padding: 24px;
5021
5416
  box-sizing: border-box;
5022
- background: var(--fp-bg-canvas, #525659);
5417
+ `;
5418
+ const sizer = document.createElement("div");
5419
+ sizer.className = "fp-pptx-sizer";
5420
+ sizer.style.cssText = `
5421
+ position: relative;
5422
+ flex-shrink: 0;
5423
+ display: flex;
5424
+ justify-content: center;
5425
+ align-items: center;
5023
5426
  `;
5024
5427
  const slideContainer = document.createElement("div");
5025
5428
  slideContainer.className = "fp-slide-container";
@@ -5028,14 +5431,15 @@ var PptxPlugin = class {
5028
5431
  border-radius: 4px;
5029
5432
  overflow: hidden;
5030
5433
  background: #ffffff;
5031
- transform-origin: top center;
5434
+ transform-origin: center center;
5032
5435
  transition: transform 0.2s ease;
5033
- max-width: calc(100% - 32px);
5034
- max-height: calc(100% - 48px);
5436
+ flex-shrink: 0;
5035
5437
  `;
5036
5438
  const canvas = document.createElement("canvas");
5037
5439
  slideContainer.appendChild(canvas);
5038
- wrapper.appendChild(slideContainer);
5440
+ sizer.appendChild(slideContainer);
5441
+ scrollWrapper.appendChild(sizer);
5442
+ wrapper.appendChild(scrollWrapper);
5039
5443
  ctx.container.innerHTML = "";
5040
5444
  ctx.container.style.overflow = "auto";
5041
5445
  ctx.container.appendChild(wrapper);
@@ -5047,7 +5451,17 @@ var PptxPlugin = class {
5047
5451
  return Math.min(1, Math.min(availW / cW, availH / cH));
5048
5452
  };
5049
5453
  const applyTransform = () => {
5454
+ const cW = canvas.offsetWidth || 1280;
5455
+ const cH = canvas.offsetHeight || 720;
5456
+ const isRotated90 = rotation % 180 !== 0;
5457
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
5458
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
5459
+ sizer.style.width = `${boxW}px`;
5460
+ sizer.style.height = `${boxH}px`;
5461
+ slideContainer.style.width = `${cW}px`;
5462
+ slideContainer.style.height = `${cH}px`;
5050
5463
  slideContainer.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5464
+ slideContainer.style.transformOrigin = "center center";
5051
5465
  };
5052
5466
  const renderCurrentSlide = async () => {
5053
5467
  try {
@@ -5094,6 +5508,13 @@ var PptxPlugin = class {
5094
5508
  rotation = 0;
5095
5509
  applyTransform();
5096
5510
  },
5511
+ resetZoom: () => {
5512
+ scale = calculateFitScale();
5513
+ rotation = 0;
5514
+ wrapper.scrollTop = 0;
5515
+ wrapper.scrollLeft = 0;
5516
+ applyTransform();
5517
+ },
5097
5518
  rotateCW: () => {
5098
5519
  rotation = (rotation + 90) % 360;
5099
5520
  applyTransform();
@@ -5169,6 +5590,14 @@ var ThreeDPlugin = class {
5169
5590
  group: "zoom",
5170
5591
  execute: () => instance.fitToPage?.()
5171
5592
  },
5593
+ {
5594
+ id: "reset-zoom",
5595
+ icon: "reset-zoom",
5596
+ label: "Reset Zoom",
5597
+ type: "button",
5598
+ group: "zoom",
5599
+ execute: () => instance.resetZoom?.()
5600
+ },
5172
5601
  {
5173
5602
  id: "rotate-cw",
5174
5603
  icon: "rotate-cw",
@@ -5305,6 +5734,7 @@ var ThreeDPlugin = class {
5305
5734
  controls.update();
5306
5735
  },
5307
5736
  fitToPage: fitCamera,
5737
+ resetZoom: fitCamera,
5308
5738
  rotateCW: () => {
5309
5739
  isWireframe = !isWireframe;
5310
5740
  materials.forEach((m) => {
@@ -5519,6 +5949,14 @@ var RtfPlugin = class {
5519
5949
  group: "zoom",
5520
5950
  execute: () => instance.fitToPage?.()
5521
5951
  },
5952
+ {
5953
+ id: "reset-zoom",
5954
+ icon: "reset-zoom",
5955
+ label: "Reset Zoom",
5956
+ type: "button",
5957
+ group: "zoom",
5958
+ execute: () => instance.resetZoom?.()
5959
+ },
5522
5960
  {
5523
5961
  id: "rotate-cw",
5524
5962
  icon: "rotate-cw",
@@ -5629,13 +6067,33 @@ var RtfPlugin = class {
5629
6067
  wrapper.style.flexDirection = "column";
5630
6068
  wrapper.style.alignItems = "center";
5631
6069
  wrapper.style.backgroundColor = "transparent";
5632
- wrapper.style.transformOrigin = "top center";
6070
+ wrapper.style.transformOrigin = "center center";
5633
6071
  wrapper.style.transition = "transform 0.15s ease";
5634
- ctx.container.style.overflowX = "hidden";
5635
- ctx.container.style.overflowY = "auto";
5636
- ctx.container.style.padding = "16px 8px";
6072
+ wrapper.style.flexShrink = "0";
6073
+ const sizer = document.createElement("div");
6074
+ sizer.className = "fp-rtf-sizer";
6075
+ sizer.style.position = "relative";
6076
+ sizer.style.flexShrink = "0";
6077
+ sizer.style.display = "flex";
6078
+ sizer.style.justifyContent = "center";
6079
+ sizer.style.alignItems = "center";
6080
+ const scrollWrapper = document.createElement("div");
6081
+ scrollWrapper.className = "fp-rtf-scroll-wrapper";
6082
+ scrollWrapper.style.minWidth = "100%";
6083
+ scrollWrapper.style.minHeight = "100%";
6084
+ scrollWrapper.style.width = "max-content";
6085
+ scrollWrapper.style.height = "max-content";
6086
+ scrollWrapper.style.display = "flex";
6087
+ scrollWrapper.style.justifyContent = "center";
6088
+ scrollWrapper.style.alignItems = "flex-start";
6089
+ scrollWrapper.style.padding = "16px 8px";
6090
+ scrollWrapper.style.boxSizing = "border-box";
6091
+ sizer.appendChild(wrapper);
6092
+ scrollWrapper.appendChild(sizer);
6093
+ ctx.container.style.overflow = "auto";
6094
+ ctx.container.style.padding = "0";
5637
6095
  ctx.container.style.backgroundColor = "#f1f5f9";
5638
- ctx.container.appendChild(wrapper);
6096
+ ctx.container.appendChild(scrollWrapper);
5639
6097
  let scale = 1;
5640
6098
  let rotation = 0;
5641
6099
  let pageElements = [];
@@ -5654,12 +6112,17 @@ var RtfPlugin = class {
5654
6112
  return Math.max(0.4, Math.min(3, sW));
5655
6113
  };
5656
6114
  const applyTransform = () => {
5657
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5658
- wrapper.style.transformOrigin = "top center";
6115
+ const elW = pageWidth;
5659
6116
  const baseH = pageHeight;
5660
- const scaledH = baseH * scale;
5661
- const extraH = Math.max(0, scaledH - baseH);
5662
- wrapper.style.marginBottom = `${extraH + 32}px`;
6117
+ const isRotated90 = rotation % 180 !== 0;
6118
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6119
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6120
+ sizer.style.width = `${boxW}px`;
6121
+ sizer.style.height = `${boxH}px`;
6122
+ wrapper.style.width = `${elW}px`;
6123
+ wrapper.style.height = `${baseH}px`;
6124
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6125
+ wrapper.style.transformOrigin = "center center";
5663
6126
  };
5664
6127
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5665
6128
  if (!isUserZoomed) {
@@ -5930,7 +6393,7 @@ var RtfPlugin = class {
5930
6393
  }
5931
6394
  const cleanup = () => {
5932
6395
  resizeObserver?.disconnect();
5933
- wrapper.remove();
6396
+ scrollWrapper.remove();
5934
6397
  ctx.container.innerHTML = "";
5935
6398
  };
5936
6399
  ctx.signal.addEventListener("abort", cleanup);
@@ -5988,6 +6451,15 @@ var RtfPlugin = class {
5988
6451
  rotation = 0;
5989
6452
  applyTransform();
5990
6453
  },
6454
+ resetZoom: () => {
6455
+ isUserZoomed = false;
6456
+ fitMode = "width";
6457
+ scale = calculateFitScale("width");
6458
+ rotation = 0;
6459
+ ctx.container.scrollTop = 0;
6460
+ ctx.container.scrollLeft = 0;
6461
+ applyTransform();
6462
+ },
5991
6463
  rotateCW: () => {
5992
6464
  rotation = (rotation + 90) % 360;
5993
6465
  applyTransform();
@@ -6055,6 +6527,14 @@ var HtmlPreviewPlugin = class {
6055
6527
  group: "zoom",
6056
6528
  execute: () => instance.fitToPage?.()
6057
6529
  },
6530
+ {
6531
+ id: "reset-zoom",
6532
+ icon: "reset-zoom",
6533
+ label: "Reset Zoom",
6534
+ type: "button",
6535
+ group: "zoom",
6536
+ execute: () => instance.resetZoom?.()
6537
+ },
6058
6538
  {
6059
6539
  id: "copy",
6060
6540
  icon: "copy",
@@ -6088,23 +6568,44 @@ var HtmlPreviewPlugin = class {
6088
6568
  ADD_TAGS: ["style", "link"],
6089
6569
  ADD_ATTR: ["target", "rel"]
6090
6570
  });
6571
+ const sizer = document.createElement("div");
6572
+ sizer.className = "fp-html-sizer";
6573
+ sizer.style.position = "relative";
6091
6574
  const iframe = document.createElement("iframe");
6092
6575
  iframe.className = "fp-html-iframe";
6093
- iframe.style.width = "100%";
6094
- iframe.style.height = "100%";
6095
6576
  iframe.style.border = "none";
6096
6577
  iframe.style.backgroundColor = "#ffffff";
6097
6578
  iframe.style.transformOrigin = "top left";
6098
6579
  iframe.style.transition = "transform 0.2s ease";
6099
6580
  iframe.sandbox.add("allow-same-origin");
6581
+ sizer.appendChild(iframe);
6100
6582
  ctx.container.style.overflow = "auto";
6101
6583
  ctx.container.style.width = "100%";
6102
6584
  ctx.container.style.height = "100%";
6103
- ctx.container.appendChild(iframe);
6585
+ ctx.container.innerHTML = "";
6586
+ ctx.container.appendChild(sizer);
6104
6587
  iframe.srcdoc = sanitized;
6105
6588
  let scale = 1;
6589
+ const applyTransform = () => {
6590
+ const baseW = Math.max(600, ctx.container.clientWidth || 800);
6591
+ const baseH = Math.max(400, ctx.container.clientHeight || 600);
6592
+ const scaledW = Math.round(baseW * scale);
6593
+ const scaledH = Math.round(baseH * scale);
6594
+ sizer.style.width = `${scaledW}px`;
6595
+ sizer.style.height = `${scaledH}px`;
6596
+ iframe.style.position = "absolute";
6597
+ iframe.style.top = "0";
6598
+ iframe.style.left = "0";
6599
+ iframe.style.width = `${baseW}px`;
6600
+ iframe.style.height = `${baseH}px`;
6601
+ iframe.style.transform = `scale(${scale})`;
6602
+ iframe.style.transformOrigin = "top left";
6603
+ };
6604
+ requestAnimationFrame(() => {
6605
+ applyTransform();
6606
+ });
6106
6607
  const cleanup = () => {
6107
- iframe.remove();
6608
+ sizer.remove();
6108
6609
  ctx.container.innerHTML = "";
6109
6610
  };
6110
6611
  ctx.signal.addEventListener("abort", cleanup);
@@ -6112,20 +6613,26 @@ var HtmlPreviewPlugin = class {
6112
6613
  destroy: cleanup,
6113
6614
  zoomIn: () => {
6114
6615
  scale += 0.1;
6115
- iframe.style.transform = `scale(${scale})`;
6616
+ applyTransform();
6116
6617
  },
6117
6618
  zoomOut: () => {
6118
6619
  scale = Math.max(0.2, scale - 0.1);
6119
- iframe.style.transform = `scale(${scale})`;
6620
+ applyTransform();
6120
6621
  },
6121
6622
  getZoom: () => scale,
6122
6623
  setZoom: (level) => {
6123
6624
  scale = level;
6124
- iframe.style.transform = `scale(${scale})`;
6625
+ applyTransform();
6125
6626
  },
6126
6627
  fitToPage: () => {
6127
6628
  scale = 1;
6128
- iframe.style.transform = "scale(1)";
6629
+ applyTransform();
6630
+ },
6631
+ resetZoom: () => {
6632
+ scale = 1;
6633
+ ctx.container.scrollTop = 0;
6634
+ ctx.container.scrollLeft = 0;
6635
+ applyTransform();
6129
6636
  },
6130
6637
  copy: () => {
6131
6638
  navigator.clipboard.writeText(rawHtml);
@@ -6227,6 +6734,14 @@ var OpenDocumentPlugin = class {
6227
6734
  group: "zoom",
6228
6735
  execute: () => instance.fitToPage?.()
6229
6736
  },
6737
+ {
6738
+ id: "reset-zoom",
6739
+ icon: "reset-zoom",
6740
+ label: "Reset Zoom",
6741
+ type: "button",
6742
+ group: "zoom",
6743
+ execute: () => instance.resetZoom?.()
6744
+ },
6230
6745
  {
6231
6746
  id: "rotate-cw",
6232
6747
  icon: "rotate-cw",
@@ -6292,10 +6807,26 @@ var OpenDocumentPlugin = class {
6292
6807
  container.className = "fp-odf-container";
6293
6808
  container.style.width = "100%";
6294
6809
  container.style.height = "100%";
6295
- container.style.overflowX = "hidden";
6296
- container.style.overflowY = "auto";
6297
- container.style.padding = "16px 8px";
6810
+ container.style.overflow = "auto";
6298
6811
  container.style.backgroundColor = "#f1f5f9";
6812
+ const scrollWrapper = document.createElement("div");
6813
+ scrollWrapper.className = "fp-odf-scroll-wrapper";
6814
+ scrollWrapper.style.minWidth = "100%";
6815
+ scrollWrapper.style.minHeight = "100%";
6816
+ scrollWrapper.style.width = "max-content";
6817
+ scrollWrapper.style.height = "max-content";
6818
+ scrollWrapper.style.display = "flex";
6819
+ scrollWrapper.style.justifyContent = "center";
6820
+ scrollWrapper.style.alignItems = "flex-start";
6821
+ scrollWrapper.style.padding = "16px 8px";
6822
+ scrollWrapper.style.boxSizing = "border-box";
6823
+ const sizer = document.createElement("div");
6824
+ sizer.className = "fp-odf-sizer";
6825
+ sizer.style.position = "relative";
6826
+ sizer.style.flexShrink = "0";
6827
+ sizer.style.display = "flex";
6828
+ sizer.style.justifyContent = "center";
6829
+ sizer.style.alignItems = "center";
6299
6830
  const wrapper = document.createElement("div");
6300
6831
  wrapper.className = "fp-odf-wrapper";
6301
6832
  wrapper.style.margin = "0 auto";
@@ -6304,9 +6835,12 @@ var OpenDocumentPlugin = class {
6304
6835
  wrapper.style.backgroundColor = "#ffffff";
6305
6836
  wrapper.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
6306
6837
  wrapper.style.borderRadius = "4px";
6307
- wrapper.style.transformOrigin = "top center";
6838
+ wrapper.style.transformOrigin = "center center";
6308
6839
  wrapper.style.transition = "transform 0.15s ease";
6309
- container.appendChild(wrapper);
6840
+ wrapper.style.flexShrink = "0";
6841
+ sizer.appendChild(wrapper);
6842
+ scrollWrapper.appendChild(sizer);
6843
+ container.appendChild(scrollWrapper);
6310
6844
  ctx.container.appendChild(container);
6311
6845
  let scale = 1;
6312
6846
  let rotation = 0;
@@ -6332,13 +6866,18 @@ var OpenDocumentPlugin = class {
6332
6866
  return Math.max(0.4, Math.min(3, sW));
6333
6867
  };
6334
6868
  const applyTransform = () => {
6335
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6336
- wrapper.style.transformOrigin = "top center";
6337
6869
  const activeSlide = slides[currentPage - 1];
6870
+ const elW = isPresentation ? 960 : 816;
6338
6871
  const baseH = activeSlide?.offsetHeight || wrapper.offsetHeight || 1056;
6339
- const scaledH = baseH * scale;
6340
- const extraH = Math.max(0, scaledH - baseH);
6341
- wrapper.style.marginBottom = `${extraH + 32}px`;
6872
+ const isRotated90 = rotation % 180 !== 0;
6873
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6874
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6875
+ sizer.style.width = `${boxW}px`;
6876
+ sizer.style.height = `${boxH}px`;
6877
+ wrapper.style.width = `${elW}px`;
6878
+ wrapper.style.height = `${baseH}px`;
6879
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6880
+ wrapper.style.transformOrigin = "center center";
6342
6881
  };
6343
6882
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
6344
6883
  if (!isUserZoomed) {
@@ -6494,6 +7033,15 @@ var OpenDocumentPlugin = class {
6494
7033
  rotation = 0;
6495
7034
  applyTransform();
6496
7035
  },
7036
+ resetZoom: () => {
7037
+ isUserZoomed = false;
7038
+ fitMode = "width";
7039
+ scale = calculateFitScale("width");
7040
+ rotation = 0;
7041
+ container.scrollTop = 0;
7042
+ container.scrollLeft = 0;
7043
+ applyTransform();
7044
+ },
6497
7045
  rotateCW: () => {
6498
7046
  rotation = (rotation + 90) % 360;
6499
7047
  applyTransform();
@@ -6837,6 +7385,14 @@ var DocPlugin = class {
6837
7385
  group: "zoom",
6838
7386
  execute: () => instance.fitToPage?.()
6839
7387
  },
7388
+ {
7389
+ id: "reset-zoom",
7390
+ icon: "reset-zoom",
7391
+ label: "Reset Zoom",
7392
+ type: "button",
7393
+ group: "zoom",
7394
+ execute: () => instance.resetZoom?.()
7395
+ },
6840
7396
  {
6841
7397
  id: "rotate-cw",
6842
7398
  icon: "rotate-cw",
@@ -6885,13 +7441,28 @@ var DocPlugin = class {
6885
7441
  container.className = "fp-doc-container";
6886
7442
  container.style.width = "100%";
6887
7443
  container.style.height = "100%";
6888
- container.style.overflowX = "hidden";
6889
- container.style.overflowY = "auto";
6890
- container.style.padding = "16px 8px";
7444
+ container.style.overflow = "auto";
6891
7445
  container.style.backgroundColor = "#f1f5f9";
6892
- container.style.display = "flex";
6893
- container.style.justifyContent = "center";
6894
- container.style.alignItems = "flex-start";
7446
+ const scrollWrapper = document.createElement("div");
7447
+ scrollWrapper.className = "fp-doc-scroll-wrapper";
7448
+ scrollWrapper.style.minWidth = "100%";
7449
+ scrollWrapper.style.minHeight = "100%";
7450
+ scrollWrapper.style.width = "max-content";
7451
+ scrollWrapper.style.height = "max-content";
7452
+ scrollWrapper.style.display = "flex";
7453
+ scrollWrapper.style.justifyContent = "center";
7454
+ scrollWrapper.style.alignItems = "flex-start";
7455
+ scrollWrapper.style.padding = "16px 8px";
7456
+ scrollWrapper.style.boxSizing = "border-box";
7457
+ const sizer = document.createElement("div");
7458
+ sizer.className = "fp-doc-sizer";
7459
+ sizer.style.position = "relative";
7460
+ sizer.style.flexShrink = "0";
7461
+ sizer.style.display = "flex";
7462
+ sizer.style.justifyContent = "center";
7463
+ sizer.style.alignItems = "center";
7464
+ scrollWrapper.appendChild(sizer);
7465
+ container.appendChild(scrollWrapper);
6895
7466
  ctx.container.appendChild(container);
6896
7467
  let scale = 1;
6897
7468
  let extractedRawText = "";
@@ -6939,10 +7510,11 @@ var DocPlugin = class {
6939
7510
  pageCard.style.padding = "72px 56px";
6940
7511
  pageCard.style.boxSizing = "border-box";
6941
7512
  pageCard.style.display = i === 0 ? "block" : "none";
6942
- pageCard.style.transformOrigin = "top center";
7513
+ pageCard.style.transformOrigin = "center center";
6943
7514
  pageCard.style.transition = "transform 0.15s ease";
6944
7515
  pageCard.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
6945
7516
  pageCard.style.color = "#1e293b";
7517
+ pageCard.style.flexShrink = "0";
6946
7518
  if (isFallback && i === 0) {
6947
7519
  pageCard.innerHTML = `
6948
7520
  <div style="border-bottom: 1px solid #e2e8f0; padding-bottom: 12px; margin-bottom: 24px;">
@@ -6954,18 +7526,23 @@ var DocPlugin = class {
6954
7526
  } else {
6955
7527
  pageCard.innerHTML = this.formatDocToHtml(rawPages[i], ctx.metadata.name || "Document");
6956
7528
  }
6957
- container.appendChild(pageCard);
7529
+ sizer.appendChild(pageCard);
6958
7530
  pageCards.push(pageCard);
6959
7531
  }
6960
7532
  let rotation = 0;
6961
7533
  const applyTransform = () => {
6962
7534
  const activeCard = pageCards[currentPage - 1];
6963
7535
  if (activeCard) {
6964
- activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7536
+ const baseW = 816;
6965
7537
  const baseH = activeCard.offsetHeight || 1056;
6966
- const scaledH = baseH * scale;
6967
- const extraH = Math.max(0, scaledH - baseH);
6968
- activeCard.style.marginBottom = `${extraH + 32}px`;
7538
+ const isRotated90 = rotation % 180 !== 0;
7539
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * scale);
7540
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * scale);
7541
+ sizer.style.width = `${boxW}px`;
7542
+ sizer.style.height = `${boxH}px`;
7543
+ activeCard.style.width = `${baseW}px`;
7544
+ activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7545
+ activeCard.style.transformOrigin = "center center";
6969
7546
  }
6970
7547
  };
6971
7548
  const showPage = (pageNum) => {
@@ -6973,11 +7550,11 @@ var DocPlugin = class {
6973
7550
  pageCards.forEach((card, idx) => {
6974
7551
  if (idx + 1 === currentPage) {
6975
7552
  card.style.display = "block";
6976
- card.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6977
7553
  } else {
6978
7554
  card.style.display = "none";
6979
7555
  }
6980
7556
  });
7557
+ applyTransform();
6981
7558
  container.scrollTop = 0;
6982
7559
  ctx.emit("page-change", { page: currentPage, total: totalPages });
6983
7560
  };
@@ -7043,6 +7620,17 @@ var DocPlugin = class {
7043
7620
  rotation = 0;
7044
7621
  applyTransform();
7045
7622
  },
7623
+ resetZoom: () => {
7624
+ isUserZoomed = false;
7625
+ fitMode = "width";
7626
+ scale = calculateFitScale("width");
7627
+ rotation = 0;
7628
+ container.scrollTop = 0;
7629
+ container.scrollLeft = 0;
7630
+ ctx.container.scrollTop = 0;
7631
+ ctx.container.scrollLeft = 0;
7632
+ applyTransform();
7633
+ },
7046
7634
  rotateCW: () => {
7047
7635
  rotation = (rotation + 90) % 360;
7048
7636
  applyTransform();
@@ -7523,6 +8111,14 @@ var PptPlugin = class {
7523
8111
  group: "zoom",
7524
8112
  execute: () => instance.fitToPage?.()
7525
8113
  },
8114
+ {
8115
+ id: "reset-zoom",
8116
+ icon: "reset-zoom",
8117
+ label: "Reset Zoom",
8118
+ type: "button",
8119
+ group: "zoom",
8120
+ execute: () => instance.resetZoom?.()
8121
+ },
7526
8122
  {
7527
8123
  id: "rotate-cw",
7528
8124
  icon: "rotate-cw",
@@ -7555,17 +8151,30 @@ var PptPlugin = class {
7555
8151
  container.style.width = "100%";
7556
8152
  container.style.height = "100%";
7557
8153
  container.style.overflow = "auto";
7558
- container.style.display = "flex";
7559
- container.style.justifyContent = "center";
7560
- container.style.alignItems = "center";
7561
- container.style.padding = "32px 16px";
7562
8154
  container.style.backgroundColor = "#0f172a";
7563
8155
  container.style.boxSizing = "border-box";
8156
+ const scrollWrapper = document.createElement("div");
8157
+ scrollWrapper.className = "fp-ppt-scroll-wrapper";
8158
+ scrollWrapper.style.minWidth = "100%";
8159
+ scrollWrapper.style.minHeight = "100%";
8160
+ scrollWrapper.style.width = "max-content";
8161
+ scrollWrapper.style.height = "max-content";
8162
+ scrollWrapper.style.display = "flex";
8163
+ scrollWrapper.style.justifyContent = "center";
8164
+ scrollWrapper.style.alignItems = "center";
8165
+ scrollWrapper.style.padding = "32px 16px";
8166
+ scrollWrapper.style.boxSizing = "border-box";
8167
+ const sizer = document.createElement("div");
8168
+ sizer.className = "fp-ppt-sizer";
8169
+ sizer.style.position = "relative";
8170
+ sizer.style.flexShrink = "0";
8171
+ sizer.style.display = "flex";
8172
+ sizer.style.justifyContent = "center";
8173
+ sizer.style.alignItems = "center";
7564
8174
  const slideCard = document.createElement("div");
7565
8175
  slideCard.className = "fp-ppt-slide-card";
7566
8176
  slideCard.style.width = "960px";
7567
- slideCard.style.maxWidth = "calc(100% - 32px)";
7568
- slideCard.style.maxHeight = "calc(100% - 48px)";
8177
+ slideCard.style.height = "540px";
7569
8178
  slideCard.style.aspectRatio = "16 / 9";
7570
8179
  slideCard.style.backgroundColor = "#ffffff";
7571
8180
  slideCard.style.boxShadow = "0 12px 40px rgba(0,0,0,0.35)";
@@ -7575,7 +8184,9 @@ var PptPlugin = class {
7575
8184
  slideCard.style.transition = "transform 0.2s ease";
7576
8185
  slideCard.style.transformOrigin = "center center";
7577
8186
  slideCard.style.flexShrink = "0";
7578
- container.appendChild(slideCard);
8187
+ sizer.appendChild(slideCard);
8188
+ scrollWrapper.appendChild(sizer);
8189
+ container.appendChild(scrollWrapper);
7579
8190
  ctx.container.appendChild(container);
7580
8191
  let scale = 1;
7581
8192
  let rotation = 0;
@@ -7588,7 +8199,17 @@ var PptPlugin = class {
7588
8199
  return Math.min(1, Math.min(availW / 960, availH / 540));
7589
8200
  };
7590
8201
  const applyTransform = () => {
8202
+ const cW = 960;
8203
+ const cH = 540;
8204
+ const isRotated90 = rotation % 180 !== 0;
8205
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
8206
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
8207
+ sizer.style.width = `${boxW}px`;
8208
+ sizer.style.height = `${boxH}px`;
8209
+ slideCard.style.width = `${cW}px`;
8210
+ slideCard.style.height = `${cH}px`;
7591
8211
  slideCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
8212
+ slideCard.style.transformOrigin = "center center";
7592
8213
  };
7593
8214
  setTimeout(() => {
7594
8215
  scale = calculateFitScale();
@@ -7711,6 +8332,13 @@ var PptPlugin = class {
7711
8332
  rotation = 0;
7712
8333
  applyTransform();
7713
8334
  },
8335
+ resetZoom: () => {
8336
+ scale = calculateFitScale();
8337
+ rotation = 0;
8338
+ container.scrollTop = 0;
8339
+ container.scrollLeft = 0;
8340
+ applyTransform();
8341
+ },
7714
8342
  rotateCW: () => {
7715
8343
  rotation = (rotation + 90) % 360;
7716
8344
  applyTransform();