@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/vue.cjs CHANGED
@@ -528,6 +528,7 @@ var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" str
528
528
  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>`;
529
529
  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>`;
530
530
  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>`;
531
+ 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>`;
531
532
  var ICON_MAP = {
532
533
  "zoom-in": ICON_ZOOM_IN,
533
534
  "zoom-out": ICON_ZOOM_OUT,
@@ -557,7 +558,10 @@ var ICON_MAP = {
557
558
  "open-window": ICON_EXTERNAL_WINDOW,
558
559
  "external-window": ICON_EXTERNAL_WINDOW,
559
560
  "openWindow": ICON_EXTERNAL_WINDOW,
560
- "openSeparateWindow": ICON_EXTERNAL_WINDOW
561
+ "openSeparateWindow": ICON_EXTERNAL_WINDOW,
562
+ "reset-zoom": ICON_RESET_ZOOM,
563
+ "zoom-reset": ICON_RESET_ZOOM,
564
+ "resetZoom": ICON_RESET_ZOOM
561
565
  };
562
566
  var ToolbarController = class {
563
567
  el;
@@ -590,6 +594,10 @@ var ToolbarController = class {
590
594
  this.config.fitToPage = false;
591
595
  this.config.fitWidth = false;
592
596
  }
597
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
598
+ this.config.resetZoom = false;
599
+ this.config.zoomReset = false;
600
+ }
593
601
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = false;
594
602
  if (actionId === "fullscreen") this.config.fullscreen = false;
595
603
  if (actionId === "download") this.config.download = false;
@@ -614,6 +622,10 @@ var ToolbarController = class {
614
622
  this.config.fitToPage = true;
615
623
  this.config.fitWidth = true;
616
624
  }
625
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
626
+ this.config.resetZoom = true;
627
+ this.config.zoomReset = true;
628
+ }
617
629
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = true;
618
630
  if (actionId === "fullscreen") this.config.fullscreen = true;
619
631
  if (actionId === "download") this.config.download = true;
@@ -633,6 +645,7 @@ var ToolbarController = class {
633
645
  if (actionId === "zoomIn") return "zoom-in";
634
646
  if (actionId === "zoomOut") return "zoom-out";
635
647
  if (actionId === "fitPage" || actionId === "fitToPage" || actionId === "fitWidth") return "fit-page";
648
+ if (actionId === "resetZoom" || actionId === "zoomReset") return "reset-zoom";
636
649
  if (actionId === "rotateCW") return "rotate-cw";
637
650
  if (actionId === "rotateCCW") return "rotate-ccw";
638
651
  if (actionId === "openWindow" || actionId === "openSeparateWindow") return "open-window";
@@ -675,6 +688,9 @@ var ToolbarController = class {
675
688
  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)) {
676
689
  return false;
677
690
  }
691
+ if ((id === "reset-zoom" || id === "zoom-reset") && (c.resetZoom === false || c.zoomReset === false || c["reset-zoom"] === false || c["zoom-reset"] === false)) {
692
+ return false;
693
+ }
678
694
  if ((id === "rotate-cw" || id === "rotate-ccw" || id === "rotate") && (c.rotate === false || c.rotateCW === false || c.rotateCCW === false || c["rotate-cw"] === false)) {
679
695
  return false;
680
696
  }
