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

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,42 @@ 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
+ ctx.container.style.backgroundColor = "#1e1e1e";
4777
+ ctx.container.style.color = "#d4d4d4";
4778
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4779
+ scrollWrapper.style.minWidth = "100%";
4780
+ scrollWrapper.style.minHeight = "100%";
4781
+ scrollWrapper.style.width = "max-content";
4782
+ scrollWrapper.style.height = "max-content";
4783
+ scrollWrapper.style.display = "flex";
4784
+ scrollWrapper.style.alignItems = "flex-start";
4785
+ scrollWrapper.style.padding = "16px";
4786
+ scrollWrapper.style.boxSizing = "border-box";
4787
+ const lineCount = fullText.split(/\r?\n/).length || 1;
4788
+ const gutterLines = [];
4789
+ for (let i = 1; i <= lineCount; i++) {
4790
+ gutterLines.push(String(i));
4791
+ }
4792
+ lineGutter.className = "fp-code-gutter";
4793
+ lineGutter.style.userSelect = "none";
4794
+ lineGutter.style.textAlign = "right";
4795
+ lineGutter.style.paddingRight = "16px";
4796
+ lineGutter.style.marginRight = "16px";
4797
+ lineGutter.style.borderRight = "1px solid #333333";
4798
+ lineGutter.style.color = "#858585";
4799
+ lineGutter.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4800
+ lineGutter.style.fontSize = `${fontSize}px`;
4801
+ lineGutter.style.lineHeight = "1.6";
4802
+ lineGutter.style.flexShrink = "0";
4803
+ lineGutter.textContent = gutterLines.join("\n");
4667
4804
  pre.style.margin = "0";
4668
- pre.style.fontFamily = "Consolas, Menlo, Monaco, monospace";
4805
+ pre.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4669
4806
  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";
4807
+ pre.style.lineHeight = "1.6";
4808
+ pre.style.whiteSpace = "pre";
4809
+ pre.style.wordBreak = "normal";
4810
+ pre.style.overflowWrap = "normal";
4811
+ pre.style.flex = "1";
4674
4812
  }
4675
4813
  const ext = (ctx.metadata.extension || "").replace(".", "");
4676
4814
  const renderCodePage = (text) => {
@@ -4690,25 +4828,27 @@ var CodePlugin = class {
4690
4828
  };
4691
4829
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4692
4830
  pre.appendChild(code);
4831
+ ctx.container.innerHTML = "";
4693
4832
  if (isTxt) {
4694
4833
  sizer.appendChild(pre);
4695
4834
  scrollWrapper.appendChild(sizer);
4696
- container.appendChild(scrollWrapper);
4835
+ ctx.container.appendChild(scrollWrapper);
4697
4836
  } else {
4698
- container.appendChild(pre);
4837
+ scrollWrapper.appendChild(lineGutter);
4838
+ scrollWrapper.appendChild(pre);
4839
+ ctx.container.appendChild(scrollWrapper);
4699
4840
  }
4700
4841
  const showPage = (pageNum) => {
4701
4842
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4702
4843
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
4703
- container.scrollTop = 0;
4844
+ ctx.container.scrollTop = 0;
4704
4845
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4705
4846
  };
4706
4847
  if (totalPages > 1) {
4707
4848
  showPage(1);
4708
4849
  }
4709
- ctx.container.appendChild(container);
4710
4850
  const calculateTxtFit = () => {
4711
- const availW = Math.max(280, container.clientWidth - 32);
4851
+ const availW = Math.max(280, ctx.container.clientWidth - 32);
4712
4852
  return Math.max(0.4, Math.min(3, availW / 816));
4713
4853
  };
4714
4854
  const updateTransform = () => {
@@ -4726,6 +4866,7 @@ var CodePlugin = class {
4726
4866
  } else {
4727
4867
  pre.style.transform = `rotate(${rotation}deg)`;
4728
4868
  pre.style.fontSize = `${fontSize}px`;
4869
+ lineGutter.style.fontSize = `${fontSize}px`;
4729
4870
  }
4730
4871
  };
4731
4872
  let resizeObserver = null;
@@ -4740,11 +4881,11 @@ var CodePlugin = class {
4740
4881
  updateTransform();
4741
4882
  }
4742
4883
  }) : null;
