@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.js CHANGED
@@ -1598,19 +1598,85 @@ var FilePreviewViewer = class _FilePreviewViewer {
1598
1598
  if (this.wrapperEl?.parentNode) {
1599
1599
  this.wrapperEl.parentNode.removeChild(this.wrapperEl);
1600
1600
  }
1601
+ if (typeof document !== "undefined" && !document.getElementById("fp-core-injected-styles")) {
1602
+ const styleEl = document.createElement("style");
1603
+ styleEl.id = "fp-core-injected-styles";
1604
+ styleEl.textContent = `
1605
+ .fp-viewer {
1606
+ display: flex !important;
1607
+ flex-direction: column !important;
1608
+ width: 100% !important;
1609
+ height: 100% !important;
1610
+ overflow: hidden !important;
1611
+ position: relative !important;
1612
+ box-sizing: border-box !important;
1613
+ }
1614
+ .fp-body {
1615
+ display: flex !important;
1616
+ flex: 1 1 0% !important;
1617
+ min-height: 0 !important;
1618
+ min-width: 0 !important;
1619
+ width: 100% !important;
1620
+ height: 100% !important;
1621
+ overflow: hidden !important;
1622
+ position: relative !important;
1623
+ box-sizing: border-box !important;
1624
+ }
1625
+ .fp-content {
1626
+ flex: 1 1 0% !important;
1627
+ position: relative !important;
1628
+ overflow: auto !important;
1629
+ display: flex !important;
1630
+ flex-direction: column !important;
1631
+ align-items: stretch !important;
1632
+ justify-content: flex-start !important;
1633
+ width: 100% !important;
1634
+ height: 100% !important;
1635
+ min-width: 0 !important;
1636
+ min-height: 0 !important;
1637
+ box-sizing: border-box !important;
1638
+ }
1639
+ `;
1640
+ document.head.appendChild(styleEl);
1641
+ }
1601
1642
  const themeClass = options.theme === "dark" ? "fp-theme-dark" : "";
1602
1643
  const toolbarPos = options.toolbarPosition ?? "top";
1603
1644
  this.wrapperEl = document.createElement("div");
1604
1645
  this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
1605
1646
  this.wrapperEl.tabIndex = 0;
1647
+ this.wrapperEl.style.display = "flex";
1648
+ this.wrapperEl.style.flexDirection = "column";
1649
+ this.wrapperEl.style.width = "100%";
1650
+ this.wrapperEl.style.height = "100%";
1651
+ this.wrapperEl.style.overflow = "hidden";
1652
+ this.wrapperEl.style.position = "relative";
1606
1653
  const toolbarEl = document.createElement("div");
1607
1654
  toolbarEl.className = "fp-toolbar-container";
1608
1655
  this.contentEl = document.createElement("div");
1609
1656
  this.contentEl.className = "fp-content";
1657
+ this.contentEl.style.flex = "1 1 0%";
1658
+ this.contentEl.style.position = "relative";
1659
+ this.contentEl.style.overflow = "auto";
1660
+ this.contentEl.style.display = "flex";
1661
+ this.contentEl.style.flexDirection = "column";
1662
+ this.contentEl.style.alignItems = "stretch";
1663
+ this.contentEl.style.justifyContent = "flex-start";
1664
+ this.contentEl.style.width = "100%";
1665
+ this.contentEl.style.height = "100%";
1666
+ this.contentEl.style.minWidth = "0";
1667
+ this.contentEl.style.minHeight = "0";
1668
+ this.contentEl.style.boxSizing = "border-box";
1610
1669
  const thumbnailEl = document.createElement("div");
1611
1670
  thumbnailEl.className = "fp-thumbnail-container";
1612
1671
  const bodyEl = document.createElement("div");
1613
1672
  bodyEl.className = "fp-body";
1673
+ bodyEl.style.display = "flex";
1674
+ bodyEl.style.flex = "1 1 0%";
1675
+ bodyEl.style.minHeight = "0";
1676
+ bodyEl.style.minWidth = "0";
1677
+ bodyEl.style.width = "100%";
1678
+ bodyEl.style.overflow = "hidden";
1679
+ bodyEl.style.position = "relative";
1614
1680
  bodyEl.appendChild(thumbnailEl);
1615
1681
  bodyEl.appendChild(this.contentEl);
1616
1682
  const titleBarEl = document.createElement("div");
@@ -4404,31 +4470,80 @@ function csvPlugin() {
4404
4470
  }
4405
4471
  var CODE_EXTENSIONS = [
4406
4472
  ".txt",
4473
+ ".log",
4474
+ ".ini",
4475
+ ".cfg",
4476
+ ".conf",
4477
+ ".env",
4407
4478
  ".json",
4479
+ ".jsonc",
4480
+ ".json5",
4408
4481
  ".js",
4409
- ".ts",
4482
+ ".mjs",
4483
+ ".cjs",
4410
4484
  ".jsx",
4485
+ ".ts",
4486
+ ".mts",
4487
+ ".cts",
4411
4488
  ".tsx",
4412
4489
  ".html",
4490
+ ".htm",
4491
+ ".xhtml",
4413
4492
  ".css",
4414
4493
  ".scss",
4494
+ ".sass",
4415
4495
  ".less",
4416
4496
  ".md",
4497
+ ".markdown",
4417
4498
  ".xml",
4499
+ ".svg",
4500
+ ".xaml",
4418
4501
  ".yml",
4419
4502
  ".yaml",
4503
+ ".toml",
4420
4504
  ".sh",
4421
4505
  ".bash",
4506
+ ".zsh",
4507
+ ".fish",
4508
+ ".bat",
4509
+ ".cmd",
4510
+ ".ps1",
4422
4511
  ".py",
4512
+ ".pyw",
4423
4513
  ".java",
4514
+ ".class",
4424
4515
  ".c",
4425
4516
  ".cpp",
4517
+ ".cc",
4518
+ ".cxx",
4426
4519
  ".h",
4520
+ ".hpp",
4521
+ ".hxx",
4427
4522
  ".cs",
4523
+ ".csx",
4428
4524
  ".go",
4429
4525
  ".rs",
4430
4526
  ".sql",
4431
- ".php"
4527
+ ".php",
4528
+ ".phtml",
4529
+ ".rb",
4530
+ ".swift",
4531
+ ".kt",
4532
+ ".kts",
4533
+ ".scala",
4534
+ ".r",
4535
+ ".lua",
4536
+ ".pl",
4537
+ ".pm",
4538
+ ".dart",
4539
+ ".graphql",
4540
+ ".gql",
4541
+ ".proto",
4542
+ ".diff",
4543
+ ".patch",
4544
+ ".dockerfile",
4545
+ ".properties",
4546
+ ".gradle"
4432
4547
  ];
4433
4548
  var CodePlugin = class {
4434
4549
  id = "code";
@@ -4446,34 +4561,36 @@ var CodePlugin = class {
4446
4561
  getToolbarActions(instance) {
4447
4562
  const totalPages = instance.getPageCount?.() ?? 1;
4448
4563
  const actions = [];
4449
- actions.push({
4450
- id: "thumbnails",
4451
- icon: "thumbnails",
4452
- label: "Page Thumbnails",
4453
- type: "button",
4454
- group: "navigation",
4455
- execute: () => instance.toggleThumbnails?.()
4456
- });
4457
- actions.push({
4458
- id: "page-nav",
4459
- icon: "",
4460
- label: "Page Navigation",
4461
- type: "page-nav",
4462
- group: "navigation",
4463
- value: instance.getCurrentPage?.() ?? 1,
4464
- max: totalPages,
4465
- execute: (action, page) => {
4466
- const cur = instance.getCurrentPage?.() ?? 1;
4467
- const max = instance.getPageCount?.() ?? 1;
4468
- if (action === "prev") {
4469
- if (cur > 1) instance.goToPage?.(cur - 1);
4470
- } else if (action === "next") {
4471
- if (cur < max) instance.goToPage?.(cur + 1);
4472
- } else if (typeof page === "number") {
4473
- instance.goToPage?.(page);
4564
+ if (totalPages > 1) {
4565
+ actions.push({
4566
+ id: "thumbnails",
4567
+ icon: "thumbnails",
4568
+ label: "Page Thumbnails",
4569
+ type: "button",
4570
+ group: "navigation",
4571
+ execute: () => instance.toggleThumbnails?.()
4572
+ });
4573
+ actions.push({
4574
+ id: "page-nav",
4575
+ icon: "",
4576
+ label: "Page Navigation",
4577
+ type: "page-nav",
4578
+ group: "navigation",
4579
+ value: instance.getCurrentPage?.() ?? 1,
4580
+ max: totalPages,
4581
+ execute: (action, page) => {
4582
+ const cur = instance.getCurrentPage?.() ?? 1;
4583
+ const max = instance.getPageCount?.() ?? 1;
4584
+ if (action === "prev") {
4585
+ if (cur > 1) instance.goToPage?.(cur - 1);
4586
+ } else if (action === "next") {
4587
+ if (cur < max) instance.goToPage?.(cur + 1);
4588
+ } else if (typeof page === "number") {
4589
+ instance.goToPage?.(page);
4590
+ }
4474
4591
  }
4475
- }
4476
- });
4592
+ });
4593
+ }
4477
4594
  actions.push(
4478
4595
  {
4479
4596
  id: "zoom-out",
@@ -4610,10 +4727,6 @@ var CodePlugin = class {
4610
4727
  }
4611
4728
  const totalPages = Math.max(1, rawPages.length);
4612
4729
  let currentPage = 1;
4613
- const container = document.createElement("div");
4614
- container.style.width = "100%";
4615
- container.style.height = "100%";
4616
- container.style.overflow = "auto";
4617
4730
  let fontSize = 13;
4618
4731
  let rotation = 0;
4619
4732
  let zoomLevel = 1;
@@ -4622,9 +4735,10 @@ var CodePlugin = class {
4622
4735
  const code = document.createElement("code");
4623
4736
  const sizer = document.createElement("div");
4624
4737
  const scrollWrapper = document.createElement("div");
4738
+ const lineGutter = document.createElement("div");
4739
+ ctx.container.style.overflow = "auto";
4625
4740
  if (isTxt) {
4626
- container.style.overflow = "auto";
4627
- container.style.backgroundColor = "#f1f5f9";
4741
+ ctx.container.style.backgroundColor = "#f1f5f9";
4628
4742
  scrollWrapper.className = "fp-code-scroll-wrapper";
4629
4743
  scrollWrapper.style.minWidth = "100%";
4630
4744
  scrollWrapper.style.minHeight = "100%";
@@ -4659,18 +4773,88 @@ var CodePlugin = class {
4659
4773
  pre.style.transition = "transform 0.15s ease";
4660
4774
  pre.style.flexShrink = "0";
4661
4775
  } else {
4662
- container.style.overflow = "auto";
4663
- container.style.backgroundColor = "#1e1e1e";
4664
- container.style.color = "#d4d4d4";
4665
- container.style.padding = "16px";
4666
- container.style.boxSizing = "border-box";
4776
+ if (typeof document !== "undefined" && !document.getElementById("fp-code-syntax-styles")) {
4777
+ const style = document.createElement("style");
4778
+ style.id = "fp-code-syntax-styles";
4779
+ style.textContent = `
4780
+ .fp-code-scroll-wrapper .hljs-keyword { color: #569cd6; font-weight: normal; }
4781
+ .fp-code-scroll-wrapper .hljs-built_in { color: #4ec9b0; }
4782
+ .fp-code-scroll-wrapper .hljs-type { color: #4ec9b0; }
4783
+ .fp-code-scroll-wrapper .hljs-literal { color: #569cd6; }
4784
+ .fp-code-scroll-wrapper .hljs-number { color: #b5cea8; }
4785
+ .fp-code-scroll-wrapper .hljs-regexp { color: #d16969; }
4786
+ .fp-code-scroll-wrapper .hljs-string { color: #ce9178; }
4787
+ .fp-code-scroll-wrapper .hljs-subst { color: #d4d4d4; }
4788
+ .fp-code-scroll-wrapper .hljs-symbol { color: #569cd6; }
4789
+ .fp-code-scroll-wrapper .hljs-class { color: #4ec9b0; }
4790
+ .fp-code-scroll-wrapper .hljs-function { color: #dcdcaa; }
4791
+ .fp-code-scroll-wrapper .hljs-title { color: #dcdcaa; }
4792
+ .fp-code-scroll-wrapper .hljs-params { color: #9cdcfe; }
4793
+ .fp-code-scroll-wrapper .hljs-comment { color: #6a9955; font-style: italic; }
4794
+ .fp-code-scroll-wrapper .hljs-doctag { color: #608b4e; }
4795
+ .fp-code-scroll-wrapper .hljs-meta { color: #9cdcfe; }
4796
+ .fp-code-scroll-wrapper .hljs-section { color: #569cd6; }
4797
+ .fp-code-scroll-wrapper .hljs-tag { color: #569cd6; }
4798
+ .fp-code-scroll-wrapper .hljs-name { color: #569cd6; }
4799
+ .fp-code-scroll-wrapper .hljs-attr { color: #9cdcfe; }
4800
+ .fp-code-scroll-wrapper .hljs-attribute { color: #9cdcfe; }
4801
+ .fp-code-scroll-wrapper .hljs-variable { color: #9cdcfe; }
4802
+ .fp-code-scroll-wrapper .hljs-punctuation { color: #d4d4d4; }
4803
+ `;
4804
+ document.head.appendChild(style);
4805
+ }
4806
+ ctx.container.style.backgroundColor = "#1e1e1e";
4807
+ ctx.container.style.color = "#d4d4d4";
4808
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4809
+ scrollWrapper.style.minWidth = "100%";
4810
+ scrollWrapper.style.minHeight = "100%";
4811
+ scrollWrapper.style.width = "max-content";
4812
+ scrollWrapper.style.height = "max-content";
4813
+ scrollWrapper.style.display = "flex";
4814
+ scrollWrapper.style.alignItems = "flex-start";
4815
+ scrollWrapper.style.padding = "16px 16px 16px 0";
4816
+ scrollWrapper.style.boxSizing = "border-box";
4817
+ const rawLines = fullText.split(/\r?\n/);
4818
+ if (rawLines.length > 1 && rawLines[rawLines.length - 1] === "") {
4819
+ rawLines.pop();
4820
+ }
4821
+ const lineCount = Math.max(1, rawLines.length);
4822
+ const gutterLines = [];
4823
+ for (let i = 1; i <= lineCount; i++) {
4824
+ gutterLines.push(String(i));
4825
+ }
4826
+ lineGutter.className = "fp-code-gutter";
4827
+ lineGutter.style.userSelect = "none";
4828
+ lineGutter.style.textAlign = "right";
4829
+ lineGutter.style.padding = "0 16px";
4830
+ lineGutter.style.margin = "0 16px 0 0";
4831
+ lineGutter.style.borderRight = "1px solid #333333";
4832
+ lineGutter.style.color = "#858585";
4833
+ lineGutter.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4834
+ lineGutter.style.fontSize = `${fontSize}px`;
4835
+ lineGutter.style.lineHeight = "1.6";
4836
+ lineGutter.style.whiteSpace = "pre";
4837
+ lineGutter.style.flexShrink = "0";
4838
+ lineGutter.style.position = "sticky";
4839
+ lineGutter.style.left = "0";
4840
+ lineGutter.style.backgroundColor = "#1e1e1e";
4841
+ lineGutter.style.zIndex = "2";
4842
+ lineGutter.style.boxSizing = "border-box";
4843
+ lineGutter.textContent = gutterLines.join("\n");
4667
4844
  pre.style.margin = "0";
4668
- pre.style.fontFamily = "Consolas, Menlo, Monaco, monospace";
4845
+ pre.style.padding = "0 16px 0 0";
4846
+ pre.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4669
4847
  pre.style.fontSize = `${fontSize}px`;
4670
- pre.style.lineHeight = "1.5";
4671
- pre.style.whiteSpace = "pre-wrap";
4672
- pre.style.wordBreak = "break-all";
4673
- pre.style.transformOrigin = "top left";
4848
+ pre.style.lineHeight = "1.6";
4849
+ pre.style.whiteSpace = "pre";
4850
+ pre.style.wordBreak = "normal";
4851
+ pre.style.overflowWrap = "normal";
4852
+ pre.style.flex = "1";
4853
+ code.style.display = "block";
4854
+ code.style.fontFamily = "inherit";
4855
+ code.style.fontSize = "inherit";
4856
+ code.style.lineHeight = "inherit";
4857
+ code.style.whiteSpace = "inherit";
4674
4858
  }
4675
4859
  const ext = (ctx.metadata.extension || "").replace(".", "");
4676
4860
  const renderCodePage = (text) => {
@@ -4690,25 +4874,27 @@ var CodePlugin = class {
4690
4874
  };
4691
4875
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4692
4876
  pre.appendChild(code);
4877
+ ctx.container.innerHTML = "";
4693
4878
  if (isTxt) {
4694
4879
  sizer.appendChild(pre);
4695
4880
  scrollWrapper.appendChild(sizer);
4696
- container.appendChild(scrollWrapper);
4881
+ ctx.container.appendChild(scrollWrapper);
4697
4882
  } else {
4698
- container.appendChild(pre);
4883
+ scrollWrapper.appendChild(lineGutter);
4884
+ scrollWrapper.appendChild(pre);
4885
+ ctx.container.appendChild(scrollWrapper);
4699
4886
  }
4700
4887
  const showPage = (pageNum) => {
4701
4888
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4702
4889
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
4703
- container.scrollTop = 0;
4890
+ ctx.container.scrollTop = 0;
4704
4891
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4705
4892
  };
4706
4893
  if (totalPages > 1) {
4707
4894
  showPage(1);
4708
4895
  }
4709
- ctx.container.appendChild(container);
4710
4896
  const calculateTxtFit = () => {
4711
- const availW = Math.max(280, container.clientWidth - 32);
4897
+ const availW = Math.max(280, ctx.container.clientWidth - 32);
4712
4898
  return Math.max(0.4, Math.min(3, availW / 816));
4713
4899
  };
4714
4900
  const updateTransform = () => {
@@ -4726,6 +4912,7 @@ var CodePlugin = class {
4726
4912
  } else {
4727
4913
  pre.style.transform = `rotate(${rotation}deg)`;
4728
4914
  pre.style.fontSize = `${fontSize}px`;
4915
+ lineGutter.style.fontSize = `${fontSize}px`;
4729
4916
  }
4730
4917
  };
4731
4918
  let resizeObserver = null;
@@ -4740,11 +4927,11 @@ var CodePlugin = class {
4740
4927
  updateTransform();
4741
4928
  }
4742
4929
  }) : null;
4743
- resizeObserver?.observe(container);
4930
+ resizeObserver?.observe(ctx.container);
4744
4931
  }
4745
4932
  const cleanup = () => {
4746
4933
  resizeObserver?.disconnect();
4747
- container.remove();
4934
+ scrollWrapper.remove();
4748
4935
  ctx.container.innerHTML = "";
4749
4936
  };
4750
4937
  ctx.signal.addEventListener("abort", cleanup);
@@ -4789,7 +4976,7 @@ var CodePlugin = class {
4789
4976
  if (isTxt) {
4790
4977
  zoomLevel = Math.min(3.5, zoomLevel + 0.15);
4791
4978
  } else {
4792
- fontSize = Math.min(32, fontSize + 2);
4979
+ fontSize = Math.min(48, fontSize + 2);
4793
4980
  }
4794
4981
  updateTransform();
4795
4982
  },
@@ -4798,7 +4985,7 @@ var CodePlugin = class {
4798
4985
  if (isTxt) {
4799
4986
  zoomLevel = Math.max(0.1, zoomLevel - 0.15);
4800
4987
  } else {
4801
- fontSize = Math.max(8, fontSize - 2);
4988
+ fontSize = Math.max(9, fontSize - 2);
4802
4989
  }
4803
4990
  updateTransform();
4804
4991
  },
@@ -4831,8 +5018,8 @@ var CodePlugin = class {
4831
5018
  fontSize = 13;
4832
5019
  rotation = 0;
4833
5020
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4834
- container.scrollTop = 0;
4835
- container.scrollLeft = 0;
5021
+ ctx.container.scrollTop = 0;
5022
+ ctx.container.scrollLeft = 0;
4836
5023
  updateTransform();
4837
5024
  },
4838
5025
  rotateCW: () => {
@@ -5154,7 +5341,7 @@ var MarkdownPlugin = class {
5154
5341
  {
5155
5342
  id: "zoom-out",
5156
5343
  icon: "zoom-out",
5157
- label: "Decrease Font",
5344
+ label: "Zoom Out",
5158
5345
  type: "button",
5159
5346
  group: "zoom",
5160
5347
  execute: () => instance.zoomOut?.()
@@ -5162,19 +5349,11 @@ var MarkdownPlugin = class {
5162
5349
  {
5163
5350
  id: "zoom-in",
5164
5351
  icon: "zoom-in",
5165
- label: "Increase Font",
5352
+ label: "Zoom In",
5166
5353
  type: "button",
5167
5354
  group: "zoom",
5168
5355
  execute: () => instance.zoomIn?.()
5169
5356
  },
5170
- {
5171
- id: "fit-page",
5172
- icon: "fit-page",
5173
- label: "Default Size",
5174
- type: "button",
5175
- group: "zoom",
5176
- execute: () => instance.fitToPage?.()
5177
- },
5178
5357
  {
5179
5358
  id: "reset-zoom",
5180
5359
  icon: "reset-zoom",
@@ -5191,6 +5370,14 @@ var MarkdownPlugin = class {
5191
5370
  group: "zoom",
5192
5371
  execute: () => instance.fitToWidth?.()
5193
5372
  },
5373
+ {
5374
+ id: "fit-page",
5375
+ icon: "fit-page",
5376
+ label: "Fit to Page",
5377
+ type: "button",
5378
+ group: "zoom",
5379
+ execute: () => instance.fitToPage?.()
5380
+ },
5194
5381
  {
5195
5382
  id: "copy",
5196
5383
  icon: "copy",
@@ -5214,6 +5401,14 @@ var MarkdownPlugin = class {
5214
5401
  type: "button",
5215
5402
  group: "actions",
5216
5403
  execute: () => instance.print?.()
5404
+ },
5405
+ {
5406
+ id: "open-window",
5407
+ icon: "open-window",
5408
+ label: "Open in Separate Full Window",
5409
+ type: "button",
5410
+ group: "actions",
5411
+ execute: () => instance.openInSeparateWindow?.()
5217
5412
  }
5218
5413
  ];
5219
5414
  }
@@ -5226,35 +5421,57 @@ var MarkdownPlugin = class {
5226
5421
  const cleanHtml = DOMPurify6.sanitize(rawHtml, {
5227
5422
  USE_PROFILES: { html: true }
5228
5423
  });
5229
- const wrapper = document.createElement("div");
5230
- wrapper.className = "fp-markdown-wrapper";
5231
- wrapper.style.cssText = `
5232
- width: 100%;
5233
- height: 100%;
5234
- overflow: auto;
5235
- padding: 32px 40px;
5424
+ const scrollWrapper = document.createElement("div");
5425
+ scrollWrapper.className = "fp-markdown-scroll-wrapper";
5426
+ scrollWrapper.style.minWidth = "100%";
5427
+ scrollWrapper.style.minHeight = "100%";
5428
+ scrollWrapper.style.width = "max-content";
5429
+ scrollWrapper.style.height = "max-content";
5430
+ scrollWrapper.style.display = "flex";
5431
+ scrollWrapper.style.justifyContent = "center";
5432
+ scrollWrapper.style.alignItems = "flex-start";
5433
+ scrollWrapper.style.padding = "24px 16px";
5434
+ scrollWrapper.style.boxSizing = "border-box";
5435
+ const sizer = document.createElement("div");
5436
+ sizer.className = "fp-markdown-sizer";
5437
+ sizer.style.position = "relative";
5438
+ sizer.style.flexShrink = "0";
5439
+ sizer.style.display = "flex";
5440
+ sizer.style.justifyContent = "center";
5441
+ sizer.style.alignItems = "flex-start";
5442
+ const docCard = document.createElement("div");
5443
+ docCard.className = "fp-markdown-doc-card";
5444
+ docCard.style.cssText = `
5445
+ width: 860px;
5446
+ min-height: 600px;
5447
+ padding: 40px 48px;
5236
5448
  box-sizing: border-box;
5237
5449
  line-height: 1.6;
5238
5450
  font-size: 15px;
5239
5451
  color: var(--fp-text, #24292f);
5240
5452
  background: var(--fp-bg, #ffffff);
5453
+ border-radius: 6px;
5454
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
5241
5455
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
5456
+ transform-origin: top center;
5457
+ transition: transform 0.15s ease;
5458
+ flex-shrink: 0;
5242
5459
  `;
5243
- wrapper.innerHTML = `
5460
+ docCard.innerHTML = `
5244
5461
  <style>
5245
- .fp-markdown-wrapper h1, .fp-markdown-wrapper h2, .fp-markdown-wrapper h3,
5246
- .fp-markdown-wrapper h4, .fp-markdown-wrapper h5, .fp-markdown-wrapper h6 {
5462
+ .fp-markdown-doc-card h1, .fp-markdown-doc-card h2, .fp-markdown-doc-card h3,
5463
+ .fp-markdown-doc-card h4, .fp-markdown-doc-card h5, .fp-markdown-doc-card h6 {
5247
5464
  margin-top: 24px;
5248
5465
  margin-bottom: 16px;
5249
5466
  font-weight: 600;
5250
5467
  line-height: 1.25;
5251
5468
  color: var(--fp-text, #1f2328);
5252
5469
  }
5253
- .fp-markdown-wrapper h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5254
- .fp-markdown-wrapper h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5255
- .fp-markdown-wrapper h3 { font-size: 1.25em; }
5256
- .fp-markdown-wrapper p { margin-top: 0; margin-bottom: 16px; }
5257
- .fp-markdown-wrapper table {
5470
+ .fp-markdown-doc-card h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5471
+ .fp-markdown-doc-card h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5472
+ .fp-markdown-doc-card h3 { font-size: 1.25em; }
5473
+ .fp-markdown-doc-card p { margin-top: 0; margin-bottom: 16px; }
5474
+ .fp-markdown-doc-card table {
5258
5475
  border-spacing: 0;
5259
5476
  border-collapse: collapse;
5260
5477
  margin-top: 0;
@@ -5262,20 +5479,20 @@ var MarkdownPlugin = class {
5262
5479
  width: 100%;
5263
5480
  overflow: auto;
5264
5481
  }
5265
- .fp-markdown-wrapper table th, .fp-markdown-wrapper table td {
5482
+ .fp-markdown-doc-card table th, .fp-markdown-doc-card table td {
5266
5483
  padding: 6px 13px;
5267
5484
  border: 1px solid var(--fp-border, #d0d7de);
5268
5485
  }
5269
- .fp-markdown-wrapper table tr:nth-child(2n) {
5486
+ .fp-markdown-doc-card table tr:nth-child(2n) {
5270
5487
  background-color: var(--fp-toolbar-bg, #f6f8fa);
5271
5488
  }
5272
- .fp-markdown-wrapper blockquote {
5489
+ .fp-markdown-doc-card blockquote {
5273
5490
  margin: 0 0 16px 0;
5274
5491
  padding: 0 1em;
5275
5492
  color: var(--fp-text-muted, #59636e);
5276
5493
  border-left: 0.25em solid var(--fp-border, #d0d7de);
5277
5494
  }
5278
- .fp-markdown-wrapper pre {
5495
+ .fp-markdown-doc-card pre {
5279
5496
  padding: 16px;
5280
5497
  overflow: auto;
5281
5498
  font-size: 85%;
@@ -5284,7 +5501,7 @@ var MarkdownPlugin = class {
5284
5501
  border-radius: 6px;
5285
5502
  border: 1px solid var(--fp-border, #d0d7de);
5286
5503
  }
5287
- .fp-markdown-wrapper code {
5504
+ .fp-markdown-doc-card code {
5288
5505
  padding: 0.2em 0.4em;
5289
5506
  margin: 0;
5290
5507
  font-size: 85%;
@@ -5292,16 +5509,16 @@ var MarkdownPlugin = class {
5292
5509
  border-radius: 4px;
5293
5510
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
5294
5511
  }
5295
- .fp-markdown-wrapper pre code {
5512
+ .fp-markdown-doc-card pre code {
5296
5513
  padding: 0;
5297
5514
  background: transparent;
5298
5515
  }
5299
- .fp-markdown-wrapper ul, .fp-markdown-wrapper ol {
5516
+ .fp-markdown-doc-card ul, .fp-markdown-doc-card ol {
5300
5517
  padding-left: 2em;
5301
5518
  margin-top: 0;
5302
5519
  margin-bottom: 16px;
5303
5520
  }
5304
- .fp-markdown-wrapper hr {
5521
+ .fp-markdown-doc-card hr {
5305
5522
  height: 0.25em;
5306
5523
  padding: 0;
5307
5524
  margin: 24px 0;
@@ -5309,50 +5526,95 @@ var MarkdownPlugin = class {
5309
5526
  border: 0;
5310
5527
  }
5311
5528
  </style>
5312
- <div class="fp-markdown-content" style="max-width: 860px; margin: 0 auto;">
5529
+ <div class="fp-markdown-body">
5313
5530
  ${cleanHtml}
5314
5531
  </div>
5315
5532
  `;
5316
- wrapper.querySelectorAll("pre code").forEach((block) => {
5533
+ docCard.querySelectorAll("pre code").forEach((block) => {
5317
5534
  hljs.highlightElement(block);
5318
5535
  });
5536
+ sizer.appendChild(docCard);
5537
+ scrollWrapper.appendChild(sizer);
5319
5538
  ctx.container.innerHTML = "";
5320
5539
  ctx.container.style.overflow = "auto";
5321
- ctx.container.appendChild(wrapper);
5322
- let fontSize = 15;
5540
+ ctx.container.style.backgroundColor = "#f1f5f9";
5541
+ ctx.container.appendChild(scrollWrapper);
5542
+ let scale = 1;
5543
+ let isUserZoomed = false;
5544
+ const calculateFitScale = () => {
5545
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
5546
+ if (availW < 860) {
5547
+ return Math.max(0.35, availW / 860);
5548
+ }
5549
+ return 1;
5550
+ };
5551
+ const applyTransform = () => {
5552
+ const baseW = 860;
5553
+ const baseH = docCard.offsetHeight || 600;
5554
+ const scaledW = Math.round(baseW * scale);
5555
+ const scaledH = Math.round(baseH * scale);
5556
+ sizer.style.width = `${scaledW}px`;
5557
+ sizer.style.height = `${scaledH}px`;
5558
+ docCard.style.width = `${baseW}px`;
5559
+ docCard.style.transform = `scale(${scale})`;
5560
+ docCard.style.transformOrigin = scaledW > ctx.container.clientWidth - 32 ? "top left" : "top center";
5561
+ };
5562
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5563
+ if (!isUserZoomed) {
5564
+ scale = calculateFitScale();
5565
+ applyTransform();
5566
+ }
5567
+ }) : null;
5568
+ ro?.observe(ctx.container);
5569
+ requestAnimationFrame(() => {
5570
+ if (!isUserZoomed) {
5571
+ scale = calculateFitScale();
5572
+ }
5573
+ applyTransform();
5574
+ });
5323
5575
  const cleanup = () => {
5324
- wrapper.remove();
5576
+ ro?.disconnect();
5577
+ scrollWrapper.remove();
5325
5578
  ctx.container.innerHTML = "";
5326
5579
  };
5327
5580
  ctx.signal.addEventListener("abort", cleanup);
5328
5581
  return {
5329
5582
  destroy: cleanup,
5330
5583
  zoomIn: () => {
5331
- fontSize = Math.min(28, fontSize + 2);
5332
- wrapper.style.fontSize = `${fontSize}px`;
5584
+ isUserZoomed = true;
5585
+ scale = Math.min(3.5, scale + 0.15);
5586
+ applyTransform();
5333
5587
  },
5334
5588
  zoomOut: () => {
5335
- fontSize = Math.max(10, fontSize - 2);
5336
- wrapper.style.fontSize = `${fontSize}px`;
5589
+ isUserZoomed = true;
5590
+ scale = Math.max(0.25, scale - 0.15);
5591
+ applyTransform();
5337
5592
  },
5338
- getZoom: () => fontSize / 15,
5593
+ getZoom: () => scale,
5339
5594
  setZoom: (level) => {
5340
- fontSize = Math.round(15 * level);
5341
- wrapper.style.fontSize = `${fontSize}px`;
5595
+ isUserZoomed = true;
5596
+ scale = level;
5597
+ applyTransform();
5342
5598
  },
5343
5599
  fitToPage: () => {
5344
- fontSize = 15;
5345
- wrapper.style.fontSize = "15px";
5600
+ isUserZoomed = false;
5601
+ scale = calculateFitScale();
5602
+ applyTransform();
5346
5603
  },
5347
5604
  fitToWidth: () => {
5348
- fontSize = 15;
5349
- wrapper.style.fontSize = "15px";
5605
+ isUserZoomed = false;
5606
+ scale = calculateFitScale();
5607
+ applyTransform();
5350
5608
  },
5351
5609
  resetZoom: () => {
5352
- fontSize = 15;
5353
- wrapper.style.fontSize = "15px";
5610
+ isUserZoomed = false;
5611
+ scale = calculateFitScale();
5354
5612
  ctx.container.scrollTop = 0;
5355
5613
  ctx.container.scrollLeft = 0;
5614
+ applyTransform();
5615
+ },
5616
+ openInSeparateWindow: () => {
5617
+ ctx?.openInSeparateWindow?.();
5356
5618
  },
5357
5619
  download: () => {
5358
5620
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
@@ -6668,14 +6930,6 @@ var HtmlPreviewPlugin = class {
6668
6930
  group: "zoom",
6669
6931
  execute: () => instance.zoomIn?.()
6670
6932
  },
6671
- {
6672
- id: "fit-page",
6673
- icon: "fit-page",
6674
- label: "Fit to Page",
6675
- type: "button",
6676
- group: "zoom",
6677
- execute: () => instance.fitToPage?.()
6678
- },
6679
6933
  {
6680
6934
  id: "reset-zoom",
6681
6935
  icon: "reset-zoom",
@@ -6692,6 +6946,14 @@ var HtmlPreviewPlugin = class {
6692
6946
  group: "zoom",
6693
6947
  execute: () => instance.fitToWidth?.()
6694
6948
  },
6949
+ {
6950
+ id: "fit-page",
6951
+ icon: "fit-page",
6952
+ label: "Fit to Page",
6953
+ type: "button",
6954
+ group: "zoom",
6955
+ execute: () => instance.fitToPage?.()
6956
+ },
6695
6957
  {
6696
6958
  id: "copy",
6697
6959
  icon: "copy",
@@ -6715,6 +6977,14 @@ var HtmlPreviewPlugin = class {
6715
6977
  type: "button",
6716
6978
  group: "actions",
6717
6979
  execute: () => instance.print?.()
6980
+ },
6981
+ {
6982
+ id: "open-window",
6983
+ icon: "open-window",
6984
+ label: "Open in Separate Full Window",
6985
+ type: "button",
6986
+ group: "actions",
6987
+ execute: () => instance.openInSeparateWindow?.()
6718
6988
  }
6719
6989
  ];
6720
6990
  }
@@ -6725,27 +6995,39 @@ var HtmlPreviewPlugin = class {
6725
6995
  ADD_TAGS: ["style", "link"],
6726
6996
  ADD_ATTR: ["target", "rel"]
6727
6997
  });
6998
+ const scrollWrapper = document.createElement("div");
6999
+ scrollWrapper.className = "fp-html-scroll-wrapper";
7000
+ scrollWrapper.style.minWidth = "100%";
7001
+ scrollWrapper.style.minHeight = "100%";
7002
+ scrollWrapper.style.width = "max-content";
7003
+ scrollWrapper.style.height = "max-content";
7004
+ scrollWrapper.style.display = "flex";
7005
+ scrollWrapper.style.justifyContent = "flex-start";
7006
+ scrollWrapper.style.alignItems = "flex-start";
7007
+ scrollWrapper.style.boxSizing = "border-box";
6728
7008
  const sizer = document.createElement("div");
6729
7009
  sizer.className = "fp-html-sizer";
6730
7010
  sizer.style.position = "relative";
7011
+ sizer.style.flexShrink = "0";
6731
7012
  const iframe = document.createElement("iframe");
6732
7013
  iframe.className = "fp-html-iframe";
6733
7014
  iframe.style.border = "none";
6734
7015
  iframe.style.backgroundColor = "#ffffff";
6735
7016
  iframe.style.transformOrigin = "top left";
6736
- iframe.style.transition = "transform 0.2s ease";
7017
+ iframe.style.transition = "transform 0.15s ease";
6737
7018
  iframe.sandbox.add("allow-same-origin");
6738
7019
  sizer.appendChild(iframe);
7020
+ scrollWrapper.appendChild(sizer);
6739
7021
  ctx.container.style.overflow = "auto";
6740
7022
  ctx.container.style.width = "100%";
6741
7023
  ctx.container.style.height = "100%";
6742
7024
  ctx.container.innerHTML = "";
6743
- ctx.container.appendChild(sizer);
7025
+ ctx.container.appendChild(scrollWrapper);
6744
7026
  iframe.srcdoc = sanitized;
6745
7027
  let scale = 1;
7028
+ let baseW = Math.max(600, ctx.container.clientWidth || 800);
7029
+ let baseH = Math.max(400, ctx.container.clientHeight || 600);
6746
7030
  const applyTransform = () => {
6747
- const baseW = Math.max(600, ctx.container.clientWidth || 800);
6748
- const baseH = Math.max(400, ctx.container.clientHeight || 600);
6749
7031
  const scaledW = Math.round(baseW * scale);
6750
7032
  const scaledH = Math.round(baseH * scale);
6751
7033
  sizer.style.width = `${scaledW}px`;
@@ -6758,22 +7040,33 @@ var HtmlPreviewPlugin = class {
6758
7040
  iframe.style.transform = `scale(${scale})`;
6759
7041
  iframe.style.transformOrigin = "top left";
6760
7042
  };
7043
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
7044
+ if (Math.abs(scale - 1) < 0.05) {
7045
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7046
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
7047
+ applyTransform();
7048
+ }
7049
+ }) : null;
7050
+ ro?.observe(ctx.container);
6761
7051
  requestAnimationFrame(() => {
7052
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7053
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
6762
7054
  applyTransform();
6763
7055
  });
6764
7056
  const cleanup = () => {
6765
- sizer.remove();
7057
+ ro?.disconnect();
7058
+ scrollWrapper.remove();
6766
7059
  ctx.container.innerHTML = "";
6767
7060
  };
6768
7061
  ctx.signal.addEventListener("abort", cleanup);
6769
7062
  return {
6770
7063
  destroy: cleanup,
6771
7064
  zoomIn: () => {
6772
- scale += 0.1;
7065
+ scale = Math.min(3.5, scale + 0.15);
6773
7066
  applyTransform();
6774
7067
  },
6775
7068
  zoomOut: () => {
6776
- scale = Math.max(0.2, scale - 0.1);
7069
+ scale = Math.max(0.25, scale - 0.15);
6777
7070
  applyTransform();
6778
7071
  },
6779
7072
  getZoom: () => scale,
@@ -6795,8 +7088,11 @@ var HtmlPreviewPlugin = class {
6795
7088
  ctx.container.scrollLeft = 0;
6796
7089
  applyTransform();
6797
7090
  },
7091
+ openInSeparateWindow: () => {
7092
+ ctx?.openInSeparateWindow?.();
7093
+ },
6798
7094
  copy: () => {
6799
- navigator.clipboard.writeText(rawHtml);
7095
+ navigator.clipboard?.writeText(rawHtml);
6800
7096
  },
6801
7097
  download: () => {
6802
7098
  const blob = new Blob([ctx.buffer], { type: "text/html" });
@@ -8912,7 +9208,7 @@ var FilePreview = defineComponent({
8912
9208
  return () => {
8913
9209
  return h("div", {
8914
9210
  ref: containerRef,
8915
- style: { width: "100%", height: "100%", position: "relative" }
9211
+ style: { width: "100%", height: "100%", position: "relative", overflow: "hidden" }
8916
9212
  });
8917
9213
  };
8918
9214
  }