@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/react.js CHANGED
@@ -496,6 +496,7 @@ var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" str
496
496
  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>`;
497
497
  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>`;
498
498
  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>`;
499
+ 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>`;
499
500
  var ICON_MAP = {
500
501
  "zoom-in": ICON_ZOOM_IN,
501
502
  "zoom-out": ICON_ZOOM_OUT,
@@ -525,7 +526,10 @@ var ICON_MAP = {
525
526
  "open-window": ICON_EXTERNAL_WINDOW,
526
527
  "external-window": ICON_EXTERNAL_WINDOW,
527
528
  "openWindow": ICON_EXTERNAL_WINDOW,
528
- "openSeparateWindow": ICON_EXTERNAL_WINDOW
529
+ "openSeparateWindow": ICON_EXTERNAL_WINDOW,
530
+ "reset-zoom": ICON_RESET_ZOOM,
531
+ "zoom-reset": ICON_RESET_ZOOM,
532
+ "resetZoom": ICON_RESET_ZOOM
529
533
  };
530
534
  var ToolbarController = class {
531
535
  el;
@@ -558,6 +562,10 @@ var ToolbarController = class {
558
562
  this.config.fitToPage = false;
559
563
  this.config.fitWidth = false;
560
564
  }
565
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
566
+ this.config.resetZoom = false;
567
+ this.config.zoomReset = false;
568
+ }
561
569
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = false;
562
570
  if (actionId === "fullscreen") this.config.fullscreen = false;
563
571
  if (actionId === "download") this.config.download = false;
@@ -582,6 +590,10 @@ var ToolbarController = class {
582
590
  this.config.fitToPage = true;
583
591
  this.config.fitWidth = true;
584
592
  }
593
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
594
+ this.config.resetZoom = true;
595
+ this.config.zoomReset = true;
596
+ }
585
597
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = true;
586
598
  if (actionId === "fullscreen") this.config.fullscreen = true;
587
599
  if (actionId === "download") this.config.download = true;
@@ -601,6 +613,7 @@ var ToolbarController = class {
601
613
  if (actionId === "zoomIn") return "zoom-in";
602
614
  if (actionId === "zoomOut") return "zoom-out";
603
615
  if (actionId === "fitPage" || actionId === "fitToPage" || actionId === "fitWidth") return "fit-page";
616
+ if (actionId === "resetZoom" || actionId === "zoomReset") return "reset-zoom";
604
617
  if (actionId === "rotateCW") return "rotate-cw";
605
618
  if (actionId === "rotateCCW") return "rotate-ccw";
606
619
  if (actionId === "openWindow" || actionId === "openSeparateWindow") return "open-window";
@@ -643,6 +656,9 @@ var ToolbarController = class {
643
656
  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)) {
644
657
  return false;
645
658
  }
659
+ if ((id === "reset-zoom" || id === "zoom-reset") && (c.resetZoom === false || c.zoomReset === false || c["reset-zoom"] === false || c["zoom-reset"] === false)) {
660
+ return false;
661
+ }
646
662
  if ((id === "rotate-cw" || id === "rotate-ccw" || id === "rotate") && (c.rotate === false || c.rotateCW === false || c.rotateCCW === false || c["rotate-cw"] === false)) {
647
663
  return false;
648
664
  }