4743
- resizeObserver?.observe(container);
4884
+ resizeObserver?.observe(ctx.container);
4744
4885
  }
4745
4886
  const cleanup = () => {
4746
4887
  resizeObserver?.disconnect();
4747
- container.remove();
4888
+ scrollWrapper.remove();
4748
4889
  ctx.container.innerHTML = "";
4749
4890
  };
4750
4891
  ctx.signal.addEventListener("abort", cleanup);
@@ -4789,7 +4930,7 @@ var CodePlugin = class {
4789
4930
  if (isTxt) {
4790
4931
  zoomLevel = Math.min(3.5, zoomLevel + 0.15);
4791
4932
  } else {
4792
- fontSize = Math.min(32, fontSize + 2);
4933
+ fontSize = Math.min(48, fontSize + 2);
4793
4934
  }
4794
4935
  updateTransform();
4795
4936
  },
@@ -4798,7 +4939,7 @@ var CodePlugin = class {
4798
4939
  if (isTxt) {
4799
4940
  zoomLevel = Math.max(0.1, zoomLevel - 0.15);
4800
4941
  } else {
4801
- fontSize = Math.max(8, fontSize - 2);
4942
+ fontSize = Math.max(9, fontSize - 2);
4802
4943
  }
4803
4944
  updateTransform();
4804
4945
  },
@@ -4831,8 +4972,8 @@ var CodePlugin = class {
4831
4972
  fontSize = 13;
4832
4973
  rotation = 0;
4833
4974
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4834
- container.scrollTop = 0;
4835
- container.scrollLeft = 0;
4975
+ ctx.container.scrollTop = 0;
4976
+ ctx.container.scrollLeft = 0;
4836
4977
  updateTransform();
4837
4978
  },
