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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/angular.js CHANGED
@@ -543,6 +543,7 @@ var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" str
543
543
  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>`;
544
544
  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>`;
545
545
  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>`;
546
+ 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>`;
546
547
  var ICON_MAP = {
547
548
  "zoom-in": ICON_ZOOM_IN,
548
549
  "zoom-out": ICON_ZOOM_OUT,
@@ -572,7 +573,10 @@ var ICON_MAP = {
572
573
  "open-window": ICON_EXTERNAL_WINDOW,
573
574
  "external-window": ICON_EXTERNAL_WINDOW,
574
575
  "openWindow": ICON_EXTERNAL_WINDOW,
575
- "openSeparateWindow": ICON_EXTERNAL_WINDOW
576
+ "openSeparateWindow": ICON_EXTERNAL_WINDOW,
577
+ "reset-zoom": ICON_RESET_ZOOM,
578
+ "zoom-reset": ICON_RESET_ZOOM,
579
+ "resetZoom": ICON_RESET_ZOOM
576
580
  };
577
581
  var ToolbarController = class {
578
582
  el;
@@ -605,6 +609,10 @@ var ToolbarController = class {
605
609
  this.config.fitToPage = false;
606
610
  this.config.fitWidth = false;
607
611
  }
612
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
613
+ this.config.resetZoom = false;
614
+ this.config.zoomReset = false;
615
+ }
608
616
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = false;
609
617
  if (actionId === "fullscreen") this.config.fullscreen = false;
610
618
  if (actionId === "download") this.config.download = false;
@@ -629,6 +637,10 @@ var ToolbarController = class {
629
637
  this.config.fitToPage = true;
630
638
  this.config.fitWidth = true;
631
639
  }
640
+ if (actionId === "reset-zoom" || actionId === "zoom-reset" || actionId === "resetZoom") {
641
+ this.config.resetZoom = true;
642
+ this.config.zoomReset = true;
643
+ }
632
644
  if (actionId === "rotate-cw" || actionId === "rotate" || actionId === "rotateCW") this.config.rotate = true;
633
645
  if (actionId === "fullscreen") this.config.fullscreen = true;
634
646
  if (actionId === "download") this.config.download = true;
@@ -648,6 +660,7 @@ var ToolbarController = class {
648
660
  if (actionId === "zoomIn") return "zoom-in";
649
661
  if (actionId === "zoomOut") return "zoom-out";
650
662
  if (actionId === "fitPage" || actionId === "fitToPage" || actionId === "fitWidth") return "fit-page";
663
+ if (actionId === "resetZoom" || actionId === "zoomReset") return "reset-zoom";
651
664
  if (actionId === "rotateCW") return "rotate-cw";
652
665
  if (actionId === "rotateCCW") return "rotate-ccw";
653
666
  if (actionId === "openWindow" || actionId === "openSeparateWindow") return "open-window";
@@ -690,6 +703,9 @@ var ToolbarController = class {
690
703
  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)) {
691
704
  return false;
692
705
  }
706
+ if ((id === "reset-zoom" || id === "zoom-reset") && (c.resetZoom === false || c.zoomReset === false || c["reset-zoom"] === false || c["zoom-reset"] === false)) {
707
+ return false;
708
+ }
693
709
  if ((id === "rotate-cw" || id === "rotate-ccw" || id === "rotate") && (c.rotate === false || c.rotateCW === false || c.rotateCCW === false || c["rotate-cw"] === false)) {
694
710
  return false;
695
711
  }
@@ -1136,6 +1152,9 @@ var FilePreviewViewer = class _FilePreviewViewer {
1136
1152
  this.activeInstance = instance;
1137
1153
  instance.openInSeparateWindow = () => this.openInSeparateWindow();
1138
1154
  instance.toggleThumbnails = () => this.toggleThumbnails();
1155
+ if (!instance.resetZoom && instance.fitToPage) {
1156
+ instance.resetZoom = () => instance.fitToPage?.();
1157
+ }
1139
1158
  this.hideLoading();
1140
1159
  this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
1141
1160
  const isToolbarVisible = options.showToolbar !== false && options.toolbar !== false;
@@ -1419,6 +1438,16 @@ var FilePreviewViewer = class _FilePreviewViewer {
1419
1438
  fitToPage() {
1420
1439
  this.activeInstance?.fitToPage?.();
1421
1440
  }
1441
+ /**
1442
+ * Reset zoom level to initial/default fit state.
1443
+ */
1444
+ resetZoom() {
1445
+ if (this.activeInstance?.resetZoom) {
1446
+ this.activeInstance.resetZoom();
1447
+ } else if (this.activeInstance?.fitToPage) {
1448
+ this.activeInstance.fitToPage();
1449
+ }
1450
+ }
1422
1451
  /**
1423
1452
  * Zoom in.
1424
1453
  */
@@ -2040,6 +2069,14 @@ var PdfPlugin = class {
2040
2069
  group: "zoom",
2041
2070
  execute: () => instance.fitToPage?.()
2042
2071
  },
2072
+ {
2073
+ id: "reset-zoom",
2074
+ icon: "reset-zoom",
2075
+ label: "Reset Zoom",
2076
+ type: "button",
2077
+ group: "zoom",
2078
+ execute: () => instance.resetZoom?.()
2079
+ },
2043
2080
  {
2044
2081
  id: "fit-width",
2045
2082
  icon: "fit-width",
@@ -2095,16 +2132,22 @@ var PdfPlugin = class {
2095
2132
  container.className = "fp-pdf-container";
2096
2133
  container.style.width = "100%";
2097
2134
  container.style.height = "100%";
2098
- container.style.overflowX = "hidden";
2099
- container.style.overflowY = "auto";
2100
- container.style.display = "flex";
2101
- container.style.flexDirection = "column";
2102
- container.style.alignItems = "center";
2103
- container.style.justifyContent = "flex-start";
2104
- container.style.padding = "16px 8px";
2135
+ container.style.overflow = "auto";
2105
2136
  container.style.backgroundColor = "#0f172a";
2106
2137
  container.style.boxSizing = "border-box";
2107
2138
  container.style.position = "relative";
2139
+ const scrollWrapper = document.createElement("div");
2140
+ scrollWrapper.className = "fp-pdf-scroll-wrapper";
2141
+ scrollWrapper.style.minWidth = "100%";
2142
+ scrollWrapper.style.minHeight = "100%";
2143
+ scrollWrapper.style.width = "max-content";
2144
+ scrollWrapper.style.height = "max-content";
2145
+ scrollWrapper.style.display = "flex";
2146
+ scrollWrapper.style.flexDirection = "column";
2147
+ scrollWrapper.style.alignItems = "center";
2148
+ scrollWrapper.style.justifyContent = "flex-start";
2149
+ scrollWrapper.style.padding = "16px 8px";
2150
+ scrollWrapper.style.boxSizing = "border-box";
2108
2151
  const pageCard = document.createElement("div");
2109
2152
  pageCard.className = "fp-pdf-page-card";
2110
2153
  pageCard.style.boxShadow = "0 10px 35px rgba(0, 0, 0, 0.5)";
@@ -2117,7 +2160,8 @@ var PdfPlugin = class {
2117
2160
  pageCard.style.transition = "box-shadow 0.2s ease";
2118
2161
  let canvas = document.createElement("canvas");
2119
2162
  pageCard.appendChild(canvas);
2120
- container.appendChild(pageCard);
2163
+ scrollWrapper.appendChild(pageCard);
2164
+ container.appendChild(scrollWrapper);
2121
2165
  ctx.container.appendChild(container);
2122
2166
  const standardFontsUrl = typeof window !== "undefined" && window.__PDF_STANDARD_FONTS_URL__ || "./standard_fonts/";
2123
2167
  const cmapsUrl = typeof window !== "undefined" && window.__PDF_CMAPS_URL__ || "./cmaps/";
@@ -2302,6 +2346,14 @@ var PdfPlugin = class {
2302
2346
  zoomScale = 1;
2303
2347
  renderPage(currentPage);
2304
2348
  },
2349
+ resetZoom: () => {
2350
+ fitMode = "page";
2351
+ zoomScale = 1;
2352
+ rotation = 0;
2353
+ container.scrollTop = 0;
2354
+ container.scrollLeft = 0;
2355
+ renderPage(currentPage);
2356
+ },
2305
2357
  fitToWidth: () => {
2306
2358
  fitMode = "width";
2307
2359
  zoomScale = 1;
@@ -2469,6 +2521,16 @@ var MediaPlugin = class {
2469
2521
  instance.fitToPage?.();
2470
2522
  }
2471
2523
  },
2524
+ {
2525
+ id: "reset-zoom",
2526
+ icon: "reset-zoom",
2527
+ label: "Reset Zoom",
2528
+ type: "button",
2529
+ group: "zoom",
2530
+ execute: () => {
2531
+ instance.resetZoom?.();
2532
+ }
2533
+ },
2472
2534
  {
2473
2535
  id: "rotate-cw",
2474
2536
  icon: "rotate-cw",
@@ -2608,17 +2670,86 @@ var MediaPlugin = class {
2608
2670
  element = document.createElement("div");
2609
2671
  element.textContent = "Unsupported media type";
2610
2672
  }
2611
- ctx.container.style.display = "flex";
2612
- ctx.container.style.alignItems = "center";
2613
- ctx.container.style.justifyContent = "center";
2614
- ctx.container.style.overflow = "hidden";
2615
- ctx.container.appendChild(element);
2673
+ const scrollWrapper = document.createElement("div");
2674
+ scrollWrapper.className = "fp-media-scroll-wrapper";
2675
+ scrollWrapper.style.minWidth = "100%";
2676
+ scrollWrapper.style.minHeight = "100%";
2677
+ scrollWrapper.style.width = "max-content";
2678
+ scrollWrapper.style.height = "max-content";
2679
+ scrollWrapper.style.display = "flex";
2680
+ scrollWrapper.style.justifyContent = "center";
2681
+ scrollWrapper.style.alignItems = "center";
2682
+ scrollWrapper.style.padding = "16px";
2683
+ scrollWrapper.style.boxSizing = "border-box";
2684
+ const sizer = document.createElement("div");
2685
+ sizer.className = "fp-media-sizer";
2686
+ sizer.style.position = "relative";
2687
+ sizer.style.flexShrink = "0";
2688
+ sizer.style.display = "flex";
2689
+ sizer.style.justifyContent = "center";
2690
+ sizer.style.alignItems = "center";
2691
+ sizer.appendChild(element);
2692
+ scrollWrapper.appendChild(sizer);
2693
+ ctx.container.style.overflow = "auto";
2694
+ ctx.container.style.padding = "0";
2695
+ ctx.container.innerHTML = "";
2696
+ ctx.container.appendChild(scrollWrapper);
2697
+ let naturalW = 800;
2698
+ let naturalH = 600;
2699
+ let baseW = 800;
2700
+ let baseH = 600;
2701
+ const updateBaseDimensions = () => {
2702
+ if (!isImage) return;
2703
+ const img = element;
2704
+ naturalW = img.naturalWidth || naturalW;
2705
+ naturalH = img.naturalHeight || naturalH;
2706
+ const availW = Math.max(100, ctx.container.clientWidth - 48);
2707
+ const availH = Math.max(100, ctx.container.clientHeight - 48);
2708
+ const fitRatio = Math.min(1, availW / naturalW, availH / naturalH);
2709
+ baseW = Math.max(1, Math.round(naturalW * fitRatio));
2710
+ baseH = Math.max(1, Math.round(naturalH * fitRatio));
2711
+ };
2616
2712
  const applyTransform = () => {
2617
- element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2713
+ if (isImage) {
2714
+ updateBaseDimensions();
2715
+ const isRotated90 = rotation % 180 !== 0;
2716
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * currentZoom);
2717
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * currentZoom);
2718
+ sizer.style.width = `${boxW}px`;
2719
+ sizer.style.height = `${boxH}px`;
2720
+ element.style.width = `${baseW}px`;
2721
+ element.style.height = `${baseH}px`;
2722
+ element.style.maxWidth = "none";
2723
+ element.style.maxHeight = "none";
2724
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2725
+ element.style.transformOrigin = "center center";
2726
+ element.style.flexShrink = "0";
2727
+ } else {
2728
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2729
+ }
2618
2730
  };
2731
+ if (isImage) {
2732
+ const img = element;
2733
+ if (img.complete && img.naturalWidth > 0) {
2734
+ updateBaseDimensions();
2735
+ applyTransform();
2736
+ } else {
2737
+ img.onload = () => {
2738
+ updateBaseDimensions();
2739
+ applyTransform();
2740
+ };
2741
+ }
2742
+ }
2743
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
2744
+ if (currentZoom === 1) {
2745
+ applyTransform();
2746
+ }
2747
+ }) : null;
2748
+ ro?.observe(ctx.container);
2619
2749
  const cleanup = () => {
2750
+ ro?.disconnect();
2620
2751
  if (url) URL.revokeObjectURL(url);
2621
- element.remove();
2752
+ scrollWrapper.remove();
2622
2753
  ctx.container.innerHTML = "";
2623
2754
  };
2624
2755
  ctx.signal.addEventListener("abort", cleanup);
@@ -2642,6 +2773,13 @@ var MediaPlugin = class {
2642
2773
  rotation = 0;
2643
2774
  applyTransform();
2644
2775
  } : void 0,
2776
+ resetZoom: isImage ? () => {
2777
+ currentZoom = 1;
2778
+ rotation = 0;
2779
+ ctx.container.scrollTop = 0;
2780
+ ctx.container.scrollLeft = 0;
2781
+ applyTransform();
2782
+ } : void 0,
2645
2783
  rotateCW: isImage || isVideo ? () => {
2646
2784
  rotation = (rotation + 90) % 360;
2647
2785
  applyTransform();
@@ -2758,6 +2896,14 @@ var DocxPlugin = class {
2758
2896
  group: "zoom",
2759
2897
  execute: () => instance.fitToPage?.()
2760
2898
  },
2899
+ {
2900
+ id: "reset-zoom",
2901
+ icon: "reset-zoom",
2902
+ label: "Reset Zoom",
2903
+ type: "button",
2904
+ group: "zoom",
2905
+ execute: () => instance.resetZoom?.()
2906
+ },
2761
2907
  {
2762
2908
  id: "rotate-cw",
2763
2909
  icon: "rotate-cw",
@@ -2796,7 +2942,7 @@ var DocxPlugin = class {
2796
2942
  async render(ctx) {
2797
2943
  const wrapper = document.createElement("div");
2798
2944
  wrapper.className = "fp-docx-wrapper";
2799
- wrapper.style.transformOrigin = "top center";
2945
+ wrapper.style.transformOrigin = "center center";
2800
2946
  wrapper.style.transition = "transform 0.2s ease";
2801
2947
  wrapper.style.padding = "0";
2802
2948
  wrapper.style.maxWidth = "none";
@@ -2806,11 +2952,31 @@ var DocxPlugin = class {
2806
2952
  wrapper.style.flexDirection = "column";
2807
2953
  wrapper.style.alignItems = "center";
2808
2954
  wrapper.style.boxSizing = "border-box";
2809
- ctx.container.style.overflowX = "hidden";
2810
- ctx.container.style.overflowY = "auto";
2811
- ctx.container.style.padding = "16px 8px";
2955
+ wrapper.style.flexShrink = "0";
2956
+ const sizer = document.createElement("div");
2957
+ sizer.className = "fp-docx-sizer";
2958
+ sizer.style.position = "relative";
2959
+ sizer.style.flexShrink = "0";
2960
+ sizer.style.display = "flex";
2961
+ sizer.style.justifyContent = "center";
2962
+ sizer.style.alignItems = "center";
2963
+ const scrollWrapper = document.createElement("div");
2964
+ scrollWrapper.className = "fp-docx-scroll-wrapper";
2965
+ scrollWrapper.style.minWidth = "100%";
2966
+ scrollWrapper.style.minHeight = "100%";
2967
+ scrollWrapper.style.width = "max-content";
2968
+ scrollWrapper.style.height = "max-content";
2969
+ scrollWrapper.style.display = "flex";
2970
+ scrollWrapper.style.justifyContent = "center";
2971
+ scrollWrapper.style.alignItems = "flex-start";
2972
+ scrollWrapper.style.padding = "16px 8px";
2973
+ scrollWrapper.style.boxSizing = "border-box";
2974
+ sizer.appendChild(wrapper);
2975
+ scrollWrapper.appendChild(sizer);
2976
+ ctx.container.style.overflow = "auto";
2977
+ ctx.container.style.padding = "0";
2812
2978
  ctx.container.style.backgroundColor = "#f1f5f9";
2813
- ctx.container.appendChild(wrapper);
2979
+ ctx.container.appendChild(scrollWrapper);
2814
2980
  const styleOverride = document.createElement("style");
2815
2981
  styleOverride.textContent = `
2816
2982
  .fp-docx-wrapper .docx-wrapper {
@@ -2849,8 +3015,8 @@ var DocxPlugin = class {
2849
3015
  renderEndnotes: true,
2850
3016
  useBase64URL: true
2851
3017
  });
2852
- if (!ctx.container.contains(wrapper)) {
2853
- ctx.container.appendChild(wrapper);
3018
+ if (!sizer.contains(wrapper)) {
3019
+ sizer.appendChild(wrapper);
2854
3020
  }
2855
3021
  if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
2856
3022
  renderedSuccessfully = true;
@@ -2887,8 +3053,8 @@ var DocxPlugin = class {
2887
3053
  try {
2888
3054
  wrapper.innerHTML = "";
2889
3055
  this.renderXmlFallback(ctx, wrapper, createdBlobUrls);
2890
- if (!ctx.container.contains(wrapper)) {
2891
- ctx.container.appendChild(wrapper);
3056
+ if (!sizer.contains(wrapper)) {
3057
+ sizer.appendChild(wrapper);
2892
3058
  }
2893
3059
  renderedSuccessfully = true;
2894
3060
  } catch (fallbackErr) {
@@ -2903,8 +3069,8 @@ var DocxPlugin = class {
2903
3069
  </p>
2904
3070
  </div>
2905
3071
  `;
2906
- if (!ctx.container.contains(wrapper)) {
2907
- ctx.container.appendChild(wrapper);
3072
+ if (!sizer.contains(wrapper)) {
3073
+ sizer.appendChild(wrapper);
2908
3074
  }
2909
3075
  }
2910
3076
  }
@@ -3007,15 +3173,18 @@ var DocxPlugin = class {
3007
3173
  return Math.max(0.35, Math.min(3, sW));
3008
3174
  };
3009
3175
  const applyTransform = () => {
3010
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
3011
- wrapper.style.transformOrigin = "top center";
3012
3176
  const activeEl = pageElements[currentPage - 1] || wrapper.querySelector("section.docx") || wrapper;
3177
+ const elW = activeEl.offsetWidth || 816;
3013
3178
  const elH = activeEl.offsetHeight || 1056;
3014
- if (scale > 1) {
3015
- wrapper.style.marginBottom = `${Math.round(elH * scale - elH + 32)}px`;
3016
- } else {
3017
- wrapper.style.marginBottom = "32px";
3018
- }
3179
+ const isRotated90 = rotation % 180 !== 0;
3180
+ const boxW = Math.round((isRotated90 ? elH : elW) * scale);
3181
+ const boxH = Math.round((isRotated90 ? elW : elH) * scale);
3182
+ sizer.style.width = `${boxW}px`;
3183
+ sizer.style.height = `${boxH}px`;
3184
+ wrapper.style.width = `${elW}px`;
3185
+ wrapper.style.height = `${elH}px`;
3186
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
3187
+ wrapper.style.transformOrigin = "center center";
3019
3188
  };
3020
3189
  let resizeObserver = null;
3021
3190
  if (typeof ResizeObserver !== "undefined") {
@@ -3040,7 +3209,7 @@ var DocxPlugin = class {
3040
3209
  for (const url of createdBlobUrls) {
3041
3210
  URL.revokeObjectURL(url);
3042
3211
  }
3043
- wrapper.remove();
3212
+ scrollWrapper.remove();
3044
3213
  styleOverride.remove();
3045
3214
  ctx.container.innerHTML = "";
3046
3215
  };
@@ -3074,6 +3243,14 @@ var DocxPlugin = class {
3074
3243
  rotation = 0;
3075
3244
  applyTransform();
3076
3245
  },
3246
+ resetZoom: () => {
3247
+ isUserZoomed = false;
3248
+ scale = calculateFitScale("page");
3249
+ rotation = 0;
3250
+ ctx.container.scrollTop = 0;
3251
+ ctx.container.scrollLeft = 0;
3252
+ applyTransform();
3253
+ },
3077
3254
  rotateCW: () => {
3078
3255
  rotation = (rotation + 90) % 360;
3079
3256
  applyTransform();
@@ -3523,6 +3700,16 @@ var ExcelPlugin = class {
3523
3700
  instance.zoomIn?.();
3524
3701
  }
3525
3702
  },
3703
+ {
3704
+ id: "reset-zoom",
3705
+ icon: "reset-zoom",
3706
+ label: "Reset Zoom",
3707
+ type: "button",
3708
+ group: "zoom",
3709
+ execute: () => {
3710
+ instance.resetZoom?.();
3711
+ }
3712
+ },
3526
3713
  {
3527
3714
  id: "download",
3528
3715
  icon: "download",
@@ -3569,7 +3756,7 @@ var ExcelPlugin = class {
3569
3756
  contentArea.style.flex = "1";
3570
3757
  contentArea.style.overflow = "auto";
3571
3758
  contentArea.style.padding = "16px";
3572
- contentArea.style.transformOrigin = "top left";
3759
+ contentArea.style.boxSizing = "border-box";
3573
3760
  const tabsArea = document.createElement("div");
3574
3761
  tabsArea.className = "fp-excel-tabs";
3575
3762
  tabsArea.style.display = "flex";
@@ -3583,18 +3770,35 @@ var ExcelPlugin = class {
3583
3770
  container.appendChild(tabsArea);
3584
3771
  ctx.container.appendChild(container);
3585
3772
  let scale = 1;
3773
+ let isUserZoomed = false;
3586
3774
  let currentSheetIndex = 1;
3587
3775
  let sheetNames = [];
3588
3776
  let wb = null;
3589
3777
  const applyTransform = () => {
3590
- contentArea.style.transform = `scale(${scale})`;
3591
- contentArea.style.transformOrigin = "top left";
3778
+ const sizer = contentArea.querySelector(".fp-excel-sizer");
3779
+ const table = contentArea.querySelector("table");
3780
+ if (!sizer || !table) return;
3781
+ if (!table._baseWidth && table.offsetWidth > 0) {
3782
+ table._baseWidth = table.offsetWidth;
3783
+ table._baseHeight = table.offsetHeight;
3784
+ }
3785
+ const baseW = table._baseWidth || table.offsetWidth || 800;
3786
+ const baseH = table._baseHeight || table.offsetHeight || 600;
3787
+ const scaledW = Math.round(baseW * scale);
3788
+ const scaledH = Math.round(baseH * scale);
3789
+ sizer.style.width = `${scaledW}px`;
3790
+ sizer.style.height = `${scaledH}px`;
3791
+ table.style.position = "absolute";
3792
+ table.style.top = "0";
3793
+ table.style.left = "0";
3794
+ table.style.transform = `scale(${scale})`;
3795
+ table.style.transformOrigin = "top left";
3592
3796
  };
3593
3797
  const calculateFitScale = () => {
3594
3798
  const table = contentArea.querySelector("table");
3595
3799
  if (!table) return 1;
3596
3800
  const availW = Math.max(280, container.clientWidth - 48);
3597
- const tW = table.offsetWidth || 800;
3801
+ const tW = table._baseWidth || table.offsetWidth || 800;
3598
3802
  return Math.max(0.4, Math.min(1, availW / tW));
3599
3803
  };
3600
3804
  try {
@@ -3614,9 +3818,13 @@ var ExcelPlugin = class {
3614
3818
  contentArea.innerHTML = '<div style="padding: 24px; color: #888;">Empty sheet</div>';
3615
3819
  return;
3616
3820
  }
3821
+ const sizer = document.createElement("div");
3822
+ sizer.className = "fp-excel-sizer";
3823
+ sizer.style.position = "relative";
3617
3824
  const html = XLSX.utils.sheet_to_html(ws, { id: "fp-sheet-table", editable: false });
3618
- contentArea.innerHTML = html;
3619
- const table = contentArea.querySelector("table");
3825
+ sizer.innerHTML = html;
3826
+ contentArea.appendChild(sizer);
3827
+ const table = sizer.querySelector("table");
3620
3828
  if (table) {
3621
3829
  table.style.borderCollapse = "collapse";
3622
3830
  table.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
@@ -3651,13 +3859,17 @@ var ExcelPlugin = class {
3651
3859
  });
3652
3860
  ctx.emit("page-change", { page: currentSheetIndex, total: sheetNames.length });
3653
3861
  requestAnimationFrame(() => {
3654
- scale = calculateFitScale();
3862
+ if (!isUserZoomed) {
3863
+ scale = calculateFitScale();
3864
+ }
3655
3865
  applyTransform();
3656
3866
  });
3657
3867
  };
3658
3868
  const ro = new ResizeObserver(() => {
3659
- scale = calculateFitScale();
3660
- applyTransform();
3869
+ if (!isUserZoomed) {
3870
+ scale = calculateFitScale();
3871
+ applyTransform();
3872
+ }
3661
3873
  });
3662
3874
  ro.observe(container);
3663
3875
  if (sheetNames.length > 0) {
@@ -3694,20 +3906,31 @@ var ExcelPlugin = class {
3694
3906
  return {
3695
3907
  destroy: cleanup,
3696
3908
  zoomIn: () => {
3909
+ isUserZoomed = true;
3697
3910
  scale += 0.15;
3698
3911
  applyTransform();
3699
3912
  },
3700
3913
  zoomOut: () => {
3914
+ isUserZoomed = true;
3701
3915
  scale = Math.max(0.2, scale - 0.15);
3702
3916
  applyTransform();
3703
3917
  },
3704
3918
  getZoom: () => scale,
3705
3919
  setZoom: (level) => {
3920
+ isUserZoomed = true;
3706
3921
  scale = level;
3707
3922
  applyTransform();
3708
3923
  },
3709
3924
  fitToPage: () => {
3925
+ isUserZoomed = false;
3926
+ scale = calculateFitScale();
3927
+ applyTransform();
3928
+ },
3929
+ resetZoom: () => {
3930
+ isUserZoomed = false;
3710
3931
  scale = calculateFitScale();
3932
+ contentArea.scrollTop = 0;
3933
+ contentArea.scrollLeft = 0;
3711
3934
  applyTransform();
3712
3935
  },
3713
3936
  rotateCW: () => {
@@ -3840,6 +4063,16 @@ var CsvPlugin = class {
3840
4063
  instance.zoomIn?.();
3841
4064
  }
3842
4065
  },
4066
+ {
4067
+ id: "reset-zoom",
4068
+ icon: "reset-zoom",
4069
+ label: "Reset Zoom",
4070
+ type: "button",
4071
+ group: "zoom",
4072
+ execute: () => {
4073
+ instance.resetZoom?.();
4074
+ }
4075
+ },
3843
4076
  {
3844
4077
  id: "download",
3845
4078
  icon: "download",
@@ -3926,21 +4159,41 @@ var CsvPlugin = class {
3926
4159
  container.appendChild(tableWrapper);
3927
4160
  ctx.container.appendChild(container);
3928
4161
  let scale = 1;
4162
+ let isUserZoomed = false;
3929
4163
  const calculateFitScale = () => {
3930
4164
  const availW = Math.max(280, container.clientWidth - 48);
3931
- const tW = table.offsetWidth || 800;
4165
+ const tW = table._baseWidth || table.offsetWidth || 800;
3932
4166
  return Math.max(0.4, Math.min(1, availW / tW));
3933
4167
  };
3934
4168
  const applyScale = () => {
3935
- tableWrapper.style.transform = `scale(${scale})`;
4169
+ if (!table._baseWidth && table.offsetWidth > 0) {
4170
+ table._baseWidth = table.offsetWidth;
4171
+ table._baseHeight = table.offsetHeight;
4172
+ }
4173
+ const baseW = table._baseWidth || table.offsetWidth || 800;
4174
+ const baseH = table._baseHeight || table.offsetHeight || 600;
4175
+ const scaledW = Math.round(baseW * scale);
4176
+ const scaledH = Math.round(baseH * scale);
4177
+ tableWrapper.style.position = "relative";
4178
+ tableWrapper.style.width = `${scaledW}px`;
4179
+ tableWrapper.style.height = `${scaledH}px`;
4180
+ table.style.position = "absolute";
4181
+ table.style.top = "0";
4182
+ table.style.left = "0";
4183
+ table.style.transform = `scale(${scale})`;
4184
+ table.style.transformOrigin = "top left";
3936
4185
  };
3937
4186
  requestAnimationFrame(() => {
3938
- scale = calculateFitScale();
4187
+ if (!isUserZoomed) {
4188
+ scale = calculateFitScale();
4189
+ }
3939
4190
  applyScale();
3940
4191
  });
3941
4192
  const ro = new ResizeObserver(() => {
3942
- scale = calculateFitScale();
3943
- applyScale();
4193
+ if (!isUserZoomed) {
4194
+ scale = calculateFitScale();
4195
+ applyScale();
4196
+ }
3944
4197
  });
3945
4198
  ro.observe(container);
3946
4199
  const cleanup = () => {
@@ -4013,20 +4266,31 @@ var CsvPlugin = class {
4013
4266
  }];
4014
4267
  },
4015
4268
  zoomIn: () => {
4269
+ isUserZoomed = true;
4016
4270
  scale += 0.1;
4017
4271
  applyScale();
4018
4272
  },
4019
4273
  zoomOut: () => {
4274
+ isUserZoomed = true;
4020
4275
  scale = Math.max(0.2, scale - 0.1);
4021
4276
  applyScale();
4022
4277
  },
4023
4278
  getZoom: () => scale,
4024
4279
  setZoom: (level) => {
4280
+ isUserZoomed = true;
4025
4281
  scale = level;
4026
4282
  applyScale();
4027
4283
  },
4028
4284
  fitToPage: () => {
4285
+ isUserZoomed = false;
4286
+ scale = calculateFitScale();
4287
+ applyScale();
4288
+ },
4289
+ resetZoom: () => {
4290
+ isUserZoomed = false;
4029
4291
  scale = calculateFitScale();
4292
+ container.scrollTop = 0;
4293
+ container.scrollLeft = 0;
4030
4294
  applyScale();
4031
4295
  },
4032
4296
  rotateCW: () => {
@@ -4144,6 +4408,16 @@ var CodePlugin = class {
4144
4408
  instance.zoomIn?.();
4145
4409
  }
4146
4410
  },
4411
+ {
4412
+ id: "reset-zoom",
4413
+ icon: "reset-zoom",
4414
+ label: "Reset Zoom",
4415
+ type: "button",
4416
+ group: "zoom",
4417
+ execute: () => {
4418
+ instance.resetZoom?.();
4419
+ }
4420
+ },
4147
4421
  {
4148
4422
  id: "copy",
4149
4423
  icon: "copy",
@@ -4249,15 +4523,27 @@ var CodePlugin = class {
4249
4523
  let isUserZoomed = false;
4250
4524
  const pre = document.createElement("pre");
4251
4525
  const code = document.createElement("code");
4526
+ const sizer = document.createElement("div");
4527
+ const scrollWrapper = document.createElement("div");
4252
4528
  if (isTxt) {
4253
- container.style.overflowX = "hidden";
4254
- container.style.overflowY = "auto";
4529
+ container.style.overflow = "auto";
4255
4530
  container.style.backgroundColor = "#f1f5f9";
4256
- container.style.padding = "16px 8px";
4257
- container.style.boxSizing = "border-box";
4258
- container.style.display = "flex";
4259
- container.style.flexDirection = "column";
4260
- container.style.alignItems = "center";
4531
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4532
+ scrollWrapper.style.minWidth = "100%";
4533
+ scrollWrapper.style.minHeight = "100%";
4534
+ scrollWrapper.style.width = "max-content";
4535
+ scrollWrapper.style.height = "max-content";
4536
+ scrollWrapper.style.display = "flex";
4537
+ scrollWrapper.style.justifyContent = "center";
4538
+ scrollWrapper.style.alignItems = "flex-start";
4539
+ scrollWrapper.style.padding = "16px 8px";
4540
+ scrollWrapper.style.boxSizing = "border-box";
4541
+ sizer.className = "fp-code-sizer";
4542
+ sizer.style.position = "relative";
4543
+ sizer.style.flexShrink = "0";
4544
+ sizer.style.display = "flex";
4545
+ sizer.style.justifyContent = "center";
4546
+ sizer.style.alignItems = "center";
4261
4547
  pre.style.margin = "0 auto";
4262
4548
  pre.style.fontFamily = "Consolas, 'Courier New', monospace";
4263
4549
  pre.style.fontSize = "13px";
@@ -4272,8 +4558,9 @@ var CodePlugin = class {
4272
4558
  pre.style.boxSizing = "border-box";
4273
4559
  pre.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4274
4560
  pre.style.borderRadius = "4px";
4275
- pre.style.transformOrigin = "top center";
4561
+ pre.style.transformOrigin = "center center";
4276
4562
  pre.style.transition = "transform 0.15s ease";
4563
+ pre.style.flexShrink = "0";
4277
4564
  } else {
4278
4565
  container.style.overflow = "auto";
4279
4566
  container.style.backgroundColor = "#1e1e1e";
@@ -4306,7 +4593,13 @@ var CodePlugin = class {
4306
4593
  };
4307
4594
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4308
4595
  pre.appendChild(code);
4309
- container.appendChild(pre);
4596
+ if (isTxt) {
4597
+ sizer.appendChild(pre);
4598
+ scrollWrapper.appendChild(sizer);
4599
+ container.appendChild(scrollWrapper);
4600
+ } else {
4601
+ container.appendChild(pre);
4602
+ }
4310
4603
  const showPage = (pageNum) => {
4311
4604
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4312
4605
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
@@ -4323,10 +4616,16 @@ var CodePlugin = class {
4323
4616
  };
4324
4617
  const updateTransform = () => {
4325
4618
  if (isTxt) {
4619
+ const elW = 816;
4620
+ const baseH = pre.offsetHeight || 1056;
4621
+ const isRotated90 = rotation % 180 !== 0;
4622
+ const boxW = Math.round((isRotated90 ? baseH : elW) * zoomLevel);
4623
+ const boxH = Math.round((isRotated90 ? elW : baseH) * zoomLevel);
4624
+ sizer.style.width = `${boxW}px`;
4625
+ sizer.style.height = `${boxH}px`;
4626
+ pre.style.width = `${elW}px`;
4326
4627
  pre.style.transform = `scale(${zoomLevel}) rotate(${rotation}deg)`;
4327
- const scaledH = 1056 * zoomLevel;
4328
- const extraH = Math.max(0, scaledH - 1056);
4329
- pre.style.marginBottom = `${extraH + 32}px`;
4628
+ pre.style.transformOrigin = "center center";
4330
4629
  } else {
4331
4630
  pre.style.transform = `rotate(${rotation}deg)`;
4332
4631
  pre.style.fontSize = `${fontSize}px`;
@@ -4423,6 +4722,15 @@ var CodePlugin = class {
4423
4722
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4424
4723
  updateTransform();
4425
4724
  },
4725
+ resetZoom: () => {
4726
+ isUserZoomed = false;
4727
+ fontSize = 13;
4728
+ rotation = 0;
4729
+ zoomLevel = isTxt ? calculateTxtFit() : 1;
4730
+ container.scrollTop = 0;
4731
+ container.scrollLeft = 0;
4732
+ updateTransform();
4733
+ },
4426
4734
  rotateCW: () => {
4427
4735
  rotation = (rotation + 90) % 360;
4428
4736
  updateTransform();
@@ -4485,11 +4793,19 @@ var ArchivePlugin = class {
4485
4793
  {
4486
4794
  id: "fit-page",
4487
4795
  icon: "fit-page",
4488
- label: "Reset Zoom",
4796
+ label: "Fit to Page",
4489
4797
  type: "button",
4490
4798
  group: "zoom",
4491
4799
  execute: () => instance.fitToPage?.()
4492
4800
  },
4801
+ {
4802
+ id: "reset-zoom",
4803
+ icon: "reset-zoom",
4804
+ label: "Reset Zoom",
4805
+ type: "button",
4806
+ group: "zoom",
4807
+ execute: () => instance.resetZoom?.()
4808
+ },
4493
4809
  {
4494
4810
  id: "download",
4495
4811
  icon: "download",
@@ -4515,16 +4831,56 @@ var ArchivePlugin = class {
4515
4831
  width: 100%;
4516
4832
  height: 100%;
4517
4833
  overflow: auto;
4518
- padding: 24px;
4519
4834
  box-sizing: border-box;
4520
4835
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
4521
- transform-origin: top left;
4522
- transition: transform 0.2s ease;
4523
4836
  `;
4837
+ const scrollWrapper = document.createElement("div");
4838
+ scrollWrapper.className = "fp-archive-scroll-wrapper";
4839
+ scrollWrapper.style.cssText = `
4840
+ min-width: 100%;
4841
+ min-height: 100%;
4842
+ width: max-content;
4843
+ height: max-content;
4844
+ display: flex;
4845
+ justify-content: center;
4846
+ align-items: flex-start;
4847
+ padding: 24px;
4848
+ box-sizing: border-box;
4849
+ `;
4850
+ const sizer = document.createElement("div");
4851
+ sizer.className = "fp-archive-sizer";
4852
+ sizer.style.cssText = `
4853
+ position: relative;
4854
+ flex-shrink: 0;
4855
+ display: flex;
4856
+ justify-content: center;
4857
+ align-items: flex-start;
4858
+ `;
4859
+ const card = document.createElement("div");
4860
+ card.className = "fp-archive-card";
4861
+ card.style.cssText = `
4862
+ width: 900px;
4863
+ box-sizing: border-box;
4864
+ transform-origin: top center;
4865
+ transition: transform 0.15s ease;
4866
+ flex-shrink: 0;
4867
+ `;
4868
+ sizer.appendChild(card);
4869
+ scrollWrapper.appendChild(sizer);
4870
+ wrapper.appendChild(scrollWrapper);
4524
4871
  ctx.container.innerHTML = "";
4525
4872
  ctx.container.style.overflow = "auto";
4526
4873
  ctx.container.appendChild(wrapper);
4527
4874
  let scale = 1;
4875
+ const applyTransform = () => {
4876
+ const boxW = Math.round(900 * scale);
4877
+ const cardH = card.offsetHeight || 600;
4878
+ const boxH = Math.round(cardH * scale);
4879
+ sizer.style.width = `${boxW}px`;
4880
+ sizer.style.height = `${boxH}px`;
4881
+ card.style.transform = `scale(${scale})`;
4882
+ card.style.transformOrigin = "top center";
4883
+ };
4528
4884
  const entries = await new Promise((resolve, reject) => {
4529
4885
  unzip(new Uint8Array(ctx.buffer), (err, unzipped) => {
4530
4886
  if (err) {
@@ -4548,7 +4904,7 @@ var ArchivePlugin = class {
4548
4904
  });
4549
4905
  const totalUncompressedSize = entries.reduce((acc, e) => acc + e.size, 0);
4550
4906
  const renderUI = (filteredEntries) => {
4551
- wrapper.innerHTML = `
4907
+ card.innerHTML = `
4552
4908
  <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;">
4553
4909
  <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;">
4554
4910
  <div>
@@ -4578,7 +4934,7 @@ var ArchivePlugin = class {
4578
4934
  </div>
4579
4935
  </div>
4580
4936
  `;
4581
- const tbody = wrapper.querySelector("#fp-archive-body");
4937
+ const tbody = card.querySelector("#fp-archive-body");
4582
4938
  if (filteredEntries.length === 0) {
4583
4939
  tbody.innerHTML = `<tr><td colspan="3" style="padding: 24px; text-align: center; color: #9ca3af;">No matching files found</td></tr>`;
4584
4940
  } else {
@@ -4607,19 +4963,20 @@ var ArchivePlugin = class {
4607
4963
  }
4608
4964
  });
4609
4965
  });
4610
- const searchInput = wrapper.querySelector("#fp-archive-search");
4966
+ const searchInput = card.querySelector("#fp-archive-search");
4611
4967
  if (searchInput) {
4612
4968
  searchInput.addEventListener("input", () => {
4613
4969
  const q = searchInput.value.toLowerCase().trim();
4614
4970
  const filtered = q ? entries.filter((e) => e.path.toLowerCase().includes(q)) : entries;
4615
4971
  renderUI(filtered);
4616
- const newSearch = wrapper.querySelector("#fp-archive-search");
4972
+ const newSearch = card.querySelector("#fp-archive-search");
4617
4973
  if (newSearch) {
4618
4974
  newSearch.value = q;
4619
4975
  newSearch.focus();
4620
4976
  }
4621
4977
  });
4622
4978
  }
4979
+ applyTransform();
4623
4980
  };
4624
4981
  renderUI(entries);
4625
4982
  const cleanup = () => {
@@ -4631,20 +4988,26 @@ var ArchivePlugin = class {
4631
4988
  destroy: cleanup,
4632
4989
  zoomIn: () => {
4633
4990
  scale += 0.1;
4634
- wrapper.style.transform = `scale(${scale})`;
4991
+ applyTransform();
4635
4992
  },
4636
4993
  zoomOut: () => {
4637
4994
  scale = Math.max(0.3, scale - 0.1);
4638
- wrapper.style.transform = `scale(${scale})`;
4995
+ applyTransform();
4639
4996
  },
4640
4997
  getZoom: () => scale,
4641
4998
  setZoom: (level) => {
4642
4999
  scale = level;
4643
- wrapper.style.transform = `scale(${scale})`;
5000
+ applyTransform();
4644
5001
  },
4645
5002
  fitToPage: () => {
4646
5003
  scale = 1;
4647
- wrapper.style.transform = `scale(1)`;
5004
+ applyTransform();
5005
+ },
5006
+ resetZoom: () => {
5007
+ scale = 1;
5008
+ wrapper.scrollTop = 0;
5009
+ wrapper.scrollLeft = 0;
5010
+ applyTransform();
4648
5011
  },
4649
5012
  download: () => {
4650
5013
  downloadFile(ctx.buffer, ctx.metadata.name || "archive.zip", "application/zip");
@@ -4696,6 +5059,14 @@ var MarkdownPlugin = class {
4696
5059
  group: "zoom",
4697
5060
  execute: () => instance.fitToPage?.()
4698
5061
  },
5062
+ {
5063
+ id: "reset-zoom",
5064
+ icon: "reset-zoom",
5065
+ label: "Reset Zoom",
5066
+ type: "button",
5067
+ group: "zoom",
5068
+ execute: () => instance.resetZoom?.()
5069
+ },
4699
5070
  {
4700
5071
  id: "copy",
4701
5072
  icon: "copy",
@@ -4849,6 +5220,12 @@ var MarkdownPlugin = class {
4849
5220
  fontSize = 15;
4850
5221
  wrapper.style.fontSize = "15px";
4851
5222
  },
5223
+ resetZoom: () => {
5224
+ fontSize = 15;
5225
+ wrapper.style.fontSize = "15px";
5226
+ ctx.container.scrollTop = 0;
5227
+ ctx.container.scrollLeft = 0;
5228
+ },
4852
5229
  download: () => {
4853
5230
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
4854
5231
  },
@@ -4942,6 +5319,14 @@ var PptxPlugin = class {
4942
5319
  group: "zoom",
4943
5320
  execute: () => instance.fitToPage?.()
4944
5321
  },
5322
+ {
5323
+ id: "reset-zoom",
5324
+ icon: "reset-zoom",
5325
+ label: "Reset Zoom",
5326
+ type: "button",
5327
+ group: "zoom",
5328
+ execute: () => instance.resetZoom?.()
5329
+ },
4945
5330
  {
4946
5331
  id: "rotate-cw",
4947
5332
  icon: "rotate-cw",
@@ -4981,12 +5366,30 @@ var PptxPlugin = class {
4981
5366
  width: 100%;
4982
5367
  height: 100%;
4983
5368
  overflow: auto;
5369
+ box-sizing: border-box;
5370
+ background: var(--fp-bg-canvas, #525659);
5371
+ `;
5372
+ const scrollWrapper = document.createElement("div");
5373
+ scrollWrapper.className = "fp-pptx-scroll-wrapper";
5374
+ scrollWrapper.style.cssText = `
5375
+ min-width: 100%;
5376
+ min-height: 100%;
5377
+ width: max-content;
5378
+ height: max-content;
4984
5379
  display: flex;
4985
5380
  justify-content: center;
4986
- align-items: flex-start;
5381
+ align-items: center;
4987
5382
  padding: 24px;
4988
5383
  box-sizing: border-box;
4989
- background: var(--fp-bg-canvas, #525659);
5384
+ `;
5385
+ const sizer = document.createElement("div");
5386
+ sizer.className = "fp-pptx-sizer";
5387
+ sizer.style.cssText = `
5388
+ position: relative;
5389
+ flex-shrink: 0;
5390
+ display: flex;
5391
+ justify-content: center;
5392
+ align-items: center;
4990
5393
  `;
4991
5394
  const slideContainer = document.createElement("div");
4992
5395
  slideContainer.className = "fp-slide-container";
@@ -4995,14 +5398,15 @@ var PptxPlugin = class {
4995
5398
  border-radius: 4px;
4996
5399
  overflow: hidden;
4997
5400
  background: #ffffff;
4998
- transform-origin: top center;
5401
+ transform-origin: center center;
4999
5402
  transition: transform 0.2s ease;
5000
- max-width: calc(100% - 32px);
5001
- max-height: calc(100% - 48px);
5403
+ flex-shrink: 0;
5002
5404
  `;
5003
5405
  const canvas = document.createElement("canvas");
5004
5406
  slideContainer.appendChild(canvas);
5005
- wrapper.appendChild(slideContainer);
5407
+ sizer.appendChild(slideContainer);
5408
+ scrollWrapper.appendChild(sizer);
5409
+ wrapper.appendChild(scrollWrapper);
5006
5410
  ctx.container.innerHTML = "";
5007
5411
  ctx.container.style.overflow = "auto";
5008
5412
  ctx.container.appendChild(wrapper);
@@ -5014,7 +5418,17 @@ var PptxPlugin = class {
5014
5418
  return Math.min(1, Math.min(availW / cW, availH / cH));
5015
5419
  };
5016
5420
  const applyTransform = () => {
5421
+ const cW = canvas.offsetWidth || 1280;
5422
+ const cH = canvas.offsetHeight || 720;
5423
+ const isRotated90 = rotation % 180 !== 0;
5424
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
5425
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
5426
+ sizer.style.width = `${boxW}px`;
5427
+ sizer.style.height = `${boxH}px`;
5428
+ slideContainer.style.width = `${cW}px`;
5429
+ slideContainer.style.height = `${cH}px`;
5017
5430
  slideContainer.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5431
+ slideContainer.style.transformOrigin = "center center";
5018
5432
  };
5019
5433
  const renderCurrentSlide = async () => {
5020
5434
  try {
@@ -5061,6 +5475,13 @@ var PptxPlugin = class {
5061
5475
  rotation = 0;
5062
5476
  applyTransform();
5063
5477
  },
5478
+ resetZoom: () => {
5479
+ scale = calculateFitScale();
5480
+ rotation = 0;
5481
+ wrapper.scrollTop = 0;
5482
+ wrapper.scrollLeft = 0;
5483
+ applyTransform();
5484
+ },
5064
5485
  rotateCW: () => {
5065
5486
  rotation = (rotation + 90) % 360;
5066
5487
  applyTransform();
@@ -5136,6 +5557,14 @@ var ThreeDPlugin = class {
5136
5557
  group: "zoom",
5137
5558
  execute: () => instance.fitToPage?.()
5138
5559
  },
5560
+ {
5561
+ id: "reset-zoom",
5562
+ icon: "reset-zoom",
5563
+ label: "Reset Zoom",
5564
+ type: "button",
5565
+ group: "zoom",
5566
+ execute: () => instance.resetZoom?.()
5567
+ },
5139
5568
  {
5140
5569
  id: "rotate-cw",
5141
5570
  icon: "rotate-cw",
@@ -5272,6 +5701,7 @@ var ThreeDPlugin = class {
5272
5701
  controls.update();
5273
5702
  },
5274
5703
  fitToPage: fitCamera,
5704
+ resetZoom: fitCamera,
5275
5705
  rotateCW: () => {
5276
5706
  isWireframe = !isWireframe;
5277
5707
  materials.forEach((m) => {
@@ -5486,6 +5916,14 @@ var RtfPlugin = class {
5486
5916
  group: "zoom",
5487
5917
  execute: () => instance.fitToPage?.()
5488
5918
  },
5919
+ {
5920
+ id: "reset-zoom",
5921
+ icon: "reset-zoom",
5922
+ label: "Reset Zoom",
5923
+ type: "button",
5924
+ group: "zoom",
5925
+ execute: () => instance.resetZoom?.()
5926
+ },
5489
5927
  {
5490
5928
  id: "rotate-cw",
5491
5929
  icon: "rotate-cw",
@@ -5596,13 +6034,33 @@ var RtfPlugin = class {
5596
6034
  wrapper.style.flexDirection = "column";
5597
6035
  wrapper.style.alignItems = "center";
5598
6036
  wrapper.style.backgroundColor = "transparent";
5599
- wrapper.style.transformOrigin = "top center";
6037
+ wrapper.style.transformOrigin = "center center";
5600
6038
  wrapper.style.transition = "transform 0.15s ease";
5601
- ctx.container.style.overflowX = "hidden";
5602
- ctx.container.style.overflowY = "auto";
5603
- ctx.container.style.padding = "16px 8px";
6039
+ wrapper.style.flexShrink = "0";
6040
+ const sizer = document.createElement("div");
6041
+ sizer.className = "fp-rtf-sizer";
6042
+ sizer.style.position = "relative";
6043
+ sizer.style.flexShrink = "0";
6044
+ sizer.style.display = "flex";
6045
+ sizer.style.justifyContent = "center";
6046
+ sizer.style.alignItems = "center";
6047
+ const scrollWrapper = document.createElement("div");
6048
+ scrollWrapper.className = "fp-rtf-scroll-wrapper";
6049
+ scrollWrapper.style.minWidth = "100%";
6050
+ scrollWrapper.style.minHeight = "100%";
6051
+ scrollWrapper.style.width = "max-content";
6052
+ scrollWrapper.style.height = "max-content";
6053
+ scrollWrapper.style.display = "flex";
6054
+ scrollWrapper.style.justifyContent = "center";
6055
+ scrollWrapper.style.alignItems = "flex-start";
6056
+ scrollWrapper.style.padding = "16px 8px";
6057
+ scrollWrapper.style.boxSizing = "border-box";
6058
+ sizer.appendChild(wrapper);
6059
+ scrollWrapper.appendChild(sizer);
6060
+ ctx.container.style.overflow = "auto";
6061
+ ctx.container.style.padding = "0";
5604
6062
  ctx.container.style.backgroundColor = "#f1f5f9";
5605
- ctx.container.appendChild(wrapper);
6063
+ ctx.container.appendChild(scrollWrapper);
5606
6064
  let scale = 1;
5607
6065
  let rotation = 0;
5608
6066
  let pageElements = [];
@@ -5621,12 +6079,17 @@ var RtfPlugin = class {
5621
6079
  return Math.max(0.4, Math.min(3, sW));
5622
6080
  };
5623
6081
  const applyTransform = () => {
5624
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
5625
- wrapper.style.transformOrigin = "top center";
6082
+ const elW = pageWidth;
5626
6083
  const baseH = pageHeight;
5627
- const scaledH = baseH * scale;
5628
- const extraH = Math.max(0, scaledH - baseH);
5629
- wrapper.style.marginBottom = `${extraH + 32}px`;
6084
+ const isRotated90 = rotation % 180 !== 0;
6085
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6086
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6087
+ sizer.style.width = `${boxW}px`;
6088
+ sizer.style.height = `${boxH}px`;
6089
+ wrapper.style.width = `${elW}px`;
6090
+ wrapper.style.height = `${baseH}px`;
6091
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6092
+ wrapper.style.transformOrigin = "center center";
5630
6093
  };
5631
6094
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5632
6095
  if (!isUserZoomed) {
@@ -5897,7 +6360,7 @@ var RtfPlugin = class {
5897
6360
  }
5898
6361
  const cleanup = () => {
5899
6362
  resizeObserver?.disconnect();
5900
- wrapper.remove();
6363
+ scrollWrapper.remove();
5901
6364
  ctx.container.innerHTML = "";
5902
6365
  };
5903
6366
  ctx.signal.addEventListener("abort", cleanup);
@@ -5955,6 +6418,15 @@ var RtfPlugin = class {
5955
6418
  rotation = 0;
5956
6419
  applyTransform();
5957
6420
  },
6421
+ resetZoom: () => {
6422
+ isUserZoomed = false;
6423
+ fitMode = "width";
6424
+ scale = calculateFitScale("width");
6425
+ rotation = 0;
6426
+ ctx.container.scrollTop = 0;
6427
+ ctx.container.scrollLeft = 0;
6428
+ applyTransform();
6429
+ },
5958
6430
  rotateCW: () => {
5959
6431
  rotation = (rotation + 90) % 360;
5960
6432
  applyTransform();
@@ -6022,6 +6494,14 @@ var HtmlPreviewPlugin = class {
6022
6494
  group: "zoom",
6023
6495
  execute: () => instance.fitToPage?.()
6024
6496
  },
6497
+ {
6498
+ id: "reset-zoom",
6499
+ icon: "reset-zoom",
6500
+ label: "Reset Zoom",
6501
+ type: "button",
6502
+ group: "zoom",
6503
+ execute: () => instance.resetZoom?.()
6504
+ },
6025
6505
  {
6026
6506
  id: "copy",
6027
6507
  icon: "copy",
@@ -6055,23 +6535,44 @@ var HtmlPreviewPlugin = class {
6055
6535
  ADD_TAGS: ["style", "link"],
6056
6536
  ADD_ATTR: ["target", "rel"]
6057
6537
  });
6538
+ const sizer = document.createElement("div");
6539
+ sizer.className = "fp-html-sizer";
6540
+ sizer.style.position = "relative";
6058
6541
  const iframe = document.createElement("iframe");
6059
6542
  iframe.className = "fp-html-iframe";
6060
- iframe.style.width = "100%";
6061
- iframe.style.height = "100%";
6062
6543
  iframe.style.border = "none";
6063
6544
  iframe.style.backgroundColor = "#ffffff";
6064
6545
  iframe.style.transformOrigin = "top left";
6065
6546
  iframe.style.transition = "transform 0.2s ease";
6066
6547
  iframe.sandbox.add("allow-same-origin");
6548
+ sizer.appendChild(iframe);
6067
6549
  ctx.container.style.overflow = "auto";
6068
6550
  ctx.container.style.width = "100%";
6069
6551
  ctx.container.style.height = "100%";
6070
- ctx.container.appendChild(iframe);
6552
+ ctx.container.innerHTML = "";
6553
+ ctx.container.appendChild(sizer);
6071
6554
  iframe.srcdoc = sanitized;
6072
6555
  let scale = 1;
6556
+ const applyTransform = () => {
6557
+ const baseW = Math.max(600, ctx.container.clientWidth || 800);
6558
+ const baseH = Math.max(400, ctx.container.clientHeight || 600);
6559
+ const scaledW = Math.round(baseW * scale);
6560
+ const scaledH = Math.round(baseH * scale);
6561
+ sizer.style.width = `${scaledW}px`;
6562
+ sizer.style.height = `${scaledH}px`;
6563
+ iframe.style.position = "absolute";
6564
+ iframe.style.top = "0";
6565
+ iframe.style.left = "0";
6566
+ iframe.style.width = `${baseW}px`;
6567
+ iframe.style.height = `${baseH}px`;
6568
+ iframe.style.transform = `scale(${scale})`;
6569
+ iframe.style.transformOrigin = "top left";
6570
+ };
6571
+ requestAnimationFrame(() => {
6572
+ applyTransform();
6573
+ });
6073
6574
  const cleanup = () => {
6074
- iframe.remove();
6575
+ sizer.remove();
6075
6576
  ctx.container.innerHTML = "";
6076
6577
  };
6077
6578
  ctx.signal.addEventListener("abort", cleanup);
@@ -6079,20 +6580,26 @@ var HtmlPreviewPlugin = class {
6079
6580
  destroy: cleanup,
6080
6581
  zoomIn: () => {
6081
6582
  scale += 0.1;
6082
- iframe.style.transform = `scale(${scale})`;
6583
+ applyTransform();
6083
6584
  },
6084
6585
  zoomOut: () => {
6085
6586
  scale = Math.max(0.2, scale - 0.1);
6086
- iframe.style.transform = `scale(${scale})`;
6587
+ applyTransform();
6087
6588
  },
6088
6589
  getZoom: () => scale,
6089
6590
  setZoom: (level) => {
6090
6591
  scale = level;
6091
- iframe.style.transform = `scale(${scale})`;
6592
+ applyTransform();
6092
6593
  },
6093
6594
  fitToPage: () => {
6094
6595
  scale = 1;
6095
- iframe.style.transform = "scale(1)";
6596
+ applyTransform();
6597
+ },
6598
+ resetZoom: () => {
6599
+ scale = 1;
6600
+ ctx.container.scrollTop = 0;
6601
+ ctx.container.scrollLeft = 0;
6602
+ applyTransform();
6096
6603
  },
6097
6604
  copy: () => {
6098
6605
  navigator.clipboard.writeText(rawHtml);
@@ -6194,6 +6701,14 @@ var OpenDocumentPlugin = class {
6194
6701
  group: "zoom",
6195
6702
  execute: () => instance.fitToPage?.()
6196
6703
  },
6704
+ {
6705
+ id: "reset-zoom",
6706
+ icon: "reset-zoom",
6707
+ label: "Reset Zoom",
6708
+ type: "button",
6709
+ group: "zoom",
6710
+ execute: () => instance.resetZoom?.()
6711
+ },
6197
6712
  {
6198
6713
  id: "rotate-cw",
6199
6714
  icon: "rotate-cw",
@@ -6259,10 +6774,26 @@ var OpenDocumentPlugin = class {
6259
6774
  container.className = "fp-odf-container";
6260
6775
  container.style.width = "100%";
6261
6776
  container.style.height = "100%";
6262
- container.style.overflowX = "hidden";
6263
- container.style.overflowY = "auto";
6264
- container.style.padding = "16px 8px";
6777
+ container.style.overflow = "auto";
6265
6778
  container.style.backgroundColor = "#f1f5f9";
6779
+ const scrollWrapper = document.createElement("div");
6780
+ scrollWrapper.className = "fp-odf-scroll-wrapper";
6781
+ scrollWrapper.style.minWidth = "100%";
6782
+ scrollWrapper.style.minHeight = "100%";
6783
+ scrollWrapper.style.width = "max-content";
6784
+ scrollWrapper.style.height = "max-content";
6785
+ scrollWrapper.style.display = "flex";
6786
+ scrollWrapper.style.justifyContent = "center";
6787
+ scrollWrapper.style.alignItems = "flex-start";
6788
+ scrollWrapper.style.padding = "16px 8px";
6789
+ scrollWrapper.style.boxSizing = "border-box";
6790
+ const sizer = document.createElement("div");
6791
+ sizer.className = "fp-odf-sizer";
6792
+ sizer.style.position = "relative";
6793
+ sizer.style.flexShrink = "0";
6794
+ sizer.style.display = "flex";
6795
+ sizer.style.justifyContent = "center";
6796
+ sizer.style.alignItems = "center";
6266
6797
  const wrapper = document.createElement("div");
6267
6798
  wrapper.className = "fp-odf-wrapper";
6268
6799
  wrapper.style.margin = "0 auto";
@@ -6271,9 +6802,12 @@ var OpenDocumentPlugin = class {
6271
6802
  wrapper.style.backgroundColor = "#ffffff";
6272
6803
  wrapper.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
6273
6804
  wrapper.style.borderRadius = "4px";
6274
- wrapper.style.transformOrigin = "top center";
6805
+ wrapper.style.transformOrigin = "center center";
6275
6806
  wrapper.style.transition = "transform 0.15s ease";
6276
- container.appendChild(wrapper);
6807
+ wrapper.style.flexShrink = "0";
6808
+ sizer.appendChild(wrapper);
6809
+ scrollWrapper.appendChild(sizer);
6810
+ container.appendChild(scrollWrapper);
6277
6811
  ctx.container.appendChild(container);
6278
6812
  let scale = 1;
6279
6813
  let rotation = 0;
@@ -6299,13 +6833,18 @@ var OpenDocumentPlugin = class {
6299
6833
  return Math.max(0.4, Math.min(3, sW));
6300
6834
  };
6301
6835
  const applyTransform = () => {
6302
- wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6303
- wrapper.style.transformOrigin = "top center";
6304
6836
  const activeSlide = slides[currentPage - 1];
6837
+ const elW = isPresentation ? 960 : 816;
6305
6838
  const baseH = activeSlide?.offsetHeight || wrapper.offsetHeight || 1056;
6306
- const scaledH = baseH * scale;
6307
- const extraH = Math.max(0, scaledH - baseH);
6308
- wrapper.style.marginBottom = `${extraH + 32}px`;
6839
+ const isRotated90 = rotation % 180 !== 0;
6840
+ const boxW = Math.round((isRotated90 ? baseH : elW) * scale);
6841
+ const boxH = Math.round((isRotated90 ? elW : baseH) * scale);
6842
+ sizer.style.width = `${boxW}px`;
6843
+ sizer.style.height = `${boxH}px`;
6844
+ wrapper.style.width = `${elW}px`;
6845
+ wrapper.style.height = `${baseH}px`;
6846
+ wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6847
+ wrapper.style.transformOrigin = "center center";
6309
6848
  };
6310
6849
  const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
6311
6850
  if (!isUserZoomed) {
@@ -6461,6 +7000,15 @@ var OpenDocumentPlugin = class {
6461
7000
  rotation = 0;
6462
7001
  applyTransform();
6463
7002
  },
7003
+ resetZoom: () => {
7004
+ isUserZoomed = false;
7005
+ fitMode = "width";
7006
+ scale = calculateFitScale("width");
7007
+ rotation = 0;
7008
+ container.scrollTop = 0;
7009
+ container.scrollLeft = 0;
7010
+ applyTransform();
7011
+ },
6464
7012
  rotateCW: () => {
6465
7013
  rotation = (rotation + 90) % 360;
6466
7014
  applyTransform();
@@ -6804,6 +7352,14 @@ var DocPlugin = class {
6804
7352
  group: "zoom",
6805
7353
  execute: () => instance.fitToPage?.()
6806
7354
  },
7355
+ {
7356
+ id: "reset-zoom",
7357
+ icon: "reset-zoom",
7358
+ label: "Reset Zoom",
7359
+ type: "button",
7360
+ group: "zoom",
7361
+ execute: () => instance.resetZoom?.()
7362
+ },
6807
7363
  {
6808
7364
  id: "rotate-cw",
6809
7365
  icon: "rotate-cw",
@@ -6852,13 +7408,28 @@ var DocPlugin = class {
6852
7408
  container.className = "fp-doc-container";
6853
7409
  container.style.width = "100%";
6854
7410
  container.style.height = "100%";
6855
- container.style.overflowX = "hidden";
6856
- container.style.overflowY = "auto";
6857
- container.style.padding = "16px 8px";
7411
+ container.style.overflow = "auto";
6858
7412
  container.style.backgroundColor = "#f1f5f9";
6859
- container.style.display = "flex";
6860
- container.style.justifyContent = "center";
6861
- container.style.alignItems = "flex-start";
7413
+ const scrollWrapper = document.createElement("div");
7414
+ scrollWrapper.className = "fp-doc-scroll-wrapper";
7415
+ scrollWrapper.style.minWidth = "100%";
7416
+ scrollWrapper.style.minHeight = "100%";
7417
+ scrollWrapper.style.width = "max-content";
7418
+ scrollWrapper.style.height = "max-content";
7419
+ scrollWrapper.style.display = "flex";
7420
+ scrollWrapper.style.justifyContent = "center";
7421
+ scrollWrapper.style.alignItems = "flex-start";
7422
+ scrollWrapper.style.padding = "16px 8px";
7423
+ scrollWrapper.style.boxSizing = "border-box";
7424
+ const sizer = document.createElement("div");
7425
+ sizer.className = "fp-doc-sizer";
7426
+ sizer.style.position = "relative";
7427
+ sizer.style.flexShrink = "0";
7428
+ sizer.style.display = "flex";
7429
+ sizer.style.justifyContent = "center";
7430
+ sizer.style.alignItems = "center";
7431
+ scrollWrapper.appendChild(sizer);
7432
+ container.appendChild(scrollWrapper);
6862
7433
  ctx.container.appendChild(container);
6863
7434
  let scale = 1;
6864
7435
  let extractedRawText = "";
@@ -6906,10 +7477,11 @@ var DocPlugin = class {
6906
7477
  pageCard.style.padding = "72px 56px";
6907
7478
  pageCard.style.boxSizing = "border-box";
6908
7479
  pageCard.style.display = i === 0 ? "block" : "none";
6909
- pageCard.style.transformOrigin = "top center";
7480
+ pageCard.style.transformOrigin = "center center";
6910
7481
  pageCard.style.transition = "transform 0.15s ease";
6911
7482
  pageCard.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
6912
7483
  pageCard.style.color = "#1e293b";
7484
+ pageCard.style.flexShrink = "0";
6913
7485
  if (isFallback && i === 0) {
6914
7486
  pageCard.innerHTML = `
6915
7487
  <div style="border-bottom: 1px solid #e2e8f0; padding-bottom: 12px; margin-bottom: 24px;">
@@ -6921,18 +7493,23 @@ var DocPlugin = class {
6921
7493
  } else {
6922
7494
  pageCard.innerHTML = this.formatDocToHtml(rawPages[i], ctx.metadata.name || "Document");
6923
7495
  }
6924
- container.appendChild(pageCard);
7496
+ sizer.appendChild(pageCard);
6925
7497
  pageCards.push(pageCard);
6926
7498
  }
6927
7499
  let rotation = 0;
6928
7500
  const applyTransform = () => {
6929
7501
  const activeCard = pageCards[currentPage - 1];
6930
7502
  if (activeCard) {
6931
- activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7503
+ const baseW = 816;
6932
7504
  const baseH = activeCard.offsetHeight || 1056;
6933
- const scaledH = baseH * scale;
6934
- const extraH = Math.max(0, scaledH - baseH);
6935
- activeCard.style.marginBottom = `${extraH + 32}px`;
7505
+ const isRotated90 = rotation % 180 !== 0;
7506
+ const boxW = Math.round((isRotated90 ? baseH : baseW) * scale);
7507
+ const boxH = Math.round((isRotated90 ? baseW : baseH) * scale);
7508
+ sizer.style.width = `${boxW}px`;
7509
+ sizer.style.height = `${boxH}px`;
7510
+ activeCard.style.width = `${baseW}px`;
7511
+ activeCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
7512
+ activeCard.style.transformOrigin = "center center";
6936
7513
  }
6937
7514
  };
6938
7515
  const showPage = (pageNum) => {
@@ -6940,11 +7517,11 @@ var DocPlugin = class {
6940
7517
  pageCards.forEach((card, idx) => {
6941
7518
  if (idx + 1 === currentPage) {
6942
7519
  card.style.display = "block";
6943
- card.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
6944
7520
  } else {
6945
7521
  card.style.display = "none";
6946
7522
  }
6947
7523
  });
7524
+ applyTransform();
6948
7525
  container.scrollTop = 0;
6949
7526
  ctx.emit("page-change", { page: currentPage, total: totalPages });
6950
7527
  };
@@ -7010,6 +7587,17 @@ var DocPlugin = class {
7010
7587
  rotation = 0;
7011
7588
  applyTransform();
7012
7589
  },
7590
+ resetZoom: () => {
7591
+ isUserZoomed = false;
7592
+ fitMode = "width";
7593
+ scale = calculateFitScale("width");
7594
+ rotation = 0;
7595
+ container.scrollTop = 0;
7596
+ container.scrollLeft = 0;
7597
+ ctx.container.scrollTop = 0;
7598
+ ctx.container.scrollLeft = 0;
7599
+ applyTransform();
7600
+ },
7013
7601
  rotateCW: () => {
7014
7602
  rotation = (rotation + 90) % 360;
7015
7603
  applyTransform();
@@ -7490,6 +8078,14 @@ var PptPlugin = class {
7490
8078
  group: "zoom",
7491
8079
  execute: () => instance.fitToPage?.()
7492
8080
  },
8081
+ {
8082
+ id: "reset-zoom",
8083
+ icon: "reset-zoom",
8084
+ label: "Reset Zoom",
8085
+ type: "button",
8086
+ group: "zoom",
8087
+ execute: () => instance.resetZoom?.()
8088
+ },
7493
8089
  {
7494
8090
  id: "rotate-cw",
7495
8091
  icon: "rotate-cw",
@@ -7522,17 +8118,30 @@ var PptPlugin = class {
7522
8118
  container.style.width = "100%";
7523
8119
  container.style.height = "100%";
7524
8120
  container.style.overflow = "auto";
7525
- container.style.display = "flex";
7526
- container.style.justifyContent = "center";
7527
- container.style.alignItems = "center";
7528
- container.style.padding = "32px 16px";
7529
8121
  container.style.backgroundColor = "#0f172a";
7530
8122
  container.style.boxSizing = "border-box";
8123
+ const scrollWrapper = document.createElement("div");
8124
+ scrollWrapper.className = "fp-ppt-scroll-wrapper";
8125
+ scrollWrapper.style.minWidth = "100%";
8126
+ scrollWrapper.style.minHeight = "100%";
8127
+ scrollWrapper.style.width = "max-content";
8128
+ scrollWrapper.style.height = "max-content";
8129
+ scrollWrapper.style.display = "flex";
8130
+ scrollWrapper.style.justifyContent = "center";
8131
+ scrollWrapper.style.alignItems = "center";
8132
+ scrollWrapper.style.padding = "32px 16px";
8133
+ scrollWrapper.style.boxSizing = "border-box";
8134
+ const sizer = document.createElement("div");
8135
+ sizer.className = "fp-ppt-sizer";
8136
+ sizer.style.position = "relative";
8137
+ sizer.style.flexShrink = "0";
8138
+ sizer.style.display = "flex";
8139
+ sizer.style.justifyContent = "center";
8140
+ sizer.style.alignItems = "center";
7531
8141
  const slideCard = document.createElement("div");
7532
8142
  slideCard.className = "fp-ppt-slide-card";
7533
8143
  slideCard.style.width = "960px";
7534
- slideCard.style.maxWidth = "calc(100% - 32px)";
7535
- slideCard.style.maxHeight = "calc(100% - 48px)";
8144
+ slideCard.style.height = "540px";
7536
8145
  slideCard.style.aspectRatio = "16 / 9";
7537
8146
  slideCard.style.backgroundColor = "#ffffff";
7538
8147
  slideCard.style.boxShadow = "0 12px 40px rgba(0,0,0,0.35)";
@@ -7542,7 +8151,9 @@ var PptPlugin = class {
7542
8151
  slideCard.style.transition = "transform 0.2s ease";
7543
8152
  slideCard.style.transformOrigin = "center center";
7544
8153
  slideCard.style.flexShrink = "0";
7545
- container.appendChild(slideCard);
8154
+ sizer.appendChild(slideCard);
8155
+ scrollWrapper.appendChild(sizer);
8156
+ container.appendChild(scrollWrapper);
7546
8157
  ctx.container.appendChild(container);
7547
8158
  let scale = 1;
7548
8159
  let rotation = 0;
@@ -7555,7 +8166,17 @@ var PptPlugin = class {
7555
8166
  return Math.min(1, Math.min(availW / 960, availH / 540));
7556
8167
  };
7557
8168
  const applyTransform = () => {
8169
+ const cW = 960;
8170
+ const cH = 540;
8171
+ const isRotated90 = rotation % 180 !== 0;
8172
+ const boxW = Math.round((isRotated90 ? cH : cW) * scale);
8173
+ const boxH = Math.round((isRotated90 ? cW : cH) * scale);
8174
+ sizer.style.width = `${boxW}px`;
8175
+ sizer.style.height = `${boxH}px`;
8176
+ slideCard.style.width = `${cW}px`;
8177
+ slideCard.style.height = `${cH}px`;
7558
8178
  slideCard.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
8179
+ slideCard.style.transformOrigin = "center center";
7559
8180
  };
7560
8181
  setTimeout(() => {
7561
8182
  scale = calculateFitScale();
@@ -7678,6 +8299,13 @@ var PptPlugin = class {
7678
8299
  rotation = 0;
7679
8300
  applyTransform();
7680
8301
  },
8302
+ resetZoom: () => {
8303
+ scale = calculateFitScale();
8304
+ rotation = 0;
8305
+ container.scrollTop = 0;
8306
+ container.scrollLeft = 0;
8307
+ applyTransform();
8308
+ },
7681
8309
  rotateCW: () => {
7682
8310
  rotation = (rotation + 90) % 360;
7683
8311
  applyTransform();