@files-preview-app/preview-file 1.3.8 → 1.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.cjs CHANGED
@@ -1632,19 +1632,85 @@ var FilePreviewViewer = class _FilePreviewViewer {
1632
1632
  if (this.wrapperEl?.parentNode) {
1633
1633
  this.wrapperEl.parentNode.removeChild(this.wrapperEl);
1634
1634
  }
1635
+ if (typeof document !== "undefined" && !document.getElementById("fp-core-injected-styles")) {
1636
+ const styleEl = document.createElement("style");
1637
+ styleEl.id = "fp-core-injected-styles";
1638
+ styleEl.textContent = `
1639
+ .fp-viewer {
1640
+ display: flex !important;
1641
+ flex-direction: column !important;
1642
+ width: 100% !important;
1643
+ height: 100% !important;
1644
+ overflow: hidden !important;
1645
+ position: relative !important;
1646
+ box-sizing: border-box !important;
1647
+ }
1648
+ .fp-body {
1649
+ display: flex !important;
1650
+ flex: 1 1 0% !important;
1651
+ min-height: 0 !important;
1652
+ min-width: 0 !important;
1653
+ width: 100% !important;
1654
+ height: 100% !important;
1655
+ overflow: hidden !important;
1656
+ position: relative !important;
1657
+ box-sizing: border-box !important;
1658
+ }
1659
+ .fp-content {
1660
+ flex: 1 1 0% !important;
1661
+ position: relative !important;
1662
+ overflow: auto !important;
1663
+ display: flex !important;
1664
+ flex-direction: column !important;
1665
+ align-items: stretch !important;
1666
+ justify-content: flex-start !important;
1667
+ width: 100% !important;
1668
+ height: 100% !important;
1669
+ min-width: 0 !important;
1670
+ min-height: 0 !important;
1671
+ box-sizing: border-box !important;
1672
+ }
1673
+ `;
1674
+ document.head.appendChild(styleEl);
1675
+ }
1635
1676
  const themeClass = options.theme === "dark" ? "fp-theme-dark" : "";
1636
1677
  const toolbarPos = options.toolbarPosition ?? "top";
1637
1678
  this.wrapperEl = document.createElement("div");
1638
1679
  this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
1639
1680
  this.wrapperEl.tabIndex = 0;
1681
+ this.wrapperEl.style.display = "flex";
1682
+ this.wrapperEl.style.flexDirection = "column";
1683
+ this.wrapperEl.style.width = "100%";
1684
+ this.wrapperEl.style.height = "100%";
1685
+ this.wrapperEl.style.overflow = "hidden";
1686
+ this.wrapperEl.style.position = "relative";
1640
1687
  const toolbarEl = document.createElement("div");
1641
1688
  toolbarEl.className = "fp-toolbar-container";
1642
1689
  this.contentEl = document.createElement("div");
1643
1690
  this.contentEl.className = "fp-content";
1691
+ this.contentEl.style.flex = "1 1 0%";
1692
+ this.contentEl.style.position = "relative";
1693
+ this.contentEl.style.overflow = "auto";
1694
+ this.contentEl.style.display = "flex";
1695
+ this.contentEl.style.flexDirection = "column";
1696
+ this.contentEl.style.alignItems = "stretch";
1697
+ this.contentEl.style.justifyContent = "flex-start";
1698
+ this.contentEl.style.width = "100%";
1699
+ this.contentEl.style.height = "100%";
1700
+ this.contentEl.style.minWidth = "0";
1701
+ this.contentEl.style.minHeight = "0";
1702
+ this.contentEl.style.boxSizing = "border-box";
1644
1703
  const thumbnailEl = document.createElement("div");
1645
1704
  thumbnailEl.className = "fp-thumbnail-container";
1646
1705
  const bodyEl = document.createElement("div");
1647
1706
  bodyEl.className = "fp-body";
1707
+ bodyEl.style.display = "flex";
1708
+ bodyEl.style.flex = "1 1 0%";
1709
+ bodyEl.style.minHeight = "0";
1710
+ bodyEl.style.minWidth = "0";
1711
+ bodyEl.style.width = "100%";
1712
+ bodyEl.style.overflow = "hidden";
1713
+ bodyEl.style.position = "relative";
1648
1714
  bodyEl.appendChild(thumbnailEl);
1649
1715
  bodyEl.appendChild(this.contentEl);
1650
1716
  const titleBarEl = document.createElement("div");
@@ -4438,31 +4504,80 @@ function csvPlugin() {
4438
4504
  }
4439
4505
  var CODE_EXTENSIONS = [
4440
4506
  ".txt",
4507
+ ".log",
4508
+ ".ini",
4509
+ ".cfg",
4510
+ ".conf",
4511
+ ".env",
4441
4512
  ".json",
4513
+ ".jsonc",
4514
+ ".json5",
4442
4515
  ".js",
4443
- ".ts",
4516
+ ".mjs",
4517
+ ".cjs",
4444
4518
  ".jsx",
4519
+ ".ts",
4520
+ ".mts",
4521
+ ".cts",
4445
4522
  ".tsx",
4446
4523
  ".html",
4524
+ ".htm",
4525
+ ".xhtml",
4447
4526
  ".css",
4448
4527
  ".scss",
4528
+ ".sass",
4449
4529
  ".less",
4450
4530
  ".md",
4531
+ ".markdown",
4451
4532
  ".xml",
4533
+ ".svg",
4534
+ ".xaml",
4452
4535
  ".yml",
4453
4536
  ".yaml",
4537
+ ".toml",
4454
4538
  ".sh",
4455
4539
  ".bash",
4540
+ ".zsh",
4541
+ ".fish",
4542
+ ".bat",
4543
+ ".cmd",
4544
+ ".ps1",
4456
4545
  ".py",
4546
+ ".pyw",
4457
4547
  ".java",
4548
+ ".class",
4458
4549
  ".c",
4459
4550
  ".cpp",
4551
+ ".cc",
4552
+ ".cxx",
4460
4553
  ".h",
4554
+ ".hpp",
4555
+ ".hxx",
4461
4556
  ".cs",
4557
+ ".csx",
4462
4558
  ".go",
4463
4559
  ".rs",
4464
4560
  ".sql",
4465
- ".php"
4561
+ ".php",
4562
+ ".phtml",
4563
+ ".rb",
4564
+ ".swift",
4565
+ ".kt",
4566
+ ".kts",
4567
+ ".scala",
4568
+ ".r",
4569
+ ".lua",
4570
+ ".pl",
4571
+ ".pm",
4572
+ ".dart",
4573
+ ".graphql",
4574
+ ".gql",
4575
+ ".proto",
4576
+ ".diff",
4577
+ ".patch",
4578
+ ".dockerfile",
4579
+ ".properties",
4580
+ ".gradle"
4466
4581
  ];
4467
4582
  var CodePlugin = class {
4468
4583
  id = "code";
@@ -4480,34 +4595,36 @@ var CodePlugin = class {
4480
4595
  getToolbarActions(instance) {
4481
4596
  const totalPages = instance.getPageCount?.() ?? 1;
4482
4597
  const actions = [];
4483
- actions.push({
4484
- id: "thumbnails",
4485
- icon: "thumbnails",
4486
- label: "Page Thumbnails",
4487
- type: "button",
4488
- group: "navigation",
4489
- execute: () => instance.toggleThumbnails?.()
4490
- });
4491
- actions.push({
4492
- id: "page-nav",
4493
- icon: "",
4494
- label: "Page Navigation",
4495
- type: "page-nav",
4496
- group: "navigation",
4497
- value: instance.getCurrentPage?.() ?? 1,
4498
- max: totalPages,
4499
- execute: (action, page) => {
4500
- const cur = instance.getCurrentPage?.() ?? 1;
4501
- const max = instance.getPageCount?.() ?? 1;
4502
- if (action === "prev") {
4503
- if (cur > 1) instance.goToPage?.(cur - 1);
4504
- } else if (action === "next") {
4505
- if (cur < max) instance.goToPage?.(cur + 1);
4506
- } else if (typeof page === "number") {
4507
- instance.goToPage?.(page);
4598
+ if (totalPages > 1) {
4599
+ actions.push({
4600
+ id: "thumbnails",
4601
+ icon: "thumbnails",
4602
+ label: "Page Thumbnails",
4603
+ type: "button",
4604
+ group: "navigation",
4605
+ execute: () => instance.toggleThumbnails?.()
4606
+ });
4607
+ actions.push({
4608
+ id: "page-nav",
4609
+ icon: "",
4610
+ label: "Page Navigation",
4611
+ type: "page-nav",
4612
+ group: "navigation",
4613
+ value: instance.getCurrentPage?.() ?? 1,
4614
+ max: totalPages,
4615
+ execute: (action, page) => {
4616
+ const cur = instance.getCurrentPage?.() ?? 1;
4617
+ const max = instance.getPageCount?.() ?? 1;
4618
+ if (action === "prev") {
4619
+ if (cur > 1) instance.goToPage?.(cur - 1);
4620
+ } else if (action === "next") {
4621
+ if (cur < max) instance.goToPage?.(cur + 1);
4622
+ } else if (typeof page === "number") {
4623
+ instance.goToPage?.(page);
4624
+ }
4508
4625
  }
4509
- }
4510
- });
4626
+ });
4627
+ }
4511
4628
  actions.push(
4512
4629
  {
4513
4630
  id: "zoom-out",
@@ -4644,10 +4761,6 @@ var CodePlugin = class {
4644
4761
  }
4645
4762
  const totalPages = Math.max(1, rawPages.length);
4646
4763
  let currentPage = 1;
4647
- const container = document.createElement("div");
4648
- container.style.width = "100%";
4649
- container.style.height = "100%";
4650
- container.style.overflow = "auto";
4651
4764
  let fontSize = 13;
4652
4765
  let rotation = 0;
4653
4766
  let zoomLevel = 1;
@@ -4656,9 +4769,10 @@ var CodePlugin = class {
4656
4769
  const code = document.createElement("code");
4657
4770
  const sizer = document.createElement("div");
4658
4771
  const scrollWrapper = document.createElement("div");
4772
+ const lineGutter = document.createElement("div");
4773
+ ctx.container.style.overflow = "auto";
4659
4774
  if (isTxt) {
4660
- container.style.overflow = "auto";
4661
- container.style.backgroundColor = "#f1f5f9";
4775
+ ctx.container.style.backgroundColor = "#f1f5f9";
4662
4776
  scrollWrapper.className = "fp-code-scroll-wrapper";
4663
4777
  scrollWrapper.style.minWidth = "100%";
4664
4778
  scrollWrapper.style.minHeight = "100%";
@@ -4693,18 +4807,88 @@ var CodePlugin = class {
4693
4807
  pre.style.transition = "transform 0.15s ease";
4694
4808
  pre.style.flexShrink = "0";
4695
4809
  } else {
4696
- container.style.overflow = "auto";
4697
- container.style.backgroundColor = "#1e1e1e";
4698
- container.style.color = "#d4d4d4";
4699
- container.style.padding = "16px";
4700
- container.style.boxSizing = "border-box";
4810
+ if (typeof document !== "undefined" && !document.getElementById("fp-code-syntax-styles")) {
4811
+ const style = document.createElement("style");
4812
+ style.id = "fp-code-syntax-styles";
4813
+ style.textContent = `
4814
+ .fp-code-scroll-wrapper .hljs-keyword { color: #569cd6; font-weight: normal; }
4815
+ .fp-code-scroll-wrapper .hljs-built_in { color: #4ec9b0; }
4816
+ .fp-code-scroll-wrapper .hljs-type { color: #4ec9b0; }
4817
+ .fp-code-scroll-wrapper .hljs-literal { color: #569cd6; }
4818
+ .fp-code-scroll-wrapper .hljs-number { color: #b5cea8; }
4819
+ .fp-code-scroll-wrapper .hljs-regexp { color: #d16969; }
4820
+ .fp-code-scroll-wrapper .hljs-string { color: #ce9178; }
4821
+ .fp-code-scroll-wrapper .hljs-subst { color: #d4d4d4; }
4822
+ .fp-code-scroll-wrapper .hljs-symbol { color: #569cd6; }
4823
+ .fp-code-scroll-wrapper .hljs-class { color: #4ec9b0; }
4824
+ .fp-code-scroll-wrapper .hljs-function { color: #dcdcaa; }
4825
+ .fp-code-scroll-wrapper .hljs-title { color: #dcdcaa; }
4826
+ .fp-code-scroll-wrapper .hljs-params { color: #9cdcfe; }
4827
+ .fp-code-scroll-wrapper .hljs-comment { color: #6a9955; font-style: italic; }
4828
+ .fp-code-scroll-wrapper .hljs-doctag { color: #608b4e; }
4829
+ .fp-code-scroll-wrapper .hljs-meta { color: #9cdcfe; }
4830
+ .fp-code-scroll-wrapper .hljs-section { color: #569cd6; }
4831
+ .fp-code-scroll-wrapper .hljs-tag { color: #569cd6; }
4832
+ .fp-code-scroll-wrapper .hljs-name { color: #569cd6; }
4833
+ .fp-code-scroll-wrapper .hljs-attr { color: #9cdcfe; }
4834
+ .fp-code-scroll-wrapper .hljs-attribute { color: #9cdcfe; }
4835
+ .fp-code-scroll-wrapper .hljs-variable { color: #9cdcfe; }
4836
+ .fp-code-scroll-wrapper .hljs-punctuation { color: #d4d4d4; }
4837
+ `;
4838
+ document.head.appendChild(style);
4839
+ }
4840
+ ctx.container.style.backgroundColor = "#1e1e1e";
4841
+ ctx.container.style.color = "#d4d4d4";
4842
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4843
+ scrollWrapper.style.minWidth = "100%";
4844
+ scrollWrapper.style.minHeight = "100%";
4845
+ scrollWrapper.style.width = "max-content";
4846
+ scrollWrapper.style.height = "max-content";
4847
+ scrollWrapper.style.display = "flex";
4848
+ scrollWrapper.style.alignItems = "flex-start";
4849
+ scrollWrapper.style.padding = "16px 16px 16px 0";
4850
+ scrollWrapper.style.boxSizing = "border-box";
4851
+ const rawLines = fullText.split(/\r?\n/);
4852
+ if (rawLines.length > 1 && rawLines[rawLines.length - 1] === "") {
4853
+ rawLines.pop();
4854
+ }
4855
+ const lineCount = Math.max(1, rawLines.length);
4856
+ const gutterLines = [];
4857
+ for (let i = 1; i <= lineCount; i++) {
4858
+ gutterLines.push(String(i));
4859
+ }
4860
+ lineGutter.className = "fp-code-gutter";
4861
+ lineGutter.style.userSelect = "none";
4862
+ lineGutter.style.textAlign = "right";
4863
+ lineGutter.style.padding = "0 16px";
4864
+ lineGutter.style.margin = "0 16px 0 0";
4865
+ lineGutter.style.borderRight = "1px solid #333333";
4866
+ lineGutter.style.color = "#858585";
4867
+ lineGutter.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4868
+ lineGutter.style.fontSize = `${fontSize}px`;
4869
+ lineGutter.style.lineHeight = "1.6";
4870
+ lineGutter.style.whiteSpace = "pre";
4871
+ lineGutter.style.flexShrink = "0";
4872
+ lineGutter.style.position = "sticky";
4873
+ lineGutter.style.left = "0";
4874
+ lineGutter.style.backgroundColor = "#1e1e1e";
4875
+ lineGutter.style.zIndex = "2";
4876
+ lineGutter.style.boxSizing = "border-box";
4877
+ lineGutter.textContent = gutterLines.join("\n");
4701
4878
  pre.style.margin = "0";
4702
- pre.style.fontFamily = "Consolas, Menlo, Monaco, monospace";
4879
+ pre.style.padding = "0 16px 0 0";
4880
+ pre.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4703
4881
  pre.style.fontSize = `${fontSize}px`;
4704
- pre.style.lineHeight = "1.5";
4705
- pre.style.whiteSpace = "pre-wrap";
4706
- pre.style.wordBreak = "break-all";
4707
- pre.style.transformOrigin = "top left";
4882
+ pre.style.lineHeight = "1.6";
4883
+ pre.style.whiteSpace = "pre";
4884
+ pre.style.wordBreak = "normal";
4885
+ pre.style.overflowWrap = "normal";
4886
+ pre.style.flex = "1";
4887
+ code.style.display = "block";
4888
+ code.style.fontFamily = "inherit";
4889
+ code.style.fontSize = "inherit";
4890
+ code.style.lineHeight = "inherit";
4891
+ code.style.whiteSpace = "inherit";
4708
4892
  }
4709
4893
  const ext = (ctx.metadata.extension || "").replace(".", "");
4710
4894
  const renderCodePage = (text) => {
@@ -4724,25 +4908,27 @@ var CodePlugin = class {
4724
4908
  };
4725
4909
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4726
4910
  pre.appendChild(code);
4911
+ ctx.container.innerHTML = "";
4727
4912
  if (isTxt) {
4728
4913
  sizer.appendChild(pre);
4729
4914
  scrollWrapper.appendChild(sizer);
4730
- container.appendChild(scrollWrapper);
4915
+ ctx.container.appendChild(scrollWrapper);
4731
4916
  } else {
4732
- container.appendChild(pre);
4917
+ scrollWrapper.appendChild(lineGutter);
4918
+ scrollWrapper.appendChild(pre);
4919
+ ctx.container.appendChild(scrollWrapper);
4733
4920
  }
4734
4921
  const showPage = (pageNum) => {
4735
4922
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4736
4923
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
4737
- container.scrollTop = 0;
4924
+ ctx.container.scrollTop = 0;
4738
4925
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4739
4926
  };
4740
4927
  if (totalPages > 1) {
4741
4928
  showPage(1);
4742
4929
  }
4743
- ctx.container.appendChild(container);
4744
4930
  const calculateTxtFit = () => {
4745
- const availW = Math.max(280, container.clientWidth - 32);
4931
+ const availW = Math.max(280, ctx.container.clientWidth - 32);
4746
4932
  return Math.max(0.4, Math.min(3, availW / 816));
4747
4933
  };
4748
4934
  const updateTransform = () => {
@@ -4760,6 +4946,7 @@ var CodePlugin = class {
4760
4946
  } else {
4761
4947
  pre.style.transform = `rotate(${rotation}deg)`;
4762
4948
  pre.style.fontSize = `${fontSize}px`;
4949
+ lineGutter.style.fontSize = `${fontSize}px`;
4763
4950
  }
4764
4951
  };
4765
4952
  let resizeObserver = null;
@@ -4774,11 +4961,11 @@ var CodePlugin = class {
4774
4961
  updateTransform();
4775
4962
  }
4776
4963
  }) : null;
4777
- resizeObserver?.observe(container);
4964
+ resizeObserver?.observe(ctx.container);
4778
4965
  }
4779
4966
  const cleanup = () => {
4780
4967
  resizeObserver?.disconnect();
4781
- container.remove();
4968
+ scrollWrapper.remove();
4782
4969
  ctx.container.innerHTML = "";
4783
4970
  };
4784
4971
  ctx.signal.addEventListener("abort", cleanup);
@@ -4823,7 +5010,7 @@ var CodePlugin = class {
4823
5010
  if (isTxt) {
4824
5011
  zoomLevel = Math.min(3.5, zoomLevel + 0.15);
4825
5012
  } else {
4826
- fontSize = Math.min(32, fontSize + 2);
5013
+ fontSize = Math.min(48, fontSize + 2);
4827
5014
  }
4828
5015
  updateTransform();
4829
5016
  },
@@ -4832,7 +5019,7 @@ var CodePlugin = class {
4832
5019
  if (isTxt) {
4833
5020
  zoomLevel = Math.max(0.1, zoomLevel - 0.15);
4834
5021
  } else {
4835
- fontSize = Math.max(8, fontSize - 2);
5022
+ fontSize = Math.max(9, fontSize - 2);
4836
5023
  }
4837
5024
  updateTransform();
4838
5025
  },
@@ -4865,8 +5052,8 @@ var CodePlugin = class {
4865
5052
  fontSize = 13;
4866
5053
  rotation = 0;
4867
5054
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4868
- container.scrollTop = 0;
4869
- container.scrollLeft = 0;
5055
+ ctx.container.scrollTop = 0;
5056
+ ctx.container.scrollLeft = 0;
4870
5057
  updateTransform();
4871
5058
  },
4872
5059
  rotateCW: () => {
@@ -5188,7 +5375,7 @@ var MarkdownPlugin = class {
5188
5375
  {
5189
5376
  id: "zoom-out",
5190
5377
  icon: "zoom-out",
5191
- label: "Decrease Font",
5378
+ label: "Zoom Out",
5192
5379
  type: "button",
5193
5380
  group: "zoom",
5194
5381
  execute: () => instance.zoomOut?.()
@@ -5196,19 +5383,11 @@ var MarkdownPlugin = class {
5196
5383
  {
5197
5384
  id: "zoom-in",
5198
5385
  icon: "zoom-in",
5199
- label: "Increase Font",
5386
+ label: "Zoom In",
5200
5387
  type: "button",
5201
5388
  group: "zoom",
5202
5389
  execute: () => instance.zoomIn?.()
5203
5390
  },
5204
- {
5205
- id: "fit-page",
5206
- icon: "fit-page",
5207
- label: "Default Size",
5208
- type: "button",
5209
- group: "zoom",
5210
- execute: () => instance.fitToPage?.()
5211
- },
5212
5391
  {
5213
5392
  id: "reset-zoom",
5214
5393
  icon: "reset-zoom",
@@ -5225,6 +5404,14 @@ var MarkdownPlugin = class {
5225
5404
  group: "zoom",
5226
5405
  execute: () => instance.fitToWidth?.()
5227
5406
  },
5407
+ {
5408
+ id: "fit-page",
5409
+ icon: "fit-page",
5410
+ label: "Fit to Page",
5411
+ type: "button",
5412
+ group: "zoom",
5413
+ execute: () => instance.fitToPage?.()
5414
+ },
5228
5415
  {
5229
5416
  id: "copy",
5230
5417
  icon: "copy",
@@ -5248,6 +5435,14 @@ var MarkdownPlugin = class {
5248
5435
  type: "button",
5249
5436
  group: "actions",
5250
5437
  execute: () => instance.print?.()
5438
+ },
5439
+ {
5440
+ id: "open-window",
5441
+ icon: "open-window",
5442
+ label: "Open in Separate Full Window",
5443
+ type: "button",
5444
+ group: "actions",
5445
+ execute: () => instance.openInSeparateWindow?.()
5251
5446
  }
5252
5447
  ];
5253
5448
  }
@@ -5260,35 +5455,57 @@ var MarkdownPlugin = class {
5260
5455
  const cleanHtml = DOMPurify6__default.default.sanitize(rawHtml, {
5261
5456
  USE_PROFILES: { html: true }
5262
5457
  });
5263
- const wrapper = document.createElement("div");
5264
- wrapper.className = "fp-markdown-wrapper";
5265
- wrapper.style.cssText = `
5266
- width: 100%;
5267
- height: 100%;
5268
- overflow: auto;
5269
- padding: 32px 40px;
5458
+ const scrollWrapper = document.createElement("div");
5459
+ scrollWrapper.className = "fp-markdown-scroll-wrapper";
5460
+ scrollWrapper.style.minWidth = "100%";
5461
+ scrollWrapper.style.minHeight = "100%";
5462
+ scrollWrapper.style.width = "max-content";
5463
+ scrollWrapper.style.height = "max-content";
5464
+ scrollWrapper.style.display = "flex";
5465
+ scrollWrapper.style.justifyContent = "center";
5466
+ scrollWrapper.style.alignItems = "flex-start";
5467
+ scrollWrapper.style.padding = "24px 16px";
5468
+ scrollWrapper.style.boxSizing = "border-box";
5469
+ const sizer = document.createElement("div");
5470
+ sizer.className = "fp-markdown-sizer";
5471
+ sizer.style.position = "relative";
5472
+ sizer.style.flexShrink = "0";
5473
+ sizer.style.display = "flex";
5474
+ sizer.style.justifyContent = "center";
5475
+ sizer.style.alignItems = "flex-start";
5476
+ const docCard = document.createElement("div");
5477
+ docCard.className = "fp-markdown-doc-card";
5478
+ docCard.style.cssText = `
5479
+ width: 860px;
5480
+ min-height: 600px;
5481
+ padding: 40px 48px;
5270
5482
  box-sizing: border-box;
5271
5483
  line-height: 1.6;
5272
5484
  font-size: 15px;
5273
5485
  color: var(--fp-text, #24292f);
5274
5486
  background: var(--fp-bg, #ffffff);
5487
+ border-radius: 6px;
5488
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
5275
5489
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
5490
+ transform-origin: top center;
5491
+ transition: transform 0.15s ease;
5492
+ flex-shrink: 0;
5276
5493
  `;
5277
- wrapper.innerHTML = `
5494
+ docCard.innerHTML = `
5278
5495
  <style>
5279
- .fp-markdown-wrapper h1, .fp-markdown-wrapper h2, .fp-markdown-wrapper h3,
5280
- .fp-markdown-wrapper h4, .fp-markdown-wrapper h5, .fp-markdown-wrapper h6 {
5496
+ .fp-markdown-doc-card h1, .fp-markdown-doc-card h2, .fp-markdown-doc-card h3,
5497
+ .fp-markdown-doc-card h4, .fp-markdown-doc-card h5, .fp-markdown-doc-card h6 {
5281
5498
  margin-top: 24px;
5282
5499
  margin-bottom: 16px;
5283
5500
  font-weight: 600;
5284
5501
  line-height: 1.25;
5285
5502
  color: var(--fp-text, #1f2328);
5286
5503
  }
5287
- .fp-markdown-wrapper h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5288
- .fp-markdown-wrapper h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5289
- .fp-markdown-wrapper h3 { font-size: 1.25em; }
5290
- .fp-markdown-wrapper p { margin-top: 0; margin-bottom: 16px; }
5291
- .fp-markdown-wrapper table {
5504
+ .fp-markdown-doc-card h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5505
+ .fp-markdown-doc-card h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5506
+ .fp-markdown-doc-card h3 { font-size: 1.25em; }
5507
+ .fp-markdown-doc-card p { margin-top: 0; margin-bottom: 16px; }
5508
+ .fp-markdown-doc-card table {
5292
5509
  border-spacing: 0;
5293
5510
  border-collapse: collapse;
5294
5511
  margin-top: 0;
@@ -5296,20 +5513,20 @@ var MarkdownPlugin = class {
5296
5513
  width: 100%;
5297
5514
  overflow: auto;
5298
5515
  }
5299
- .fp-markdown-wrapper table th, .fp-markdown-wrapper table td {
5516
+ .fp-markdown-doc-card table th, .fp-markdown-doc-card table td {
5300
5517
  padding: 6px 13px;
5301
5518
  border: 1px solid var(--fp-border, #d0d7de);
5302
5519
  }
5303
- .fp-markdown-wrapper table tr:nth-child(2n) {
5520
+ .fp-markdown-doc-card table tr:nth-child(2n) {
5304
5521
  background-color: var(--fp-toolbar-bg, #f6f8fa);
5305
5522
  }
5306
- .fp-markdown-wrapper blockquote {
5523
+ .fp-markdown-doc-card blockquote {
5307
5524
  margin: 0 0 16px 0;
5308
5525
  padding: 0 1em;
5309
5526
  color: var(--fp-text-muted, #59636e);
5310
5527
  border-left: 0.25em solid var(--fp-border, #d0d7de);
5311
5528
  }
5312
- .fp-markdown-wrapper pre {
5529
+ .fp-markdown-doc-card pre {
5313
5530
  padding: 16px;
5314
5531
  overflow: auto;
5315
5532
  font-size: 85%;
@@ -5318,7 +5535,7 @@ var MarkdownPlugin = class {
5318
5535
  border-radius: 6px;
5319
5536
  border: 1px solid var(--fp-border, #d0d7de);
5320
5537
  }
5321
- .fp-markdown-wrapper code {
5538
+ .fp-markdown-doc-card code {
5322
5539
  padding: 0.2em 0.4em;
5323
5540
  margin: 0;
5324
5541
  font-size: 85%;
@@ -5326,16 +5543,16 @@ var MarkdownPlugin = class {
5326
5543
  border-radius: 4px;
5327
5544
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
5328
5545
  }
5329
- .fp-markdown-wrapper pre code {
5546
+ .fp-markdown-doc-card pre code {
5330
5547
  padding: 0;
5331
5548
  background: transparent;
5332
5549
  }
5333
- .fp-markdown-wrapper ul, .fp-markdown-wrapper ol {
5550
+ .fp-markdown-doc-card ul, .fp-markdown-doc-card ol {
5334
5551
  padding-left: 2em;
5335
5552
  margin-top: 0;
5336
5553
  margin-bottom: 16px;
5337
5554
  }
5338
- .fp-markdown-wrapper hr {
5555
+ .fp-markdown-doc-card hr {
5339
5556
  height: 0.25em;
5340
5557
  padding: 0;
5341
5558
  margin: 24px 0;
@@ -5343,50 +5560,95 @@ var MarkdownPlugin = class {
5343
5560
  border: 0;
5344
5561
  }
5345
5562
  </style>
5346
- <div class="fp-markdown-content" style="max-width: 860px; margin: 0 auto;">
5563
+ <div class="fp-markdown-body">
5347
5564
  ${cleanHtml}
5348
5565
  </div>
5349
5566
  `;
5350
- wrapper.querySelectorAll("pre code").forEach((block) => {
5567
+ docCard.querySelectorAll("pre code").forEach((block) => {
5351
5568
  hljs__default.default.highlightElement(block);
5352
5569
  });
5570
+ sizer.appendChild(docCard);
5571
+ scrollWrapper.appendChild(sizer);
5353
5572
  ctx.container.innerHTML = "";
5354
5573
  ctx.container.style.overflow = "auto";
5355
- ctx.container.appendChild(wrapper);
5356
- let fontSize = 15;
5574
+ ctx.container.style.backgroundColor = "#f1f5f9";
5575
+ ctx.container.appendChild(scrollWrapper);
5576
+ let scale = 1;
5577
+ let isUserZoomed = false;
5578
+ const calculateFitScale = () => {
5579
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
5580
+ if (availW < 860) {
5581
+ return Math.max(0.35, availW / 860);
5582
+ }
5583
+ return 1;
5584
+ };
5585
+ const applyTransform = () => {
5586
+ const baseW = 860;
5587
+ const baseH = docCard.offsetHeight || 600;
5588
+ const scaledW = Math.round(baseW * scale);
5589
+ const scaledH = Math.round(baseH * scale);
5590
+ sizer.style.width = `${scaledW}px`;
5591
+ sizer.style.height = `${scaledH}px`;
5592
+ docCard.style.width = `${baseW}px`;
5593
+ docCard.style.transform = `scale(${scale})`;
5594
+ docCard.style.transformOrigin = scaledW > ctx.container.clientWidth - 32 ? "top left" : "top center";
5595
+ };
5596
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5597
+ if (!isUserZoomed) {
5598
+ scale = calculateFitScale();
5599
+ applyTransform();
5600
+ }
5601
+ }) : null;
5602
+ ro?.observe(ctx.container);
5603
+ requestAnimationFrame(() => {
5604
+ if (!isUserZoomed) {
5605
+ scale = calculateFitScale();
5606
+ }
5607
+ applyTransform();
5608
+ });
5357
5609
  const cleanup = () => {
5358
- wrapper.remove();
5610
+ ro?.disconnect();
5611
+ scrollWrapper.remove();
5359
5612
  ctx.container.innerHTML = "";
5360
5613
  };
5361
5614
  ctx.signal.addEventListener("abort", cleanup);
5362
5615
  return {
5363
5616
  destroy: cleanup,
5364
5617
  zoomIn: () => {
5365
- fontSize = Math.min(28, fontSize + 2);
5366
- wrapper.style.fontSize = `${fontSize}px`;
5618
+ isUserZoomed = true;
5619
+ scale = Math.min(3.5, scale + 0.15);
5620
+ applyTransform();
5367
5621
  },
5368
5622
  zoomOut: () => {
5369
- fontSize = Math.max(10, fontSize - 2);
5370
- wrapper.style.fontSize = `${fontSize}px`;
5623
+ isUserZoomed = true;
5624
+ scale = Math.max(0.25, scale - 0.15);
5625
+ applyTransform();
5371
5626
  },
5372
- getZoom: () => fontSize / 15,
5627
+ getZoom: () => scale,
5373
5628
  setZoom: (level) => {
5374
- fontSize = Math.round(15 * level);
5375
- wrapper.style.fontSize = `${fontSize}px`;
5629
+ isUserZoomed = true;
5630
+ scale = level;
5631
+ applyTransform();
5376
5632
  },
5377
5633
  fitToPage: () => {
5378
- fontSize = 15;
5379
- wrapper.style.fontSize = "15px";
5634
+ isUserZoomed = false;
5635
+ scale = calculateFitScale();
5636
+ applyTransform();
5380
5637
  },
5381
5638
  fitToWidth: () => {
5382
- fontSize = 15;
5383
- wrapper.style.fontSize = "15px";
5639
+ isUserZoomed = false;
5640
+ scale = calculateFitScale();
5641
+ applyTransform();
5384
5642
  },
5385
5643
  resetZoom: () => {
5386
- fontSize = 15;
5387
- wrapper.style.fontSize = "15px";
5644
+ isUserZoomed = false;
5645
+ scale = calculateFitScale();
5388
5646
  ctx.container.scrollTop = 0;
5389
5647
  ctx.container.scrollLeft = 0;
5648
+ applyTransform();
5649
+ },
5650
+ openInSeparateWindow: () => {
5651
+ ctx?.openInSeparateWindow?.();
5390
5652
  },
5391
5653
  download: () => {
5392
5654
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
@@ -6702,14 +6964,6 @@ var HtmlPreviewPlugin = class {
6702
6964
  group: "zoom",
6703
6965
  execute: () => instance.zoomIn?.()
6704
6966
  },
6705
- {
6706
- id: "fit-page",
6707
- icon: "fit-page",
6708
- label: "Fit to Page",
6709
- type: "button",
6710
- group: "zoom",
6711
- execute: () => instance.fitToPage?.()
6712
- },
6713
6967
  {
6714
6968
  id: "reset-zoom",
6715
6969
  icon: "reset-zoom",
@@ -6726,6 +6980,14 @@ var HtmlPreviewPlugin = class {
6726
6980
  group: "zoom",
6727
6981
  execute: () => instance.fitToWidth?.()
6728
6982
  },
6983
+ {
6984
+ id: "fit-page",
6985
+ icon: "fit-page",
6986
+ label: "Fit to Page",
6987
+ type: "button",
6988
+ group: "zoom",
6989
+ execute: () => instance.fitToPage?.()
6990
+ },
6729
6991
  {
6730
6992
  id: "copy",
6731
6993
  icon: "copy",
@@ -6749,6 +7011,14 @@ var HtmlPreviewPlugin = class {
6749
7011
  type: "button",
6750
7012
  group: "actions",
6751
7013
  execute: () => instance.print?.()
7014
+ },
7015
+ {
7016
+ id: "open-window",
7017
+ icon: "open-window",
7018
+ label: "Open in Separate Full Window",
7019
+ type: "button",
7020
+ group: "actions",
7021
+ execute: () => instance.openInSeparateWindow?.()
6752
7022
  }
6753
7023
  ];
6754
7024
  }
@@ -6759,27 +7029,39 @@ var HtmlPreviewPlugin = class {
6759
7029
  ADD_TAGS: ["style", "link"],
6760
7030
  ADD_ATTR: ["target", "rel"]
6761
7031
  });
7032
+ const scrollWrapper = document.createElement("div");
7033
+ scrollWrapper.className = "fp-html-scroll-wrapper";
7034
+ scrollWrapper.style.minWidth = "100%";
7035
+ scrollWrapper.style.minHeight = "100%";
7036
+ scrollWrapper.style.width = "max-content";
7037
+ scrollWrapper.style.height = "max-content";
7038
+ scrollWrapper.style.display = "flex";
7039
+ scrollWrapper.style.justifyContent = "flex-start";
7040
+ scrollWrapper.style.alignItems = "flex-start";
7041
+ scrollWrapper.style.boxSizing = "border-box";
6762
7042
  const sizer = document.createElement("div");
6763
7043
  sizer.className = "fp-html-sizer";
6764
7044
  sizer.style.position = "relative";
7045
+ sizer.style.flexShrink = "0";
6765
7046
  const iframe = document.createElement("iframe");
6766
7047
  iframe.className = "fp-html-iframe";
6767
7048
  iframe.style.border = "none";
6768
7049
  iframe.style.backgroundColor = "#ffffff";
6769
7050
  iframe.style.transformOrigin = "top left";
6770
- iframe.style.transition = "transform 0.2s ease";
7051
+ iframe.style.transition = "transform 0.15s ease";
6771
7052
  iframe.sandbox.add("allow-same-origin");
6772
7053
  sizer.appendChild(iframe);
7054
+ scrollWrapper.appendChild(sizer);
6773
7055
  ctx.container.style.overflow = "auto";
6774
7056
  ctx.container.style.width = "100%";
6775
7057
  ctx.container.style.height = "100%";
6776
7058
  ctx.container.innerHTML = "";
6777
- ctx.container.appendChild(sizer);
7059
+ ctx.container.appendChild(scrollWrapper);
6778
7060
  iframe.srcdoc = sanitized;
6779
7061
  let scale = 1;
7062
+ let baseW = Math.max(600, ctx.container.clientWidth || 800);
7063
+ let baseH = Math.max(400, ctx.container.clientHeight || 600);
6780
7064
  const applyTransform = () => {
6781
- const baseW = Math.max(600, ctx.container.clientWidth || 800);
6782
- const baseH = Math.max(400, ctx.container.clientHeight || 600);
6783
7065
  const scaledW = Math.round(baseW * scale);
6784
7066
  const scaledH = Math.round(baseH * scale);
6785
7067
  sizer.style.width = `${scaledW}px`;
@@ -6792,22 +7074,33 @@ var HtmlPreviewPlugin = class {
6792
7074
  iframe.style.transform = `scale(${scale})`;
6793
7075
  iframe.style.transformOrigin = "top left";
6794
7076
  };
7077
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
7078
+ if (Math.abs(scale - 1) < 0.05) {
7079
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7080
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
7081
+ applyTransform();
7082
+ }
7083
+ }) : null;
7084
+ ro?.observe(ctx.container);
6795
7085
  requestAnimationFrame(() => {
7086
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7087
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
6796
7088
  applyTransform();
6797
7089
  });
6798
7090
  const cleanup = () => {
6799
- sizer.remove();
7091
+ ro?.disconnect();
7092
+ scrollWrapper.remove();
6800
7093
  ctx.container.innerHTML = "";
6801
7094
  };
6802
7095
  ctx.signal.addEventListener("abort", cleanup);
6803
7096
  return {
6804
7097
  destroy: cleanup,
6805
7098
  zoomIn: () => {
6806
- scale += 0.1;
7099
+ scale = Math.min(3.5, scale + 0.15);
6807
7100
  applyTransform();
6808
7101
  },
6809
7102
  zoomOut: () => {
6810
- scale = Math.max(0.2, scale - 0.1);
7103
+ scale = Math.max(0.25, scale - 0.15);
6811
7104
  applyTransform();
6812
7105
  },
6813
7106
  getZoom: () => scale,
@@ -6829,8 +7122,11 @@ var HtmlPreviewPlugin = class {
6829
7122
  ctx.container.scrollLeft = 0;
6830
7123
  applyTransform();
6831
7124
  },
7125
+ openInSeparateWindow: () => {
7126
+ ctx?.openInSeparateWindow?.();
7127
+ },
6832
7128
  copy: () => {
6833
- navigator.clipboard.writeText(rawHtml);
7129
+ navigator.clipboard?.writeText(rawHtml);
6834
7130
  },
6835
7131
  download: () => {
6836
7132
  const blob = new Blob([ctx.buffer], { type: "text/html" });
@@ -8951,7 +9247,7 @@ var FilePreview = react.memo(react.forwardRef(
8951
9247
  {
8952
9248
  ref: containerRef,
8953
9249
  className,
8954
- style: { width: "100%", height: "100%", position: "relative", ...style }
9250
+ style: { width: "100%", height: "100%", position: "relative", overflow: "hidden", ...style }
8955
9251
  }
8956
9252
  );
8957
9253
  }