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