4838
4979
  rotateCW: () => {
@@ -5154,7 +5295,7 @@ var MarkdownPlugin = class {
5154
5295
  {
5155
5296
  id: "zoom-out",
5156
5297
  icon: "zoom-out",
5157
- label: "Decrease Font",
5298
+ label: "Zoom Out",
5158
5299
  type: "button",
5159
5300
  group: "zoom",
5160
5301
  execute: () => instance.zoomOut?.()
@@ -5162,19 +5303,11 @@ var MarkdownPlugin = class {
5162
5303
  {
5163
5304
  id: "zoom-in",
5164
5305
  icon: "zoom-in",
5165
- label: "Increase Font",
5306
+ label: "Zoom In",
5166
5307
  type: "button",
5167
5308
  group: "zoom",
5168
5309
  execute: () => instance.zoomIn?.()
5169
5310
  },
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
5311
  {
5179
5312
  id: "reset-zoom",
5180
5313
  icon: "reset-zoom",
@@ -5191,6 +5324,14 @@ var MarkdownPlugin = class {
5191
5324
  group: "zoom",
5192
5325
  execute: () => instance.fitToWidth?.()
5193
5326
  },
5327
+ {
5328
+ id: "fit-page",
5329
+ icon: "fit-page",
5330
+ label: "Fit to Page",
5331
+ type: "button",
5332
+ group: "zoom",
5333
+ execute: () => instance.fitToPage?.()
5334
+ },
5194
5335
  {
5195
5336
  id: "copy",
5196
5337
  icon: "copy",
@@ -5214,6 +5355,14 @@ var MarkdownPlugin = class {
5214
5355
  type: "button",
5215
5356
  group: "actions",
5216
5357
  execute: () => instance.print?.()
5358
+ },
5359
+ {
5360
+ id: "open-window",
5361
+ icon: "open-window",
5362
+ label: "Open in Separate Full Window",
5363
+ type: "button",
5364
+ group: "actions",
5365
+ execute: () => instance.openInSeparateWindow?.()
5217
5366
  }
5218
5367
  ];
5219
5368
  }
@@ -5226,35 +5375,57 @@ var MarkdownPlugin = class {
5226
5375
  const cleanHtml = DOMPurify6.sanitize(rawHtml, {
5227
5376
  USE_PROFILES: { html: true }
5228
5377
  });
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;
5378
+ const scrollWrapper = document.createElement("div");
5379
+ scrollWrapper.className = "fp-markdown-scroll-wrapper";
5380
+ scrollWrapper.style.minWidth = "100%";
5381
+ scrollWrapper.style.minHeight = "100%";
5382
+ scrollWrapper.style.width = "max-content";
5383
+ scrollWrapper.style.height = "max-content";
5384
+ scrollWrapper.style.display = "flex";
5385
+ scrollWrapper.style.justifyContent = "center";
5386
+ scrollWrapper.style.alignItems = "flex-start";
5387
+ scrollWrapper.style.padding = "24px 16px";
5388
+ scrollWrapper.style.boxSizing = "border-box";
5389
+ const sizer = document.createElement("div");
5390
+ sizer.className = "fp-markdown-sizer";
5391
+ sizer.style.position = "relative";
5392
+ sizer.style.flexShrink = "0";
5393
+ sizer.style.display = "flex";
5394
+ sizer.style.justifyContent = "center";
5395
+ sizer.style.alignItems = "flex-start";
5396
+ const docCard = document.createElement("div");
5397
+ docCard.className = "fp-markdown-doc-card";
5398
+ docCard.style.cssText = `
5399
+ width: 860px;
5400
+ min-height: 600px;
5401
+ padding: 40px 48px;
5236
5402
  box-sizing: border-box;
5237
5403
  line-height: 1.6;
5238
5404
  font-size: 15px;
5239
5405
  color: var(--fp-text, #24292f);
5240
5406
  background: var(--fp-bg, #ffffff);
5407
+ border-radius: 6px;
5408
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
5241
5409
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
5410
+ transform-origin: top center;
5411
+ transition: transform 0.15s ease;
5412
+ flex-shrink: 0;
5242
5413
  `;
5243
- wrapper.innerHTML = `
5414
+ docCard.innerHTML = `
5244
5415
  <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 {
5416
+ .fp-markdown-doc-card h1, .fp-markdown-doc-card h2, .fp-markdown-doc-card h3,
5417
+ .fp-markdown-doc-card h4, .fp-markdown-doc-card h5, .fp-markdown-doc-card h6 {
5247
5418
  margin-top: 24px;
5248
5419
  margin-bottom: 16px;
5249
5420
  font-weight: 600;
5250
5421
  line-height: 1.25;
5251
5422
  color: var(--fp-text, #1f2328);
5252
5423
  }
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 {
5424
+ .fp-markdown-doc-card h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5425
+ .fp-markdown-doc-card h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5426
+ .fp-markdown-doc-card h3 { font-size: 1.25em; }
5427
+ .fp-markdown-doc-card p { margin-top: 0; margin-bottom: 16px; }
5428
+ .fp-markdown-doc-card table {
5258
5429
  border-spacing: 0;
5259
5430
  border-collapse: collapse;
5260
5431
  margin-top: 0;
@@ -5262,20 +5433,20 @@ var MarkdownPlugin = class {
5262
5433
  width: 100%;
5263
5434
  overflow: auto;
5264
5435
  }
5265
- .fp-markdown-wrapper table th, .fp-markdown-wrapper table td {
5436
+ .fp-markdown-doc-card table th, .fp-markdown-doc-card table td {
5266
5437
  padding: 6px 13px;
5267
5438
  border: 1px solid var(--fp-border, #d0d7de);
5268
5439
  }
5269
- .fp-markdown-wrapper table tr:nth-child(2n) {
5440
+ .fp-markdown-doc-card table tr:nth-child(2n) {
5270
5441
  background-color: var(--fp-toolbar-bg, #f6f8fa);
5271
5442
  }
5272
- .fp-markdown-wrapper blockquote {
5443
+ .fp-markdown-doc-card blockquote {
5273
5444
  margin: 0 0 16px 0;
5274
5445
  padding: 0 1em;
5275
5446
  color: var(--fp-text-muted, #59636e);
5276
5447
  border-left: 0.25em solid var(--fp-border, #d0d7de);
5277
5448
  }
5278
- .fp-markdown-wrapper pre {
5449
+ .fp-markdown-doc-card pre {
5279
5450
  padding: 16px;
5280
5451
  overflow: auto;
5281
5452
  font-size: 85%;
@@ -5284,7 +5455,7 @@ var MarkdownPlugin = class {
5284
5455
  border-radius: 6px;
5285
5456
  border: 1px solid var(--fp-border, #d0d7de);
5286
5457
  }
5287
- .fp-markdown-wrapper code {
5458
+ .fp-markdown-doc-card code {
5288
5459
  padding: 0.2em 0.4em;
5289
5460
  margin: 0;
5290
5461
  font-size: 85%;
@@ -5292,16 +5463,16 @@ var MarkdownPlugin = class {
5292
5463
  border-radius: 4px;
5293
5464
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
5294
5465
  }
5295
- .fp-markdown-wrapper pre code {
5466
+ .fp-markdown-doc-card pre code {
5296
5467
  padding: 0;
5297
5468
  background: transparent;
5298
5469
  }
5299
- .fp-markdown-wrapper ul, .fp-markdown-wrapper ol {
5470
+ .fp-markdown-doc-card ul, .fp-markdown-doc-card ol {
5300
5471
  padding-left: 2em;
5301
5472
  margin-top: 0;
5302
5473
  margin-bottom: 16px;
5303
5474
  }
5304
- .fp-markdown-wrapper hr {
5475
+ .fp-markdown-doc-card hr {
5305
5476
  height: 0.25em;
5306
5477
  padding: 0;
5307
5478
  margin: 24px 0;
@@ -5309,50 +5480,95 @@ var MarkdownPlugin = class {
5309
5480
  border: 0;
5310
5481
  }
5311
5482
  </style>
5312
- <div class="fp-markdown-content" style="max-width: 860px; margin: 0 auto;">
5483
+ <div class="fp-markdown-body">
5313
5484
  ${cleanHtml}
5314
5485
  </div>
5315
5486
  `;
5316
- wrapper.querySelectorAll("pre code").forEach((block) => {
5487
+ docCard.querySelectorAll("pre code").forEach((block) => {
5317
5488
  hljs.highlightElement(block);
5318
5489
  });
5490
+ sizer.appendChild(docCard);
5491
+ scrollWrapper.appendChild(sizer);
5319
5492
  ctx.container.innerHTML = "";
5320
5493
  ctx.container.style.overflow = "auto";
5321
- ctx.container.appendChild(wrapper);
5322
- let fontSize = 15;
5494
+ ctx.container.style.backgroundColor = "#f1f5f9";
5495
+ ctx.container.appendChild(scrollWrapper);
5496
+ let scale = 1;
5497
+ let isUserZoomed = false;
5498
+ const calculateFitScale = () => {
5499
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
5500
+ if (availW < 860) {
5501
+ return Math.max(0.35, availW / 860);
5502
+ }
5503
+ return 1;
5504
+ };
5505
+ const applyTransform = () => {
5506
+ const baseW = 860;
5507
+ const baseH = docCard.offsetHeight || 600;
5508
+ const scaledW = Math.round(baseW * scale);
5509
+ const scaledH = Math.round(baseH * scale);
5510
+ sizer.style.width = `${scaledW}px`;
5511
+ sizer.style.height = `${scaledH}px`;
5512
+ docCard.style.width = `${baseW}px`;
5513
+ docCard.style.transform = `scale(${scale})`;
5514
+ docCard.style.transformOrigin = scaledW > ctx.container.clientWidth - 32 ? "top left" : "top center";
5515
+ };
5516
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5517
+ if (!isUserZoomed) {
5518
+ scale = calculateFitScale();
5519
+ applyTransform();
5520
+ }
5521
+ }) : null;
5522
+ ro?.observe(ctx.container);
5523
+ requestAnimationFrame(() => {
5524
+ if (!isUserZoomed) {
5525
+ scale = calculateFitScale();
5526
+ }
5527
+ applyTransform();
5528
+ });
5323
5529
  const cleanup = () => {
5324
- wrapper.remove();
5530
+ ro?.disconnect();
5531
+ scrollWrapper.remove();
5325
5532
  ctx.container.innerHTML = "";
5326
5533
  };
5327
5534
  ctx.signal.addEventListener("abort", cleanup);
5328
5535
  return {
5329
5536
  destroy: cleanup,
5330
5537
  zoomIn: () => {
5331
- fontSize = Math.min(28, fontSize + 2);
5332
- wrapper.style.fontSize = `${fontSize}px`;
5538
+ isUserZoomed = true;
5539
+ scale = Math.min(3.5, scale + 0.15);
5540
+ applyTransform();
5333
5541
  },
5334
5542
  zoomOut: () => {
5335
- fontSize = Math.max(10, fontSize - 2);
5336
- wrapper.style.fontSize = `${fontSize}px`;
5543
+ isUserZoomed = true;
5544
+ scale = Math.max(0.25, scale - 0.15);
5545
+ applyTransform();
5337
5546
  },
5338
- getZoom: () => fontSize / 15,
5547
+ getZoom: () => scale,
5339
5548
  setZoom: (level) => {
5340
- fontSize = Math.round(15 * level);
5341
- wrapper.style.fontSize = `${fontSize}px`;
5549
+ isUserZoomed = true;
5550
+ scale = level;
5551
+ applyTransform();
5342
5552
  },
5343
5553
  fitToPage: () => {
5344
- fontSize = 15;
5345
- wrapper.style.fontSize = "15px";
5554
+ isUserZoomed = false;
5555
+ scale = calculateFitScale();
5556
+ applyTransform();
5346
5557
  },
5347
5558
  fitToWidth: () => {
5348
- fontSize = 15;
5349
- wrapper.style.fontSize = "15px";
5559
+ isUserZoomed = false;
5560
+ scale = calculateFitScale();
5561
+ applyTransform();
5350
5562
  },
5351
5563
  resetZoom: () => {
5352
- fontSize = 15;
5353
- wrapper.style.fontSize = "15px";
5564
+ isUserZoomed = false;
5565
+ scale = calculateFitScale();
5354
5566
  ctx.container.scrollTop = 0;
5355
5567
  ctx.container.scrollLeft = 0;
5568
+ applyTransform();
5569
+ },
5570
+ openInSeparateWindow: () => {
5571
+ ctx?.openInSeparateWindow?.();
5356
5572
  },
5357
5573
  download: () => {
5358
5574
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
@@ -6668,14 +6884,6 @@ var HtmlPreviewPlugin = class {
6668
6884
  group: "zoom",
6669
6885
  execute: () => instance.zoomIn?.()
6670
6886
  },
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
6887
  {
6680
6888
  id: "reset-zoom",
6681
6889
  icon: "reset-zoom",
@@ -6692,6 +6900,14 @@ var HtmlPreviewPlugin = class {
6692
6900
  group: "zoom",
6693
6901
  execute: () => instance.fitToWidth?.()
6694
6902
  },
6903
+ {
6904
+ id: "fit-page",
6905
+ icon: "fit-page",
6906
+ label: "Fit to Page",
6907
+ type: "button",
6908
+ group: "zoom",
6909
+ execute: () => instance.fitToPage?.()
6910
+ },
6695
6911
  {
6696
6912
  id: "copy",
6697
6913
  icon: "copy",
@@ -6715,6 +6931,14 @@ var HtmlPreviewPlugin = class {
6715
6931
  type: "button",
6716
6932
  group: "actions",
6717
6933
  execute: () => instance.print?.()
6934
+ },
6935
+ {
6936
+ id: "open-window",
6937
+ icon: "open-window",
6938
+ label: "Open in Separate Full Window",
6939
+ type: "button",
6940
+ group: "actions",
6941
+ execute: () => instance.openInSeparateWindow?.()
6718
6942
  }
6719
6943
  ];
6720
6944
  }
@@ -6725,27 +6949,39 @@ var HtmlPreviewPlugin = class {
6725
6949
  ADD_TAGS: ["style", "link"],
6726
6950
  ADD_ATTR: ["target", "rel"]
6727
6951
  });
6952
+ const scrollWrapper = document.createElement("div");
6953
+ scrollWrapper.className = "fp-html-scroll-wrapper";
6954
+ scrollWrapper.style.minWidth = "100%";
6955
+ scrollWrapper.style.minHeight = "100%";
6956
+ scrollWrapper.style.width = "max-content";
6957
+ scrollWrapper.style.height = "max-content";
6958
+ scrollWrapper.style.display = "flex";
6959
+ scrollWrapper.style.justifyContent = "flex-start";
6960
+ scrollWrapper.style.alignItems = "flex-start";
6961
+ scrollWrapper.style.boxSizing = "border-box";
6728
6962
  const sizer = document.createElement("div");
6729
6963
  sizer.className = "fp-html-sizer";
6730
6964
  sizer.style.position = "relative";
6965
+ sizer.style.flexShrink = "0";
6731
6966
  const iframe = document.createElement("iframe");
6732
6967
  iframe.className = "fp-html-iframe";
6733
6968
  iframe.style.border = "none";
6734
6969
  iframe.style.backgroundColor = "#ffffff";
6735
6970
  iframe.style.transformOrigin = "top left";
6736
- iframe.style.transition = "transform 0.2s ease";
6971
+ iframe.style.transition = "transform 0.15s ease";
6737
6972
  iframe.sandbox.add("allow-same-origin");
6738
6973
  sizer.appendChild(iframe);
6974
+ scrollWrapper.appendChild(sizer);
6739
6975
  ctx.container.style.overflow = "auto";
6740
6976
  ctx.container.style.width = "100%";
6741
6977
  ctx.container.style.height = "100%";
6742
6978
  ctx.container.innerHTML = "";
6743
- ctx.container.appendChild(sizer);
6979
+ ctx.container.appendChild(scrollWrapper);
6744
6980
  iframe.srcdoc = sanitized;
6745
6981
  let scale = 1;
6982
+ let baseW = Math.max(600, ctx.container.clientWidth || 800);
6983
+ let baseH = Math.max(400, ctx.container.clientHeight || 600);
6746
6984
  const applyTransform = () => {
6747
- const baseW = Math.max(600, ctx.container.clientWidth || 800);
6748
- const baseH = Math.max(400, ctx.container.clientHeight || 600);
6749
6985
  const scaledW = Math.round(baseW * scale);
6750
6986
  const scaledH = Math.round(baseH * scale);
6751
6987
  sizer.style.width = `${scaledW}px`;
@@ -6758,22 +6994,33 @@ var HtmlPreviewPlugin = class {
6758
6994
  iframe.style.transform = `scale(${scale})`;
6759
6995
  iframe.style.transformOrigin = "top left";
6760
6996
  };
6997
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
6998
+ if (Math.abs(scale - 1) < 0.05) {
6999
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7000
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
7001
+ applyTransform();
7002
+ }
7003
+ }) : null;
7004
+ ro?.observe(ctx.container);
6761
7005
  requestAnimationFrame(() => {
7006
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7007
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
6762
7008
  applyTransform();
6763
7009
  });
6764
7010
  const cleanup = () => {
6765
- sizer.remove();
7011
+ ro?.disconnect();
7012
+ scrollWrapper.remove();
6766
7013
  ctx.container.innerHTML = "";
6767
7014
  };
6768
7015
  ctx.signal.addEventListener("abort", cleanup);
6769
7016
  return {
6770
7017
  destroy: cleanup,
6771
7018
  zoomIn: () => {
6772
- scale += 0.1;
7019
+ scale = Math.min(3.5, scale + 0.15);
6773
7020
  applyTransform();
6774
7021
  },
6775
7022
  zoomOut: () => {
6776
- scale = Math.max(0.2, scale - 0.1);
7023
+ scale = Math.max(0.25, scale - 0.15);
6777
7024
  applyTransform();
6778
7025
  },
6779
7026
  getZoom: () => scale,
@@ -6795,8 +7042,11 @@ var HtmlPreviewPlugin = class {
6795
7042
  ctx.container.scrollLeft = 0;
6796
7043
  applyTransform();
6797
7044
  },
7045
+ openInSeparateWindow: () => {
7046
+ ctx?.openInSeparateWindow?.();
7047
+ },
6798
7048
  copy: () => {
6799
- navigator.clipboard.writeText(rawHtml);
7049
+ navigator.clipboard?.writeText(rawHtml);
6800
7050
  },
6801
7051
  download: () => {
6802
7052
  const blob = new Blob([ctx.buffer], { type: "text/html" });
@@ -8912,7 +9162,7 @@ var FilePreview = defineComponent({
8912
9162
  return () => {
8913
9163
  return h("div", {
8914
9164
  ref: containerRef,
8915
- style: { width: "100%", height: "100%", position: "relative" }
9165
+ style: { width: "100%", height: "100%", position: "relative", overflow: "hidden" }
8916
9166
  });
8917
9167
  };
8918
9168
  }