@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/react.js CHANGED
@@ -1599,19 +1599,85 @@ var FilePreviewViewer = class _FilePreviewViewer {
1599
1599
  if (this.wrapperEl?.parentNode) {
1600
1600
  this.wrapperEl.parentNode.removeChild(this.wrapperEl);
1601
1601
  }
1602
+ if (typeof document !== "undefined" && !document.getElementById("fp-core-injected-styles")) {
1603
+ const styleEl = document.createElement("style");
1604
+ styleEl.id = "fp-core-injected-styles";
1605
+ styleEl.textContent = `
1606
+ .fp-viewer {
1607
+ display: flex !important;
1608
+ flex-direction: column !important;
1609
+ width: 100% !important;
1610
+ height: 100% !important;
1611
+ overflow: hidden !important;
1612
+ position: relative !important;
1613
+ box-sizing: border-box !important;
1614
+ }
1615
+ .fp-body {
1616
+ display: flex !important;
1617
+ flex: 1 1 0% !important;
1618
+ min-height: 0 !important;
1619
+ min-width: 0 !important;
1620
+ width: 100% !important;
1621
+ height: 100% !important;
1622
+ overflow: hidden !important;
1623
+ position: relative !important;
1624
+ box-sizing: border-box !important;
1625
+ }
1626
+ .fp-content {
1627
+ flex: 1 1 0% !important;
1628
+ position: relative !important;
1629
+ overflow: auto !important;
1630
+ display: flex !important;
1631
+ flex-direction: column !important;
1632
+ align-items: stretch !important;
1633
+ justify-content: flex-start !important;
1634
+ width: 100% !important;
1635
+ height: 100% !important;
1636
+ min-width: 0 !important;
1637
+ min-height: 0 !important;
1638
+ box-sizing: border-box !important;
1639
+ }
1640
+ `;
1641
+ document.head.appendChild(styleEl);
1642
+ }
1602
1643
  const themeClass = options.theme === "dark" ? "fp-theme-dark" : "";
1603
1644
  const toolbarPos = options.toolbarPosition ?? "top";
1604
1645
  this.wrapperEl = document.createElement("div");
1605
1646
  this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
1606
1647
  this.wrapperEl.tabIndex = 0;
1648
+ this.wrapperEl.style.display = "flex";
1649
+ this.wrapperEl.style.flexDirection = "column";
1650
+ this.wrapperEl.style.width = "100%";
1651
+ this.wrapperEl.style.height = "100%";
1652
+ this.wrapperEl.style.overflow = "hidden";
1653
+ this.wrapperEl.style.position = "relative";
1607
1654
  const toolbarEl = document.createElement("div");
1608
1655
  toolbarEl.className = "fp-toolbar-container";
1609
1656
  this.contentEl = document.createElement("div");
1610
1657
  this.contentEl.className = "fp-content";
1658
+ this.contentEl.style.flex = "1 1 0%";
1659
+ this.contentEl.style.position = "relative";
1660
+ this.contentEl.style.overflow = "auto";
1661
+ this.contentEl.style.display = "flex";
1662
+ this.contentEl.style.flexDirection = "column";
1663
+ this.contentEl.style.alignItems = "stretch";
1664
+ this.contentEl.style.justifyContent = "flex-start";
1665
+ this.contentEl.style.width = "100%";
1666
+ this.contentEl.style.height = "100%";
1667
+ this.contentEl.style.minWidth = "0";
1668
+ this.contentEl.style.minHeight = "0";
1669
+ this.contentEl.style.boxSizing = "border-box";
1611
1670
  const thumbnailEl = document.createElement("div");
1612
1671
  thumbnailEl.className = "fp-thumbnail-container";
1613
1672
  const bodyEl = document.createElement("div");
1614
1673
  bodyEl.className = "fp-body";
1674
+ bodyEl.style.display = "flex";
1675
+ bodyEl.style.flex = "1 1 0%";
1676
+ bodyEl.style.minHeight = "0";
1677
+ bodyEl.style.minWidth = "0";
1678
+ bodyEl.style.width = "100%";
1679
+ bodyEl.style.overflow = "hidden";
1680
+ bodyEl.style.position = "relative";
1615
1681
  bodyEl.appendChild(thumbnailEl);
1616
1682
  bodyEl.appendChild(this.contentEl);
1617
1683
  const titleBarEl = document.createElement("div");
@@ -4405,31 +4471,80 @@ function csvPlugin() {
4405
4471
  }
4406
4472
  var CODE_EXTENSIONS = [
4407
4473
  ".txt",
4474
+ ".log",
4475
+ ".ini",
4476
+ ".cfg",
4477
+ ".conf",
4478
+ ".env",
4408
4479
  ".json",
4480
+ ".jsonc",
4481
+ ".json5",
4409
4482
  ".js",
4410
- ".ts",
4483
+ ".mjs",
4484
+ ".cjs",
4411
4485
  ".jsx",
4486
+ ".ts",
4487
+ ".mts",
4488
+ ".cts",
4412
4489
  ".tsx",
4413
4490
  ".html",
4491
+ ".htm",
4492
+ ".xhtml",
4414
4493
  ".css",
4415
4494
  ".scss",
4495
+ ".sass",
4416
4496
  ".less",
4417
4497
  ".md",
4498
+ ".markdown",
4418
4499
  ".xml",
4500
+ ".svg",
4501
+ ".xaml",
4419
4502
  ".yml",
4420
4503
  ".yaml",
4504
+ ".toml",
4421
4505
  ".sh",
4422
4506
  ".bash",
4507
+ ".zsh",
4508
+ ".fish",
4509
+ ".bat",
4510
+ ".cmd",
4511
+ ".ps1",
4423
4512
  ".py",
4513
+ ".pyw",
4424
4514
  ".java",
4515
+ ".class",
4425
4516
  ".c",
4426
4517
  ".cpp",
4518
+ ".cc",
4519
+ ".cxx",
4427
4520
  ".h",
4521
+ ".hpp",
4522
+ ".hxx",
4428
4523
  ".cs",
4524
+ ".csx",
4429
4525
  ".go",
4430
4526
  ".rs",
4431
4527
  ".sql",
4432
- ".php"
4528
+ ".php",
4529
+ ".phtml",
4530
+ ".rb",
4531
+ ".swift",
4532
+ ".kt",
4533
+ ".kts",
4534
+ ".scala",
4535
+ ".r",
4536
+ ".lua",
4537
+ ".pl",
4538
+ ".pm",
4539
+ ".dart",
4540
+ ".graphql",
4541
+ ".gql",
4542
+ ".proto",
4543
+ ".diff",
4544
+ ".patch",
4545
+ ".dockerfile",
4546
+ ".properties",
4547
+ ".gradle"
4433
4548
  ];
4434
4549
  var CodePlugin = class {
4435
4550
  id = "code";
@@ -4447,34 +4562,36 @@ var CodePlugin = class {
4447
4562
  getToolbarActions(instance) {
4448
4563
  const totalPages = instance.getPageCount?.() ?? 1;
4449
4564
  const actions = [];
4450
- actions.push({
4451
- id: "thumbnails",
4452
- icon: "thumbnails",
4453
- label: "Page Thumbnails",
4454
- type: "button",
4455
- group: "navigation",
4456
- execute: () => instance.toggleThumbnails?.()
4457
- });
4458
- actions.push({
4459
- id: "page-nav",
4460
- icon: "",
4461
- label: "Page Navigation",
4462
- type: "page-nav",
4463
- group: "navigation",
4464
- value: instance.getCurrentPage?.() ?? 1,
4465
- max: totalPages,
4466
- execute: (action, page) => {
4467
- const cur = instance.getCurrentPage?.() ?? 1;
4468
- const max = instance.getPageCount?.() ?? 1;
4469
- if (action === "prev") {
4470
- if (cur > 1) instance.goToPage?.(cur - 1);
4471
- } else if (action === "next") {
4472
- if (cur < max) instance.goToPage?.(cur + 1);
4473
- } else if (typeof page === "number") {
4474
- instance.goToPage?.(page);
4565
+ if (totalPages > 1) {
4566
+ actions.push({
4567
+ id: "thumbnails",
4568
+ icon: "thumbnails",
4569
+ label: "Page Thumbnails",
4570
+ type: "button",
4571
+ group: "navigation",
4572
+ execute: () => instance.toggleThumbnails?.()
4573
+ });
4574
+ actions.push({
4575
+ id: "page-nav",
4576
+ icon: "",
4577
+ label: "Page Navigation",
4578
+ type: "page-nav",
4579
+ group: "navigation",
4580
+ value: instance.getCurrentPage?.() ?? 1,
4581
+ max: totalPages,
4582
+ execute: (action, page) => {
4583
+ const cur = instance.getCurrentPage?.() ?? 1;
4584
+ const max = instance.getPageCount?.() ?? 1;
4585
+ if (action === "prev") {
4586
+ if (cur > 1) instance.goToPage?.(cur - 1);
4587
+ } else if (action === "next") {
4588
+ if (cur < max) instance.goToPage?.(cur + 1);
4589
+ } else if (typeof page === "number") {
4590
+ instance.goToPage?.(page);
4591
+ }
4475
4592
  }
4476
- }
4477
- });
4593
+ });
4594
+ }
4478
4595
  actions.push(
4479
4596
  {
4480
4597
  id: "zoom-out",
@@ -4611,10 +4728,6 @@ var CodePlugin = class {
4611
4728
  }
4612
4729
  const totalPages = Math.max(1, rawPages.length);
4613
4730
  let currentPage = 1;
4614
- const container = document.createElement("div");
4615
- container.style.width = "100%";
4616
- container.style.height = "100%";
4617
- container.style.overflow = "auto";
4618
4731
  let fontSize = 13;
4619
4732
  let rotation = 0;
4620
4733
  let zoomLevel = 1;
@@ -4623,9 +4736,10 @@ var CodePlugin = class {
4623
4736
  const code = document.createElement("code");
4624
4737
  const sizer = document.createElement("div");
4625
4738
  const scrollWrapper = document.createElement("div");
4739
+ const lineGutter = document.createElement("div");
4740
+ ctx.container.style.overflow = "auto";
4626
4741
  if (isTxt) {
4627
- container.style.overflow = "auto";
4628
- container.style.backgroundColor = "#f1f5f9";
4742
+ ctx.container.style.backgroundColor = "#f1f5f9";
4629
4743
  scrollWrapper.className = "fp-code-scroll-wrapper";
4630
4744
  scrollWrapper.style.minWidth = "100%";
4631
4745
  scrollWrapper.style.minHeight = "100%";
@@ -4660,18 +4774,42 @@ var CodePlugin = class {
4660
4774
  pre.style.transition = "transform 0.15s ease";
4661
4775
  pre.style.flexShrink = "0";
4662
4776
  } else {
4663
- container.style.overflow = "auto";
4664
- container.style.backgroundColor = "#1e1e1e";
4665
- container.style.color = "#d4d4d4";
4666
- container.style.padding = "16px";
4667
- container.style.boxSizing = "border-box";
4777
+ ctx.container.style.backgroundColor = "#1e1e1e";
4778
+ ctx.container.style.color = "#d4d4d4";
4779
+ scrollWrapper.className = "fp-code-scroll-wrapper";
4780
+ scrollWrapper.style.minWidth = "100%";
4781
+ scrollWrapper.style.minHeight = "100%";
4782
+ scrollWrapper.style.width = "max-content";
4783
+ scrollWrapper.style.height = "max-content";
4784
+ scrollWrapper.style.display = "flex";
4785
+ scrollWrapper.style.alignItems = "flex-start";
4786
+ scrollWrapper.style.padding = "16px";
4787
+ scrollWrapper.style.boxSizing = "border-box";
4788
+ const lineCount = fullText.split(/\r?\n/).length || 1;
4789
+ const gutterLines = [];
4790
+ for (let i = 1; i <= lineCount; i++) {
4791
+ gutterLines.push(String(i));
4792
+ }
4793
+ lineGutter.className = "fp-code-gutter";
4794
+ lineGutter.style.userSelect = "none";
4795
+ lineGutter.style.textAlign = "right";
4796
+ lineGutter.style.paddingRight = "16px";
4797
+ lineGutter.style.marginRight = "16px";
4798
+ lineGutter.style.borderRight = "1px solid #333333";
4799
+ lineGutter.style.color = "#858585";
4800
+ lineGutter.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4801
+ lineGutter.style.fontSize = `${fontSize}px`;
4802
+ lineGutter.style.lineHeight = "1.6";
4803
+ lineGutter.style.flexShrink = "0";
4804
+ lineGutter.textContent = gutterLines.join("\n");
4668
4805
  pre.style.margin = "0";
4669
- pre.style.fontFamily = "Consolas, Menlo, Monaco, monospace";
4806
+ pre.style.fontFamily = "Consolas, Menlo, Monaco, 'Courier New', monospace";
4670
4807
  pre.style.fontSize = `${fontSize}px`;
4671
- pre.style.lineHeight = "1.5";
4672
- pre.style.whiteSpace = "pre-wrap";
4673
- pre.style.wordBreak = "break-all";
4674
- pre.style.transformOrigin = "top left";
4808
+ pre.style.lineHeight = "1.6";
4809
+ pre.style.whiteSpace = "pre";
4810
+ pre.style.wordBreak = "normal";
4811
+ pre.style.overflowWrap = "normal";
4812
+ pre.style.flex = "1";
4675
4813
  }
4676
4814
  const ext = (ctx.metadata.extension || "").replace(".", "");
4677
4815
  const renderCodePage = (text) => {
@@ -4691,25 +4829,27 @@ var CodePlugin = class {
4691
4829
  };
4692
4830
  renderCodePage(rawPages[0] || (isTxt ? "" : fullText));
4693
4831
  pre.appendChild(code);
4832
+ ctx.container.innerHTML = "";
4694
4833
  if (isTxt) {
4695
4834
  sizer.appendChild(pre);
4696
4835
  scrollWrapper.appendChild(sizer);
4697
- container.appendChild(scrollWrapper);
4836
+ ctx.container.appendChild(scrollWrapper);
4698
4837
  } else {
4699
- container.appendChild(pre);
4838
+ scrollWrapper.appendChild(lineGutter);
4839
+ scrollWrapper.appendChild(pre);
4840
+ ctx.container.appendChild(scrollWrapper);
4700
4841
  }
4701
4842
  const showPage = (pageNum) => {
4702
4843
  currentPage = Math.max(1, Math.min(totalPages, pageNum));
4703
4844
  renderCodePage(rawPages[currentPage - 1] || (isTxt ? "" : fullText));
4704
- container.scrollTop = 0;
4845
+ ctx.container.scrollTop = 0;
4705
4846
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4706
4847
  };
4707
4848
  if (totalPages > 1) {
4708
4849
  showPage(1);
4709
4850
  }
4710
- ctx.container.appendChild(container);
4711
4851
  const calculateTxtFit = () => {
4712
- const availW = Math.max(280, container.clientWidth - 32);
4852
+ const availW = Math.max(280, ctx.container.clientWidth - 32);
4713
4853
  return Math.max(0.4, Math.min(3, availW / 816));
4714
4854
  };
4715
4855
  const updateTransform = () => {
@@ -4727,6 +4867,7 @@ var CodePlugin = class {
4727
4867
  } else {
4728
4868
  pre.style.transform = `rotate(${rotation}deg)`;
4729
4869
  pre.style.fontSize = `${fontSize}px`;
4870
+ lineGutter.style.fontSize = `${fontSize}px`;
4730
4871
  }
4731
4872
  };
4732
4873
  let resizeObserver = null;
@@ -4741,11 +4882,11 @@ var CodePlugin = class {
4741
4882
  updateTransform();
4742
4883
  }
4743
4884
  }) : null;
4744
- resizeObserver?.observe(container);
4885
+ resizeObserver?.observe(ctx.container);
4745
4886
  }
4746
4887
  const cleanup = () => {
4747
4888
  resizeObserver?.disconnect();
4748
- container.remove();
4889
+ scrollWrapper.remove();
4749
4890
  ctx.container.innerHTML = "";
4750
4891
  };
4751
4892
  ctx.signal.addEventListener("abort", cleanup);
@@ -4790,7 +4931,7 @@ var CodePlugin = class {
4790
4931
  if (isTxt) {
4791
4932
  zoomLevel = Math.min(3.5, zoomLevel + 0.15);
4792
4933
  } else {
4793
- fontSize = Math.min(32, fontSize + 2);
4934
+ fontSize = Math.min(48, fontSize + 2);
4794
4935
  }
4795
4936
  updateTransform();
4796
4937
  },
@@ -4799,7 +4940,7 @@ var CodePlugin = class {
4799
4940
  if (isTxt) {
4800
4941
  zoomLevel = Math.max(0.1, zoomLevel - 0.15);
4801
4942
  } else {
4802
- fontSize = Math.max(8, fontSize - 2);
4943
+ fontSize = Math.max(9, fontSize - 2);
4803
4944
  }
4804
4945
  updateTransform();
4805
4946
  },
@@ -4832,8 +4973,8 @@ var CodePlugin = class {
4832
4973
  fontSize = 13;
4833
4974
  rotation = 0;
4834
4975
  zoomLevel = isTxt ? calculateTxtFit() : 1;
4835
- container.scrollTop = 0;
4836
- container.scrollLeft = 0;
4976
+ ctx.container.scrollTop = 0;
4977
+ ctx.container.scrollLeft = 0;
4837
4978
  updateTransform();
4838
4979
  },
4839
4980
  rotateCW: () => {
@@ -5155,7 +5296,7 @@ var MarkdownPlugin = class {
5155
5296
  {
5156
5297
  id: "zoom-out",
5157
5298
  icon: "zoom-out",
5158
- label: "Decrease Font",
5299
+ label: "Zoom Out",
5159
5300
  type: "button",
5160
5301
  group: "zoom",
5161
5302
  execute: () => instance.zoomOut?.()
@@ -5163,19 +5304,11 @@ var MarkdownPlugin = class {
5163
5304
  {
5164
5305
  id: "zoom-in",
5165
5306
  icon: "zoom-in",
5166
- label: "Increase Font",
5307
+ label: "Zoom In",
5167
5308
  type: "button",
5168
5309
  group: "zoom",
5169
5310
  execute: () => instance.zoomIn?.()
5170
5311
  },
5171
- {
5172
- id: "fit-page",
5173
- icon: "fit-page",
5174
- label: "Default Size",
5175
- type: "button",
5176
- group: "zoom",
5177
- execute: () => instance.fitToPage?.()
5178
- },
5179
5312
  {
5180
5313
  id: "reset-zoom",
5181
5314
  icon: "reset-zoom",
@@ -5192,6 +5325,14 @@ var MarkdownPlugin = class {
5192
5325
  group: "zoom",
5193
5326
  execute: () => instance.fitToWidth?.()
5194
5327
  },
5328
+ {
5329
+ id: "fit-page",
5330
+ icon: "fit-page",
5331
+ label: "Fit to Page",
5332
+ type: "button",
5333
+ group: "zoom",
5334
+ execute: () => instance.fitToPage?.()
5335
+ },
5195
5336
  {
5196
5337
  id: "copy",
5197
5338
  icon: "copy",
@@ -5215,6 +5356,14 @@ var MarkdownPlugin = class {
5215
5356
  type: "button",
5216
5357
  group: "actions",
5217
5358
  execute: () => instance.print?.()
5359
+ },
5360
+ {
5361
+ id: "open-window",
5362
+ icon: "open-window",
5363
+ label: "Open in Separate Full Window",
5364
+ type: "button",
5365
+ group: "actions",
5366
+ execute: () => instance.openInSeparateWindow?.()
5218
5367
  }
5219
5368
  ];
5220
5369
  }
@@ -5227,35 +5376,57 @@ var MarkdownPlugin = class {
5227
5376
  const cleanHtml = DOMPurify6.sanitize(rawHtml, {
5228
5377
  USE_PROFILES: { html: true }
5229
5378
  });
5230
- const wrapper = document.createElement("div");
5231
- wrapper.className = "fp-markdown-wrapper";
5232
- wrapper.style.cssText = `
5233
- width: 100%;
5234
- height: 100%;
5235
- overflow: auto;
5236
- padding: 32px 40px;
5379
+ const scrollWrapper = document.createElement("div");
5380
+ scrollWrapper.className = "fp-markdown-scroll-wrapper";
5381
+ scrollWrapper.style.minWidth = "100%";
5382
+ scrollWrapper.style.minHeight = "100%";
5383
+ scrollWrapper.style.width = "max-content";
5384
+ scrollWrapper.style.height = "max-content";
5385
+ scrollWrapper.style.display = "flex";
5386
+ scrollWrapper.style.justifyContent = "center";
5387
+ scrollWrapper.style.alignItems = "flex-start";
5388
+ scrollWrapper.style.padding = "24px 16px";
5389
+ scrollWrapper.style.boxSizing = "border-box";
5390
+ const sizer = document.createElement("div");
5391
+ sizer.className = "fp-markdown-sizer";
5392
+ sizer.style.position = "relative";
5393
+ sizer.style.flexShrink = "0";
5394
+ sizer.style.display = "flex";
5395
+ sizer.style.justifyContent = "center";
5396
+ sizer.style.alignItems = "flex-start";
5397
+ const docCard = document.createElement("div");
5398
+ docCard.className = "fp-markdown-doc-card";
5399
+ docCard.style.cssText = `
5400
+ width: 860px;
5401
+ min-height: 600px;
5402
+ padding: 40px 48px;
5237
5403
  box-sizing: border-box;
5238
5404
  line-height: 1.6;
5239
5405
  font-size: 15px;
5240
5406
  color: var(--fp-text, #24292f);
5241
5407
  background: var(--fp-bg, #ffffff);
5408
+ border-radius: 6px;
5409
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
5242
5410
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
5411
+ transform-origin: top center;
5412
+ transition: transform 0.15s ease;
5413
+ flex-shrink: 0;
5243
5414
  `;
5244
- wrapper.innerHTML = `
5415
+ docCard.innerHTML = `
5245
5416
  <style>
5246
- .fp-markdown-wrapper h1, .fp-markdown-wrapper h2, .fp-markdown-wrapper h3,
5247
- .fp-markdown-wrapper h4, .fp-markdown-wrapper h5, .fp-markdown-wrapper h6 {
5417
+ .fp-markdown-doc-card h1, .fp-markdown-doc-card h2, .fp-markdown-doc-card h3,
5418
+ .fp-markdown-doc-card h4, .fp-markdown-doc-card h5, .fp-markdown-doc-card h6 {
5248
5419
  margin-top: 24px;
5249
5420
  margin-bottom: 16px;
5250
5421
  font-weight: 600;
5251
5422
  line-height: 1.25;
5252
5423
  color: var(--fp-text, #1f2328);
5253
5424
  }
5254
- .fp-markdown-wrapper h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5255
- .fp-markdown-wrapper h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5256
- .fp-markdown-wrapper h3 { font-size: 1.25em; }
5257
- .fp-markdown-wrapper p { margin-top: 0; margin-bottom: 16px; }
5258
- .fp-markdown-wrapper table {
5425
+ .fp-markdown-doc-card h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5426
+ .fp-markdown-doc-card h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--fp-border, #d0d7de); }
5427
+ .fp-markdown-doc-card h3 { font-size: 1.25em; }
5428
+ .fp-markdown-doc-card p { margin-top: 0; margin-bottom: 16px; }
5429
+ .fp-markdown-doc-card table {
5259
5430
  border-spacing: 0;
5260
5431
  border-collapse: collapse;
5261
5432
  margin-top: 0;
@@ -5263,20 +5434,20 @@ var MarkdownPlugin = class {
5263
5434
  width: 100%;
5264
5435
  overflow: auto;
5265
5436
  }
5266
- .fp-markdown-wrapper table th, .fp-markdown-wrapper table td {
5437
+ .fp-markdown-doc-card table th, .fp-markdown-doc-card table td {
5267
5438
  padding: 6px 13px;
5268
5439
  border: 1px solid var(--fp-border, #d0d7de);
5269
5440
  }
5270
- .fp-markdown-wrapper table tr:nth-child(2n) {
5441
+ .fp-markdown-doc-card table tr:nth-child(2n) {
5271
5442
  background-color: var(--fp-toolbar-bg, #f6f8fa);
5272
5443
  }
5273
- .fp-markdown-wrapper blockquote {
5444
+ .fp-markdown-doc-card blockquote {
5274
5445
  margin: 0 0 16px 0;
5275
5446
  padding: 0 1em;
5276
5447
  color: var(--fp-text-muted, #59636e);
5277
5448
  border-left: 0.25em solid var(--fp-border, #d0d7de);
5278
5449
  }
5279
- .fp-markdown-wrapper pre {
5450
+ .fp-markdown-doc-card pre {
5280
5451
  padding: 16px;
5281
5452
  overflow: auto;
5282
5453
  font-size: 85%;
@@ -5285,7 +5456,7 @@ var MarkdownPlugin = class {
5285
5456
  border-radius: 6px;
5286
5457
  border: 1px solid var(--fp-border, #d0d7de);
5287
5458
  }
5288
- .fp-markdown-wrapper code {
5459
+ .fp-markdown-doc-card code {
5289
5460
  padding: 0.2em 0.4em;
5290
5461
  margin: 0;
5291
5462
  font-size: 85%;
@@ -5293,16 +5464,16 @@ var MarkdownPlugin = class {
5293
5464
  border-radius: 4px;
5294
5465
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
5295
5466
  }
5296
- .fp-markdown-wrapper pre code {
5467
+ .fp-markdown-doc-card pre code {
5297
5468
  padding: 0;
5298
5469
  background: transparent;
5299
5470
  }
5300
- .fp-markdown-wrapper ul, .fp-markdown-wrapper ol {
5471
+ .fp-markdown-doc-card ul, .fp-markdown-doc-card ol {
5301
5472
  padding-left: 2em;
5302
5473
  margin-top: 0;
5303
5474
  margin-bottom: 16px;
5304
5475
  }
5305
- .fp-markdown-wrapper hr {
5476
+ .fp-markdown-doc-card hr {
5306
5477
  height: 0.25em;
5307
5478
  padding: 0;
5308
5479
  margin: 24px 0;
@@ -5310,50 +5481,95 @@ var MarkdownPlugin = class {
5310
5481
  border: 0;
5311
5482
  }
5312
5483
  </style>
5313
- <div class="fp-markdown-content" style="max-width: 860px; margin: 0 auto;">
5484
+ <div class="fp-markdown-body">
5314
5485
  ${cleanHtml}
5315
5486
  </div>
5316
5487
  `;
5317
- wrapper.querySelectorAll("pre code").forEach((block) => {
5488
+ docCard.querySelectorAll("pre code").forEach((block) => {
5318
5489
  hljs.highlightElement(block);
5319
5490
  });
5491
+ sizer.appendChild(docCard);
5492
+ scrollWrapper.appendChild(sizer);
5320
5493
  ctx.container.innerHTML = "";
5321
5494
  ctx.container.style.overflow = "auto";
5322
- ctx.container.appendChild(wrapper);
5323
- let fontSize = 15;
5495
+ ctx.container.style.backgroundColor = "#f1f5f9";
5496
+ ctx.container.appendChild(scrollWrapper);
5497
+ let scale = 1;
5498
+ let isUserZoomed = false;
5499
+ const calculateFitScale = () => {
5500
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
5501
+ if (availW < 860) {
5502
+ return Math.max(0.35, availW / 860);
5503
+ }
5504
+ return 1;
5505
+ };
5506
+ const applyTransform = () => {
5507
+ const baseW = 860;
5508
+ const baseH = docCard.offsetHeight || 600;
5509
+ const scaledW = Math.round(baseW * scale);
5510
+ const scaledH = Math.round(baseH * scale);
5511
+ sizer.style.width = `${scaledW}px`;
5512
+ sizer.style.height = `${scaledH}px`;
5513
+ docCard.style.width = `${baseW}px`;
5514
+ docCard.style.transform = `scale(${scale})`;
5515
+ docCard.style.transformOrigin = scaledW > ctx.container.clientWidth - 32 ? "top left" : "top center";
5516
+ };
5517
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
5518
+ if (!isUserZoomed) {
5519
+ scale = calculateFitScale();
5520
+ applyTransform();
5521
+ }
5522
+ }) : null;
5523
+ ro?.observe(ctx.container);
5524
+ requestAnimationFrame(() => {
5525
+ if (!isUserZoomed) {
5526
+ scale = calculateFitScale();
5527
+ }
5528
+ applyTransform();
5529
+ });
5324
5530
  const cleanup = () => {
5325
- wrapper.remove();
5531
+ ro?.disconnect();
5532
+ scrollWrapper.remove();
5326
5533
  ctx.container.innerHTML = "";
5327
5534
  };
5328
5535
  ctx.signal.addEventListener("abort", cleanup);
5329
5536
  return {
5330
5537
  destroy: cleanup,
5331
5538
  zoomIn: () => {
5332
- fontSize = Math.min(28, fontSize + 2);
5333
- wrapper.style.fontSize = `${fontSize}px`;
5539
+ isUserZoomed = true;
5540
+ scale = Math.min(3.5, scale + 0.15);
5541
+ applyTransform();
5334
5542
  },
5335
5543
  zoomOut: () => {
5336
- fontSize = Math.max(10, fontSize - 2);
5337
- wrapper.style.fontSize = `${fontSize}px`;
5544
+ isUserZoomed = true;
5545
+ scale = Math.max(0.25, scale - 0.15);
5546
+ applyTransform();
5338
5547
  },
5339
- getZoom: () => fontSize / 15,
5548
+ getZoom: () => scale,
5340
5549
  setZoom: (level) => {
5341
- fontSize = Math.round(15 * level);
5342
- wrapper.style.fontSize = `${fontSize}px`;
5550
+ isUserZoomed = true;
5551
+ scale = level;
5552
+ applyTransform();
5343
5553
  },
5344
5554
  fitToPage: () => {
5345
- fontSize = 15;
5346
- wrapper.style.fontSize = "15px";
5555
+ isUserZoomed = false;
5556
+ scale = calculateFitScale();
5557
+ applyTransform();
5347
5558
  },
5348
5559
  fitToWidth: () => {
5349
- fontSize = 15;
5350
- wrapper.style.fontSize = "15px";
5560
+ isUserZoomed = false;
5561
+ scale = calculateFitScale();
5562
+ applyTransform();
5351
5563
  },
5352
5564
  resetZoom: () => {
5353
- fontSize = 15;
5354
- wrapper.style.fontSize = "15px";
5565
+ isUserZoomed = false;
5566
+ scale = calculateFitScale();
5355
5567
  ctx.container.scrollTop = 0;
5356
5568
  ctx.container.scrollLeft = 0;
5569
+ applyTransform();
5570
+ },
5571
+ openInSeparateWindow: () => {
5572
+ ctx?.openInSeparateWindow?.();
5357
5573
  },
5358
5574
  download: () => {
5359
5575
  downloadFile(ctx.buffer, ctx.metadata.name || "document.md", "text/markdown");
@@ -6669,14 +6885,6 @@ var HtmlPreviewPlugin = class {
6669
6885
  group: "zoom",
6670
6886
  execute: () => instance.zoomIn?.()
6671
6887
  },
6672
- {
6673
- id: "fit-page",
6674
- icon: "fit-page",
6675
- label: "Fit to Page",
6676
- type: "button",
6677
- group: "zoom",
6678
- execute: () => instance.fitToPage?.()
6679
- },
6680
6888
  {
6681
6889
  id: "reset-zoom",
6682
6890
  icon: "reset-zoom",
@@ -6693,6 +6901,14 @@ var HtmlPreviewPlugin = class {
6693
6901
  group: "zoom",
6694
6902
  execute: () => instance.fitToWidth?.()
6695
6903
  },
6904
+ {
6905
+ id: "fit-page",
6906
+ icon: "fit-page",
6907
+ label: "Fit to Page",
6908
+ type: "button",
6909
+ group: "zoom",
6910
+ execute: () => instance.fitToPage?.()
6911
+ },
6696
6912
  {
6697
6913
  id: "copy",
6698
6914
  icon: "copy",
@@ -6716,6 +6932,14 @@ var HtmlPreviewPlugin = class {
6716
6932
  type: "button",
6717
6933
  group: "actions",
6718
6934
  execute: () => instance.print?.()
6935
+ },
6936
+ {
6937
+ id: "open-window",
6938
+ icon: "open-window",
6939
+ label: "Open in Separate Full Window",
6940
+ type: "button",
6941
+ group: "actions",
6942
+ execute: () => instance.openInSeparateWindow?.()
6719
6943
  }
6720
6944
  ];
6721
6945
  }
@@ -6726,27 +6950,39 @@ var HtmlPreviewPlugin = class {
6726
6950
  ADD_TAGS: ["style", "link"],
6727
6951
  ADD_ATTR: ["target", "rel"]
6728
6952
  });
6953
+ const scrollWrapper = document.createElement("div");
6954
+ scrollWrapper.className = "fp-html-scroll-wrapper";
6955
+ scrollWrapper.style.minWidth = "100%";
6956
+ scrollWrapper.style.minHeight = "100%";
6957
+ scrollWrapper.style.width = "max-content";
6958
+ scrollWrapper.style.height = "max-content";
6959
+ scrollWrapper.style.display = "flex";
6960
+ scrollWrapper.style.justifyContent = "flex-start";
6961
+ scrollWrapper.style.alignItems = "flex-start";
6962
+ scrollWrapper.style.boxSizing = "border-box";
6729
6963
  const sizer = document.createElement("div");
6730
6964
  sizer.className = "fp-html-sizer";
6731
6965
  sizer.style.position = "relative";
6966
+ sizer.style.flexShrink = "0";
6732
6967
  const iframe = document.createElement("iframe");
6733
6968
  iframe.className = "fp-html-iframe";
6734
6969
  iframe.style.border = "none";
6735
6970
  iframe.style.backgroundColor = "#ffffff";
6736
6971
  iframe.style.transformOrigin = "top left";
6737
- iframe.style.transition = "transform 0.2s ease";
6972
+ iframe.style.transition = "transform 0.15s ease";
6738
6973
  iframe.sandbox.add("allow-same-origin");
6739
6974
  sizer.appendChild(iframe);
6975
+ scrollWrapper.appendChild(sizer);
6740
6976
  ctx.container.style.overflow = "auto";
6741
6977
  ctx.container.style.width = "100%";
6742
6978
  ctx.container.style.height = "100%";
6743
6979
  ctx.container.innerHTML = "";
6744
- ctx.container.appendChild(sizer);
6980
+ ctx.container.appendChild(scrollWrapper);
6745
6981
  iframe.srcdoc = sanitized;
6746
6982
  let scale = 1;
6983
+ let baseW = Math.max(600, ctx.container.clientWidth || 800);
6984
+ let baseH = Math.max(400, ctx.container.clientHeight || 600);
6747
6985
  const applyTransform = () => {
6748
- const baseW = Math.max(600, ctx.container.clientWidth || 800);
6749
- const baseH = Math.max(400, ctx.container.clientHeight || 600);
6750
6986
  const scaledW = Math.round(baseW * scale);
6751
6987
  const scaledH = Math.round(baseH * scale);
6752
6988
  sizer.style.width = `${scaledW}px`;
@@ -6759,22 +6995,33 @@ var HtmlPreviewPlugin = class {
6759
6995
  iframe.style.transform = `scale(${scale})`;
6760
6996
  iframe.style.transformOrigin = "top left";
6761
6997
  };
6998
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
6999
+ if (Math.abs(scale - 1) < 0.05) {
7000
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7001
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
7002
+ applyTransform();
7003
+ }
7004
+ }) : null;
7005
+ ro?.observe(ctx.container);
6762
7006
  requestAnimationFrame(() => {
7007
+ baseW = Math.max(600, ctx.container.clientWidth || 800);
7008
+ baseH = Math.max(400, ctx.container.clientHeight || 600);
6763
7009
  applyTransform();
6764
7010
  });
6765
7011
  const cleanup = () => {
6766
- sizer.remove();
7012
+ ro?.disconnect();
7013
+ scrollWrapper.remove();
6767
7014
  ctx.container.innerHTML = "";
6768
7015
  };
6769
7016
  ctx.signal.addEventListener("abort", cleanup);
6770
7017
  return {
6771
7018
  destroy: cleanup,
6772
7019
  zoomIn: () => {
6773
- scale += 0.1;
7020
+ scale = Math.min(3.5, scale + 0.15);
6774
7021
  applyTransform();
6775
7022
  },
6776
7023
  zoomOut: () => {
6777
- scale = Math.max(0.2, scale - 0.1);
7024
+ scale = Math.max(0.25, scale - 0.15);
6778
7025
  applyTransform();
6779
7026
  },
6780
7027
  getZoom: () => scale,
@@ -6796,8 +7043,11 @@ var HtmlPreviewPlugin = class {
6796
7043
  ctx.container.scrollLeft = 0;
6797
7044
  applyTransform();
6798
7045
  },
7046
+ openInSeparateWindow: () => {
7047
+ ctx?.openInSeparateWindow?.();
7048
+ },
6799
7049
  copy: () => {
6800
- navigator.clipboard.writeText(rawHtml);
7050
+ navigator.clipboard?.writeText(rawHtml);
6801
7051
  },
6802
7052
  download: () => {
6803
7053
  const blob = new Blob([ctx.buffer], { type: "text/html" });
@@ -8918,7 +9168,7 @@ var FilePreview = memo(forwardRef(
8918
9168
  {
8919
9169
  ref: containerRef,
8920
9170
  className,
8921
- style: { width: "100%", height: "100%", position: "relative", ...style }
9171
+ style: { width: "100%", height: "100%", position: "relative", overflow: "hidden", ...style }
8922
9172
  }
8923
9173
  );
8924
9174
  }