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