@@ -1089,6 +1105,9 @@ var FilePreviewViewer = class _FilePreviewViewer {
1089
1105
  this.activeInstance = instance;
1090
1106
  instance.openInSeparateWindow = () => this.openInSeparateWindow();
1091
1107
  instance.toggleThumbnails = () => this.toggleThumbnails();
1108
+ if (!instance.resetZoom && instance.fitToPage) {
1109
+ instance.resetZoom = () => instance.fitToPage?.();
1110
+ }
1092
1111
  this.hideLoading();
1093
1112
  this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
1094
1113
  const isToolbarVisible = options.showToolbar !== false && options.toolbar !== false;
@@ -1372,6 +1391,16 @@ var FilePreviewViewer = class _FilePreviewViewer {
1372
1391
  fitToPage() {
1373
1392
  this.activeInstance?.fitToPage?.();
1374
1393
  }
1394
+ /**
1395
+ * Reset zoom level to initial/default fit state.
1396
+ */
1397
+ resetZoom() {
1398
+ if (this.activeInstance?.resetZoom) {
1399
+ this.activeInstance.resetZoom();
1400
+ } else if (this.activeInstance?.fitToPage) {
1401
+ this.activeInstance.fitToPage();
1402
+ }
1403
+ }
1375
1404
  /**
1376
1405
  * Zoom in.
1377
1406
  */
@@ -1993,6 +2022,14 @@ var PdfPlugin = class {
1993
2022
  group: "zoom",
1994
2023
  execute: () => instance.fitToPage?.()
1995
2024
  },
2025
+ {
2026
+ id: "reset-zoom",
2027
+ icon: "reset-zoom",
2028
+ label: "Reset Zoom",
2029
+ type: "button",
2030
+ group: "zoom",
2031
+ execute: () => instance.resetZoom?.()
2032
+ },
1996
2033
  {
1997
2034
  id: "fit-width",
1998
2035
  icon: "fit-width",
@@ -2048,16 +2085,22 @@ var PdfPlugin = class {
2048
2085
  container.className = "fp-pdf-container";
2049
2086
  container.style.width = "100%";
2050
2087
  container.style.height = "100%";
2051
- container.style.overflowX = "hidden";
2052
- container.style.overflowY = "auto";
2053
- container.style.display = "flex";
2054
- container.style.flexDirection = "column";
2055
- container.style.alignItems = "center";
2056
- container.style.justifyContent = "flex-start";
2057
- container.style.padding = "16px 8px";
2088
+ container.style.overflow = "auto";
2058
2089
  container.style.backgroundColor = "#0f172a";
2059
2090
  container.style.boxSizing = "border-box";
2060
2091
  container.style.position = "relative";
2092
+ const scrollWrapper = document.createElement("div");
2093
+ scrollWrapper.className = "fp-pdf-scroll-wrapper";
2094
+ scrollWrapper.style.minWidth = "100%";
2095
+ scrollWrapper.style.minHeight = "100%";
2096
+ scrollWrapper.style.width = "max-content";
2097
+ scrollWrapper.style.height = "max-content";
2098
+ scrollWrapper.style.display = "flex";
2099
+ scrollWrapper.style.flexDirection = "column";
2100
+ scrollWrapper.style.alignItems = "center";
2101
+ scrollWrapper.style.justifyContent = "flex-start";
2102
+ scrollWrapper.style.padding = "16px 8px";
2103
+ scrollWrapper.style.boxSizing = "border-box";
2061
2104
  const pageCard = document.createElement("div");
2062
2105
  pageCard.className = "fp-pdf-page-card";
2063
2106
  pageCard.style.boxShadow = "0 10px 35px rgba(0, 0, 0, 0.5)";
@@ -2070,7 +2113,8 @@ var PdfPlugin = class {
2070
2113
  pageCard.style.transition = "box-shadow 0.2s ease";
2071
2114
  let canvas = document.createElement("canvas");
2072
2115
  pageCard.appendChild(canvas);
2073
- container.appendChild(pageCard);
2116
+ scrollWrapper.appendChild(pageCard);
2117
+ container.appendChild(scrollWrapper);
2074
2118
  ctx.container.appendChild(container);
2075
2119
  const standardFontsUrl = typeof window !== "undefined" && window.__PDF_STANDARD_FONTS_URL__ || "./standard_fonts/";
2076
2120
  const cmapsUrl = typeof window !== "undefined" && window.__PDF_CMAPS_URL__ || "./cmaps/";
@@ -2255,6 +2299,14 @@ var PdfPlugin = class {
2255
2299
  zoomScale = 1;
2256
2300
  renderPage(currentPage);
2257
2301
  },
2302
+ resetZoom: () => {
2303
+ fitMode = "page";
2304
+ zoomScale = 1;
2305
+ rotation = 0;
2306
+ container.scrollTop = 0;
2307
+ container.scrollLeft = 0;
2308
+ renderPage(currentPage);
2309
+ },
2258
2310
  fitToWidth: () => {
2259
2311
  fitMode = "width";
2260
2312
  zoomScale = 1;
@@ -2422,6 +2474,16 @@ var MediaPlugin = class {
2422
2474
  instance.fitToPage?.();
2423
2475
  }
2424
2476
  },
2477
+ {
2478
+ id: "reset-zoom",
2479
+ icon: "reset-zoom",
2480
+ label: "Reset Zoom",
2481
+ type: "button",
2482
+ group: "zoom",
2483
+ execute: () => {
2484
+ instance.resetZoom?.();
2485
+ }
2486
+ },
2425
2487
  {
2426
2488
  id: "rotate-cw",
2427
2489
  icon: "rotate-cw",
@@ -2561,17 +2623,86 @@ var MediaPlugin = class {
2561
2623
  element = document.createElement("div");
2562
2624
  element.textContent = "Unsupported media type";
2563
2625
  }
2564
- ctx.container.style.display = "flex";
2565
- ctx.container.style.alignItems = "center";
2566
- ctx.container.style.justifyContent = "center";
2567
- ctx.container.style.overflow = "hidden";
2568
- ctx.container.appendChild(element);
2626
+ const scrollWrapper = document.createElement("div");
2627
+ scrollWrapper.className = "fp-media-scroll-wrapper";
2628
+ scrollWrapper.style.minWidth = "100%";
2629
+ scrollWrapper.style.minHeight = "100%";
2630
+ scrollWrapper.style.width = "max-content";
2631
+ scrollWrapper.style.height = "max-content";
2632
+ scrollWrapper.style.display = "flex";
2633
+ scrollWrapper.style.justifyContent = "center";
2634
+ scrollWrapper.style.alignItems = "center";
2635
+ scrollWrapper.style.padding = "16px";
2636
+ scrollWrapper.style.boxSizing = "border-box";
2637
+ const sizer = document.createElement("div");
2638
+ sizer.className = "fp-media-sizer";
2639
+ sizer.style.position = "relative";
2640
+ sizer.style.flexShrink = "0";
2641
+ sizer.style.display = "flex";
2642
+ sizer.style.justifyContent = "center";
2643
+ sizer.style.alignItems = "center";
2644
+ sizer.appendChild(element);
2645
+ scrollWrapper.appendChild(sizer);
2646
+ ctx.container.style.overflow = "auto";
2647
+ ctx.container.style.padding = "0";
2648
+ ctx.container.innerHTML = "";
2649
+ ctx.container.appendChild(scrollWrapper);
2650
+ let naturalW = 800;
2651
+ let naturalH = 600;
2652
+ let baseW = 800;
2653
+ let baseH = 600;
2654
+ const updateBaseDimensions = () => {
2655
+ if (!isImage) return;
2656
+ const img = element;
2657
+ naturalW = img.naturalWidth || naturalW;
2658
+ naturalH = img.naturalHeight || naturalH;
2659
+ const availW = Math.max(100, ctx.container.clientWidth - 48);
2660
+ const availH = Math.max(100, ctx.container.clientHeight - 48);
2661
+ const fitRatio = Math.min(1, availW / naturalW, availH / naturalH);
2662
+ baseW = Math.max(1, Math.round(naturalW * fitRatio));
2663
+ baseH = Math.max(1, Math.round(naturalH * fitRatio));
2664
+ };
2569
2665
  const applyTransform = () => {
2570
- element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2666
+ if (isImage) {
2667
+ updateBaseDimensions();
2668
+ const isRotated90 = rotation % 180 !== 0;
2669
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * currentZoom);
2670
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * currentZoom);
2671
+ sizer.style.width = `${boxW}px`;
2672
+ sizer.style.height = `${boxH}px`;
2673
+ element.style.width = `${baseW}px`;
2674
+ element.style.height = `${baseH}px`;
2675
+ element.style.maxWidth = "none";
2676
+ element.style.maxHeight = "none";
2677
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2678
+ element.style.transformOrigin = "center center";
2679
+ element.style.flexShrink = "0";
2680
+ } else {
2681
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2682
+ }
2571
2683
  };
2684
+ if (isImage) {
2685
+ const img = element;
2686
+ if (img.complete && img.naturalWidth > 0) {
2687
+ updateBaseDimensions();
2688
+ applyTransform();
2689
+ } else {
2690
+ img.onload = () => {
2691
+ updateBaseDimensions();
2692
+ applyTransform();
2693
+ };
2694
+ }
2695
+ }
2696
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
2697
+ if (currentZoom === 1) {
2698
+ applyTransform();
2699
+ }
2700
+ }) : null;
2701
+ ro?.observe(ctx.container);
2572
2702
  const cleanup = () => {
2703
+ ro?.disconnect();
2573
2704
  if (url) URL.revokeObjectURL(url);
2574
- element.remove();
2705
+ scrollWrapper.remove();
2575
2706
  ctx.container.innerHTML = "";
2576
2707
  };
2577
2708
  ctx.signal.addEventListener("abort", cleanup);
@@ -2595,6 +2726,13 @@ var MediaPlugin = class {
2595
2726
  rotation = 0;
2596
2727
  applyTransform();
2597
2728
  } : void 0,
2729
+ resetZoom: isImage ? () => {
2730
+ currentZoom = 1;
2731
+ rotation = 0;
2732
+ ctx.container.scrollTop = 0;
2733
+ ctx.container.scrollLeft = 0;
2734
+ applyTransform();
2735
+ } : void 0,
2598
2736
  rotateCW: isImage || isVideo ? () => {
2599
2737
  rotation = (rotation + 90) % 360;
2600
2738
  applyTransform();
@@ -2711,6 +2849,14 @@ var DocxPlugin = class {
2711
2849
  group: "zoom",
2712
2850
  execute: () => instance.fitToPage?.()
2713
2851
  },
2852
+ {
2853
+ id: "reset-zoom",
2854
+ icon: "reset-zoom",
2855
+ label: "Reset Zoom",
2856
+ type: "button",
2857
+ group: "zoom",
2858
+ execute: () => instance.resetZoom?.()
2859
+ },
2714
2860
  {
2715
2861
  id: "rotate-cw",
2716
2862
  icon: "rotate-cw",
@@ -2749,7 +2895,7 @@ var DocxPlugin = class {
2749
2895
  async render(ctx) {
2750
2896
  const wrapper = document.createElement("div");
2751
2897
  wrapper.className = "fp-docx-wrapper";
2752
- wrapper.style.transformOrigin = "top center";
2898
+ wrapper.style.transformOrigin = "center center";
2753
2899
  wrapper.style.transition = "transform 0.2s ease";
2754
2900
  wrapper.style.padding = "0";
2755
2901
  wrapper.style.maxWidth = "none";
@@ -2759,11 +2905,31 @@ var DocxPlugin = class {
2759
2905
  wrapper.style.flexDirection = "column";
2760
2906
  wrapper.style.alignItems = "center";
2761
2907
  wrapper.style.boxSizing = "border-box";
2762
- ctx.container.style.overflowX = "hidden";
2763
- ctx.container.style.overflowY = "auto";
2764
- ctx.container.style.padding = "16px 8px";
2908
+ wrapper.style.flexShrink = "0";
2909
+ const sizer = document.createElement("div");
2910
+ sizer.className = "fp-docx-sizer";
2911
+ sizer.style.position = "relative";
2912
+ sizer.style.flexShrink = "0";
2913
+ sizer.style.display = "flex";
2914
+ sizer.style.justifyContent = "center";
2915
+ sizer.style.alignItems = "center";
2916
+ const scrollWrapper = document.createElement("div");
2917
+ scrollWrapper.className = "fp-docx-scroll-wrapper";
2918
+ scrollWrapper.style.minWidth = "100%";
2919
+ scrollWrapper.style.minHeight = "100%";
2920
+ scrollWrapper.style.width = "max-content";
2921
+ scrollWrapper.style.height = "max-content";
2922
+ scrollWrapper.style.display = "flex";
2923
+ scrollWrapper.style.justifyContent = "center";
2924
+ scrollWrapper.style.alignItems = "flex-start";
2925
+ scrollWrapper.style.padding = "16px 8px";
2926
+ scrollWrapper.style.boxSizing = "border-box";
2927
+ sizer.appendChild(wrapper);
2928
+ scrollWrapper.appendChild(sizer);
2929
+ ctx.container.style.overflow = "auto";
2930
+ ctx.container.style.padding = "0";
2765
2931
  ctx.container.style.backgroundColor = "#f1f5f9";
2766
- ctx.container.appendChild(wrapper);
2932
+ ctx.container.appendChild(scrollWrapper);
2767
2933
  const styleOverride = document.createElement("style");
2768
2934
  styleOverride.textContent = `
2769
2935
  .fp-docx-wrapper .docx-wrapper {
@@ -2802,8 +2968,8 @@ var DocxPlugin = class {
2802
2968
  renderEndnotes: true,
2803
2969
  useBase64URL: true
2804
2970
  });
2805
- if (!ctx.container.contains(wrapper)) {
2806
- ctx.container.appendChild(wrapper);
2971
+ if (!sizer.contains(wrapper)) {
2972
+ sizer.appendChild(wrapper);
2807
2973
  }
2808
2974
  if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
2809
2975
  renderedSuccessfully = true;
@@ -2840,8 +3006,8 @@ var DocxPlugin = class {
2840
3006
  try {
2841
3007
  wrapper.innerHTML = "";
2842
3008
  this.renderXmlFallback(ctx, wrapper, createdBlobUrls);
2843
- if (!ctx.container.contains(wrapper)) {
2844
- ctx.container.appendChild(wrapper);
3009
+ if (!sizer.contains(wrapper)) {
3010
+ sizer.appendChild(wrapper);
2845
3011
  }
2846
3012
  renderedSuccessfully = true;
2847
3013
  } catch (fallbackErr) {
@@ -2856,8 +3022,8 @@ var DocxPlugin = class {
2856
3022
  </p>
2857
3023
  </div>
2858
3024
  `;
2859
- if (!ctx.container.contains(wrapper)) {
2860
- ctx.container.appendChild(wrapper);
3025
+ if (!sizer.contains(wrapper)) {
3026
+ sizer.appendChild(wrapper);
2861
3027
  }
2862
3028
  }
2863
3029
  }
@@ -2960,15 +3126,18 @@ var DocxPlugin = class {
2960
3126
  return Math.max(0.35, Math.min(3, sW));
2961
3127
  };
2962
3128
  const applyTransform = () => {
2963
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
2964
- wrapper.style.transformOrigin = "top center";
2965
3129
  const activeEl = pageElements[currentPage - 1] || wrapper.querySelector("section.docx") || wrapper;
3130
+ const elW = activeEl.offsetWidth || 816;
2966
3131
  const elH = activeEl.offsetHeight || 1056;
2967
- if (scale > 1) {
2968
- wrapper.style.marginBottom = `${Math.round(elH * scale - elH + 32)}px`;
2969
- } else {
2970
- wrapper.style.marginBottom = "32px";
2971
- }
3132
+ const isRotated90 = rotation % 180 !== 0;
3133
+ const boxW = Math.round((isRotated90 ? elH : elW) * scale);
3134
+ const boxH = Math.round((isRotated90 ? elW : elH) * scale);
3135
+ sizer.style.width = `${boxW}px`;
3136
+ sizer.style.height = `${boxH}px`;
3137
+ wrapper.style.width = `${elW}px`;
3138
+ wrapper.style.height = `${elH}px`;
3139
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
3140
+ wrapper.style.transformOrigin = "center center";
2972
3141
  };
2973
3142
  let resizeObserver = null;
2974
3143
  if (typeof ResizeObserver !== "undefined") {
@@ -2993,7 +3162,7 @@ var DocxPlugin = class {
2993
3162
  for (const url of createdBlobUrls) {
2994
3163
  URL.revokeObjectURL(url);
2995
3164
  }
2996
- wrapper.remove();
3165
+ scrollWrapper.remove();
2997
3166
  styleOverride.remove();
2998
3167
  ctx.container.innerHTML = "";
2999
3168
  };
@@ -3027,6 +3196,14 @@ var DocxPlugin = class {
3027
3196
  rotation = 0;
3028
3197
  applyTransform();
3029
3198
  },
3199
+ resetZoom: () => {
3200
+ isUserZoomed = false;
3201
+ scale = calculateFitScale("page");
3202
+ rotation = 0;
3203
+ ctx.container.scrollTop = 0;
3204
+ ctx.container.scrollLeft = 0;
3205
+ applyTransform();
3206
+ },
3030
3207
  rotateCW: () => {
3031
3208
  rotation = (rotation + 90) % 360;
3032
3209
  applyTransform();
@@ -3476,6 +3653,16 @@ var ExcelPlugin = class {
3476
3653
  instance.zoomIn?.();
3477
3654
  }
3478
3655
  },
3656
+ {
3657
+ id: "reset-zoom",
3658
+ icon: "reset-zoom",
3659
+ label: "Reset Zoom",
3660
+ type: "button",
3661
+ group: "zoom",
3662
+ execute: () => {
3663
+ instance.resetZoom?.();
3664
+ }
3665
+ },
3479
3666
  {
3480
3667
  id: "download",
3481
3668
  icon: "download",
@@ -3522,7 +3709,7 @@ var ExcelPlugin = class {
3522
3709
  contentArea.style.flex = "1";
3523
3710
  contentArea.style.overflow = "auto";
3524
3711
  contentArea.style.padding = "16px";
3525
- contentArea.style.transformOrigin = "top left";
3712
+ contentArea.style.boxSizing = "border-box";
3526
3713
  const tabsArea = document.createElement("div");
3527
3714
  tabsArea.className = "fp-excel-tabs";
3528
3715
  tabsArea.style.display = "flex";
@@ -3536,18 +3723,35 @@ var ExcelPlugin = class {
3536
3723
  container.appendChild(tabsArea);
3537
3724
  ctx.container.appendChild(container);
3538
3725
  let scale = 1;
3726
+ let isUserZoomed = false;
3539
3727
  let currentSheetIndex = 1;
3540
3728
  let sheetNames = [];
3541
3729
  let wb = null;
3542
3730
  const applyTransform = () => {
3543
- contentArea.style.transform = `scale(${scale})`;
3544
- contentArea.style.transformOrigin = "top left";
3731
+ const sizer = contentArea.querySelector(".fp-excel-sizer");
3732
+ const table = contentArea.querySelector("table");
3733
+ if (!sizer || !table) return;
3734
+ if (!table._baseWidth && table.offsetWidth > 0) {
3735
+ table._baseWidth = table.offsetWidth;
3736
+ table._baseHeight = table.offsetHeight;
3737
+ }
3738
+ const baseW = table._baseWidth || table.offsetWidth || 800;
3739
+ const baseH = table._baseHeight || table.offsetHeight || 600;
3740
+ const scaledW = Math.round(baseW * scale);
3741
+ const scaledH = Math.round(baseH * scale);
3742
+ sizer.style.width = `${scaledW}px`;
3743
+ sizer.style.height = `${scaledH}px`;
3744
+ table.style.position = "absolute";
3745
+ table.style.top = "0";
3746
+ table.style.left = "0";
3747
+ table.style.transform = `scale(${scale})`;
3748
+ table.style.transformOrigin = "top left";
3545
3749
  };
3546
3750
  const calculateFitScale = () => {
3547
3751
  const table = contentArea.querySelector("table");
3548
3752
  if (!table) return 1;
3549
3753
  const availW = Math.max(280, container.clientWidth - 48);
3550
- const tW = table.offsetWidth || 800;
3754
+ const tW = table._baseWidth || table.offsetWidth || 800;
3551
3755
  return Math.max(0.4, Math.min(1, availW / tW));
3552
3756
  };
3553
3757
  try {
@@ -3567,9 +3771,13 @@ var ExcelPlugin = class {
3567
3771
  contentArea.innerHTML = '<div style="padding: 24px; color: #888;">Empty sheet</div>';
3568
3772
  return;
3569
3773
  }
3774
+ const sizer = document.createElement("div");
3775
+ sizer.className = "fp-excel-sizer";
3776
+ sizer.style.position = "relative";
3570
3777
  const html = XLSX.utils.sheet_to_html(ws, { id: "fp-sheet-table", editable: false });
3571
- contentArea.innerHTML = html;
3572
- const table = contentArea.querySelector("table");
3778
+ sizer.innerHTML = html;
3779
+ contentArea.appendChild(sizer);
3780
+ const table = sizer.querySelector("table");
3573
3781
  if (table) {
3574
3782
  table.style.borderCollapse = "collapse";
3575
3783
  table.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
@@ -3604,13 +3812,17 @@ var ExcelPlugin = class {
3604
3812
  });
3605
3813
  ctx.emit("page-change", { page: currentSheetIndex, total: sheetNames.length });
3606
3814
  requestAnimationFrame(() => {
3607
- scale = calculateFitScale();
3815
+ if (!isUserZoomed) {
3816
+ scale = calculateFitScale();
3817
+ }
3608
3818
  applyTransform();
3609
3819
  });
3610
3820
  };
3611
3821
  const ro = new ResizeObserver(() => {
3612
- scale = calculateFitScale();
3613
- applyTransform();
3822
+ if (!isUserZoomed) {
3823
+ scale = calculateFitScale();
3824
+ applyTransform();
3825
+ }
3614
3826
  });
3615
3827
  ro.observe(container);
3616
3828
  if (sheetNames.length > 0) {
@@ -3647,20 +3859,31 @@ var ExcelPlugin = class {
3647
3859
  return {
3648
3860
  destroy: cleanup,
3649
3861
  zoomIn: () => {
3862
+ isUserZoomed = true;
3650
3863
  scale += 0.15;
3651
3864
  applyTransform();
3652
3865
  },
3653
3866
  zoomOut: () => {
3867
+ isUserZoomed = true;
3654
3868
  scale = Math.max(0.2, scale - 0.15);
3655
3869
  applyTransform();
3656
3870
  },
3657
3871
  getZoom: () => scale,
3658
3872
  setZoom: (level) => {
3873
+ isUserZoomed = true;
3659
3874
  scale = level;
3660
3875
  applyTransform();
3661
3876
  },
3662
3877
  fitToPage: () => {
3878
+ isUserZoomed = false;
3879
+ scale = calculateFitScale();
3880
+ applyTransform();
3881
+ },
3882
+ resetZoom: () => {
3883
+ isUserZoomed = false;
3663
3884
  scale = calculateFitScale();
3885
+ contentArea.scrollTop = 0;
3886
+ contentArea.scrollLeft = 0;
3664
3887
  applyTransform();
3665
3888
  },
3666
3889
  rotateCW: () => {
@@ -3793,6 +4016,16 @@ var CsvPlugin = class {
3793
4016
  instance.zoomIn?.();
3794
4017
  }
3795
4018
  },
4019
+ {
4020
+ id: "reset-zoom",
4021
+ icon: "reset-zoom",
4022
+ label: "Reset Zoom",
4023
+ type: "button",
4024
+ group: "zoom",
4025
+ execute: () => {
4026
+ instance.resetZoom?.();
4027
+ }
4028
+ },
3796
4029
  {
3797
4030
  id: "download",
3798
4031
  icon: "download",
@@ -3879,21 +4112,41 @@ var CsvPlugin = class {
3879
4112
  container.appendChild(tableWrapper);
3880
4113
  ctx.container.appendChild(container);
3881
4114
  let scale = 1;
4115
+ let isUserZoomed = false;
3882
4116
  const calculateFitScale = () => {
3883
4117
  const availW = Math.max(280, container.clientWidth - 48);
3884
- const tW = table.offsetWidth || 800;
4118
+ const tW = table._baseWidth || table.offsetWidth || 800;
3885
4119
  return Math.max(0.4, Math.min(1, availW / tW));
3886
4120
  };
3887
4121
  const applyScale = () => {
3888
- tableWrapper.style.transform = `scale(${scale})`;
4122
+ if (!table._baseWidth && table.offsetWidth > 0) {
4123
+ table._baseWidth = table.offsetWidth;
4124
+ table._baseHeight = table.offsetHeight;
4125
+ }
4126
+ const baseW = table._baseWidth || table.offsetWidth || 800;
4127
+ const baseH = table._baseHeight || table.offsetHeight || 600;
4128
+ const scaledW = Math.round(baseW * scale);
4129
+ const scaledH = Math.round(baseH * scale);
4130
+ tableWrapper.style.position = "relative";
4131
+ tableWrapper.style.width = `${scaledW}px`;
4132
+ tableWrapper.style.height = `${scaledH}px`;
4133
+ table.style.position = "absolute";
4134
+ table.style.top = "0";
4135
+ table.style.left = "0";
4136
+ table.style.transform = `scale(${scale})`;
4137
+ table.style.transformOrigin = "top left";
3889
4138
  };
3890
4139
  requestAnimationFrame(() => {
3891
- scale = calculateFitScale();
4140
+ if (!isUserZoomed) {
4141
+ scale = calculateFitScale();
4142
+ }
3892
4143
  applyScale();
3893
4144
  });
3894
4145
  const ro = new ResizeObserver(() => {
3895
- scale = calculateFitScale();
3896
- applyScale();
4146
+ if (!isUserZoomed) {
4147
+ scale = calculateFitScale();
4148
+ applyScale();
4149
+ }
3897
4150
  });
3898
4151
  ro.observe(container);
3899
4152
  const cleanup = () => {
@@ -3966,20 +4219,31 @@ var CsvPlugin = class {
3966
4219
  }];
3967
4220
  },
3968
4221
  zoomIn: () => {
4222
+ isUserZoomed = true;
3969
4223
  scale += 0.1;
3970
4224
  applyScale();
3971
4225
  },
3972
4226
  zoomOut: () => {
4227
+ isUserZoomed = true;
3973
4228
  scale = Math.max(0.2, scale - 0.1);
3974
4229
  applyScale();
3975
4230
  },
3976
4231
  getZoom: () => scale,
3977
4232
  setZoom: (level) => {
4233
+ isUserZoomed = true;
3978
4234
  scale = level;
3979
4235
  applyScale();
3980
4236
  },
3981
4237
  fitToPage: () => {
4238
+ isUserZoomed = false;
4239
+ scale = calculateFitScale();
4240
+ applyScale();
4241
+ },
4242
+ resetZoom: () => {
4243
+ isUserZoomed = false;
3982
4244
  scale = calculateFitScale();
4245
+ container.scrollTop = 0;
4246
+ container.scrollLeft = 0;
3983
4247
  applyScale();
3984
4248
  },
3985
4249
  rotateCW: () => {
@@ -4097,6 +4361,16 @@ var CodePlugin = class {
4097
4361
  instance.zoomIn?.();
4098
4362
  }
4099
4363
  },
4364
+ {
4365
+ id: "reset-zoom",
4366
+ icon: "reset-zoom",
4367
+ label: "Reset Zoom",
4368
+ type: "button",
4369
+ group: "zoom",
4370
+ execute: () => {
4371
+ instance.resetZoom?.();
4372
+ }
4373
+ },
4100
4374
  {
4101
4375
  id: "copy",
4102
4376
  icon: "copy",
@@ -4202,15 +4476,27 @@ var CodePlugin = class {
4202
4476
  let isUserZoomed = false;
4203
4477
  const pre = document.createElement("pre");
4204
4478
  const code = document.createElement("code");
4479
+ const sizer = document.createElement("div");
4480
+ const scrollWrapper = document.createElement("div");
4205
4481
  if (isTxt) {
4206
- container.style.overflowX = "hidden";
4207
- container.style.overflowY = "auto";
4482
+ container.style.overflow = "auto";
4208
4483
  container.style.backgroundColor = "#f1f5f9";
4209
- container.style.padding = "16px 8px";
4210
- container.style.boxSizing = "border-box";
4211
- container.style.display = "flex";
4212
- container.style.flexDirection = "column";
4213
- container.style.alignItems = "center";
4484
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4485
+ scrollWrapper.style.minWidth = "100%";
4486
+ scrollWrapper.style.minHeight = "100%";
4487
+ scrollWrapper.style.width = "max-content";
4488
+ scrollWrapper.style.height = "max-content";
4489
+ scrollWrapper.style.display = "flex";
4490
+ scrollWrapper.style.justifyContent = "center";
4491
+ scrollWrapper.style.alignItems = "flex-start";
4492
+ scrollWrapper.style.padding = "16px 8px";
4493
+ scrollWrapper.style.boxSizing = "border-box";
4494
+ sizer.className = "fp-code-sizer";
4495
+ sizer.style.position = "relative";
4496
+ sizer.style.flexShrink = "0";
4497
+ sizer.style.display = "flex";
4498
+ sizer.style.justifyContent = "center";
4499
+ sizer.style.alignItems = "center";
4214
4500
  pre.style.margin = "0 auto";
4215
4501
  pre.style.fontFamily = "Consolas, 'Courier New', monospace";
4216
4502
  pre.style.fontSize = "13px";
@@ -4225,8 +4511,9 @@ var CodePlugin = class {
4225
4511
  pre.style.boxSizing = "border-box";
4226
4512
  pre.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4227
4513
  pre.style.borderRadius = "4px";
4228
- pre.style.transformOrigin = "top center";
4514
+ pre.style.transformOrigin = "center center";
4229
4515
  pre.style.transition = "transform 0.15s ease";
4516
+ pre.style.flexShrink = "0";
4230
4517
  } else {
4231
4518
  container.style.overflow = "auto";
4232
4519
  container.style.backgroundColor = "#1e1e1e";
@@ -4259,7 +4546,13 @@ var CodePlugin = class {
4259
4546
  };
4260
4547
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4261
4548
  pre.appendChild(code);
4262
- container.appendChild(pre);
4549
+ if (isTxt) {
4550
+ sizer.appendChild(pre);
4551
+ scrollWrapper.appendChild(sizer);
4552
+ container.appendChild(scrollWrapper);
4553
+ } else {
4554
+ container.appendChild(pre);
4555
+ }
4263
4556
  const showPage = (pageNum) => {
4264
4557
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4265
4558
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
@@ -4276,10 +4569,16 @@ var CodePlugin = class {
4276
4569
  };
4277
4570
  const updateTransform = () => {
4278
4571
  if (isTxt) {
4572
+ const elW = 816;
4573
+ const baseH = pre.offsetHeight || 1056;
4574
+ const isRotated90 = rotation % 180 !== 0;
4575
+ const boxW = Math.round((isRotated90 ? baseH : elW) * zoomLevel);
4576
+ const boxH = Math.round((isRotated90 ? elW : baseH) * zoomLevel);
4577
+ sizer.style.width = `${boxW}px`;
4578
+ sizer.style.height = `${boxH}px`;
4579
+ pre.style.width = `${elW}px`;
4279
4580
  pre.style.transform = `scale(${zoomLevel}) rotate(${rotation}deg)`;
4280
- const scaledH = 1056 * zoomLevel;
4281
- const extraH = Math.max(0, scaledH - 1056);
4282
- pre.style.marginBottom = `${extraH + 32}px`;
4581
+ pre.style.transformOrigin = "center center";
4283
4582
  } else {
4284
4583
  pre.style.transform = `rotate(${rotation}deg)`;
4285
4584
  pre.style.fontSize = `${fontSize}px`;
@@ -4376,6 +4675,15 @@ var CodePlugin = class {
4376
4675
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4377
4676
  updateTransform();
4378
4677
  },
4678
+ resetZoom: () => {
4679
+ isUserZoomed = false;
4680
+ fontSize = 13;
4681
+ rotation = 0;
4682
+ zoomLevel = isTxt ? calculateTxtFit() : 1;
4683
+ container.scrollTop = 0;
4684
+ container.scrollLeft = 0;
4685
+ updateTransform();
4686
+ },
4379
4687
  rotateCW: () => {
4380
4688
  rotation = (rotation + 90) % 360;
4381
4689
  updateTransform();
@@ -4438,11 +4746,19 @@ var ArchivePlugin = class {
4438
4746
  {
4439
4747
  id: "fit-page",
4440
4748
  icon: "fit-page",
4441
- label: "Reset Zoom",
4749
+ label: "Fit to Page",
4442
4750
  type: "button",
4443
4751
  group: "zoom",
4444
4752
  execute: () => instance.fitToPage?.()
4445
4753
  },
4754
+ {
4755
+ id: "reset-zoom",
4756
+ icon: "reset-zoom",
4757
+ label: "Reset Zoom",
4758
+ type: "button",
4759
+ group: "zoom",
4760
+ execute: () => instance.resetZoom?.()
4761
+ },
4446
4762
  {
4447
4763
  id: "download",
4448
4764
  icon: "download",
@@ -4468,16 +4784,56 @@ var ArchivePlugin = class {
4468
4784
  width: 100%;
4469
4785
  height: 100%;
4470
4786
  overflow: auto;
4471
- padding: 24px;
4472
4787
  box-sizing: border-box;
4473
4788
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
4474
- transform-origin: top left;
4475
- transition: transform 0.2s ease;
4476
4789
  `;
4790
+ const scrollWrapper = document.createElement("div");
4791
+ scrollWrapper.className = "fp-archive-scroll-wrapper";
4792
+ scrollWrapper.style.cssText = `
4793
+ min-width: 100%;
4794
+ min-height: 100%;
4795
+ width: max-content;
4796
+ height: max-content;
4797
+ display: flex;
4798
+ justify-content: center;
4799
+ align-items: flex-start;
4800
+ padding: 24px;
4801
+ box-sizing: border-box;
4802
+ `;
4803
+ const sizer = document.createElement("div");
4804
+ sizer.className = "fp-archive-sizer";
4805
+ sizer.style.cssText = `
4806
+ position: relative;
4807
+ flex-shrink: 0;
4808
+ display: flex;
4809
+ justify-content: center;
4810
+ align-items: flex-start;
4811
+ `;
4812
+ const card = document.createElement("div");
4813
+ card.className = "fp-archive-card";
4814
+ card.style.cssText = `
4815
+ width: 900px;
4816
+ box-sizing: border-box;
4817
+ transform-origin: top center;
4818
+ transition: transform 0.15s ease;
4819
+ flex-shrink: 0;
4820
+ `;
4821
+ sizer.appendChild(card);
4822
+ scrollWrapper.appendChild(sizer);
4823
+ wrapper.appendChild(scrollWrapper);
4477
4824
  ctx.container.innerHTML = "";
4478
4825
  ctx.container.style.overflow = "auto";
4479
4826
  ctx.container.appendChild(wrapper);
4480
4827
  let scale = 1;
4828
+ const applyTransform = () => {
4829
+ const boxW = Math.round(900 * scale);
4830
+ const cardH = card.offsetHeight || 600;
4831
+ const boxH = Math.round(cardH * scale);
4832
+ sizer.style.width = `${boxW}px`;
4833
+ sizer.style.height = `${boxH}px`;
4834
+ card.style.transform = `scale(${scale})`;
4835
+ card.style.transformOrigin = "top center";
4836
+ };
4481
4837
  const entries = await new Promise((resolve, reject) => {
4482
4838
  unzip(new Uint8Array(ctx.buffer), (err, unzipped) => {
4483
4839
  if (err) {
@@ -4501,7 +4857,7 @@ var ArchivePlugin = class {
4501
4857
  });
4502
4858
  const totalUncompressedSize = entries.reduce((acc, e) => acc + e.size, 0);
4503
4859
  const renderUI = (filteredEntries) => {
4504
- wrapper.innerHTML = `
4860
+ card.innerHTML = `
4505
4861
  <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;">
4506
4862
  <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;">
4507
4863
  <div>
@@ -4531,7 +4887,7 @@ var ArchivePlugin = class {
4531
4887
  </div>
4532
4888
  </div>
4533
4889
  `;
4534
- const tbody = wrapper.querySelector("#fp-archive-body");
4890
+ const tbody = card.querySelector("#fp-archive-body");
4535
4891
  if (filteredEntries.length === 0) {
4536
4892
  tbody.innerHTML = `<tr><td colspan="3" style="padding: 24px; text-align: center; color: #9ca3af;">No matching files found</td></tr>`;
4537
4893
  } else {
@@ -4560,19 +4916,20 @@ var ArchivePlugin = class {
4560
4916
  }
4561
4917
  });
4562
4918
  });
4563
- const searchInput = wrapper.querySelector("#fp-archive-search");
4919
+ const searchInput = card.querySelector("#fp-archive-search");
4564
4920
  if (searchInput) {
4565
4921
  searchInput.addEventListener("input", () => {
4566
4922
  const q = searchInput.value.toLowerCase().trim();
4567
4923
  const filtered = q ? entries.filter((e) => e.path.toLowerCase().includes(q)) : entries;
4568
4924
  renderUI(filtered);
4569
- const newSearch = wrapper.querySelector("#fp-archive-search");
4925
+ const newSearch = card.querySelector("#fp-archive-search");
4570
4926
  if (newSearch) {
4571
4927
  newSearch.value = q;
4572
4928
  newSearch.focus();
4573
4929
  }
4574
4930
  });
4575
4931
  }
4932
+ applyTransform();
4576
4933
  };
4577
4934
  renderUI(entries);
4578
4935
  const cleanup = () => {
@@ -4584,20 +4941,26 @@ var ArchivePlugin = class {
4584
4941
  destroy: cleanup,
4585
4942
  zoomIn: () => {
4586
4943
  scale += 0.1;
4587
- wrapper.style.transform = `scale(${scale})`;
4944
+ applyTransform();
4588
4945
  },
4589
4946
  zoomOut: () => {
4590
4947
  scale = Math.max(0.3, scale - 0.1);
4591
- wrapper.style.transform = `scale(${scale})`;
4948
+ applyTransform();
4592
4949
  },
4593
4950
  getZoom: () => scale,
4594
4951
  setZoom: (level) => {
4595
4952
  scale = level;
4596
- wrapper.style.transform = `scale(${scale})`;
4953
+ applyTransform();
4597
4954
  },
4598
4955
  fitToPage: () => {
4599
4956
  scale = 1;
4600
- wrapper.style.transform = `scale(1)`;
4957
+ applyTransform();
4958
+ },
4959
+ resetZoom: () => {
4960
+ scale = 1;
4961
+ wrapper.scrollTop = 0;
4962
+ wrapper.scrollLeft = 0;
4963
+ applyTransform();
4601
4964
  },
4602
4965
  download: () => {
4603
4966
  downloadFile(ctx.buffer, ctx.metadata.name || "archive.zip", "application/zip");
@@ -4649,6 +5012,14 @@ var MarkdownPlugin = class {
4649
5012
  group: "zoom",
4650
5013
  execute: () => instance.fitToPage?.()
4651
5014
  },
5015
+ {
5016
+ id: "reset-zoom",
5017
+ icon: "reset-zoom",
5018
+ label: "Reset Zoom",
5019
+ type: "button",
5020
+ group: "zoom",
5021
+ execute: () => instance.resetZoom?.()
5022
+ },
4652
5023
  {
4653
5024
  id: "copy",
4654
5025
  icon: "copy",
@@ -4802,6 +5173,12 @@ var MarkdownPlugin = class {
4802
5173
  fontSize = 15;
4803
5174
  wrapper.style.fontSize = "15px";
4804
5175
  },
5176
+ resetZoom: () => {
5177
+ fontSize = 15;
5178
+ wrapper.style.fontSize = "15px";
5179
+ ctx.container.scrollTop = 0;
5180
+ ctx.container.scrollLeft = 0;
5181
+ },
4805
5182
  download: () => {
4806
5183
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
4807
5184
  },
@@ -4895,6 +5272,14 @@ var PptxPlugin = class {
4895
5272
  group: "zoom",
4896
5273
  execute: () => instance.fitToPage?.()
4897
5274
  },
5275
+ {
5276
+ id: "reset-zoom",
5277
+ icon: "reset-zoom",
5278
+ label: "Reset Zoom",
5279
+ type: "button",
5280
+ group: "zoom",
5281
+ execute: () => instance.resetZoom?.()
5282
+ },
4898
5283
  {
4899
5284
  id: "rotate-cw",
4900
5285
  icon: "rotate-cw",
@@ -4934,12 +5319,30 @@ var PptxPlugin = class {
4934
5319
  width: 100%;
4935
5320
  height: 100%;
4936
5321
  overflow: auto;
5322
+ box-sizing: border-box;
5323
+ background: var(--fp-bg-canvas, #525659);
5324
+ `;
5325
+ const scrollWrapper = document.createElement("div");
5326
+ scrollWrapper.className = "fp-pptx-scroll-wrapper";
5327
+ scrollWrapper.style.cssText = `
5328
+ min-width: 100%;
5329
+ min-height: 100%;
5330
+ width: max-content;
5331
+ height: max-content;
4937
5332
  display: flex;
4938
5333
  justify-content: center;
4939
- align-items: flex-start;
5334
+ align-items: center;
4940
5335
  padding: 24px;
4941
5336
  box-sizing: border-box;
4942
- background: var(--fp-bg-canvas, #525659);
5337
+ `;
5338
+ const sizer = document.createElement("div");
5339
+ sizer.className = "fp-pptx-sizer";
5340
+ sizer.style.cssText = `
5341
+ position: relative;
5342
+ flex-shrink: 0;
5343
+ display: flex;
5344
+ justify-content: center;
5345
+ align-items: center;
4943
5346
  `;
4944
5347
  const slideContainer = document.createElement("div");
4945
5348
  slideContainer.className = "fp-slide-container";
@@ -4948,14 +5351,15 @@ var PptxPlugin = class {
4948
5351
  border-radius: 4px;
4949
5352
  overflow: hidden;
4950
5353
  background: #ffffff;
4951
- transform-origin: top center;
5354
+ transform-origin: center center;
4952
5355
  transition: transform 0.2s ease;
4953
- max-width: calc(100% - 32px);
4954
- max-height: calc(100% - 48px);
5356
+ flex-shrink: 0;
4955
5357
  `;
4956
5358
  const canvas = document.createElement("canvas");
4957
5359
  slideContainer.appendChild(canvas);
4958
- wrapper.appendChild(slideContainer);
5360
+ sizer.appendChild(slideContainer);
5361
+ scrollWrapper.appendChild(sizer);
5362
+ wrapper.appendChild(scrollWrapper);
4959
5363
  ctx.container.innerHTML = "";
4960
5364
  ctx.container.style.overflow = "auto";
4961
5365
  ctx.container.appendChild(wrapper);
@@ -4967,7 +5371,17 @@ var PptxPlugin = class {
4967
5371
  return Math.min(1, Math.min(availW / cW, availH / cH));
4968
5372
  };
4969
5373
  const applyTransform = () => {
5374
+ const cW = canvas.offsetWidth || 1280;
5375
+ const cH = canvas.offsetHeight || 720;
5376
+ const isRotated90 = rotation % 180 !== 0;
5377
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
5378
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
5379
+ sizer.style.width = `${boxW}px`;
5380
+ sizer.style.height = `${boxH}px`;
5381
+ slideContainer.style.width = `${cW}px`;
5382
+ slideContainer.style.height = `${cH}px`;
4970
5383
  slideContainer.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5384
+ slideContainer.style.transformOrigin = "center center";
4971
5385
  };
4972
5386
  const renderCurrentSlide = async () => {
4973
5387
  try {
@@ -5014,6 +5428,13 @@ var PptxPlugin = class {
5014
5428
  rotation = 0;
5015
5429
  applyTransform();
5016
5430
  },
5431
+ resetZoom: () => {
5432
+ scale = calculateFitScale();
5433
+ rotation = 0;
5434
+ wrapper.scrollTop = 0;
5435
+ wrapper.scrollLeft = 0;
5436
+ applyTransform();
5437
+ },
5017
5438
  rotateCW: () => {
5018
5439
  rotation = (rotation + 90) % 360;
5019
5440
  applyTransform();
@@ -5089,6 +5510,14 @@ var ThreeDPlugin = class {
5089
5510
  group: "zoom",
5090
5511
  execute: () => instance.fitToPage?.()
5091
5512
  },
5513
+ {
5514
+ id: "reset-zoom",
5515
+ icon: "reset-zoom",
5516
+ label: "Reset Zoom",
5517
+ type: "button",
5518
+ group: "zoom",
5519
+ execute: () => instance.resetZoom?.()
5520
+ },
5092
5521
  {
5093
5522
  id: "rotate-cw",
5094
5523
  icon: "rotate-cw",
@@ -5225,6 +5654,7 @@ var ThreeDPlugin = class {
5225
5654
  controls.update();
5226
5655
  },
5227
5656
  fitToPage: fitCamera,
5657
+ resetZoom: fitCamera,
5228
5658
  rotateCW: () => {
5229
5659
  isWireframe = !isWireframe;
5230
5660
  materials.forEach((m) => {
@@ -5439,6 +5869,14 @@ var RtfPlugin = class {
5439
5869
  group: "zoom",
5440
5870
  execute: () => instance.fitToPage?.()
5441
5871
  },
5872
+ {
5873
+ id: "reset-zoom",
5874
+ icon: "reset-zoom",
5875
+ label: "Reset Zoom",
5876
+ type: "button",
5877
+ group: "zoom",
5878
+ execute: () => instance.resetZoom?.()
5879
+ },
5442
5880
  {
5443
5881
  id: "rotate-cw",
5444
5882
  icon: "rotate-cw",
@@ -5549,13 +5987,33 @@ var RtfPlugin = class {
5549
5987
  wrapper.style.flexDirection = "column";
5550
5988
  wrapper.style.alignItems = "center";
5551
5989
  wrapper.style.backgroundColor = "transparent";
5552
- wrapper.style.transformOrigin = "top center";
5990
+ wrapper.style.transformOrigin = "center center";
5553
5991
  wrapper.style.transition = "transform 0.15s ease";
5554
- ctx.container.style.overflowX = "hidden";
5555
- ctx.container.style.overflowY = "auto";
5556
- ctx.container.style.padding = "16px 8px";
5992
+ wrapper.style.flexShrink = "0";
5993
+ const sizer = document.createElement("div");
5994
+ sizer.className = "fp-rtf-sizer";
5995
+ sizer.style.position = "relative";
5996
+ sizer.style.flexShrink = "0";
5997
+ sizer.style.display = "flex";
5998
+ sizer.style.justifyContent = "center";
5999
+ sizer.style.alignItems = "center";
6000
+ const scrollWrapper = document.createElement("div");
6001
+ scrollWrapper.className = "fp-rtf-scroll-wrapper";
6002
+ scrollWrapper.style.minWidth = "100%";
6003
+ scrollWrapper.style.minHeight = "100%";
6004
+ scrollWrapper.style.width = "max-content";
6005
+ scrollWrapper.style.height = "max-content";
6006
+ scrollWrapper.style.display = "flex";
6007
+ scrollWrapper.style.justifyContent = "center";
6008
+ scrollWrapper.style.alignItems = "flex-start";
6009
+ scrollWrapper.style.padding = "16px 8px";
6010
+ scrollWrapper.style.boxSizing = "border-box";
6011
+ sizer.appendChild(wrapper);
6012
+ scrollWrapper.appendChild(sizer);
6013
+ ctx.container.style.overflow = "auto";
6014
+ ctx.container.style.padding = "0";
5557
6015
  ctx.container.style.backgroundColor = "#f1f5f9";
5558
- ctx.container.appendChild(wrapper);
6016
+ ctx.container.appendChild(scrollWrapper);
5559
6017
  let scale = 1;
5560
6018
  let rotation = 0;
5561
6019
  let pageElements = [];
@@ -5574,12 +6032,17 @@ var RtfPlugin = class {
5574
6032
  return Math.max(0.4, Math.min(3, sW));
5575
6033
  };
5576
6034
  const applyTransform = () => {
5577
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5578
- wrapper.style.transformOrigin = "top center";
6035
+ const elW = pageWidth;
5579
6036
  const baseH = pageHeight;
5580
- const scaledH = baseH * scale;
5581
- const extraH = Math.max(0, scaledH - baseH);
5582
- wrapper.style.marginBottom = `${extraH + 32}px`;
6037
+ const isRotated90 = rotation % 180 !== 0;
6038
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6039
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6040
+ sizer.style.width = `${boxW}px`;
6041
+ sizer.style.height = `${boxH}px`;
6042
+ wrapper.style.width = `${elW}px`;
6043
+ wrapper.style.height = `${baseH}px`;
6044
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6045
+ wrapper.style.transformOrigin = "center center";
5583
6046
  };
5584
6047
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5585
6048
  if (!isUserZoomed) {
@@ -5850,7 +6313,7 @@ var RtfPlugin = class {
5850
6313
  }
5851
6314
  const cleanup = () => {
5852
6315
  resizeObserver?.disconnect();
5853
- wrapper.remove();
6316
+ scrollWrapper.remove();
5854
6317
  ctx.container.innerHTML = "";
5855
6318
  };
5856
6319
  ctx.signal.addEventListener("abort", cleanup);
@@ -5908,6 +6371,15 @@ var RtfPlugin = class {
5908
6371
  rotation = 0;
5909
6372
  applyTransform();
5910
6373
  },
6374
+ resetZoom: () => {
6375
+ isUserZoomed = false;
6376
+ fitMode = "width";
6377
+ scale = calculateFitScale("width");
6378
+ rotation = 0;
6379
+ ctx.container.scrollTop = 0;
6380
+ ctx.container.scrollLeft = 0;
6381
+ applyTransform();
6382
+ },
5911
6383
  rotateCW: () => {
5912
6384
  rotation = (rotation + 90) % 360;
5913
6385
  applyTransform();
@@ -5975,6 +6447,14 @@ var HtmlPreviewPlugin = class {
5975
6447
  group: "zoom",
5976
6448
  execute: () => instance.fitToPage?.()
5977
6449
  },
6450
+ {
6451
+ id: "reset-zoom",
6452
+ icon: "reset-zoom",
6453
+ label: "Reset Zoom",
6454
+ type: "button",
6455
+ group: "zoom",
6456
+ execute: () => instance.resetZoom?.()
6457
+ },
5978
6458
  {
5979
6459
  id: "copy",
5980
6460
  icon: "copy",
@@ -6008,23 +6488,44 @@ var HtmlPreviewPlugin = class {
6008
6488
  ADD_TAGS: ["style", "link"],
6009
6489
  ADD_ATTR: ["target", "rel"]
6010
6490
  });
6491
+ const sizer = document.createElement("div");
6492
+ sizer.className = "fp-html-sizer";
6493
+ sizer.style.position = "relative";
6011
6494
  const iframe = document.createElement("iframe");
6012
6495
  iframe.className = "fp-html-iframe";
6013
- iframe.style.width = "100%";
6014
- iframe.style.height = "100%";
6015
6496
  iframe.style.border = "none";
6016
6497
  iframe.style.backgroundColor = "#ffffff";
6017
6498
  iframe.style.transformOrigin = "top left";
6018
6499
  iframe.style.transition = "transform 0.2s ease";
6019
6500
  iframe.sandbox.add("allow-same-origin");
6501
+ sizer.appendChild(iframe);
6020
6502
  ctx.container.style.overflow = "auto";
6021
6503
  ctx.container.style.width = "100%";
6022
6504
  ctx.container.style.height = "100%";
6023
- ctx.container.appendChild(iframe);
6505
+ ctx.container.innerHTML = "";
6506
+ ctx.container.appendChild(sizer);
6024
6507
  iframe.srcdoc = sanitized;
6025
6508
  let scale = 1;
6509
+ const applyTransform = () => {
6510
+ const baseW = Math.max(600, ctx.container.clientWidth || 800);
6511
+ const baseH = Math.max(400, ctx.container.clientHeight || 600);
6512
+ const scaledW = Math.round(baseW * scale);
6513
+ const scaledH = Math.round(baseH * scale);
6514
+ sizer.style.width = `${scaledW}px`;
6515
+ sizer.style.height = `${scaledH}px`;
6516
+ iframe.style.position = "absolute";
6517
+ iframe.style.top = "0";
6518
+ iframe.style.left = "0";
6519
+ iframe.style.width = `${baseW}px`;
6520
+ iframe.style.height = `${baseH}px`;
6521
+ iframe.style.transform = `scale(${scale})`;
6522
+ iframe.style.transformOrigin = "top left";
6523
+ };
6524
+ requestAnimationFrame(() => {
6525
+ applyTransform();
6526
+ });
6026
6527
  const cleanup = () => {
6027
- iframe.remove();
6528
+ sizer.remove();
6028
6529
  ctx.container.innerHTML = "";
6029
6530
  };
6030
6531
  ctx.signal.addEventListener("abort", cleanup);
@@ -6032,20 +6533,26 @@ var HtmlPreviewPlugin = class {
6032
6533
  destroy: cleanup,
6033
6534
  zoomIn: () => {
6034
6535
  scale += 0.1;
6035
- iframe.style.transform = `scale(${scale})`;
6536
+ applyTransform();
6036
6537
  },
6037
6538
  zoomOut: () => {
6038
6539
  scale = Math.max(0.2, scale - 0.1);
6039
- iframe.style.transform = `scale(${scale})`;
6540
+ applyTransform();
6040
6541
  },
6041
6542
  getZoom: () => scale,
6042
6543
  setZoom: (level) => {
6043
6544
  scale = level;
6044
- iframe.style.transform = `scale(${scale})`;
6545
+ applyTransform();
6045
6546
  },
6046
6547
  fitToPage: () => {
6047
6548
  scale = 1;
6048
- iframe.style.transform = "scale(1)";
6549
+ applyTransform();
6550
+ },
6551
+ resetZoom: () => {
6552
+ scale = 1;
6553
+ ctx.container.scrollTop = 0;
6554
+ ctx.container.scrollLeft = 0;
6555
+ applyTransform();
6049
6556
  },
6050
6557
  copy: () => {
6051
6558
  navigator.clipboard.writeText(rawHtml);
@@ -6147,6 +6654,14 @@ var OpenDocumentPlugin = class {
6147
6654
  group: "zoom",
6148
6655
  execute: () => instance.fitToPage?.()
6149
6656
  },
6657
+ {
6658
+ id: "reset-zoom",
6659
+ icon: "reset-zoom",
6660
+ label: "Reset Zoom",
6661
+ type: "button",
6662
+ group: "zoom",
6663
+ execute: () => instance.resetZoom?.()
6664
+ },
6150
6665
  {
6151
6666
  id: "rotate-cw",
6152
6667
  icon: "rotate-cw",
@@ -6212,10 +6727,26 @@ var OpenDocumentPlugin = class {
6212
6727
  container.className = "fp-odf-container";
6213
6728
  container.style.width = "100%";
6214
6729
  container.style.height = "100%";
6215
- container.style.overflowX = "hidden";
6216
- container.style.overflowY = "auto";
6217
- container.style.padding = "16px 8px";
6730
+ container.style.overflow = "auto";
6218
6731
  container.style.backgroundColor = "#f1f5f9";
6732
+ const scrollWrapper = document.createElement("div");
6733
+ scrollWrapper.className = "fp-odf-scroll-wrapper";
6734
+ scrollWrapper.style.minWidth = "100%";
6735
+ scrollWrapper.style.minHeight = "100%";
6736
+ scrollWrapper.style.width = "max-content";
6737
+ scrollWrapper.style.height = "max-content";
6738
+ scrollWrapper.style.display = "flex";
6739
+ scrollWrapper.style.justifyContent = "center";
6740
+ scrollWrapper.style.alignItems = "flex-start";
6741
+ scrollWrapper.style.padding = "16px 8px";
6742
+ scrollWrapper.style.boxSizing = "border-box";
6743
+ const sizer = document.createElement("div");
6744
+ sizer.className = "fp-odf-sizer";
6745
+ sizer.style.position = "relative";
6746
+ sizer.style.flexShrink = "0";
6747
+ sizer.style.display = "flex";
6748
+ sizer.style.justifyContent = "center";
6749
+ sizer.style.alignItems = "center";
6219
6750
  const wrapper = document.createElement("div");
6220
6751
  wrapper.className = "fp-odf-wrapper";
6221
6752
  wrapper.style.margin = "0 auto";
@@ -6224,9 +6755,12 @@ var OpenDocumentPlugin = class {
6224
6755
  wrapper.style.backgroundColor = "#ffffff";
6225
6756
  wrapper.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
6226
6757
  wrapper.style.borderRadius = "4px";
6227
- wrapper.style.transformOrigin = "top center";
6758
+ wrapper.style.transformOrigin = "center center";
6228
6759
  wrapper.style.transition = "transform 0.15s ease";
6229
- container.appendChild(wrapper);
6760
+ wrapper.style.flexShrink = "0";
6761
+ sizer.appendChild(wrapper);
6762
+ scrollWrapper.appendChild(sizer);
6763
+ container.appendChild(scrollWrapper);
6230
6764
  ctx.container.appendChild(container);
6231
6765
  let scale = 1;
6232
6766
  let rotation = 0;
@@ -6252,13 +6786,18 @@ var OpenDocumentPlugin = class {
6252
6786
  return Math.max(0.4, Math.min(3, sW));
6253
6787
  };
6254
6788
  const applyTransform = () => {
6255
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6256
- wrapper.style.transformOrigin = "top center";
6257
6789
  const activeSlide = slides[currentPage - 1];
6790
+ const elW = isPresentation ? 960 : 816;
6258
6791
  const baseH = activeSlide?.offsetHeight || wrapper.offsetHeight || 1056;
6259
- const scaledH = baseH * scale;
6260
- const extraH = Math.max(0, scaledH - baseH);
6261
- wrapper.style.marginBottom = `${extraH + 32}px`;
6792
+ const isRotated90 = rotation % 180 !== 0;
6793
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6794
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6795
+ sizer.style.width = `${boxW}px`;
6796
+ sizer.style.height = `${boxH}px`;
6797
+ wrapper.style.width = `${elW}px`;
6798
+ wrapper.style.height = `${baseH}px`;
6799
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6800
+ wrapper.style.transformOrigin = "center center";
6262
6801
  };
6263
6802
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
6264
6803
  if (!isUserZoomed) {
@@ -6414,6 +6953,15 @@ var OpenDocumentPlugin = class {
6414
6953
  rotation = 0;
6415
6954
  applyTransform();
6416
6955
  },
6956
+ resetZoom: () => {
6957
+ isUserZoomed = false;
6958
+ fitMode = "width";
6959
+ scale = calculateFitScale("width");
6960
+ rotation = 0;
6961
+ container.scrollTop = 0;
6962
+ container.scrollLeft = 0;
6963
+ applyTransform();
6964
+ },
6417
6965
  rotateCW: () => {
6418
6966
  rotation = (rotation + 90) % 360;
6419
6967
  applyTransform();
@@ -6757,6 +7305,14 @@ var DocPlugin = class {
6757
7305
  group: "zoom",
6758
7306
  execute: () => instance.fitToPage?.()
6759
7307
  },
7308
+ {
7309
+ id: "reset-zoom",
7310
+ icon: "reset-zoom",
7311
+ label: "Reset Zoom",
7312
+ type: "button",
7313
+ group: "zoom",
7314
+ execute: () => instance.resetZoom?.()
7315
+ },
6760
7316
  {
6761
7317
  id: "rotate-cw",
6762
7318
  icon: "rotate-cw",
@@ -6805,13 +7361,28 @@ var DocPlugin = class {
6805
7361
  container.className = "fp-doc-container";
6806
7362
  container.style.width = "100%";
6807
7363
  container.style.height = "100%";
6808
- container.style.overflowX = "hidden";
6809
- container.style.overflowY = "auto";
6810
- container.style.padding = "16px 8px";
7364
+ container.style.overflow = "auto";
6811
7365
  container.style.backgroundColor = "#f1f5f9";
6812
- container.style.display = "flex";
6813
- container.style.justifyContent = "center";
6814
- container.style.alignItems = "flex-start";
7366
+ const scrollWrapper = document.createElement("div");
7367
+ scrollWrapper.className = "fp-doc-scroll-wrapper";
7368
+ scrollWrapper.style.minWidth = "100%";
7369
+ scrollWrapper.style.minHeight = "100%";
7370
+ scrollWrapper.style.width = "max-content";
7371
+ scrollWrapper.style.height = "max-content";
7372
+ scrollWrapper.style.display = "flex";
7373
+ scrollWrapper.style.justifyContent = "center";
7374
+ scrollWrapper.style.alignItems = "flex-start";
7375
+ scrollWrapper.style.padding = "16px 8px";
7376
+ scrollWrapper.style.boxSizing = "border-box";
7377
+ const sizer = document.createElement("div");
7378
+ sizer.className = "fp-doc-sizer";
7379
+ sizer.style.position = "relative";
7380
+ sizer.style.flexShrink = "0";
7381
+ sizer.style.display = "flex";
7382
+ sizer.style.justifyContent = "center";
7383
+ sizer.style.alignItems = "center";
7384
+ scrollWrapper.appendChild(sizer);
7385
+ container.appendChild(scrollWrapper);
6815
7386
  ctx.container.appendChild(container);
6816
7387
  let scale = 1;
6817
7388
  let extractedRawText = "";
@@ -6859,10 +7430,11 @@ var DocPlugin = class {
6859
7430
  pageCard.style.padding = "72px 56px";
6860
7431
  pageCard.style.boxSizing = "border-box";
6861
7432
  pageCard.style.display = i === 0 ? "block" : "none";
6862
- pageCard.style.transformOrigin = "top center";
7433
+ pageCard.style.transformOrigin = "center center";
6863
7434
  pageCard.style.transition = "transform 0.15s ease";
6864
7435
  pageCard.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
6865
7436
  pageCard.style.color = "#1e293b";
7437
+ pageCard.style.flexShrink = "0";
6866
7438
  if (isFallback && i === 0) {
6867
7439
  pageCard.innerHTML = `
6868
7440
  <div style="border-bottom: 1px solid #e2e8f0; padding-bottom: 12px; margin-bottom: 24px;">
@@ -6874,18 +7446,23 @@ var DocPlugin = class {
6874
7446
  } else {
6875
7447
  pageCard.innerHTML = this.formatDocToHtml(rawPages[i], ctx.metadata.name || "Document");
6876
7448
  }
6877
- container.appendChild(pageCard);
7449
+ sizer.appendChild(pageCard);
6878
7450
  pageCards.push(pageCard);
6879
7451
  }
6880
7452
  let rotation = 0;
6881
7453
  const applyTransform = () => {
6882
7454
  const activeCard = pageCards[currentPage - 1];
6883
7455
  if (activeCard) {
6884
- activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7456
+ const baseW = 816;
6885
7457
  const baseH = activeCard.offsetHeight || 1056;
6886
- const scaledH = baseH * scale;
6887
- const extraH = Math.max(0, scaledH - baseH);
6888
- activeCard.style.marginBottom = `${extraH + 32}px`;
7458
+ const isRotated90 = rotation % 180 !== 0;
7459
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * scale);
7460
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * scale);
7461
+ sizer.style.width = `${boxW}px`;
7462
+ sizer.style.height = `${boxH}px`;
7463
+ activeCard.style.width = `${baseW}px`;
7464
+ activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7465
+ activeCard.style.transformOrigin = "center center";
6889
7466
  }
6890
7467
  };
6891
7468
  const showPage = (pageNum) => {
@@ -6893,11 +7470,11 @@ var DocPlugin = class {
6893
7470
  pageCards.forEach((card, idx) => {
6894
7471
  if (idx + 1 === currentPage) {
6895
7472
  card.style.display = "block";
6896
- card.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6897
7473
  } else {
6898
7474
  card.style.display = "none";
6899
7475
  }
6900
7476
  });
7477
+ applyTransform();
6901
7478
  container.scrollTop = 0;
6902
7479
  ctx.emit("page-change", { page: currentPage, total: totalPages });
6903
7480
  };
@@ -6963,6 +7540,17 @@ var DocPlugin = class {
6963
7540
  rotation = 0;
6964
7541
  applyTransform();
6965
7542
  },
7543
+ resetZoom: () => {
7544
+ isUserZoomed = false;
7545
+ fitMode = "width";
7546
+ scale = calculateFitScale("width");
7547
+ rotation = 0;
7548
+ container.scrollTop = 0;
7549
+ container.scrollLeft = 0;
7550
+ ctx.container.scrollTop = 0;
7551
+ ctx.container.scrollLeft = 0;
7552
+ applyTransform();
7553
+ },
6966
7554
  rotateCW: () => {
6967
7555
  rotation = (rotation + 90) % 360;
6968
7556
  applyTransform();
@@ -7443,6 +8031,14 @@ var PptPlugin = class {
7443
8031
  group: "zoom",
7444
8032
  execute: () => instance.fitToPage?.()
7445
8033
  },
8034
+ {
8035
+ id: "reset-zoom",
8036
+ icon: "reset-zoom",
8037
+ label: "Reset Zoom",
8038
+ type: "button",
8039
+ group: "zoom",
8040
+ execute: () => instance.resetZoom?.()
8041
+ },
7446
8042
  {
7447
8043
  id: "rotate-cw",
7448
8044
  icon: "rotate-cw",
@@ -7475,17 +8071,30 @@ var PptPlugin = class {
7475
8071
  container.style.width = "100%";
7476
8072
  container.style.height = "100%";
7477
8073
  container.style.overflow = "auto";
7478
- container.style.display = "flex";
7479
- container.style.justifyContent = "center";
7480
- container.style.alignItems = "center";
7481
- container.style.padding = "32px 16px";
7482
8074
  container.style.backgroundColor = "#0f172a";
7483
8075
  container.style.boxSizing = "border-box";
8076
+ const scrollWrapper = document.createElement("div");
8077
+ scrollWrapper.className = "fp-ppt-scroll-wrapper";
8078
+ scrollWrapper.style.minWidth = "100%";
8079
+ scrollWrapper.style.minHeight = "100%";
8080
+ scrollWrapper.style.width = "max-content";
8081
+ scrollWrapper.style.height = "max-content";
8082
+ scrollWrapper.style.display = "flex";
8083
+ scrollWrapper.style.justifyContent = "center";
8084
+ scrollWrapper.style.alignItems = "center";
8085
+ scrollWrapper.style.padding = "32px 16px";
8086
+ scrollWrapper.style.boxSizing = "border-box";
8087
+ const sizer = document.createElement("div");
8088
+ sizer.className = "fp-ppt-sizer";
8089
+ sizer.style.position = "relative";
8090
+ sizer.style.flexShrink = "0";
8091
+ sizer.style.display = "flex";
8092
+ sizer.style.justifyContent = "center";
8093
+ sizer.style.alignItems = "center";
7484
8094
  const slideCard = document.createElement("div");
7485
8095
  slideCard.className = "fp-ppt-slide-card";
7486
8096
  slideCard.style.width = "960px";
7487
- slideCard.style.maxWidth = "calc(100% - 32px)";
7488
- slideCard.style.maxHeight = "calc(100% - 48px)";
8097
+ slideCard.style.height = "540px";
7489
8098
  slideCard.style.aspectRatio = "16 / 9";
7490
8099
  slideCard.style.backgroundColor = "#ffffff";
7491
8100
  slideCard.style.boxShadow = "0 12px 40px rgba(0,0,0,0.35)";
@@ -7495,7 +8104,9 @@ var PptPlugin = class {
7495
8104
  slideCard.style.transition = "transform 0.2s ease";
7496
8105
  slideCard.style.transformOrigin = "center center";
7497
8106
  slideCard.style.flexShrink = "0";
7498
- container.appendChild(slideCard);
8107
+ sizer.appendChild(slideCard);
8108
+ scrollWrapper.appendChild(sizer);
8109
+ container.appendChild(scrollWrapper);
7499
8110
  ctx.container.appendChild(container);
7500
8111
  let scale = 1;
7501
8112
  let rotation = 0;
@@ -7508,7 +8119,17 @@ var PptPlugin = class {
7508
8119
  return Math.min(1, Math.min(availW / 960, availH / 540));
7509
8120
  };
7510
8121
  const applyTransform = () => {
8122
+ const cW = 960;
8123
+ const cH = 540;
8124
+ const isRotated90 = rotation % 180 !== 0;
8125
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
8126
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
8127
+ sizer.style.width = `${boxW}px`;
8128
+ sizer.style.height = `${boxH}px`;
8129
+ slideCard.style.width = `${cW}px`;
8130
+ slideCard.style.height = `${cH}px`;
7511
8131
  slideCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
8132
+ slideCard.style.transformOrigin = "center center";
7512
8133
  };
7513
8134
  setTimeout(() => {
7514
8135
  scale = calculateFitScale();
@@ -7631,6 +8252,13 @@ var PptPlugin = class {
7631
8252
  rotation = 0;
7632
8253
  applyTransform();
7633
8254
  },
8255
+ resetZoom: () => {
8256
+ scale = calculateFitScale();
8257
+ rotation = 0;
8258
+ container.scrollTop = 0;
8259
+ container.scrollLeft = 0;
8260
+ applyTransform();
8261
+ },
7634
8262
  rotateCW: () => {
7635
8263
  rotation = (rotation + 90) % 360;
7636
8264
  applyTransform();