@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/angular.js CHANGED
@@ -1646,19 +1646,85 @@ var FilePreviewViewer = class _FilePreviewViewer {
1646
1646
  if (this.wrapperEl?.parentNode) {
1647
1647
  this.wrapperEl.parentNode.removeChild(this.wrapperEl);
1648
1648
  }
1649
+ if (typeof document !== "undefined" && !document.getElementById("fp-core-injected-styles")) {
1650
+ const styleEl = document.createElement("style");
1651
+ styleEl.id = "fp-core-injected-styles";
1652
+ styleEl.textContent = `
1653
+ .fp-viewer {
1654
+ display: flex !important;
1655
+ flex-direction: column !important;
1656
+ width: 100% !important;
1657
+ height: 100% !important;
1658
+ overflow: hidden !important;
1659
+ position: relative !important;
1660
+ box-sizing: border-box !important;
1661
+ }
1662
+ .fp-body {
1663
+ display: flex !important;
1664
+ flex: 1 1 0% !important;
1665
+ min-height: 0 !important;
1666
+ min-width: 0 !important;
1667
+ width: 100% !important;
1668
+ height: 100% !important;
1669
+ overflow: hidden !important;
1670
+ position: relative !important;
1671
+ box-sizing: border-box !important;
1672
+ }
1673
+ .fp-content {
1674
+ flex: 1 1 0% !important;
1675
+ position: relative !important;
1676
+ overflow: auto !important;
1677
+ display: flex !important;
1678
+ flex-direction: column !important;
1679
+ align-items: stretch !important;
1680
+ justify-content: flex-start !important;
1681
+ width: 100% !important;
1682
+ height: 100% !important;
1683
+ min-width: 0 !important;
1684
+ min-height: 0 !important;
1685
+ box-sizing: border-box !important;
1686
+ }
1687
+ `;
1688
+ document.head.appendChild(styleEl);
1689
+ }
1649
1690
  const themeClass = options.theme === "dark" ? "fp-theme-dark" : "";
1650
1691
  const toolbarPos = options.toolbarPosition ?? "top";
1651
1692
  this.wrapperEl = document.createElement("div");
1652
1693
  this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
1653
1694
  this.wrapperEl.tabIndex = 0;
1695
+ this.wrapperEl.style.display = "flex";
1696
+ this.wrapperEl.style.flexDirection = "column";
1697
+ this.wrapperEl.style.width = "100%";
1698
+ this.wrapperEl.style.height = "100%";
1699
+ this.wrapperEl.style.overflow = "hidden";
1700
+ this.wrapperEl.style.position = "relative";
1654
1701
  const toolbarEl = document.createElement("div");
1655
1702
  toolbarEl.className = "fp-toolbar-container";
1656
1703
  this.contentEl = document.createElement("div");
1657
1704
  this.contentEl.className = "fp-content";
1705
+ this.contentEl.style.flex = "1 1 0%";
1706
+ this.contentEl.style.position = "relative";
1707
+ this.contentEl.style.overflow = "auto";
1708
+ this.contentEl.style.display = "flex";
1709
+ this.contentEl.style.flexDirection = "column";
1710
+ this.contentEl.style.alignItems = "stretch";
1711
+ this.contentEl.style.justifyContent = "flex-start";
1712
+ this.contentEl.style.width = "100%";
1713
+ this.contentEl.style.height = "100%";
1714
+ this.contentEl.style.minWidth = "0";
1715
+ this.contentEl.style.minHeight = "0";
1716
+ this.contentEl.style.boxSizing = "border-box";
1658
1717
  const thumbnailEl = document.createElement("div");
1659
1718
  thumbnailEl.className = "fp-thumbnail-container";
1660
1719
  const bodyEl = document.createElement("div");
1661
1720
  bodyEl.className = "fp-body";
1721
+ bodyEl.style.display = "flex";
1722
+ bodyEl.style.flex = "1 1 0%";
1723
+ bodyEl.style.minHeight = "0";
1724
+ bodyEl.style.minWidth = "0";
1725
+ bodyEl.style.width = "100%";
1726
+ bodyEl.style.overflow = "hidden";
1727
+ bodyEl.style.position = "relative";
1662
1728
  bodyEl.appendChild(thumbnailEl);
1663
1729
  bodyEl.appendChild(this.contentEl);
1664
1730
  const titleBarEl = document.createElement("div");
@@ -4452,31 +4518,80 @@ function csvPlugin() {
4452
4518
  }
4453
4519
  var CODE_EXTENSIONS = [
4454
4520
  ".txt",
4521
+ ".log",
4522
+ ".ini",
4523
+ ".cfg",
4524
+ ".conf",
4525
+ ".env",
4455
4526
  ".json",
4527
+ ".jsonc",
4528
+ ".json5",
4456
4529
  ".js",
4457
- ".ts",
4530
+ ".mjs",
4531
+ ".cjs",
4458
4532
  ".jsx",
4533
+ ".ts",
4534
+ ".mts",
4535
+ ".cts",
4459
4536
  ".tsx",
4460
4537
  ".html",
4538
+ ".htm",
4539
+ ".xhtml",
4461
4540
  ".css",
4462
4541
  ".scss",
4542
+ ".sass",
4463
4543
  ".less",
4464
4544
  ".md",
4545
+ ".markdown",
4465
4546
  ".xml",
4547
+ ".svg",
4548
+ ".xaml",
4466
4549
  ".yml",
4467
4550
  ".yaml",
4551
+ ".toml",
4468
4552
  ".sh",
4469
4553
  ".bash",
4554
+ ".zsh",
4555
+ ".fish",
4556
+ ".bat",
4557
+ ".cmd",
4558
+ ".ps1",
4470
4559
  ".py",
4560
+ ".pyw",
4471
4561
  ".java",
4562
+ ".class",
4472
4563
  ".c",
4473
4564
  ".cpp",
4565
+ ".cc",
4566
+ ".cxx",
4474
4567
  ".h",
4568
+ ".hpp",
4569
+ ".hxx",
4475
4570
  ".cs",
4571
+ ".csx",
4476
4572
  ".go",
4477
4573
  ".rs",
4478
4574
  ".sql",
4479
- ".php"
4575
+ ".php",
4576
+ ".phtml",
4577
+ ".rb",
4578
+ ".swift",
4579
+ ".kt",
4580
+ ".kts",
4581
+ ".scala",
4582
+ ".r",
4583
+ ".lua",
4584
+ ".pl",
4585
+ ".pm",
4586
+ ".dart",
4587
+ ".graphql",
4588
+ ".gql",
4589
+ ".proto",
4590
+ ".diff",
4591
+ ".patch",
4592
+ ".dockerfile",
4593
+ ".properties",
4594
+ ".gradle"
4480
4595
  ];
4481
4596
  var CodePlugin = class {
4482
4597
  id = "code";
@@ -4494,34 +4609,36 @@ var CodePlugin = class {
4494
4609
  getToolbarActions(instance) {
4495
4610
  const totalPages = instance.getPageCount?.() ?? 1;
4496
4611
  const actions = [];
4497
- actions.push({
4498
- id: "thumbnails",
4499
- icon: "thumbnails",
4500
- label: "Page Thumbnails",
4501
- type: "button",
4502
- group: "navigation",
4503
- execute: () => instance.toggleThumbnails?.()
4504
- });
4505
- actions.push({
4506
- id: "page-nav",
4507
- icon: "",
4508
- label: "Page Navigation",
4509
- type: "page-nav",
4510
- group: "navigation",
4511
- value: instance.getCurrentPage?.() ?? 1,
4512
- max: totalPages,
4513
- execute: (action, page) => {
4514
- const cur = instance.getCurrentPage?.() ?? 1;
4515
- const max = instance.getPageCount?.() ?? 1;
4516
- if (action === "prev") {
4517
- if (cur > 1) instance.goToPage?.(cur - 1);
4518
- } else if (action === "next") {
4519
- if (cur < max) instance.goToPage?.(cur + 1);
4520
- } else if (typeof page === "number") {
4521
- instance.goToPage?.(page);
4612
+ if (totalPages > 1) {
4613
+ actions.push({
4614
+ id: "thumbnails",
4615
+ icon: "thumbnails",
4616
+ label: "Page Thumbnails",
4617
+ type: "button",
4618
+ group: "navigation",
4619
+ execute: () => instance.toggleThumbnails?.()
4620
+ });
4621
+ actions.push({
4622
+ id: "page-nav",
4623
+ icon: "",
4624
+ label: "Page Navigation",
4625
+ type: "page-nav",
4626
+ group: "navigation",
4627
+ value: instance.getCurrentPage?.() ?? 1,
4628
+ max: totalPages,
4629
+ execute: (action, page) => {
4630
+ const cur = instance.getCurrentPage?.() ?? 1;
4631
+ const max = instance.getPageCount?.() ?? 1;
4632
+ if (action === "prev") {
4633
+ if (cur > 1) instance.goToPage?.(cur - 1);
4634
+ } else if (action === "next") {
4635
+ if (cur < max) instance.goToPage?.(cur + 1);
4636
+ } else if (typeof page === "number") {
4637
+ instance.goToPage?.(page);
4638
+ }
4522
4639
  }
4523
- }
4524
- });
4640
+ });
4641
+ }
4525
4642
  actions.push(
4526
4643
  {
4527
4644
  id: "zoom-out",
@@ -4658,10 +4775,6 @@ var CodePlugin = class {
4658
4775
  }
4659
4776
  const totalPages = Math.max(1, rawPages.length);
4660
4777
  let currentPage = 1;
4661
- const container = document.createElement("div");
4662
- container.style.width = "100%";
4663
- container.style.height = "100%";
4664
- container.style.overflow = "auto";
4665
4778
  let fontSize = 13;
4666
4779
  let rotation = 0;
4667
4780
  let zoomLevel = 1;
@@ -4670,9 +4783,10 @@ var CodePlugin = class {
4670
4783
  const code = document.createElement("code");
4671
4784
  const sizer = document.createElement("div");
4672
4785
  const scrollWrapper = document.createElement("div");
4786
+ const lineGutter = document.createElement("div");
4787
+ ctx.container.style.overflow = "auto";
4673
4788
  if (isTxt) {
4674
- container.style.overflow = "auto";
4675
- container.style.backgroundColor = "#f1f5f9";
4789
+ ctx.container.style.backgroundColor = "#f1f5f9";
4676
4790
  scrollWrapper.className = "fp-code-scroll-wrapper";
4677
4791
  scrollWrapper.style.minWidth = "100%";
4678
4792
  scrollWrapper.style.minHeight = "100%";
@@ -4707,18 +4821,88 @@ var CodePlugin = class {
4707
4821
  pre.style.transition = "transform 0.15s ease";
4708
4822
  pre.style.flexShrink = "0";
4709
4823
  } else {
4710
- container.style.overflow = "auto";
4711
- container.style.backgroundColor = "#1e1e1e";
4712
- container.style.color = "#d4d4d4";
4713
- container.style.padding = "16px";
4714
- container.style.boxSizing = "border-box";
4824
+ if (typeof document !== "undefined" && !document.getElementById("fp-code-syntax-styles")) {
4825
+ const style = document.createElement("style");
4826
+ style.id = "fp-code-syntax-styles";
4827
+ style.textContent = `
4828
+ .fp-code-scroll-wrapper .hljs-keyword { color: #569cd6; font-weight: normal; }
4829
+ .fp-code-scroll-wrapper .hljs-built_in { color: #4ec9b0; }
4830
+ .fp-code-scroll-wrapper .hljs-type { color: #4ec9b0; }
4831
+ .fp-code-scroll-wrapper .hljs-literal { color: #569cd6; }
4832
+ .fp-code-scroll-wrapper .hljs-number { color: #b5cea8; }
4833
+ .fp-code-scroll-wrapper .hljs-regexp { color: #d16969; }
4834
+ .fp-code-scroll-wrapper .hljs-string { color: #ce9178; }
4835
+ .fp-code-scroll-wrapper .hljs-subst { color: #d4d4d4; }
4836
+ .fp-code-scroll-wrapper .hljs-symbol { color: #569cd6; }
4837
+ .fp-code-scroll-wrapper .hljs-class { color: #4ec9b0; }
4838
+ .fp-code-scroll-wrapper .hljs-function { color: #dcdcaa; }
4839
+ .fp-code-scroll-wrapper .hljs-title { color: #dcdcaa; }
4840
+ .fp-code-scroll-wrapper .hljs-params { color: #9cdcfe; }
4841
+ .fp-code-scroll-wrapper .hljs-comment { color: #6a9955; font-style: italic; }
4842
+ .fp-code-scroll-wrapper .hljs-doctag { color: #608b4e; }
4843
+ .fp-code-scroll-wrapper .hljs-meta { color: #9cdcfe; }
4844
+ .fp-code-scroll-wrapper .hljs-section { color: #569cd6; }
4845
+ .fp-code-scroll-wrapper .hljs-tag { color: #569cd6; }
4846
+ .fp-code-scroll-wrapper .hljs-name { color: #569cd6; }
4847
+ .fp-code-scroll-wrapper .hljs-attr { color: #9cdcfe; }
4848
+ .fp-code-scroll-wrapper .hljs-attribute { color: #9cdcfe; }
4849
+ .fp-code-scroll-wrapper .hljs-variable { color: #9cdcfe; }
4850
+ .fp-code-scroll-wrapper .hljs-punctuation { color: #d4d4d4; }
4851
+ `;
4852
+ document.head.appendChild(style);
4853
+ }
4854
+ ctx.container.style.backgroundColor = "#1e1e1e";
4855
+ ctx.container.style.color = "#d4d4d4";
4856
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4857
+ scrollWrapper.style.minWidth = "100%";
4858
+ scrollWrapper.style.minHeight = "100%";
4859
+ scrollWrapper.style.width = "max-content";
4860
+ scrollWrapper.style.height = "max-content";
4861
+ scrollWrapper.style.display = "flex";
4862
+ scrollWrapper.style.alignItems = "flex-start";
4863
+ scrollWrapper.style.padding = "16px 16px 16px 0";
4864
+ scrollWrapper.style.boxSizing = "border-box";
4865
+ const rawLines = fullText.split(/\r?\n/);
4866
+ if (rawLines.length > 1 && rawLines[rawLines.length - 1] === "") {
4867
+ rawLines.pop();
4868
+ }
4869
+ const lineCount = Math.max(1, rawLines.length);
4870
+ const gutterLines = [];
4871
+ for (let i = 1; i <= lineCount; i++) {
4872
+ gutterLines.push(String(i));
4873
+ }
4874
+ lineGutter.className = "fp-code-gutter";
4875
+ lineGutter.style.userSelect = "none";
4876
+ lineGutter.style.textAlign = "right";
4877
+ lineGutter.style.padding = "0 16px";
4878
+ lineGutter.style.margin = "0 16px 0 0";
4879
+ lineGutter.style.borderRight = "1px solid #333333";
4880
+ lineGutter.style.color = "#858585";
4881
+ lineGutter.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4882
+ lineGutter.style.fontSize = `${fontSize}px`;
4883
+ lineGutter.style.lineHeight = "1.6";
4884
+ lineGutter.style.whiteSpace = "pre";
4885
+ lineGutter.style.flexShrink = "0";
4886
+ lineGutter.style.position = "sticky";
4887
+ lineGutter.style.left = "0";
4888
+ lineGutter.style.backgroundColor = "#1e1e1e";
4889
+ lineGutter.style.zIndex = "2";
4890
+ lineGutter.style.boxSizing = "border-box";
4891
+ lineGutter.textContent = gutterLines.join("\n");
4715
4892
  pre.style.margin = "0";
4716
- pre.style.fontFamily = "Consolas, Menlo, Monaco, monospace";
4893
+ pre.style.padding = "0 16px 0 0";
4894
+ pre.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4717
4895
  pre.style.fontSize = `${fontSize}px`;
4718
- pre.style.lineHeight = "1.5";
4719
- pre.style.whiteSpace = "pre-wrap";
4720
- pre.style.wordBreak = "break-all";
4721
- pre.style.transformOrigin = "top left";
4896
+ pre.style.lineHeight = "1.6";
4897
+ pre.style.whiteSpace = "pre";
4898
+ pre.style.wordBreak = "normal";
4899
+ pre.style.overflowWrap = "normal";
4900
+ pre.style.flex = "1";
4901
+ code.style.display = "block";
4902
+ code.style.fontFamily = "inherit";
4903
+ code.style.fontSize = "inherit";
4904
+ code.style.lineHeight = "inherit";
4905
+ code.style.whiteSpace = "inherit";
4722
4906
  }
4723
4907
  const ext = (ctx.metadata.extension || "").replace(".", "");
4724
4908
  const renderCodePage = (text) => {
@@ -4738,25 +4922,27 @@ var CodePlugin = class {
4738
4922
  };
4739
4923
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4740
4924
  pre.appendChild(code);
4925
+ ctx.container.innerHTML = "";
4741
4926
  if (isTxt) {
4742
4927
  sizer.appendChild(pre);
4743
4928
  scrollWrapper.appendChild(sizer);
4744
- container.appendChild(scrollWrapper);
4929
+ ctx.container.appendChild(scrollWrapper);
4745
4930
  } else {
4746
- container.appendChild(pre);
4931
+ scrollWrapper.appendChild(lineGutter);
4932
+ scrollWrapper.appendChild(pre);
4933
+ ctx.container.appendChild(scrollWrapper);
4747
4934
  }
4748
4935
  const showPage = (pageNum) => {
4749
4936
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4750
4937
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
4751
- container.scrollTop = 0;
4938
+ ctx.container.scrollTop = 0;
4752
4939
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4753
4940
  };
4754
4941
  if (totalPages > 1) {
4755
4942
  showPage(1);
4756
4943
  }
4757
- ctx.container.appendChild(container);
4758
4944
  const calculateTxtFit = () => {
4759
- const availW = Math.max(280, container.clientWidth - 32);
4945
+ const availW = Math.max(280, ctx.container.clientWidth - 32);
4760
4946
  return Math.max(0.4, Math.min(3, availW / 816));
4761
4947
  };
4762
4948
  const updateTransform = () => {
@@ -4774,6 +4960,7 @@ var CodePlugin = class {
4774
4960
  } else {
4775
4961
  pre.style.transform = `rotate(${rotation}deg)`;
4776
4962
  pre.style.fontSize = `${fontSize}px`;
4963
+ lineGutter.style.fontSize = `${fontSize}px`;
4777
4964
  }
4778
4965
  };
4779
4966
  let resizeObserver = null;
@@ -4788,11 +4975,11 @@ var CodePlugin = class {
4788
4975
  updateTransform();
4789
4976
  }
4790
4977
  }) : null;
4791
- resizeObserver?.observe(container);
4978
+ resizeObserver?.observe(ctx.container);
4792
4979
  }
4793
4980
  const cleanup = () => {
4794
4981
  resizeObserver?.disconnect();
4795
- container.remove();
4982
+ scrollWrapper.remove();
4796
4983
  ctx.container.innerHTML = "";
4797
4984
  };
4798
4985
  ctx.signal.addEventListener("abort", cleanup);
@@ -4837,7 +5024,7 @@ var CodePlugin = class {
4837
5024
  if (isTxt) {
4838
5025
  zoomLevel = Math.min(3.5, zoomLevel + 0.15);
4839
5026
  } else {
4840
- fontSize = Math.min(32, fontSize + 2);
5027
+ fontSize = Math.min(48, fontSize + 2);
4841
5028
  }
4842
5029
  updateTransform();
4843
5030
  },
@@ -4846,7 +5033,7 @@ var CodePlugin = class {
4846
5033
  if (isTxt) {
4847
5034
  zoomLevel = Math.max(0.1, zoomLevel - 0.15);
4848
5035
  } else {
4849
- fontSize = Math.max(8, fontSize - 2);
5036
+ fontSize = Math.max(9, fontSize - 2);
4850
5037
  }
4851
5038
  updateTransform();
4852
5039
  },
@@ -4879,8 +5066,8 @@ var CodePlugin = class {
4879
5066
  fontSize = 13;
4880
5067
  rotation = 0;
4881
5068
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4882
- container.scrollTop = 0;
4883
- container.scrollLeft = 0;
5069
+ ctx.container.scrollTop = 0;
5070
+ ctx.container.scrollLeft = 0;
4884
5071
  updateTransform();
4885
5072
  },
4886
5073
  rotateCW: () => {
@@ -5202,7 +5389,7 @@ var MarkdownPlugin = class {
5202
5389
  {
5203
5390
  id: "zoom-out",
5204
5391
  icon: "zoom-out",
5205
- label: "Decrease Font",
5392
+ label: "Zoom Out",
5206
5393
  type: "button",
5207
5394
  group: "zoom",
5208
5395
  execute: () => instance.zoomOut?.()
@@ -5210,19 +5397,11 @@ var MarkdownPlugin = class {
5210
5397
  {
5211
5398
  id: "zoom-in",
5212
5399
  icon: "zoom-in",
5213
- label: "Increase Font",
5400
+ label: "Zoom In",
5214
5401
  type: "button",
5215
5402
  group: "zoom",
5216
5403
  execute: () => instance.zoomIn?.()
5217
5404
  },
5218
- {
5219
- id: "fit-page",
5220
- icon: "fit-page",
5221
- label: "Default Size",
5222
- type: "button",
5223
- group: "zoom",
5224
- execute: () => instance.fitToPage?.()
5225
- },
5226
5405
  {
5227
5406
  id: "reset-zoom",
5228
5407
  icon: "reset-zoom",
@@ -5239,6 +5418,14 @@ var MarkdownPlugin = class {
5239
5418
  group: "zoom",
5240
5419
  execute: () => instance.fitToWidth?.()
5241
5420
  },
5421
+ {
5422
+ id: "fit-page",
5423
+ icon: "fit-page",
5424
+ label: "Fit to Page",
5425
+ type: "button",
5426
+ group: "zoom",
5427
+ execute: () => instance.fitToPage?.()
5428
+ },
5242
5429
  {
5243
5430
  id: "copy",
5244
5431
  icon: "copy",
@@ -5262,6 +5449,14 @@ var MarkdownPlugin = class {
5262
5449
  type: "button",
5263
5450
  group: "actions",
5264
5451
  execute: () => instance.print?.()
5452
+ },
5453
+ {
5454
+ id: "open-window",
5455
+ icon: "open-window",
5456
+ label: "Open in Separate Full Window",
5457
+ type: "button",
5458
+ group: "actions",
5459
+ execute: () => instance.openInSeparateWindow?.()
5265
5460
  }
5266
5461
  ];
5267
5462
  }
@@ -5274,35 +5469,57 @@ var MarkdownPlugin = class {
5274
5469
  const cleanHtml = DOMPurify6.sanitize(rawHtml, {
5275
5470
  USE_PROFILES: { html: true }
5276
5471
  });
5277
- const wrapper = document.createElement("div");
5278
- wrapper.className = "fp-markdown-wrapper";
5279
- wrapper.style.cssText = `
5280
- width: 100%;
5281
- height: 100%;
5282
- overflow: auto;
5283
- padding: 32px 40px;
5472
+ const scrollWrapper = document.createElement("div");
5473
+ scrollWrapper.className = "fp-markdown-scroll-wrapper";
5474
+ scrollWrapper.style.minWidth = "100%";
5475
+ scrollWrapper.style.minHeight = "100%";
5476
+ scrollWrapper.style.width = "max-content";
5477
+ scrollWrapper.style.height = "max-content";
5478
+ scrollWrapper.style.display = "flex";
5479
+ scrollWrapper.style.justifyContent = "center";
5480
+ scrollWrapper.style.alignItems = "flex-start";
5481
+ scrollWrapper.style.padding = "24px 16px";
5482
+ scrollWrapper.style.boxSizing = "border-box";
5483
+ const sizer = document.createElement("div");
5484
+ sizer.className = "fp-markdown-sizer";
5485
+ sizer.style.position = "relative";
5486
+ sizer.style.flexShrink = "0";
5487
+ sizer.style.display = "flex";
5488
+ sizer.style.justifyContent = "center";
5489
+ sizer.style.alignItems = "flex-start";
5490
+ const docCard = document.createElement("div");
5491
+ docCard.className = "fp-markdown-doc-card";
5492
+ docCard.style.cssText = `
5493
+ width: 860px;
5494
+ min-height: 600px;
5495
+ padding: 40px 48px;
5284
5496
  box-sizing: border-box;
5285
5497
  line-height: 1.6;
5286
5498
  font-size: 15px;
5287
5499
  color: var(--fp-text, #24292f);
5288
5500
  background: var(--fp-bg, #ffffff);
5501
+ border-radius: 6px;
5502
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
5289
5503
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
5504
+ transform-origin: top center;
5505
+ transition: transform 0.15s ease;
5506
+ flex-shrink: 0;
5290
5507
  `;
5291
- wrapper.innerHTML = `
5508
+ docCard.innerHTML = `
5292
5509
  <style>
5293
- .fp-markdown-wrapper h1, .fp-markdown-wrapper h2, .fp-markdown-wrapper h3,
5294
- .fp-markdown-wrapper h4, .fp-markdown-wrapper h5, .fp-markdown-wrapper h6 {
5510
+ .fp-markdown-doc-card h1, .fp-markdown-doc-card h2, .fp-markdown-doc-card h3,
5511
+ .fp-markdown-doc-card h4, .fp-markdown-doc-card h5, .fp-markdown-doc-card h6 {
5295
5512
  margin-top: 24px;
5296
5513
  margin-bottom: 16px;
5297
5514
  font-weight: 600;
5298
5515
  line-height: 1.25;
5299
5516
  color: var(--fp-text, #1f2328);
5300
5517
  }
5301
- .fp-markdown-wrapper h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5302
- .fp-markdown-wrapper h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5303
- .fp-markdown-wrapper h3 { font-size: 1.25em; }
5304
- .fp-markdown-wrapper p { margin-top: 0; margin-bottom: 16px; }
5305
- .fp-markdown-wrapper table {
5518
+ .fp-markdown-doc-card h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5519
+ .fp-markdown-doc-card h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5520
+ .fp-markdown-doc-card h3 { font-size: 1.25em; }
5521
+ .fp-markdown-doc-card p { margin-top: 0; margin-bottom: 16px; }
5522
+ .fp-markdown-doc-card table {
5306
5523
  border-spacing: 0;
5307
5524
  border-collapse: collapse;
5308
5525
  margin-top: 0;
@@ -5310,20 +5527,20 @@ var MarkdownPlugin = class {
5310
5527
  width: 100%;
5311
5528
  overflow: auto;
5312
5529
  }
5313
- .fp-markdown-wrapper table th, .fp-markdown-wrapper table td {
5530
+ .fp-markdown-doc-card table th, .fp-markdown-doc-card table td {
5314
5531
  padding: 6px 13px;
5315
5532
  border: 1px solid var(--fp-border, #d0d7de);
5316
5533
  }
5317
- .fp-markdown-wrapper table tr:nth-child(2n) {
5534
+ .fp-markdown-doc-card table tr:nth-child(2n) {
5318
5535
  background-color: var(--fp-toolbar-bg, #f6f8fa);
5319
5536
  }
5320
- .fp-markdown-wrapper blockquote {
5537
+ .fp-markdown-doc-card blockquote {
5321
5538
  margin: 0 0 16px 0;
5322
5539
  padding: 0 1em;
5323
5540
  color: var(--fp-text-muted, #59636e);
5324
5541
  border-left: 0.25em solid var(--fp-border, #d0d7de);
5325
5542
  }
5326
- .fp-markdown-wrapper pre {
5543
+ .fp-markdown-doc-card pre {
5327
5544
  padding: 16px;
5328
5545
  overflow: auto;
5329
5546
  font-size: 85%;
@@ -5332,7 +5549,7 @@ var MarkdownPlugin = class {
5332
5549
  border-radius: 6px;
5333
5550
  border: 1px solid var(--fp-border, #d0d7de);
5334
5551
  }
5335
- .fp-markdown-wrapper code {
5552
+ .fp-markdown-doc-card code {
5336
5553
  padding: 0.2em 0.4em;
5337
5554
  margin: 0;
5338
5555
  font-size: 85%;
@@ -5340,16 +5557,16 @@ var MarkdownPlugin = class {
5340
5557
  border-radius: 4px;
5341
5558
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
5342
5559
  }
5343
- .fp-markdown-wrapper pre code {
5560
+ .fp-markdown-doc-card pre code {
5344
5561
  padding: 0;
5345
5562
  background: transparent;
5346
5563
  }
5347
- .fp-markdown-wrapper ul, .fp-markdown-wrapper ol {
5564
+ .fp-markdown-doc-card ul, .fp-markdown-doc-card ol {
5348
5565
  padding-left: 2em;
5349
5566
  margin-top: 0;
5350
5567
  margin-bottom: 16px;
5351
5568
  }
5352
- .fp-markdown-wrapper hr {
5569
+ .fp-markdown-doc-card hr {
5353
5570
  height: 0.25em;
5354
5571
  padding: 0;
5355
5572
  margin: 24px 0;
@@ -5357,50 +5574,95 @@ var MarkdownPlugin = class {
5357
5574
  border: 0;
5358
5575
  }
5359
5576
  </style>
5360
- <div class="fp-markdown-content" style="max-width: 860px; margin: 0 auto;">
5577
+ <div class="fp-markdown-body">
5361
5578
  ${cleanHtml}
5362
5579
  </div>
5363
5580
  `;
5364
- wrapper.querySelectorAll("pre code").forEach((block) => {
5581
+ docCard.querySelectorAll("pre code").forEach((block) => {
5365
5582
  hljs.highlightElement(block);
5366
5583
  });
5584
+ sizer.appendChild(docCard);
5585
+ scrollWrapper.appendChild(sizer);
5367
5586
  ctx.container.innerHTML = "";
5368
5587
  ctx.container.style.overflow = "auto";
5369
- ctx.container.appendChild(wrapper);
5370
- let fontSize = 15;
5588
+ ctx.container.style.backgroundColor = "#f1f5f9";
5589
+ ctx.container.appendChild(scrollWrapper);
5590
+ let scale = 1;
5591
+ let isUserZoomed = false;
5592
+ const calculateFitScale = () => {
5593
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
5594
+ if (availW < 860) {
5595
+ return Math.max(0.35, availW / 860);
5596
+ }
5597
+ return 1;
5598
+ };
5599
+ const applyTransform = () => {
5600
+ const baseW = 860;
5601
+ const baseH = docCard.offsetHeight || 600;
5602
+ const scaledW = Math.round(baseW * scale);
5603
+ const scaledH = Math.round(baseH * scale);
5604
+ sizer.style.width = `${scaledW}px`;
5605
+ sizer.style.height = `${scaledH}px`;
5606
+ docCard.style.width = `${baseW}px`;
5607
+ docCard.style.transform = `scale(${scale})`;
5608
+ docCard.style.transformOrigin = scaledW > ctx.container.clientWidth - 32 ? "top left" : "top center";
5609
+ };
5610
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5611
+ if (!isUserZoomed) {
5612
+ scale = calculateFitScale();
5613
+ applyTransform();
5614
+ }
5615
+ }) : null;
5616
+ ro?.observe(ctx.container);
5617
+ requestAnimationFrame(() => {
5618
+ if (!isUserZoomed) {
5619
+ scale = calculateFitScale();
5620
+ }
5621
+ applyTransform();
5622
+ });
5371
5623
  const cleanup = () => {
5372
- wrapper.remove();
5624
+ ro?.disconnect();
5625
+ scrollWrapper.remove();
5373
5626
  ctx.container.innerHTML = "";
5374
5627
  };
5375
5628
  ctx.signal.addEventListener("abort", cleanup);
5376
5629
  return {
5377
5630
  destroy: cleanup,
5378
5631
  zoomIn: () => {
5379
- fontSize = Math.min(28, fontSize + 2);
5380
- wrapper.style.fontSize = `${fontSize}px`;
5632
+ isUserZoomed = true;
5633
+ scale = Math.min(3.5, scale + 0.15);
5634
+ applyTransform();
5381
5635
  },
5382
5636
  zoomOut: () => {
5383
- fontSize = Math.max(10, fontSize - 2);
5384
- wrapper.style.fontSize = `${fontSize}px`;
5637
+ isUserZoomed = true;
5638
+ scale = Math.max(0.25, scale - 0.15);
5639
+ applyTransform();
5385
5640
  },
5386
- getZoom: () => fontSize / 15,
5641
+ getZoom: () => scale,
5387
5642
  setZoom: (level) => {
5388
- fontSize = Math.round(15 * level);
5389
- wrapper.style.fontSize = `${fontSize}px`;
5643
+ isUserZoomed = true;
5644
+ scale = level;
5645
+ applyTransform();
5390
5646
  },
5391
5647
  fitToPage: () => {
5392
- fontSize = 15;
5393
- wrapper.style.fontSize = "15px";
5648
+ isUserZoomed = false;
5649
+ scale = calculateFitScale();
5650
+ applyTransform();
5394
5651
  },
5395
5652
  fitToWidth: () => {
5396
- fontSize = 15;
5397
- wrapper.style.fontSize = "15px";
5653
+ isUserZoomed = false;
5654
+ scale = calculateFitScale();
5655
+ applyTransform();
5398
5656
  },
5399
5657
  resetZoom: () => {
5400
- fontSize = 15;
5401
- wrapper.style.fontSize = "15px";
5658
+ isUserZoomed = false;
5659
+ scale = calculateFitScale();
5402
5660
  ctx.container.scrollTop = 0;
5403
5661
  ctx.container.scrollLeft = 0;
5662
+ applyTransform();
5663
+ },
5664
+ openInSeparateWindow: () => {
5665
+ ctx?.openInSeparateWindow?.();
5404
5666
  },
5405
5667
  download: () => {
5406
5668
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
@@ -6716,14 +6978,6 @@ var HtmlPreviewPlugin = class {
6716
6978
  group: "zoom",
6717
6979
  execute: () => instance.zoomIn?.()
6718
6980
  },
6719
- {
6720
- id: "fit-page",
6721
- icon: "fit-page",
6722
- label: "Fit to Page",
6723
- type: "button",
6724
- group: "zoom",
6725
- execute: () => instance.fitToPage?.()
6726
- },
6727
6981
  {
6728
6982
  id: "reset-zoom",
6729
6983
  icon: "reset-zoom",
@@ -6740,6 +6994,14 @@ var HtmlPreviewPlugin = class {
6740
6994
  group: "zoom",
6741
6995
  execute: () => instance.fitToWidth?.()
6742
6996
  },
6997
+ {
6998
+ id: "fit-page",
6999
+ icon: "fit-page",
7000
+ label: "Fit to Page",
7001
+ type: "button",
7002
+ group: "zoom",
7003
+ execute: () => instance.fitToPage?.()
7004
+ },
6743
7005
  {
6744
7006
  id: "copy",
6745
7007
  icon: "copy",
@@ -6763,6 +7025,14 @@ var HtmlPreviewPlugin = class {
6763
7025
  type: "button",
6764
7026
  group: "actions",
6765
7027
  execute: () => instance.print?.()
7028
+ },
7029
+ {
7030
+ id: "open-window",
7031
+ icon: "open-window",
7032
+ label: "Open in Separate Full Window",
7033
+ type: "button",
7034
+ group: "actions",
7035
+ execute: () => instance.openInSeparateWindow?.()
6766
7036
  }
6767
7037
  ];
6768
7038
  }
@@ -6773,27 +7043,39 @@ var HtmlPreviewPlugin = class {
6773
7043
  ADD_TAGS: ["style", "link"],
6774
7044
  ADD_ATTR: ["target", "rel"]
6775
7045
  });
7046
+ const scrollWrapper = document.createElement("div");
7047
+ scrollWrapper.className = "fp-html-scroll-wrapper";
7048
+ scrollWrapper.style.minWidth = "100%";
7049
+ scrollWrapper.style.minHeight = "100%";
7050
+ scrollWrapper.style.width = "max-content";
7051
+ scrollWrapper.style.height = "max-content";
7052
+ scrollWrapper.style.display = "flex";
7053
+ scrollWrapper.style.justifyContent = "flex-start";
7054
+ scrollWrapper.style.alignItems = "flex-start";
7055
+ scrollWrapper.style.boxSizing = "border-box";
6776
7056
  const sizer = document.createElement("div");
6777
7057
  sizer.className = "fp-html-sizer";
6778
7058
  sizer.style.position = "relative";
7059
+ sizer.style.flexShrink = "0";
6779
7060
  const iframe = document.createElement("iframe");
6780
7061
  iframe.className = "fp-html-iframe";
6781
7062
  iframe.style.border = "none";
6782
7063
  iframe.style.backgroundColor = "#ffffff";
6783
7064
  iframe.style.transformOrigin = "top left";
6784
- iframe.style.transition = "transform 0.2s ease";
7065
+ iframe.style.transition = "transform 0.15s ease";
6785
7066
  iframe.sandbox.add("allow-same-origin");
6786
7067
  sizer.appendChild(iframe);
7068
+ scrollWrapper.appendChild(sizer);
6787
7069
  ctx.container.style.overflow = "auto";
6788
7070
  ctx.container.style.width = "100%";
6789
7071
  ctx.container.style.height = "100%";
6790
7072
  ctx.container.innerHTML = "";
6791
- ctx.container.appendChild(sizer);
7073
+ ctx.container.appendChild(scrollWrapper);
6792
7074
  iframe.srcdoc = sanitized;
6793
7075
  let scale = 1;
7076
+ let baseW = Math.max(600, ctx.container.clientWidth || 800);
7077
+ let baseH = Math.max(400, ctx.container.clientHeight || 600);
6794
7078
  const applyTransform = () => {
6795
- const baseW = Math.max(600, ctx.container.clientWidth || 800);
6796
- const baseH = Math.max(400, ctx.container.clientHeight || 600);
6797
7079
  const scaledW = Math.round(baseW * scale);
6798
7080
  const scaledH = Math.round(baseH * scale);
6799
7081
  sizer.style.width = `${scaledW}px`;
@@ -6806,22 +7088,33 @@ var HtmlPreviewPlugin = class {
6806
7088
  iframe.style.transform = `scale(${scale})`;
6807
7089
  iframe.style.transformOrigin = "top left";
6808
7090
  };
7091
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
7092
+ if (Math.abs(scale - 1) < 0.05) {
7093
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7094
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
7095
+ applyTransform();
7096
+ }
7097
+ }) : null;
7098
+ ro?.observe(ctx.container);
6809
7099
  requestAnimationFrame(() => {
7100
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7101
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
6810
7102
  applyTransform();
6811
7103
  });
6812
7104
  const cleanup = () => {
6813
- sizer.remove();
7105
+ ro?.disconnect();
7106
+ scrollWrapper.remove();
6814
7107
  ctx.container.innerHTML = "";
6815
7108
  };
6816
7109
  ctx.signal.addEventListener("abort", cleanup);
6817
7110
  return {
6818
7111
  destroy: cleanup,
6819
7112
  zoomIn: () => {
6820
- scale += 0.1;
7113
+ scale = Math.min(3.5, scale + 0.15);
6821
7114
  applyTransform();
6822
7115
  },
6823
7116
  zoomOut: () => {
6824
- scale = Math.max(0.2, scale - 0.1);
7117
+ scale = Math.max(0.25, scale - 0.15);
6825
7118
  applyTransform();
6826
7119
  },
6827
7120
  getZoom: () => scale,
@@ -6843,8 +7136,11 @@ var HtmlPreviewPlugin = class {
6843
7136
  ctx.container.scrollLeft = 0;
6844
7137
  applyTransform();
6845
7138
  },
7139
+ openInSeparateWindow: () => {
7140
+ ctx?.openInSeparateWindow?.();
7141
+ },
6846
7142
  copy: () => {
6847
- navigator.clipboard.writeText(rawHtml);
7143
+ navigator.clipboard?.writeText(rawHtml);
6848
7144
  },
6849
7145
  download: () => {
6850
7146
  const blob = new Blob([ctx.buffer], { type: "text/html" });
@@ -8906,7 +9202,7 @@ _FilePreviewComponent_decorators = [Component({
8906
9202
  selector: "fp-file-preview",
8907
9203
  standalone: true,
8908
9204
  imports: [CommonModule],
8909
- template: `<div #container [style.width]="'100%'" [style.height]="'100%'"></div>`,
9205
+ template: `<div #container [style.width]="'100%'" [style.height]="'100%'" [style.position]="'relative'" [style.overflow]="'hidden'"></div>`,
8910
9206
  changeDetection: ChangeDetectionStrategy.OnPush
8911
9207
  })], _src_dec = [Input({ required: true })], _plugins_dec = [Input()], _options_dec = [Input()], _loading_dec = [Output()], _loaded_dec = [Output()], _error_dec = [Output()], _pageChange_dec = [Output()], _zoomChange_dec = [Output()], _rotate_dec = [Output()], _destroyed_dec = [Output()], _container_dec = [ViewChild("container", { static: true })];
8912
9208
  var FilePreviewComponent = class {