@@ -1121,6 +1137,9 @@ var FilePreviewViewer = class _FilePreviewViewer {
1121
1137
  this.activeInstance = instance;
1122
1138
  instance.openInSeparateWindow = () => this.openInSeparateWindow();
1123
1139
  instance.toggleThumbnails = () => this.toggleThumbnails();
1140
+ if (!instance.resetZoom && instance.fitToPage) {
1141
+ instance.resetZoom = () => instance.fitToPage?.();
1142
+ }
1124
1143
  this.hideLoading();
1125
1144
  this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
1126
1145
  const isToolbarVisible = options.showToolbar !== false && options.toolbar !== false;
@@ -1404,6 +1423,16 @@ var FilePreviewViewer = class _FilePreviewViewer {
1404
1423
  fitToPage() {
1405
1424
  this.activeInstance?.fitToPage?.();
1406
1425
  }
1426
+ /**
1427
+ * Reset zoom level to initial/default fit state.
1428
+ */
1429
+ resetZoom() {
1430
+ if (this.activeInstance?.resetZoom) {
1431
+ this.activeInstance.resetZoom();
1432
+ } else if (this.activeInstance?.fitToPage) {
1433
+ this.activeInstance.fitToPage();
1434
+ }
1435
+ }
1407
1436
  /**
1408
1437
  * Zoom in.
1409
1438
  */
@@ -2025,6 +2054,14 @@ var PdfPlugin = class {
2025
2054
  group: "zoom",
2026
2055
  execute: () => instance.fitToPage?.()
2027
2056
  },
2057
+ {
2058
+ id: "reset-zoom",
2059
+ icon: "reset-zoom",
2060
+ label: "Reset Zoom",
2061
+ type: "button",
2062
+ group: "zoom",
2063
+ execute: () => instance.resetZoom?.()
2064
+ },
2028
2065
  {
2029
2066
  id: "fit-width",
2030
2067
  icon: "fit-width",
@@ -2080,16 +2117,22 @@ var PdfPlugin = class {
2080
2117
  container.className = "fp-pdf-container";
2081
2118
  container.style.width = "100%";
2082
2119
  container.style.height = "100%";
2083
- container.style.overflowX = "hidden";
2084
- container.style.overflowY = "auto";
2085
- container.style.display = "flex";
2086
- container.style.flexDirection = "column";
2087
- container.style.alignItems = "center";
2088
- container.style.justifyContent = "flex-start";
2089
- container.style.padding = "16px 8px";
2120
+ container.style.overflow = "auto";
2090
2121
  container.style.backgroundColor = "#0f172a";
2091
2122
  container.style.boxSizing = "border-box";
2092
2123
  container.style.position = "relative";
2124
+ const scrollWrapper = document.createElement("div");
2125
+ scrollWrapper.className = "fp-pdf-scroll-wrapper";
2126
+ scrollWrapper.style.minWidth = "100%";
2127
+ scrollWrapper.style.minHeight = "100%";
2128
+ scrollWrapper.style.width = "max-content";
2129
+ scrollWrapper.style.height = "max-content";
2130
+ scrollWrapper.style.display = "flex";
2131
+ scrollWrapper.style.flexDirection = "column";
2132
+ scrollWrapper.style.alignItems = "center";
2133
+ scrollWrapper.style.justifyContent = "flex-start";
2134
+ scrollWrapper.style.padding = "16px 8px";
2135
+ scrollWrapper.style.boxSizing = "border-box";
2093
2136
  const pageCard = document.createElement("div");
2094
2137
  pageCard.className = "fp-pdf-page-card";
2095
2138
  pageCard.style.boxShadow = "0 10px 35px rgba(0, 0, 0, 0.5)";
@@ -2102,7 +2145,8 @@ var PdfPlugin = class {
2102
2145
  pageCard.style.transition = "box-shadow 0.2s ease";
2103
2146
  let canvas = document.createElement("canvas");
2104
2147
  pageCard.appendChild(canvas);
2105
- container.appendChild(pageCard);
2148
+ scrollWrapper.appendChild(pageCard);
2149
+ container.appendChild(scrollWrapper);
2106
2150
  ctx.container.appendChild(container);
2107
2151
  const standardFontsUrl = typeof window !== "undefined" && window.__PDF_STANDARD_FONTS_URL__ || "./standard_fonts/";
2108
2152
  const cmapsUrl = typeof window !== "undefined" && window.__PDF_CMAPS_URL__ || "./cmaps/";
@@ -2287,6 +2331,14 @@ var PdfPlugin = class {
2287
2331
  zoomScale = 1;
2288
2332
  renderPage(currentPage);
2289
2333
  },
2334
+ resetZoom: () => {
2335
+ fitMode = "page";
2336
+ zoomScale = 1;
2337
+ rotation = 0;
2338
+ container.scrollTop = 0;
2339
+ container.scrollLeft = 0;
2340
+ renderPage(currentPage);
2341
+ },
2290
2342
  fitToWidth: () => {
2291
2343
  fitMode = "width";
2292
2344
  zoomScale = 1;
@@ -2454,6 +2506,16 @@ var MediaPlugin = class {
2454
2506
  instance.fitToPage?.();
2455
2507
  }
2456
2508
  },
2509
+ {
2510
+ id: "reset-zoom",
2511
+ icon: "reset-zoom",
2512
+ label: "Reset Zoom",
2513
+ type: "button",
2514
+ group: "zoom",
2515
+ execute: () => {
2516
+ instance.resetZoom?.();
2517
+ }
2518
+ },
2457
2519
  {
2458
2520
  id: "rotate-cw",
2459
2521
  icon: "rotate-cw",
@@ -2593,17 +2655,86 @@ var MediaPlugin = class {
2593
2655
  element = document.createElement("div");
2594
2656
  element.textContent = "Unsupported media type";
2595
2657
  }
2596
- ctx.container.style.display = "flex";
2597
- ctx.container.style.alignItems = "center";
2598
- ctx.container.style.justifyContent = "center";
2599
- ctx.container.style.overflow = "hidden";
2600
- ctx.container.appendChild(element);
2658
+ const scrollWrapper = document.createElement("div");
2659
+ scrollWrapper.className = "fp-media-scroll-wrapper";
2660
+ scrollWrapper.style.minWidth = "100%";
2661
+ scrollWrapper.style.minHeight = "100%";
2662
+ scrollWrapper.style.width = "max-content";
2663
+ scrollWrapper.style.height = "max-content";
2664
+ scrollWrapper.style.display = "flex";
2665
+ scrollWrapper.style.justifyContent = "center";
2666
+ scrollWrapper.style.alignItems = "center";
2667
+ scrollWrapper.style.padding = "16px";
2668
+ scrollWrapper.style.boxSizing = "border-box";
2669
+ const sizer = document.createElement("div");
2670
+ sizer.className = "fp-media-sizer";
2671
+ sizer.style.position = "relative";
2672
+ sizer.style.flexShrink = "0";
2673
+ sizer.style.display = "flex";
2674
+ sizer.style.justifyContent = "center";
2675
+ sizer.style.alignItems = "center";
2676
+ sizer.appendChild(element);
2677
+ scrollWrapper.appendChild(sizer);
2678
+ ctx.container.style.overflow = "auto";
2679
+ ctx.container.style.padding = "0";
2680
+ ctx.container.innerHTML = "";
2681
+ ctx.container.appendChild(scrollWrapper);
2682
+ let naturalW = 800;
2683
+ let naturalH = 600;
2684
+ let baseW = 800;
2685
+ let baseH = 600;
2686
+ const updateBaseDimensions = () => {
2687
+ if (!isImage) return;
2688
+ const img = element;
2689
+ naturalW = img.naturalWidth || naturalW;
2690
+ naturalH = img.naturalHeight || naturalH;
2691
+ const availW = Math.max(100, ctx.container.clientWidth - 48);
2692
+ const availH = Math.max(100, ctx.container.clientHeight - 48);
2693
+ const fitRatio = Math.min(1, availW / naturalW, availH / naturalH);
2694
+ baseW = Math.max(1, Math.round(naturalW * fitRatio));
2695
+ baseH = Math.max(1, Math.round(naturalH * fitRatio));
2696
+ };
2601
2697
  const applyTransform = () => {
2602
- element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2698
+ if (isImage) {
2699
+ updateBaseDimensions();
2700
+ const isRotated90 = rotation % 180 !== 0;
2701
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * currentZoom);
2702
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * currentZoom);
2703
+ sizer.style.width = `${boxW}px`;
2704
+ sizer.style.height = `${boxH}px`;
2705
+ element.style.width = `${baseW}px`;
2706
+ element.style.height = `${baseH}px`;
2707
+ element.style.maxWidth = "none";
2708
+ element.style.maxHeight = "none";
2709
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2710
+ element.style.transformOrigin = "center center";
2711
+ element.style.flexShrink = "0";
2712
+ } else {
2713
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2714
+ }
2603
2715
  };
2716
+ if (isImage) {
2717
+ const img = element;
2718
+ if (img.complete && img.naturalWidth > 0) {
2719
+ updateBaseDimensions();
2720
+ applyTransform();
2721
+ } else {
2722
+ img.onload = () => {
2723
+ updateBaseDimensions();
2724
+ applyTransform();
2725
+ };
2726
+ }
2727
+ }
2728
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
2729
+ if (currentZoom === 1) {
2730
+ applyTransform();
2731
+ }
2732
+ }) : null;
2733
+ ro?.observe(ctx.container);
2604
2734
  const cleanup = () => {
2735
+ ro?.disconnect();
2605
2736
  if (url) URL.revokeObjectURL(url);
2606
- element.remove();
2737
+ scrollWrapper.remove();
2607
2738
  ctx.container.innerHTML = "";
2608
2739
  };
2609
2740
  ctx.signal.addEventListener("abort", cleanup);
@@ -2627,6 +2758,13 @@ var MediaPlugin = class {
2627
2758
  rotation = 0;
2628
2759
  applyTransform();
2629
2760
  } : void 0,
2761
+ resetZoom: isImage ? () => {
2762
+ currentZoom = 1;
2763
+ rotation = 0;
2764
+ ctx.container.scrollTop = 0;
2765
+ ctx.container.scrollLeft = 0;
2766
+ applyTransform();
2767
+ } : void 0,
2630
2768
  rotateCW: isImage || isVideo ? () => {
2631
2769
  rotation = (rotation + 90) % 360;
2632
2770
  applyTransform();
@@ -2743,6 +2881,14 @@ var DocxPlugin = class {
2743
2881
  group: "zoom",
2744
2882
  execute: () => instance.fitToPage?.()
2745
2883
  },
2884
+ {
2885
+ id: "reset-zoom",
2886
+ icon: "reset-zoom",
2887
+ label: "Reset Zoom",
2888
+ type: "button",
2889
+ group: "zoom",
2890
+ execute: () => instance.resetZoom?.()
2891
+ },
2746
2892
  {
2747
2893
  id: "rotate-cw",
2748
2894
  icon: "rotate-cw",
@@ -2781,7 +2927,7 @@ var DocxPlugin = class {
2781
2927
  async render(ctx) {
2782
2928
  const wrapper = document.createElement("div");
2783
2929
  wrapper.className = "fp-docx-wrapper";
2784
- wrapper.style.transformOrigin = "top center";
2930
+ wrapper.style.transformOrigin = "center center";
2785
2931
  wrapper.style.transition = "transform 0.2s ease";
2786
2932
  wrapper.style.padding = "0";
2787
2933
  wrapper.style.maxWidth = "none";
@@ -2791,11 +2937,31 @@ var DocxPlugin = class {
2791
2937
  wrapper.style.flexDirection = "column";
2792
2938
  wrapper.style.alignItems = "center";
2793
2939
  wrapper.style.boxSizing = "border-box";
2794
- ctx.container.style.overflowX = "hidden";
2795
- ctx.container.style.overflowY = "auto";
2796
- ctx.container.style.padding = "16px 8px";
2940
+ wrapper.style.flexShrink = "0";
2941
+ const sizer = document.createElement("div");
2942
+ sizer.className = "fp-docx-sizer";
2943
+ sizer.style.position = "relative";
2944
+ sizer.style.flexShrink = "0";
2945
+ sizer.style.display = "flex";
2946
+ sizer.style.justifyContent = "center";
2947
+ sizer.style.alignItems = "center";
2948
+ const scrollWrapper = document.createElement("div");
2949
+ scrollWrapper.className = "fp-docx-scroll-wrapper";
2950
+ scrollWrapper.style.minWidth = "100%";
2951
+ scrollWrapper.style.minHeight = "100%";
2952
+ scrollWrapper.style.width = "max-content";
2953
+ scrollWrapper.style.height = "max-content";
2954
+ scrollWrapper.style.display = "flex";
2955
+ scrollWrapper.style.justifyContent = "center";
2956
+ scrollWrapper.style.alignItems = "flex-start";
2957
+ scrollWrapper.style.padding = "16px 8px";
2958
+ scrollWrapper.style.boxSizing = "border-box";
2959
+ sizer.appendChild(wrapper);
2960
+ scrollWrapper.appendChild(sizer);
2961
+ ctx.container.style.overflow = "auto";
2962
+ ctx.container.style.padding = "0";
2797
2963
  ctx.container.style.backgroundColor = "#f1f5f9";
2798
- ctx.container.appendChild(wrapper);
2964
+ ctx.container.appendChild(scrollWrapper);
2799
2965
  const styleOverride = document.createElement("style");
2800
2966
  styleOverride.textContent = `
2801
2967
  .fp-docx-wrapper .docx-wrapper {
@@ -2834,8 +3000,8 @@ var DocxPlugin = class {
2834
3000
  renderEndnotes: true,
2835
3001
  useBase64URL: true
2836
3002
  });
2837
- if (!ctx.container.contains(wrapper)) {
2838
- ctx.container.appendChild(wrapper);
3003
+ if (!sizer.contains(wrapper)) {
3004
+ sizer.appendChild(wrapper);
2839
3005
  }
2840
3006
  if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
2841
3007
  renderedSuccessfully = true;
@@ -2872,8 +3038,8 @@ var DocxPlugin = class {
2872
3038
  try {
2873
3039
  wrapper.innerHTML = "";
2874
3040
  this.renderXmlFallback(ctx, wrapper, createdBlobUrls);
2875
- if (!ctx.container.contains(wrapper)) {
2876
- ctx.container.appendChild(wrapper);
3041
+ if (!sizer.contains(wrapper)) {
3042
+ sizer.appendChild(wrapper);
2877
3043
  }
2878
3044
  renderedSuccessfully = true;
2879
3045
  } catch (fallbackErr) {
@@ -2888,8 +3054,8 @@ var DocxPlugin = class {
2888
3054
  </p>
2889
3055
  </div>
2890
3056
  `;
2891
- if (!ctx.container.contains(wrapper)) {
2892
- ctx.container.appendChild(wrapper);
3057
+ if (!sizer.contains(wrapper)) {
3058
+ sizer.appendChild(wrapper);
2893
3059
  }
2894
3060
  }
2895
3061
  }
@@ -2992,15 +3158,18 @@ var DocxPlugin = class {
2992
3158
  return Math.max(0.35, Math.min(3, sW));
2993
3159
  };
2994
3160
  const applyTransform = () => {
2995
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
2996
- wrapper.style.transformOrigin = "top center";
2997
3161
  const activeEl = pageElements[currentPage - 1] || wrapper.querySelector("section.docx") || wrapper;
3162
+ const elW = activeEl.offsetWidth || 816;
2998
3163
  const elH = activeEl.offsetHeight || 1056;
2999
- if (scale > 1) {
3000
- wrapper.style.marginBottom = `${Math.round(elH * scale - elH + 32)}px`;
3001
- } else {
3002
- wrapper.style.marginBottom = "32px";
3003
- }
3164
+ const isRotated90 = rotation % 180 !== 0;
3165
+ const boxW = Math.round((isRotated90 ? elH : elW) * scale);
3166
+ const boxH = Math.round((isRotated90 ? elW : elH) * scale);
3167
+ sizer.style.width = `${boxW}px`;
3168
+ sizer.style.height = `${boxH}px`;
3169
+ wrapper.style.width = `${elW}px`;
3170
+ wrapper.style.height = `${elH}px`;
3171
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
3172
+ wrapper.style.transformOrigin = "center center";
3004
3173
  };
3005
3174
  let resizeObserver = null;
3006
3175
  if (typeof ResizeObserver !== "undefined") {
@@ -3025,7 +3194,7 @@ var DocxPlugin = class {
3025
3194
  for (const url of createdBlobUrls) {
3026
3195
  URL.revokeObjectURL(url);
3027
3196
  }
3028
- wrapper.remove();
3197
+ scrollWrapper.remove();
3029
3198
  styleOverride.remove();
3030
3199
  ctx.container.innerHTML = "";
3031
3200
  };
@@ -3059,6 +3228,14 @@ var DocxPlugin = class {
3059
3228
  rotation = 0;
3060
3229
  applyTransform();
3061
3230
  },
3231
+ resetZoom: () => {
3232
+ isUserZoomed = false;
3233
+ scale = calculateFitScale("page");
3234
+ rotation = 0;
3235
+ ctx.container.scrollTop = 0;
3236
+ ctx.container.scrollLeft = 0;
3237
+ applyTransform();
3238
+ },
3062
3239
  rotateCW: () => {
3063
3240
  rotation = (rotation + 90) % 360;
3064
3241
  applyTransform();
@@ -3508,6 +3685,16 @@ var ExcelPlugin = class {
3508
3685
  instance.zoomIn?.();
3509
3686
  }
3510
3687
  },
3688
+ {
3689
+ id: "reset-zoom",
3690
+ icon: "reset-zoom",
3691
+ label: "Reset Zoom",
3692
+ type: "button",
3693
+ group: "zoom",
3694
+ execute: () => {
3695
+ instance.resetZoom?.();
3696
+ }
3697
+ },
3511
3698
  {
3512
3699
  id: "download",
3513
3700
  icon: "download",
@@ -3554,7 +3741,7 @@ var ExcelPlugin = class {
3554
3741
  contentArea.style.flex = "1";
3555
3742
  contentArea.style.overflow = "auto";
3556
3743
  contentArea.style.padding = "16px";
3557
- contentArea.style.transformOrigin = "top left";
3744
+ contentArea.style.boxSizing = "border-box";
3558
3745
  const tabsArea = document.createElement("div");
3559
3746
  tabsArea.className = "fp-excel-tabs";
3560
3747
  tabsArea.style.display = "flex";
@@ -3568,18 +3755,35 @@ var ExcelPlugin = class {
3568
3755
  container.appendChild(tabsArea);
3569
3756
  ctx.container.appendChild(container);
3570
3757
  let scale = 1;
3758
+ let isUserZoomed = false;
3571
3759
  let currentSheetIndex = 1;
3572
3760
  let sheetNames = [];
3573
3761
  let wb = null;
3574
3762
  const applyTransform = () => {
3575
- contentArea.style.transform = `scale(${scale})`;
3576
- contentArea.style.transformOrigin = "top left";
3763
+ const sizer = contentArea.querySelector(".fp-excel-sizer");
3764
+ const table = contentArea.querySelector("table");
3765
+ if (!sizer || !table) return;
3766
+ if (!table._baseWidth && table.offsetWidth > 0) {
3767
+ table._baseWidth = table.offsetWidth;
3768
+ table._baseHeight = table.offsetHeight;
3769
+ }
3770
+ const baseW = table._baseWidth || table.offsetWidth || 800;
3771
+ const baseH = table._baseHeight || table.offsetHeight || 600;
3772
+ const scaledW = Math.round(baseW * scale);
3773
+ const scaledH = Math.round(baseH * scale);
3774
+ sizer.style.width = `${scaledW}px`;
3775
+ sizer.style.height = `${scaledH}px`;
3776
+ table.style.position = "absolute";
3777
+ table.style.top = "0";
3778
+ table.style.left = "0";
3779
+ table.style.transform = `scale(${scale})`;
3780
+ table.style.transformOrigin = "top left";
3577
3781
  };
3578
3782
  const calculateFitScale = () => {
3579
3783
  const table = contentArea.querySelector("table");
3580
3784
  if (!table) return 1;
3581
3785
  const availW = Math.max(280, container.clientWidth - 48);
3582
- const tW = table.offsetWidth || 800;
3786
+ const tW = table._baseWidth || table.offsetWidth || 800;
3583
3787
  return Math.max(0.4, Math.min(1, availW / tW));
3584
3788
  };
3585
3789
  try {
@@ -3599,9 +3803,13 @@ var ExcelPlugin = class {
3599
3803
  contentArea.innerHTML = '<div style="padding: 24px; color: #888;">Empty sheet</div>';
3600
3804
  return;
3601
3805
  }
3806
+ const sizer = document.createElement("div");
3807
+ sizer.className = "fp-excel-sizer";
3808
+ sizer.style.position = "relative";
3602
3809
  const html = XLSX__namespace.utils.sheet_to_html(ws, { id: "fp-sheet-table", editable: false });
3603
- contentArea.innerHTML = html;
3604
- const table = contentArea.querySelector("table");
3810
+ sizer.innerHTML = html;
3811
+ contentArea.appendChild(sizer);
3812
+ const table = sizer.querySelector("table");
3605
3813
  if (table) {
3606
3814
  table.style.borderCollapse = "collapse";
3607
3815
  table.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
@@ -3636,13 +3844,17 @@ var ExcelPlugin = class {
3636
3844
  });
3637
3845
  ctx.emit("page-change", { page: currentSheetIndex, total: sheetNames.length });
3638
3846
  requestAnimationFrame(() => {
3639
- scale = calculateFitScale();
3847
+ if (!isUserZoomed) {
3848
+ scale = calculateFitScale();
3849
+ }
3640
3850
  applyTransform();
3641
3851
  });
3642
3852
  };
3643
3853
  const ro = new ResizeObserver(() => {
3644
- scale = calculateFitScale();
3645
- applyTransform();
3854
+ if (!isUserZoomed) {
3855
+ scale = calculateFitScale();
3856
+ applyTransform();
3857
+ }
3646
3858
  });
3647
3859
  ro.observe(container);
3648
3860
  if (sheetNames.length > 0) {
@@ -3679,20 +3891,31 @@ var ExcelPlugin = class {
3679
3891
  return {
3680
3892
  destroy: cleanup,
3681
3893
  zoomIn: () => {
3894
+ isUserZoomed = true;
3682
3895
  scale += 0.15;
3683
3896
  applyTransform();
3684
3897
  },
3685
3898
  zoomOut: () => {
3899
+ isUserZoomed = true;
3686
3900
  scale = Math.max(0.2, scale - 0.15);
3687
3901
  applyTransform();
3688
3902
  },
3689
3903
  getZoom: () => scale,
3690
3904
  setZoom: (level) => {
3905
+ isUserZoomed = true;
3691
3906
  scale = level;
3692
3907
  applyTransform();
3693
3908
  },
3694
3909
  fitToPage: () => {
3910
+ isUserZoomed = false;
3911
+ scale = calculateFitScale();
3912
+ applyTransform();
3913
+ },
3914
+ resetZoom: () => {
3915
+ isUserZoomed = false;
3695
3916
  scale = calculateFitScale();
3917
+ contentArea.scrollTop = 0;
3918
+ contentArea.scrollLeft = 0;
3696
3919
  applyTransform();
3697
3920
  },
3698
3921
  rotateCW: () => {
@@ -3825,6 +4048,16 @@ var CsvPlugin = class {
3825
4048
  instance.zoomIn?.();
3826
4049
  }
3827
4050
  },
4051
+ {
4052
+ id: "reset-zoom",
4053
+ icon: "reset-zoom",
4054
+ label: "Reset Zoom",
4055
+ type: "button",
4056
+ group: "zoom",
4057
+ execute: () => {
4058
+ instance.resetZoom?.();
4059
+ }
4060
+ },
3828
4061
  {
3829
4062
  id: "download",
3830
4063
  icon: "download",
@@ -3911,21 +4144,41 @@ var CsvPlugin = class {
3911
4144
  container.appendChild(tableWrapper);
3912
4145
  ctx.container.appendChild(container);
3913
4146
  let scale = 1;
4147
+ let isUserZoomed = false;
3914
4148
  const calculateFitScale = () => {
3915
4149
  const availW = Math.max(280, container.clientWidth - 48);
3916
- const tW = table.offsetWidth || 800;
4150
+ const tW = table._baseWidth || table.offsetWidth || 800;
3917
4151
  return Math.max(0.4, Math.min(1, availW / tW));
3918
4152
  };
3919
4153
  const applyScale = () => {
3920
- tableWrapper.style.transform = `scale(${scale})`;
4154
+ if (!table._baseWidth && table.offsetWidth > 0) {
4155
+ table._baseWidth = table.offsetWidth;
4156
+ table._baseHeight = table.offsetHeight;
4157
+ }
4158
+ const baseW = table._baseWidth || table.offsetWidth || 800;
4159
+ const baseH = table._baseHeight || table.offsetHeight || 600;
4160
+ const scaledW = Math.round(baseW * scale);
4161
+ const scaledH = Math.round(baseH * scale);
4162
+ tableWrapper.style.position = "relative";
4163
+ tableWrapper.style.width = `${scaledW}px`;
4164
+ tableWrapper.style.height = `${scaledH}px`;
4165
+ table.style.position = "absolute";
4166
+ table.style.top = "0";
4167
+ table.style.left = "0";
4168
+ table.style.transform = `scale(${scale})`;
4169
+ table.style.transformOrigin = "top left";
3921
4170
  };
3922
4171
  requestAnimationFrame(() => {
3923
- scale = calculateFitScale();
4172
+ if (!isUserZoomed) {
4173
+ scale = calculateFitScale();
4174
+ }
3924
4175
  applyScale();
3925
4176
  });
3926
4177
  const ro = new ResizeObserver(() => {
3927
- scale = calculateFitScale();
3928
- applyScale();
4178
+ if (!isUserZoomed) {
4179
+ scale = calculateFitScale();
4180
+ applyScale();
4181
+ }
3929
4182
  });
3930
4183
  ro.observe(container);
3931
4184
  const cleanup = () => {
@@ -3998,20 +4251,31 @@ var CsvPlugin = class {
3998
4251
  }];
3999
4252
  },
4000
4253
  zoomIn: () => {
4254
+ isUserZoomed = true;
4001
4255
  scale += 0.1;
4002
4256
  applyScale();
4003
4257
  },
4004
4258
  zoomOut: () => {
4259
+ isUserZoomed = true;
4005
4260
  scale = Math.max(0.2, scale - 0.1);
4006
4261
  applyScale();
4007
4262
  },
4008
4263
  getZoom: () => scale,
4009
4264
  setZoom: (level) => {
4265
+ isUserZoomed = true;
4010
4266
  scale = level;
4011
4267
  applyScale();
4012
4268
  },
4013
4269
  fitToPage: () => {
4270
+ isUserZoomed = false;
4271
+ scale = calculateFitScale();
4272
+ applyScale();
4273
+ },
4274
+ resetZoom: () => {
4275
+ isUserZoomed = false;
4014
4276
  scale = calculateFitScale();
4277
+ container.scrollTop = 0;
4278
+ container.scrollLeft = 0;
4015
4279
  applyScale();
4016
4280
  },
4017
4281
  rotateCW: () => {
@@ -4129,6 +4393,16 @@ var CodePlugin = class {
4129
4393
  instance.zoomIn?.();
4130
4394
  }
4131
4395
  },
4396
+ {
4397
+ id: "reset-zoom",
4398
+ icon: "reset-zoom",
4399
+ label: "Reset Zoom",
4400
+ type: "button",
4401
+ group: "zoom",
4402
+ execute: () => {
4403
+ instance.resetZoom?.();
4404
+ }
4405
+ },
4132
4406
  {
4133
4407
  id: "copy",
4134
4408
  icon: "copy",
@@ -4234,15 +4508,27 @@ var CodePlugin = class {
4234
4508
  let isUserZoomed = false;
4235
4509
  const pre = document.createElement("pre");
4236
4510
  const code = document.createElement("code");
4511
+ const sizer = document.createElement("div");
4512
+ const scrollWrapper = document.createElement("div");
4237
4513
  if (isTxt) {
4238
- container.style.overflowX = "hidden";
4239
- container.style.overflowY = "auto";
4514
+ container.style.overflow = "auto";
4240
4515
  container.style.backgroundColor = "#f1f5f9";
4241
- container.style.padding = "16px 8px";
4242
- container.style.boxSizing = "border-box";
4243
- container.style.display = "flex";
4244
- container.style.flexDirection = "column";
4245
- container.style.alignItems = "center";
4516
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4517
+ scrollWrapper.style.minWidth = "100%";
4518
+ scrollWrapper.style.minHeight = "100%";
4519
+ scrollWrapper.style.width = "max-content";
4520
+ scrollWrapper.style.height = "max-content";
4521
+ scrollWrapper.style.display = "flex";
4522
+ scrollWrapper.style.justifyContent = "center";
4523
+ scrollWrapper.style.alignItems = "flex-start";
4524
+ scrollWrapper.style.padding = "16px 8px";
4525
+ scrollWrapper.style.boxSizing = "border-box";
4526
+ sizer.className = "fp-code-sizer";
4527
+ sizer.style.position = "relative";
4528
+ sizer.style.flexShrink = "0";
4529
+ sizer.style.display = "flex";
4530
+ sizer.style.justifyContent = "center";
4531
+ sizer.style.alignItems = "center";
4246
4532
  pre.style.margin = "0 auto";
4247
4533
  pre.style.fontFamily = "Consolas, 'Courier New', monospace";
4248
4534
  pre.style.fontSize = "13px";
@@ -4257,8 +4543,9 @@ var CodePlugin = class {
4257
4543
  pre.style.boxSizing = "border-box";
4258
4544
  pre.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4259
4545
  pre.style.borderRadius = "4px";
4260
- pre.style.transformOrigin = "top center";
4546
+ pre.style.transformOrigin = "center center";
4261
4547
  pre.style.transition = "transform 0.15s ease";
4548
+ pre.style.flexShrink = "0";
4262
4549
  } else {
4263
4550
  container.style.overflow = "auto";
4264
4551
  container.style.backgroundColor = "#1e1e1e";
@@ -4291,7 +4578,13 @@ var CodePlugin = class {
4291
4578
  };
4292
4579
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4293
4580
  pre.appendChild(code);
4294
- container.appendChild(pre);
4581
+ if (isTxt) {
4582
+ sizer.appendChild(pre);
4583
+ scrollWrapper.appendChild(sizer);
4584
+ container.appendChild(scrollWrapper);
4585
+ } else {
4586
+ container.appendChild(pre);
4587
+ }
4295
4588
  const showPage = (pageNum) => {
4296
4589
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4297
4590
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
@@ -4308,10 +4601,16 @@ var CodePlugin = class {
4308
4601
  };
4309
4602
  const updateTransform = () => {
4310
4603
  if (isTxt) {
4604
+ const elW = 816;
4605
+ const baseH = pre.offsetHeight || 1056;
4606
+ const isRotated90 = rotation % 180 !== 0;
4607
+ const boxW = Math.round((isRotated90 ? baseH : elW) * zoomLevel);
4608
+ const boxH = Math.round((isRotated90 ? elW : baseH) * zoomLevel);
4609
+ sizer.style.width = `${boxW}px`;
4610
+ sizer.style.height = `${boxH}px`;
4611
+ pre.style.width = `${elW}px`;
4311
4612
  pre.style.transform = `scale(${zoomLevel}) rotate(${rotation}deg)`;
4312
- const scaledH = 1056 * zoomLevel;
4313
- const extraH = Math.max(0, scaledH - 1056);
4314
- pre.style.marginBottom = `${extraH + 32}px`;
4613
+ pre.style.transformOrigin = "center center";
4315
4614
  } else {
4316
4615
  pre.style.transform = `rotate(${rotation}deg)`;
4317
4616
  pre.style.fontSize = `${fontSize}px`;
@@ -4408,6 +4707,15 @@ var CodePlugin = class {
4408
4707
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4409
4708
  updateTransform();
4410
4709
  },
4710
+ resetZoom: () => {
4711
+ isUserZoomed = false;
4712
+ fontSize = 13;
4713
+ rotation = 0;
4714
+ zoomLevel = isTxt ? calculateTxtFit() : 1;
4715
+ container.scrollTop = 0;
4716
+ container.scrollLeft = 0;
4717
+ updateTransform();
4718
+ },
4411
4719
  rotateCW: () => {
4412
4720
  rotation = (rotation + 90) % 360;
4413
4721
  updateTransform();
@@ -4470,11 +4778,19 @@ var ArchivePlugin = class {
4470
4778
  {
4471
4779
  id: "fit-page",
4472
4780
  icon: "fit-page",
4473
- label: "Reset Zoom",
4781
+ label: "Fit to Page",
4474
4782
  type: "button",
4475
4783
  group: "zoom",
4476
4784
  execute: () => instance.fitToPage?.()
4477
4785
  },
4786
+ {
4787
+ id: "reset-zoom",
4788
+ icon: "reset-zoom",
4789
+ label: "Reset Zoom",
4790
+ type: "button",
4791
+ group: "zoom",
4792
+ execute: () => instance.resetZoom?.()
4793
+ },
4478
4794
  {
4479
4795
  id: "download",
4480
4796
  icon: "download",
@@ -4500,16 +4816,56 @@ var ArchivePlugin = class {
4500
4816
  width: 100%;
4501
4817
  height: 100%;
4502
4818
  overflow: auto;
4503
- padding: 24px;
4504
4819
  box-sizing: border-box;
4505
4820
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
4506
- transform-origin: top left;
4507
- transition: transform 0.2s ease;
4508
4821
  `;
4822
+ const scrollWrapper = document.createElement("div");
4823
+ scrollWrapper.className = "fp-archive-scroll-wrapper";
4824
+ scrollWrapper.style.cssText = `
4825
+ min-width: 100%;
4826
+ min-height: 100%;
4827
+ width: max-content;
4828
+ height: max-content;
4829
+ display: flex;
4830
+ justify-content: center;
4831
+ align-items: flex-start;
4832
+ padding: 24px;
4833
+ box-sizing: border-box;
4834
+ `;
4835
+ const sizer = document.createElement("div");
4836
+ sizer.className = "fp-archive-sizer";
4837
+ sizer.style.cssText = `
4838
+ position: relative;
4839
+ flex-shrink: 0;
4840
+ display: flex;
4841
+ justify-content: center;
4842
+ align-items: flex-start;
4843
+ `;
4844
+ const card = document.createElement("div");
4845
+ card.className = "fp-archive-card";
4846
+ card.style.cssText = `
4847
+ width: 900px;
4848
+ box-sizing: border-box;
4849
+ transform-origin: top center;
4850
+ transition: transform 0.15s ease;
4851
+ flex-shrink: 0;
4852
+ `;
4853
+ sizer.appendChild(card);
4854
+ scrollWrapper.appendChild(sizer);
4855
+ wrapper.appendChild(scrollWrapper);
4509
4856
  ctx.container.innerHTML = "";
4510
4857
  ctx.container.style.overflow = "auto";
4511
4858
  ctx.container.appendChild(wrapper);
4512
4859
  let scale = 1;
4860
+ const applyTransform = () => {
4861
+ const boxW = Math.round(900 * scale);
4862
+ const cardH = card.offsetHeight || 600;
4863
+ const boxH = Math.round(cardH * scale);
4864
+ sizer.style.width = `${boxW}px`;
4865
+ sizer.style.height = `${boxH}px`;
4866
+ card.style.transform = `scale(${scale})`;
4867
+ card.style.transformOrigin = "top center";
4868
+ };
4513
4869
  const entries = await new Promise((resolve, reject) => {
4514
4870
  fflate.unzip(new Uint8Array(ctx.buffer), (err, unzipped) => {
4515
4871
  if (err) {
@@ -4533,7 +4889,7 @@ var ArchivePlugin = class {
4533
4889
  });
4534
4890
  const totalUncompressedSize = entries.reduce((acc, e) => acc + e.size, 0);
4535
4891
  const renderUI = (filteredEntries) => {
4536
- wrapper.innerHTML = `
4892
+ card.innerHTML = `
4537
4893
  <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;">
4538
4894
  <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;">
4539
4895
  <div>
@@ -4563,7 +4919,7 @@ var ArchivePlugin = class {
4563
4919
  </div>
4564
4920
  </div>
4565
4921
  `;
4566
- const tbody = wrapper.querySelector("#fp-archive-body");
4922
+ const tbody = card.querySelector("#fp-archive-body");
4567
4923
  if (filteredEntries.length === 0) {
4568
4924
  tbody.innerHTML = `<tr><td colspan="3" style="padding: 24px; text-align: center; color: #9ca3af;">No matching files found</td></tr>`;
4569
4925
  } else {
@@ -4592,19 +4948,20 @@ var ArchivePlugin = class {
4592
4948
  }
4593
4949
  });
4594
4950
  });
4595
- const searchInput = wrapper.querySelector("#fp-archive-search");
4951
+ const searchInput = card.querySelector("#fp-archive-search");
4596
4952
  if (searchInput) {
4597
4953
  searchInput.addEventListener("input", () => {
4598
4954
  const q = searchInput.value.toLowerCase().trim();
4599
4955
  const filtered = q ? entries.filter((e) => e.path.toLowerCase().includes(q)) : entries;
4600
4956
  renderUI(filtered);
4601
- const newSearch = wrapper.querySelector("#fp-archive-search");
4957
+ const newSearch = card.querySelector("#fp-archive-search");
4602
4958
  if (newSearch) {
4603
4959
  newSearch.value = q;
4604
4960
  newSearch.focus();
4605
4961
  }
4606
4962
  });
4607
4963
  }
4964
+ applyTransform();
4608
4965
  };
4609
4966
  renderUI(entries);
4610
4967
  const cleanup = () => {
@@ -4616,20 +4973,26 @@ var ArchivePlugin = class {
4616
4973
  destroy: cleanup,
4617
4974
  zoomIn: () => {
4618
4975
  scale += 0.1;
4619
- wrapper.style.transform = `scale(${scale})`;
4976
+ applyTransform();
4620
4977
  },
4621
4978
  zoomOut: () => {
4622
4979
  scale = Math.max(0.3, scale - 0.1);
4623
- wrapper.style.transform = `scale(${scale})`;
4980
+ applyTransform();
4624
4981
  },
4625
4982
  getZoom: () => scale,
4626
4983
  setZoom: (level) => {
4627
4984
  scale = level;
4628
- wrapper.style.transform = `scale(${scale})`;
4985
+ applyTransform();
4629
4986
  },
4630
4987
  fitToPage: () => {
4631
4988
  scale = 1;
4632
- wrapper.style.transform = `scale(1)`;
4989
+ applyTransform();
4990
+ },
4991
+ resetZoom: () => {
4992
+ scale = 1;
4993
+ wrapper.scrollTop = 0;
4994
+ wrapper.scrollLeft = 0;
4995
+ applyTransform();
4633
4996
  },
4634
4997
  download: () => {
4635
4998
  downloadFile(ctx.buffer, ctx.metadata.name || "archive.zip", "application/zip");
@@ -4681,6 +5044,14 @@ var MarkdownPlugin = class {
4681
5044
  group: "zoom",
4682
5045
  execute: () => instance.fitToPage?.()
4683
5046
  },
5047
+ {
5048
+ id: "reset-zoom",
5049
+ icon: "reset-zoom",
5050
+ label: "Reset Zoom",
5051
+ type: "button",
5052
+ group: "zoom",
5053
+ execute: () => instance.resetZoom?.()
5054
+ },
4684
5055
  {
4685
5056
  id: "copy",
4686
5057
  icon: "copy",
@@ -4834,6 +5205,12 @@ var MarkdownPlugin = class {
4834
5205
  fontSize = 15;
4835
5206
  wrapper.style.fontSize = "15px";
4836
5207
  },
5208
+ resetZoom: () => {
5209
+ fontSize = 15;
5210
+ wrapper.style.fontSize = "15px";
5211
+ ctx.container.scrollTop = 0;
5212
+ ctx.container.scrollLeft = 0;
5213
+ },
4837
5214
  download: () => {
4838
5215
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
4839
5216
  },
@@ -4927,6 +5304,14 @@ var PptxPlugin = class {
4927
5304
  group: "zoom",
4928
5305
  execute: () => instance.fitToPage?.()
4929
5306
  },
5307
+ {
5308
+ id: "reset-zoom",
5309
+ icon: "reset-zoom",
5310
+ label: "Reset Zoom",
5311
+ type: "button",
5312
+ group: "zoom",
5313
+ execute: () => instance.resetZoom?.()
5314
+ },
4930
5315
  {
4931
5316
  id: "rotate-cw",
4932
5317
  icon: "rotate-cw",
@@ -4966,12 +5351,30 @@ var PptxPlugin = class {
4966
5351
  width: 100%;
4967
5352
  height: 100%;
4968
5353
  overflow: auto;
5354
+ box-sizing: border-box;
5355
+ background: var(--fp-bg-canvas, #525659);
5356
+ `;
5357
+ const scrollWrapper = document.createElement("div");
5358
+ scrollWrapper.className = "fp-pptx-scroll-wrapper";
5359
+ scrollWrapper.style.cssText = `
5360
+ min-width: 100%;
5361
+ min-height: 100%;
5362
+ width: max-content;
5363
+ height: max-content;
4969
5364
  display: flex;
4970
5365
  justify-content: center;
4971
- align-items: flex-start;
5366
+ align-items: center;
4972
5367
  padding: 24px;
4973
5368
  box-sizing: border-box;
4974
- background: var(--fp-bg-canvas, #525659);
5369
+ `;
5370
+ const sizer = document.createElement("div");
5371
+ sizer.className = "fp-pptx-sizer";
5372
+ sizer.style.cssText = `
5373
+ position: relative;
5374
+ flex-shrink: 0;
5375
+ display: flex;
5376
+ justify-content: center;
5377
+ align-items: center;
4975
5378
  `;
4976
5379
  const slideContainer = document.createElement("div");
4977
5380
  slideContainer.className = "fp-slide-container";
@@ -4980,14 +5383,15 @@ var PptxPlugin = class {
4980
5383
  border-radius: 4px;
4981
5384
  overflow: hidden;
4982
5385
  background: #ffffff;
4983
- transform-origin: top center;
5386
+ transform-origin: center center;
4984
5387
  transition: transform 0.2s ease;
4985
- max-width: calc(100% - 32px);
4986
- max-height: calc(100% - 48px);
5388
+ flex-shrink: 0;
4987
5389
  `;
4988
5390
  const canvas = document.createElement("canvas");
4989
5391
  slideContainer.appendChild(canvas);
4990
- wrapper.appendChild(slideContainer);
5392
+ sizer.appendChild(slideContainer);
5393
+ scrollWrapper.appendChild(sizer);
5394
+ wrapper.appendChild(scrollWrapper);
4991
5395
  ctx.container.innerHTML = "";
4992
5396
  ctx.container.style.overflow = "auto";
4993
5397
  ctx.container.appendChild(wrapper);
@@ -4999,7 +5403,17 @@ var PptxPlugin = class {
4999
5403
  return Math.min(1, Math.min(availW / cW, availH / cH));
5000
5404
  };
5001
5405
  const applyTransform = () => {
5406
+ const cW = canvas.offsetWidth || 1280;
5407
+ const cH = canvas.offsetHeight || 720;
5408
+ const isRotated90 = rotation % 180 !== 0;
5409
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
5410
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
5411
+ sizer.style.width = `${boxW}px`;
5412
+ sizer.style.height = `${boxH}px`;
5413
+ slideContainer.style.width = `${cW}px`;
5414
+ slideContainer.style.height = `${cH}px`;
5002
5415
  slideContainer.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5416
+ slideContainer.style.transformOrigin = "center center";
5003
5417
  };
5004
5418
  const renderCurrentSlide = async () => {
5005
5419
  try {
@@ -5046,6 +5460,13 @@ var PptxPlugin = class {
5046
5460
  rotation = 0;
5047
5461
  applyTransform();
5048
5462
  },
5463
+ resetZoom: () => {
5464
+ scale = calculateFitScale();
5465
+ rotation = 0;
5466
+ wrapper.scrollTop = 0;
5467
+ wrapper.scrollLeft = 0;
5468
+ applyTransform();
5469
+ },
5049
5470
  rotateCW: () => {
5050
5471
  rotation = (rotation + 90) % 360;
5051
5472
  applyTransform();
@@ -5121,6 +5542,14 @@ var ThreeDPlugin = class {
5121
5542
  group: "zoom",
5122
5543
  execute: () => instance.fitToPage?.()
5123
5544
  },
5545
+ {
5546
+ id: "reset-zoom",
5547
+ icon: "reset-zoom",
5548
+ label: "Reset Zoom",
5549
+ type: "button",
5550
+ group: "zoom",
5551
+ execute: () => instance.resetZoom?.()
5552
+ },
5124
5553
  {
5125
5554
  id: "rotate-cw",
5126
5555
  icon: "rotate-cw",
@@ -5257,6 +5686,7 @@ var ThreeDPlugin = class {
5257
5686
  controls.update();
5258
5687
  },
5259
5688
  fitToPage: fitCamera,
5689
+ resetZoom: fitCamera,
5260
5690
  rotateCW: () => {
5261
5691
  isWireframe = !isWireframe;
5262
5692
  materials.forEach((m) => {
@@ -5471,6 +5901,14 @@ var RtfPlugin = class {
5471
5901
  group: "zoom",
5472
5902
  execute: () => instance.fitToPage?.()
5473
5903
  },
5904
+ {
5905
+ id: "reset-zoom",
5906
+ icon: "reset-zoom",
5907
+ label: "Reset Zoom",
5908
+ type: "button",
5909
+ group: "zoom",
5910
+ execute: () => instance.resetZoom?.()
5911
+ },
5474
5912
  {
5475
5913
  id: "rotate-cw",
5476
5914
  icon: "rotate-cw",
@@ -5581,13 +6019,33 @@ var RtfPlugin = class {
5581
6019
  wrapper.style.flexDirection = "column";
5582
6020
  wrapper.style.alignItems = "center";
5583
6021
  wrapper.style.backgroundColor = "transparent";
5584
- wrapper.style.transformOrigin = "top center";
6022
+ wrapper.style.transformOrigin = "center center";
5585
6023
  wrapper.style.transition = "transform 0.15s ease";
5586
- ctx.container.style.overflowX = "hidden";
5587
- ctx.container.style.overflowY = "auto";
5588
- ctx.container.style.padding = "16px 8px";
6024
+ wrapper.style.flexShrink = "0";
6025
+ const sizer = document.createElement("div");
6026
+ sizer.className = "fp-rtf-sizer";
6027
+ sizer.style.position = "relative";
6028
+ sizer.style.flexShrink = "0";
6029
+ sizer.style.display = "flex";
6030
+ sizer.style.justifyContent = "center";
6031
+ sizer.style.alignItems = "center";
6032
+ const scrollWrapper = document.createElement("div");
6033
+ scrollWrapper.className = "fp-rtf-scroll-wrapper";
6034
+ scrollWrapper.style.minWidth = "100%";
6035
+ scrollWrapper.style.minHeight = "100%";
6036
+ scrollWrapper.style.width = "max-content";
6037
+ scrollWrapper.style.height = "max-content";
6038
+ scrollWrapper.style.display = "flex";
6039
+ scrollWrapper.style.justifyContent = "center";
6040
+ scrollWrapper.style.alignItems = "flex-start";
6041
+ scrollWrapper.style.padding = "16px 8px";
6042
+ scrollWrapper.style.boxSizing = "border-box";
6043
+ sizer.appendChild(wrapper);
6044
+ scrollWrapper.appendChild(sizer);
6045
+ ctx.container.style.overflow = "auto";
6046
+ ctx.container.style.padding = "0";
5589
6047
  ctx.container.style.backgroundColor = "#f1f5f9";
5590
- ctx.container.appendChild(wrapper);
6048
+ ctx.container.appendChild(scrollWrapper);
5591
6049
  let scale = 1;
5592
6050
  let rotation = 0;
5593
6051
  let pageElements = [];
@@ -5606,12 +6064,17 @@ var RtfPlugin = class {
5606
6064
  return Math.max(0.4, Math.min(3, sW));
5607
6065
  };
5608
6066
  const applyTransform = () => {
5609
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5610
- wrapper.style.transformOrigin = "top center";
6067
+ const elW = pageWidth;
5611
6068
  const baseH = pageHeight;
5612
- const scaledH = baseH * scale;
5613
- const extraH = Math.max(0, scaledH - baseH);
5614
- wrapper.style.marginBottom = `${extraH + 32}px`;
6069
+ const isRotated90 = rotation % 180 !== 0;
6070
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6071
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6072
+ sizer.style.width = `${boxW}px`;
6073
+ sizer.style.height = `${boxH}px`;
6074
+ wrapper.style.width = `${elW}px`;
6075
+ wrapper.style.height = `${baseH}px`;
6076
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6077
+ wrapper.style.transformOrigin = "center center";
5615
6078
  };
5616
6079
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5617
6080
  if (!isUserZoomed) {
@@ -5882,7 +6345,7 @@ var RtfPlugin = class {
5882
6345
  }
5883
6346
  const cleanup = () => {
5884
6347
  resizeObserver?.disconnect();
5885
- wrapper.remove();
6348
+ scrollWrapper.remove();
5886
6349
  ctx.container.innerHTML = "";
5887
6350
  };
5888
6351
  ctx.signal.addEventListener("abort", cleanup);
@@ -5940,6 +6403,15 @@ var RtfPlugin = class {
5940
6403
  rotation = 0;
5941
6404
  applyTransform();
5942
6405
  },
6406
+ resetZoom: () => {
6407
+ isUserZoomed = false;
6408
+ fitMode = "width";
6409
+ scale = calculateFitScale("width");
6410
+ rotation = 0;
6411
+ ctx.container.scrollTop = 0;
6412
+ ctx.container.scrollLeft = 0;
6413
+ applyTransform();
6414
+ },
5943
6415
  rotateCW: () => {
5944
6416
  rotation = (rotation + 90) % 360;
5945
6417
  applyTransform();
@@ -6007,6 +6479,14 @@ var HtmlPreviewPlugin = class {
6007
6479
  group: "zoom",
6008
6480
  execute: () => instance.fitToPage?.()
6009
6481
  },
6482
+ {
6483
+ id: "reset-zoom",
6484
+ icon: "reset-zoom",
6485
+ label: "Reset Zoom",
6486
+ type: "button",
6487
+ group: "zoom",
6488
+ execute: () => instance.resetZoom?.()
6489
+ },
6010
6490
  {
6011
6491
  id: "copy",
6012
6492
  icon: "copy",
@@ -6040,23 +6520,44 @@ var HtmlPreviewPlugin = class {
6040
6520
  ADD_TAGS: ["style", "link"],
6041
6521
  ADD_ATTR: ["target", "rel"]
6042
6522
  });
6523
+ const sizer = document.createElement("div");
6524
+ sizer.className = "fp-html-sizer";
6525
+ sizer.style.position = "relative";
6043
6526
  const iframe = document.createElement("iframe");
6044
6527
  iframe.className = "fp-html-iframe";
6045
- iframe.style.width = "100%";
6046
- iframe.style.height = "100%";
6047
6528
  iframe.style.border = "none";
6048
6529
  iframe.style.backgroundColor = "#ffffff";
6049
6530
  iframe.style.transformOrigin = "top left";
6050
6531
  iframe.style.transition = "transform 0.2s ease";
6051
6532
  iframe.sandbox.add("allow-same-origin");
6533
+ sizer.appendChild(iframe);
6052
6534
  ctx.container.style.overflow = "auto";
6053
6535
  ctx.container.style.width = "100%";
6054
6536
  ctx.container.style.height = "100%";
6055
- ctx.container.appendChild(iframe);
6537
+ ctx.container.innerHTML = "";
6538
+ ctx.container.appendChild(sizer);
6056
6539
  iframe.srcdoc = sanitized;
6057
6540
  let scale = 1;
6541
+ const applyTransform = () => {
6542
+ const baseW = Math.max(600, ctx.container.clientWidth || 800);
6543
+ const baseH = Math.max(400, ctx.container.clientHeight || 600);
6544
+ const scaledW = Math.round(baseW * scale);
6545
+ const scaledH = Math.round(baseH * scale);
6546
+ sizer.style.width = `${scaledW}px`;
6547
+ sizer.style.height = `${scaledH}px`;
6548
+ iframe.style.position = "absolute";
6549
+ iframe.style.top = "0";
6550
+ iframe.style.left = "0";
6551
+ iframe.style.width = `${baseW}px`;
6552
+ iframe.style.height = `${baseH}px`;
6553
+ iframe.style.transform = `scale(${scale})`;
6554
+ iframe.style.transformOrigin = "top left";
6555
+ };
6556
+ requestAnimationFrame(() => {
6557
+ applyTransform();
6558
+ });
6058
6559
  const cleanup = () => {
6059
- iframe.remove();
6560
+ sizer.remove();
6060
6561
  ctx.container.innerHTML = "";
6061
6562
  };
6062
6563
  ctx.signal.addEventListener("abort", cleanup);
@@ -6064,20 +6565,26 @@ var HtmlPreviewPlugin = class {
6064
6565
  destroy: cleanup,
6065
6566
  zoomIn: () => {
6066
6567
  scale += 0.1;
6067
- iframe.style.transform = `scale(${scale})`;
6568
+ applyTransform();
6068
6569
  },
6069
6570
  zoomOut: () => {
6070
6571
  scale = Math.max(0.2, scale - 0.1);
6071
- iframe.style.transform = `scale(${scale})`;
6572
+ applyTransform();
6072
6573
  },
6073
6574
  getZoom: () => scale,
6074
6575
  setZoom: (level) => {
6075
6576
  scale = level;
6076
- iframe.style.transform = `scale(${scale})`;
6577
+ applyTransform();
6077
6578
  },
6078
6579
  fitToPage: () => {
6079
6580
  scale = 1;
6080
- iframe.style.transform = "scale(1)";
6581
+ applyTransform();
6582
+ },
6583
+ resetZoom: () => {
6584
+ scale = 1;
6585
+ ctx.container.scrollTop = 0;
6586
+ ctx.container.scrollLeft = 0;
6587
+ applyTransform();
6081
6588
  },
6082
6589
  copy: () => {
6083
6590
  navigator.clipboard.writeText(rawHtml);
@@ -6179,6 +6686,14 @@ var OpenDocumentPlugin = class {
6179
6686
  group: "zoom",
6180
6687
  execute: () => instance.fitToPage?.()
6181
6688
  },
6689
+ {
6690
+ id: "reset-zoom",
6691
+ icon: "reset-zoom",
6692
+ label: "Reset Zoom",
6693
+ type: "button",
6694
+ group: "zoom",
6695
+ execute: () => instance.resetZoom?.()
6696
+ },
6182
6697
  {
6183
6698
  id: "rotate-cw",
6184
6699
  icon: "rotate-cw",
@@ -6244,10 +6759,26 @@ var OpenDocumentPlugin = class {
6244
6759
  container.className = "fp-odf-container";
6245
6760
  container.style.width = "100%";
6246
6761
  container.style.height = "100%";
6247
- container.style.overflowX = "hidden";
6248
- container.style.overflowY = "auto";
6249
- container.style.padding = "16px 8px";
6762
+ container.style.overflow = "auto";
6250
6763
  container.style.backgroundColor = "#f1f5f9";
6764
+ const scrollWrapper = document.createElement("div");
6765
+ scrollWrapper.className = "fp-odf-scroll-wrapper";
6766
+ scrollWrapper.style.minWidth = "100%";
6767
+ scrollWrapper.style.minHeight = "100%";
6768
+ scrollWrapper.style.width = "max-content";
6769
+ scrollWrapper.style.height = "max-content";
6770
+ scrollWrapper.style.display = "flex";
6771
+ scrollWrapper.style.justifyContent = "center";
6772
+ scrollWrapper.style.alignItems = "flex-start";
6773
+ scrollWrapper.style.padding = "16px 8px";
6774
+ scrollWrapper.style.boxSizing = "border-box";
6775
+ const sizer = document.createElement("div");
6776
+ sizer.className = "fp-odf-sizer";
6777
+ sizer.style.position = "relative";
6778
+ sizer.style.flexShrink = "0";
6779
+ sizer.style.display = "flex";
6780
+ sizer.style.justifyContent = "center";
6781
+ sizer.style.alignItems = "center";
6251
6782
  const wrapper = document.createElement("div");
6252
6783
  wrapper.className = "fp-odf-wrapper";
6253
6784
  wrapper.style.margin = "0 auto";
@@ -6256,9 +6787,12 @@ var OpenDocumentPlugin = class {
6256
6787
  wrapper.style.backgroundColor = "#ffffff";
6257
6788
  wrapper.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
6258
6789
  wrapper.style.borderRadius = "4px";
6259
- wrapper.style.transformOrigin = "top center";
6790
+ wrapper.style.transformOrigin = "center center";
6260
6791
  wrapper.style.transition = "transform 0.15s ease";
6261
- container.appendChild(wrapper);
6792
+ wrapper.style.flexShrink = "0";
6793
+ sizer.appendChild(wrapper);
6794
+ scrollWrapper.appendChild(sizer);
6795
+ container.appendChild(scrollWrapper);
6262
6796
  ctx.container.appendChild(container);
6263
6797
  let scale = 1;
6264
6798
  let rotation = 0;
@@ -6284,13 +6818,18 @@ var OpenDocumentPlugin = class {
6284
6818
  return Math.max(0.4, Math.min(3, sW));
6285
6819
  };
6286
6820
  const applyTransform = () => {
6287
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6288
- wrapper.style.transformOrigin = "top center";
6289
6821
  const activeSlide = slides[currentPage - 1];
6822
+ const elW = isPresentation ? 960 : 816;
6290
6823
  const baseH = activeSlide?.offsetHeight || wrapper.offsetHeight || 1056;
6291
- const scaledH = baseH * scale;
6292
- const extraH = Math.max(0, scaledH - baseH);
6293
- wrapper.style.marginBottom = `${extraH + 32}px`;
6824
+ const isRotated90 = rotation % 180 !== 0;
6825
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6826
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6827
+ sizer.style.width = `${boxW}px`;
6828
+ sizer.style.height = `${boxH}px`;
6829
+ wrapper.style.width = `${elW}px`;
6830
+ wrapper.style.height = `${baseH}px`;
6831
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6832
+ wrapper.style.transformOrigin = "center center";
6294
6833
  };
6295
6834
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
6296
6835
  if (!isUserZoomed) {
@@ -6446,6 +6985,15 @@ var OpenDocumentPlugin = class {
6446
6985
  rotation = 0;
6447
6986
  applyTransform();
6448
6987
  },
6988
+ resetZoom: () => {
6989
+ isUserZoomed = false;
6990
+ fitMode = "width";
6991
+ scale = calculateFitScale("width");
6992
+ rotation = 0;
6993
+ container.scrollTop = 0;
6994
+ container.scrollLeft = 0;
6995
+ applyTransform();
6996
+ },
6449
6997
  rotateCW: () => {
6450
6998
  rotation = (rotation + 90) % 360;
6451
6999
  applyTransform();
@@ -6789,6 +7337,14 @@ var DocPlugin = class {
6789
7337
  group: "zoom",
6790
7338
  execute: () => instance.fitToPage?.()
6791
7339
  },
7340
+ {
7341
+ id: "reset-zoom",
7342
+ icon: "reset-zoom",
7343
+ label: "Reset Zoom",
7344
+ type: "button",
7345
+ group: "zoom",
7346
+ execute: () => instance.resetZoom?.()
7347
+ },
6792
7348
  {
6793
7349
  id: "rotate-cw",
6794
7350
  icon: "rotate-cw",
@@ -6837,13 +7393,28 @@ var DocPlugin = class {
6837
7393
  container.className = "fp-doc-container";
6838
7394
  container.style.width = "100%";
6839
7395
  container.style.height = "100%";
6840
- container.style.overflowX = "hidden";
6841
- container.style.overflowY = "auto";
6842
- container.style.padding = "16px 8px";
7396
+ container.style.overflow = "auto";
6843
7397
  container.style.backgroundColor = "#f1f5f9";
6844
- container.style.display = "flex";
6845
- container.style.justifyContent = "center";
6846
- container.style.alignItems = "flex-start";
7398
+ const scrollWrapper = document.createElement("div");
7399
+ scrollWrapper.className = "fp-doc-scroll-wrapper";
7400
+ scrollWrapper.style.minWidth = "100%";
7401
+ scrollWrapper.style.minHeight = "100%";
7402
+ scrollWrapper.style.width = "max-content";
7403
+ scrollWrapper.style.height = "max-content";
7404
+ scrollWrapper.style.display = "flex";
7405
+ scrollWrapper.style.justifyContent = "center";
7406
+ scrollWrapper.style.alignItems = "flex-start";
7407
+ scrollWrapper.style.padding = "16px 8px";
7408
+ scrollWrapper.style.boxSizing = "border-box";
7409
+ const sizer = document.createElement("div");
7410
+ sizer.className = "fp-doc-sizer";
7411
+ sizer.style.position = "relative";
7412
+ sizer.style.flexShrink = "0";
7413
+ sizer.style.display = "flex";
7414
+ sizer.style.justifyContent = "center";
7415
+ sizer.style.alignItems = "center";
7416
+ scrollWrapper.appendChild(sizer);
7417
+ container.appendChild(scrollWrapper);
6847
7418
  ctx.container.appendChild(container);
6848
7419
  let scale = 1;
6849
7420
  let extractedRawText = "";
@@ -6891,10 +7462,11 @@ var DocPlugin = class {
6891
7462
  pageCard.style.padding = "72px 56px";
6892
7463
  pageCard.style.boxSizing = "border-box";
6893
7464
  pageCard.style.display = i === 0 ? "block" : "none";
6894
- pageCard.style.transformOrigin = "top center";
7465
+ pageCard.style.transformOrigin = "center center";
6895
7466
  pageCard.style.transition = "transform 0.15s ease";
6896
7467
  pageCard.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
6897
7468
  pageCard.style.color = "#1e293b";
7469
+ pageCard.style.flexShrink = "0";
6898
7470
  if (isFallback && i === 0) {
6899
7471
  pageCard.innerHTML = `
6900
7472
  <div style="border-bottom: 1px solid #e2e8f0; padding-bottom: 12px; margin-bottom: 24px;">
@@ -6906,18 +7478,23 @@ var DocPlugin = class {
6906
7478
  } else {
6907
7479
  pageCard.innerHTML = this.formatDocToHtml(rawPages[i], ctx.metadata.name || "Document");
6908
7480
  }
6909
- container.appendChild(pageCard);
7481
+ sizer.appendChild(pageCard);
6910
7482
  pageCards.push(pageCard);
6911
7483
  }
6912
7484
  let rotation = 0;
6913
7485
  const applyTransform = () => {
6914
7486
  const activeCard = pageCards[currentPage - 1];
6915
7487
  if (activeCard) {
6916
- activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7488
+ const baseW = 816;
6917
7489
  const baseH = activeCard.offsetHeight || 1056;
6918
- const scaledH = baseH * scale;
6919
- const extraH = Math.max(0, scaledH - baseH);
6920
- activeCard.style.marginBottom = `${extraH + 32}px`;
7490
+ const isRotated90 = rotation % 180 !== 0;
7491
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * scale);
7492
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * scale);
7493
+ sizer.style.width = `${boxW}px`;
7494
+ sizer.style.height = `${boxH}px`;
7495
+ activeCard.style.width = `${baseW}px`;
7496
+ activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7497
+ activeCard.style.transformOrigin = "center center";
6921
7498
  }
6922
7499
  };
6923
7500
  const showPage = (pageNum) => {
@@ -6925,11 +7502,11 @@ var DocPlugin = class {
6925
7502
  pageCards.forEach((card, idx) => {
6926
7503
  if (idx + 1 === currentPage) {
6927
7504
  card.style.display = "block";
6928
- card.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6929
7505
  } else {
6930
7506
  card.style.display = "none";
6931
7507
  }
6932
7508
  });
7509
+ applyTransform();
6933
7510
  container.scrollTop = 0;
6934
7511
  ctx.emit("page-change", { page: currentPage, total: totalPages });
6935
7512
  };
@@ -6995,6 +7572,17 @@ var DocPlugin = class {
6995
7572
  rotation = 0;
6996
7573
  applyTransform();
6997
7574
  },
7575
+ resetZoom: () => {
7576
+ isUserZoomed = false;
7577
+ fitMode = "width";
7578
+ scale = calculateFitScale("width");
7579
+ rotation = 0;
7580
+ container.scrollTop = 0;
7581
+ container.scrollLeft = 0;
7582
+ ctx.container.scrollTop = 0;
7583
+ ctx.container.scrollLeft = 0;
7584
+ applyTransform();
7585
+ },
6998
7586
  rotateCW: () => {
6999
7587
  rotation = (rotation + 90) % 360;
7000
7588
  applyTransform();
@@ -7475,6 +8063,14 @@ var PptPlugin = class {
7475
8063
  group: "zoom",
7476
8064
  execute: () => instance.fitToPage?.()
7477
8065
  },
8066
+ {
8067
+ id: "reset-zoom",
8068
+ icon: "reset-zoom",
8069
+ label: "Reset Zoom",
8070
+ type: "button",
8071
+ group: "zoom",
8072
+ execute: () => instance.resetZoom?.()
8073
+ },
7478
8074
  {
7479
8075
  id: "rotate-cw",
7480
8076
  icon: "rotate-cw",
@@ -7507,17 +8103,30 @@ var PptPlugin = class {
7507
8103
  container.style.width = "100%";
7508
8104
  container.style.height = "100%";
7509
8105
  container.style.overflow = "auto";
7510
- container.style.display = "flex";
7511
- container.style.justifyContent = "center";
7512
- container.style.alignItems = "center";
7513
- container.style.padding = "32px 16px";
7514
8106
  container.style.backgroundColor = "#0f172a";
7515
8107
  container.style.boxSizing = "border-box";
8108
+ const scrollWrapper = document.createElement("div");
8109
+ scrollWrapper.className = "fp-ppt-scroll-wrapper";
8110
+ scrollWrapper.style.minWidth = "100%";
8111
+ scrollWrapper.style.minHeight = "100%";
8112
+ scrollWrapper.style.width = "max-content";
8113
+ scrollWrapper.style.height = "max-content";
8114
+ scrollWrapper.style.display = "flex";
8115
+ scrollWrapper.style.justifyContent = "center";
8116
+ scrollWrapper.style.alignItems = "center";
8117
+ scrollWrapper.style.padding = "32px 16px";
8118
+ scrollWrapper.style.boxSizing = "border-box";
8119
+ const sizer = document.createElement("div");
8120
+ sizer.className = "fp-ppt-sizer";
8121
+ sizer.style.position = "relative";
8122
+ sizer.style.flexShrink = "0";
8123
+ sizer.style.display = "flex";
8124
+ sizer.style.justifyContent = "center";
8125
+ sizer.style.alignItems = "center";
7516
8126
  const slideCard = document.createElement("div");
7517
8127
  slideCard.className = "fp-ppt-slide-card";
7518
8128
  slideCard.style.width = "960px";
7519
- slideCard.style.maxWidth = "calc(100% - 32px)";
7520
- slideCard.style.maxHeight = "calc(100% - 48px)";
8129
+ slideCard.style.height = "540px";
7521
8130
  slideCard.style.aspectRatio = "16 / 9";
7522
8131
  slideCard.style.backgroundColor = "#ffffff";
7523
8132
  slideCard.style.boxShadow = "0 12px 40px rgba(0,0,0,0.35)";
@@ -7527,7 +8136,9 @@ var PptPlugin = class {
7527
8136
  slideCard.style.transition = "transform 0.2s ease";
7528
8137
  slideCard.style.transformOrigin = "center center";
7529
8138
  slideCard.style.flexShrink = "0";
7530
- container.appendChild(slideCard);
8139
+ sizer.appendChild(slideCard);
8140
+ scrollWrapper.appendChild(sizer);
8141
+ container.appendChild(scrollWrapper);
7531
8142
  ctx.container.appendChild(container);
7532
8143
  let scale = 1;
7533
8144
  let rotation = 0;
@@ -7540,7 +8151,17 @@ var PptPlugin = class {
7540
8151
  return Math.min(1, Math.min(availW / 960, availH / 540));
7541
8152
  };
7542
8153
  const applyTransform = () => {
8154
+ const cW = 960;
8155
+ const cH = 540;
8156
+ const isRotated90 = rotation % 180 !== 0;
8157
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
8158
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
8159
+ sizer.style.width = `${boxW}px`;
8160
+ sizer.style.height = `${boxH}px`;
8161
+ slideCard.style.width = `${cW}px`;
8162
+ slideCard.style.height = `${cH}px`;
7543
8163
  slideCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
8164
+ slideCard.style.transformOrigin = "center center";
7544
8165
  };
7545
8166
  setTimeout(() => {
7546
8167
  scale = calculateFitScale();
@@ -7663,6 +8284,13 @@ var PptPlugin = class {
7663
8284
  rotation = 0;
7664
8285
  applyTransform();
7665
8286
  },
8287
+ resetZoom: () => {
8288
+ scale = calculateFitScale();
8289
+ rotation = 0;
8290
+ container.scrollTop = 0;
8291
+ container.scrollLeft = 0;
8292
+ applyTransform();
8293
+ },
7666
8294
  rotateCW: () => {
7667
8295
  rotation = (rotation + 90) % 360;
7668
8296
  applyTransform();