@files-preview-app/preview-file 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue.cjs CHANGED
@@ -3,11 +3,11 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var vue = require('vue');
6
- var DOMPurify5 = require('dompurify');
6
+ var DOMPurify6 = require('dompurify');
7
7
  var docx = require('docx-preview');
8
+ var fflate = require('fflate');
8
9
  var XLSX = require('xlsx');
9
10
  var hljs = require('highlight.js');
10
- var fflate = require('fflate');
11
11
  var marked = require('marked');
12
12
  var pptxBrowser = require('pptx-browser');
13
13
  var THREE = require('three');
@@ -36,7 +36,7 @@ function _interopNamespace(e) {
36
36
  return Object.freeze(n);
37
37
  }
38
38
 
39
- var DOMPurify5__default = /*#__PURE__*/_interopDefault(DOMPurify5);
39
+ var DOMPurify6__default = /*#__PURE__*/_interopDefault(DOMPurify6);
40
40
  var docx__namespace = /*#__PURE__*/_interopNamespace(docx);
41
41
  var XLSX__namespace = /*#__PURE__*/_interopNamespace(XLSX);
42
42
  var hljs__default = /*#__PURE__*/_interopDefault(hljs);
@@ -370,7 +370,7 @@ async function sourceToArrayBuffer(source, signal) {
370
370
  return { buffer, metadata };
371
371
  }
372
372
  function sanitizeSVG(svg) {
373
- return DOMPurify5__default.default.sanitize(svg, {
373
+ return DOMPurify6__default.default.sanitize(svg, {
374
374
  USE_PROFILES: { svg: true, svgFilters: true }
375
375
  });
376
376
  }
@@ -446,7 +446,11 @@ var ICON_MAP = {
446
446
  "close": ICON_CLOSE,
447
447
  "copy": ICON_COPY,
448
448
  "prev": ICON_PAGE_PREV,
449
- "next": ICON_PAGE_NEXT
449
+ "next": ICON_PAGE_NEXT,
450
+ "page-prev": ICON_PAGE_PREV,
451
+ "page-next": ICON_PAGE_NEXT,
452
+ "chevron-left": ICON_PAGE_PREV,
453
+ "chevron-right": ICON_PAGE_NEXT
450
454
  };
451
455
  var ToolbarController = class {
452
456
  el;
@@ -478,7 +482,9 @@ var ToolbarController = class {
478
482
  view: [],
479
483
  actions: []
480
484
  };
481
- for (const action of this.actions) {
485
+ const hasPageNav = this.actions.some((a) => a.type === "page-nav");
486
+ const effectiveActions = hasPageNav ? this.actions.filter((a) => a.id !== "page-prev" && a.id !== "page-next" && a.id !== "prev" && a.id !== "next") : this.actions;
487
+ for (const action of effectiveActions) {
482
488
  if (groups[action.group]) {
483
489
  groups[action.group].push(action);
484
490
  }
@@ -501,13 +507,26 @@ var ToolbarController = class {
501
507
  "prev",
502
508
  ICON_PAGE_PREV,
503
509
  "Previous Page",
504
- () => action.execute("prev")
510
+ () => {
511
+ const cur = parseInt(input.value, 10) || 1;
512
+ if (cur > 1) {
513
+ input.value = (cur - 1).toString();
514
+ action.execute("prev", cur - 1);
515
+ }
516
+ }
505
517
  );
506
518
  const nextBtn = this.createButton(
507
519
  "next",
508
520
  ICON_PAGE_NEXT,
509
521
  "Next Page",
510
- () => action.execute("next")
522
+ () => {
523
+ const cur = parseInt(input.value, 10) || 1;
524
+ const max = action.max ?? 1;
525
+ if (cur < max) {
526
+ input.value = (cur + 1).toString();
527
+ action.execute("next", cur + 1);
528
+ }
529
+ }
511
530
  );
512
531
  const input = createElement("input", {
513
532
  className: "fp-toolbar-input",
@@ -517,7 +536,10 @@ var ToolbarController = class {
517
536
  max: (action.max ?? 1).toString()
518
537
  });
519
538
  input.addEventListener("change", () => {
520
- action.execute("go", parseInt(input.value, 10));
539
+ const val = parseInt(input.value, 10);
540
+ if (!isNaN(val)) {
541
+ action.execute("go", val);
542
+ }
521
543
  });
522
544
  const label = createElement("span", { className: "fp-toolbar-label" }, ` / ${action.max ?? 1}`);
523
545
  groupEl.appendChild(prevBtn);
@@ -558,11 +580,11 @@ var ToolbarController = class {
558
580
  type: "button",
559
581
  "data-action-id": id
560
582
  });
561
- const svg = ICON_MAP[iconHtml] || iconHtml;
562
- if (svg && svg.startsWith("<svg")) {
583
+ const svg = ICON_MAP[iconHtml] || ICON_MAP[id] || (iconHtml && iconHtml.startsWith("<svg") ? iconHtml : null);
584
+ if (svg) {
563
585
  btn.innerHTML = sanitizeSVG(svg);
564
586
  } else {
565
- btn.textContent = svg || title;
587
+ btn.textContent = title || id;
566
588
  }
567
589
  btn.addEventListener("click", onClick);
568
590
  return btn;
@@ -1305,12 +1327,12 @@ function pdfPlugin() {
1305
1327
  }
1306
1328
 
1307
1329
  // ../plugins/media/dist/index.js
1308
- var IMAGE_EXTS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"];
1309
- var VIDEO_EXTS = [".mp4", ".webm", ".ogg"];
1310
- var AUDIO_EXTS = [".mp3", ".wav", ".ogg"];
1330
+ var IMAGE_EXTS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".bmp", ".ico", ".tiff", ".tif", ".avif"];
1331
+ var VIDEO_EXTS = [".mp4", ".m4v", ".webm", ".ogv", ".ogg", ".mov", ".avi", ".mkv", ".flv", ".wmv", ".3gp", ".mpg", ".mpeg"];
1332
+ var AUDIO_EXTS = [".mp3", ".wav", ".ogg", ".flac", ".aac", ".m4a", ".wma", ".opus", ".weba"];
1311
1333
  var MediaPlugin = class {
1312
1334
  id = "media";
1313
- name = "Media Preview";
1335
+ name = "Media Preview (Image, Video, Audio)";
1314
1336
  extensions = [...IMAGE_EXTS, ...VIDEO_EXTS, ...AUDIO_EXTS];
1315
1337
  mimeTypes = [
1316
1338
  "image/jpeg",
@@ -1318,12 +1340,29 @@ var MediaPlugin = class {
1318
1340
  "image/gif",
1319
1341
  "image/webp",
1320
1342
  "image/svg+xml",
1343
+ "image/bmp",
1344
+ "image/x-icon",
1345
+ "image/tiff",
1346
+ "image/avif",
1321
1347
  "video/mp4",
1322
1348
  "video/webm",
1323
1349
  "video/ogg",
1350
+ "video/quicktime",
1351
+ "video/x-msvideo",
1352
+ "video/x-matroska",
1353
+ "video/x-flv",
1354
+ "video/x-ms-wmv",
1355
+ "video/3gpp",
1356
+ "video/mpeg",
1324
1357
  "audio/mpeg",
1325
1358
  "audio/wav",
1326
- "audio/ogg"
1359
+ "audio/ogg",
1360
+ "audio/flac",
1361
+ "audio/aac",
1362
+ "audio/mp4",
1363
+ "audio/x-ms-wma",
1364
+ "audio/opus",
1365
+ "audio/webm"
1327
1366
  ];
1328
1367
  weight = 90;
1329
1368
  supports(file) {
@@ -1456,8 +1495,12 @@ var MediaPlugin = class {
1456
1495
  const video = document.createElement("video");
1457
1496
  video.src = url;
1458
1497
  video.controls = true;
1459
- video.style.maxWidth = "100%";
1460
- video.style.maxHeight = "100%";
1498
+ video.playsInline = true;
1499
+ video.style.maxWidth = "90%";
1500
+ video.style.maxHeight = "90%";
1501
+ video.style.borderRadius = "8px";
1502
+ video.style.boxShadow = "0 8px 30px rgba(0,0,0,0.3)";
1503
+ video.style.backgroundColor = "#000000";
1461
1504
  element = video;
1462
1505
  mediaElement = video;
1463
1506
  } else if (isAudio) {
@@ -1533,7 +1576,7 @@ function mediaPlugin() {
1533
1576
  }
1534
1577
  var DocxPlugin = class {
1535
1578
  id = "docx";
1536
- name = "Word Document Preview";
1579
+ name = "Word Document Preview (.docx, .docm, .dotx, .dotm)";
1537
1580
  extensions = [".docx", ".docm", ".dotx", ".dotm"];
1538
1581
  mimeTypes = [
1539
1582
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
@@ -1555,9 +1598,7 @@ var DocxPlugin = class {
1555
1598
  label: "Zoom Out",
1556
1599
  type: "button",
1557
1600
  group: "zoom",
1558
- execute: () => {
1559
- instance.zoomOut?.();
1560
- }
1601
+ execute: () => instance.zoomOut?.()
1561
1602
  },
1562
1603
  {
1563
1604
  id: "zoom-in",
@@ -1565,9 +1606,7 @@ var DocxPlugin = class {
1565
1606
  label: "Zoom In",
1566
1607
  type: "button",
1567
1608
  group: "zoom",
1568
- execute: () => {
1569
- instance.zoomIn?.();
1570
- }
1609
+ execute: () => instance.zoomIn?.()
1571
1610
  },
1572
1611
  {
1573
1612
  id: "fit-page",
@@ -1575,9 +1614,7 @@ var DocxPlugin = class {
1575
1614
  label: "Fit to Page",
1576
1615
  type: "button",
1577
1616
  group: "zoom",
1578
- execute: () => {
1579
- instance.fitToPage?.();
1580
- }
1617
+ execute: () => instance.fitToPage?.()
1581
1618
  },
1582
1619
  {
1583
1620
  id: "download",
@@ -1585,9 +1622,7 @@ var DocxPlugin = class {
1585
1622
  label: "Download",
1586
1623
  type: "button",
1587
1624
  group: "actions",
1588
- execute: () => {
1589
- instance.download?.();
1590
- }
1625
+ execute: () => instance.download?.()
1591
1626
  },
1592
1627
  {
1593
1628
  id: "print",
@@ -1595,9 +1630,7 @@ var DocxPlugin = class {
1595
1630
  label: "Print",
1596
1631
  type: "button",
1597
1632
  group: "actions",
1598
- execute: () => {
1599
- instance.print?.();
1600
- }
1633
+ execute: () => instance.print?.()
1601
1634
  }
1602
1635
  ];
1603
1636
  }
@@ -1606,24 +1639,46 @@ var DocxPlugin = class {
1606
1639
  wrapper.className = "fp-docx-wrapper";
1607
1640
  wrapper.style.transformOrigin = "top center";
1608
1641
  wrapper.style.transition = "transform 0.2s ease";
1609
- wrapper.style.padding = "16px";
1642
+ wrapper.style.padding = "24px 16px";
1643
+ wrapper.style.maxWidth = "900px";
1644
+ wrapper.style.margin = "0 auto";
1645
+ wrapper.style.boxSizing = "border-box";
1610
1646
  ctx.container.style.overflow = "auto";
1647
+ ctx.container.style.backgroundColor = "#f1f5f9";
1611
1648
  ctx.container.appendChild(wrapper);
1612
1649
  let scale = 1;
1650
+ let renderedSuccessfully = false;
1613
1651
  try {
1614
1652
  await docx__namespace.renderAsync(ctx.buffer, wrapper, ctx.container, {
1615
1653
  inWrapper: true,
1616
1654
  ignoreWidth: false,
1617
- ignoreHeight: false
1655
+ ignoreHeight: false,
1656
+ ignoreFonts: true,
1657
+ // Avoid crashes on embedded obfuscated fonts
1658
+ breakPages: true,
1659
+ experimental: true
1618
1660
  });
1619
- } catch {
1620
- wrapper.innerHTML = `
1621
- <div style="text-align:center; padding: 40px; color: #666;">
1622
- <div style="font-size:48px; margin-bottom: 16px;">\u{1F4C4}</div>
1623
- <h3>${ctx.metadata.name || "Word Document"}</h3>
1624
- <p>DOCX render preview</p>
1625
- </div>
1626
- `;
1661
+ if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
1662
+ renderedSuccessfully = true;
1663
+ }
1664
+ } catch (err) {
1665
+ console.warn("[DocxPlugin] docx-preview failed, triggering native XML fallback:", err);
1666
+ }
1667
+ if (!renderedSuccessfully) {
1668
+ try {
1669
+ wrapper.innerHTML = "";
1670
+ this.renderXmlFallback(ctx, wrapper);
1671
+ renderedSuccessfully = true;
1672
+ } catch (fallbackErr) {
1673
+ console.error("[DocxPlugin] XML fallback failed:", fallbackErr);
1674
+ wrapper.innerHTML = `
1675
+ <div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
1676
+ <div style="font-size:48px; margin-bottom: 16px;">\u{1F4C4}</div>
1677
+ <h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
1678
+ <p style="color: #64748b; margin: 0;">Could not parse document content</p>
1679
+ </div>
1680
+ `;
1681
+ }
1627
1682
  }
1628
1683
  const cleanup = () => {
1629
1684
  wrapper.remove();
@@ -1647,7 +1702,7 @@ var DocxPlugin = class {
1647
1702
  },
1648
1703
  fitToPage: () => {
1649
1704
  scale = 1;
1650
- wrapper.style.transform = `scale(1)`;
1705
+ wrapper.style.transform = "scale(1)";
1651
1706
  },
1652
1707
  download: () => {
1653
1708
  const blob = new Blob([ctx.buffer], { type: this.mimeTypes[0] });
@@ -1663,6 +1718,100 @@ var DocxPlugin = class {
1663
1718
  }
1664
1719
  };
1665
1720
  }
1721
+ renderXmlFallback(ctx, wrapper) {
1722
+ const unzipped = fflate.unzipSync(new Uint8Array(ctx.buffer));
1723
+ const docXmlEntry = unzipped["word/document.xml"];
1724
+ if (!docXmlEntry) throw new Error("Missing word/document.xml in DOCX package");
1725
+ const xmlStr = fflate.strFromU8(docXmlEntry);
1726
+ const parser = new DOMParser();
1727
+ const doc = parser.parseFromString(xmlStr, "application/xml");
1728
+ const card = document.createElement("div");
1729
+ card.className = "fp-docx-page-card";
1730
+ card.style.backgroundColor = "#ffffff";
1731
+ card.style.borderRadius = "6px";
1732
+ card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
1733
+ card.style.padding = "48px 56px";
1734
+ card.style.fontFamily = 'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
1735
+ card.style.color = "#1e293b";
1736
+ card.style.lineHeight = "1.6";
1737
+ const body = doc.getElementsByTagNameNS("*", "body")[0] || doc.documentElement;
1738
+ let html = "";
1739
+ for (const child of Array.from(body.children)) {
1740
+ const tag = child.localName || child.nodeName.split(":").pop();
1741
+ if (tag === "p") {
1742
+ const pStyle = child.getElementsByTagNameNS("*", "pStyle")[0];
1743
+ const styleVal = pStyle?.getAttribute("w:val") || pStyle?.getAttribute("val") || "";
1744
+ const numPr = child.getElementsByTagNameNS("*", "numPr")[0];
1745
+ const textContent = this.extractParagraphHtml(child);
1746
+ if (!textContent.trim()) {
1747
+ html += '<div style="height: 10px;"></div>';
1748
+ continue;
1749
+ }
1750
+ const lowerStyle = styleVal.toLowerCase();
1751
+ if (lowerStyle.includes("title")) {
1752
+ html += `<h1 style="font-size: 28px; font-weight: 700; color: #1e3a8a; margin: 24px 0 12px; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px;">${textContent}</h1>`;
1753
+ } else if (lowerStyle.includes("heading1") || styleVal === "1") {
1754
+ html += `<h2 style="font-size: 22px; font-weight: 700; color: #1e40af; margin: 20px 0 10px;">${textContent}</h2>`;
1755
+ } else if (lowerStyle.includes("heading2") || styleVal === "2") {
1756
+ html += `<h3 style="font-size: 18px; font-weight: 600; color: #2563eb; margin: 16px 0 8px;">${textContent}</h3>`;
1757
+ } else if (lowerStyle.includes("heading3") || styleVal === "3") {
1758
+ html += `<h4 style="font-size: 15px; font-weight: 600; color: #334155; margin: 12px 0 6px;">${textContent}</h4>`;
1759
+ } else if (numPr) {
1760
+ html += `<div style="display: flex; gap: 8px; margin: 4px 0 4px 20px;"><span style="color: #2563eb; font-weight: bold;">\u2022</span><span>${textContent}</span></div>`;
1761
+ } else {
1762
+ html += `<p style="margin: 8px 0; font-size: 14px;">${textContent}</p>`;
1763
+ }
1764
+ } else if (tag === "tbl") {
1765
+ html += '<table style="width: 100%; border-collapse: collapse; margin: 20px 0; border: 1px solid #cbd5e1;">';
1766
+ const rows = Array.from(child.getElementsByTagNameNS("*", "tr"));
1767
+ rows.forEach((tr, rIdx) => {
1768
+ html += `<tr style="${rIdx === 0 ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
1769
+ const cells = Array.from(tr.getElementsByTagNameNS("*", "tc"));
1770
+ cells.forEach((tc) => {
1771
+ const cellText = this.extractParagraphHtml(tc);
1772
+ html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px; font-size: 13px;">${cellText || "&nbsp;"}</td>`;
1773
+ });
1774
+ html += "</tr>";
1775
+ });
1776
+ html += "</table>";
1777
+ }
1778
+ }
1779
+ card.innerHTML = DOMPurify6__default.default.sanitize(html, {
1780
+ ADD_TAGS: ["h1", "h2", "h3", "h4", "p", "table", "tr", "td", "span", "b", "i", "u", "img", "div"],
1781
+ ADD_ATTR: ["style", "src", "alt", "colspan", "rowspan"]
1782
+ });
1783
+ wrapper.appendChild(card);
1784
+ }
1785
+ extractParagraphHtml(pElement) {
1786
+ let result = "";
1787
+ const runs = Array.from(pElement.getElementsByTagNameNS("*", "r"));
1788
+ if (runs.length === 0) {
1789
+ return DOMPurify6__default.default.sanitize(pElement.textContent || "");
1790
+ }
1791
+ for (const r of runs) {
1792
+ const rPr = r.getElementsByTagNameNS("*", "rPr")[0];
1793
+ const isBold = !!rPr?.getElementsByTagNameNS("*", "b")[0];
1794
+ const isItalic = !!rPr?.getElementsByTagNameNS("*", "i")[0];
1795
+ const isUnderline = !!rPr?.getElementsByTagNameNS("*", "u")[0];
1796
+ const colorNode = rPr?.getElementsByTagNameNS("*", "color")[0];
1797
+ const colorVal = colorNode?.getAttribute("w:val") || colorNode?.getAttribute("val");
1798
+ const texts = Array.from(r.getElementsByTagNameNS("*", "t"));
1799
+ let text = texts.map((t) => t.textContent || "").join("");
1800
+ if (!text) continue;
1801
+ text = DOMPurify6__default.default.sanitize(text);
1802
+ let styles = "";
1803
+ if (isBold) styles += "font-weight: bold; ";
1804
+ if (isItalic) styles += "font-style: italic; ";
1805
+ if (isUnderline) styles += "text-decoration: underline; ";
1806
+ if (colorVal && colorVal !== "auto") styles += `color: #${colorVal}; `;
1807
+ if (styles) {
1808
+ result += `<span style="${styles}">${text}</span>`;
1809
+ } else {
1810
+ result += text;
1811
+ }
1812
+ }
1813
+ return result;
1814
+ }
1666
1815
  };
1667
1816
  function docxPlugin() {
1668
1817
  return new DocxPlugin();
@@ -2474,7 +2623,7 @@ var MarkdownPlugin = class {
2474
2623
  gfm: true,
2475
2624
  breaks: true
2476
2625
  });
2477
- const cleanHtml = DOMPurify5__default.default.sanitize(rawHtml, {
2626
+ const cleanHtml = DOMPurify6__default.default.sanitize(rawHtml, {
2478
2627
  USE_PROFILES: { html: true }
2479
2628
  });
2480
2629
  const wrapper = document.createElement("div");
@@ -2638,35 +2787,27 @@ var PptxPlugin = class {
2638
2787
  group: "navigation",
2639
2788
  execute: () => instance.toggleThumbnails?.()
2640
2789
  },
2641
- {
2642
- id: "page-prev",
2643
- icon: "page-prev",
2644
- label: "Previous Slide",
2645
- type: "button",
2646
- group: "navigation",
2647
- execute: () => {
2648
- const cur = instance.getCurrentPage?.() ?? 1;
2649
- if (cur > 1) instance.goToPage?.(cur - 1);
2650
- }
2651
- },
2652
2790
  {
2653
2791
  id: "page-nav",
2654
2792
  icon: "",
2655
- label: "Slide Number",
2793
+ label: "Slide Navigation",
2656
2794
  type: "page-nav",
2657
2795
  group: "navigation",
2658
- execute: (page) => instance.goToPage?.(Number(page))
2659
- },
2660
- {
2661
- id: "page-next",
2662
- icon: "page-next",
2663
- label: "Next Slide",
2664
- type: "button",
2665
- group: "navigation",
2666
- execute: () => {
2667
- const cur = instance.getCurrentPage?.() ?? 1;
2668
- const total = instance.getPageCount?.() ?? 1;
2669
- if (cur < total) instance.goToPage?.(cur + 1);
2796
+ value: instance.getCurrentPage?.() ?? 1,
2797
+ max: instance.getPageCount?.() ?? 1,
2798
+ execute: (action, page) => {
2799
+ if (action === "prev") {
2800
+ const cur = instance.getCurrentPage?.() ?? 1;
2801
+ if (cur > 1) instance.goToPage?.(cur - 1);
2802
+ } else if (action === "next") {
2803
+ const cur = instance.getCurrentPage?.() ?? 1;
2804
+ const total = instance.getPageCount?.() ?? 1;
2805
+ if (cur < total) instance.goToPage?.(cur + 1);
2806
+ } else if (typeof page === "number") {
2807
+ instance.goToPage?.(page);
2808
+ } else if (typeof action === "number") {
2809
+ instance.goToPage?.(action);
2810
+ }
2670
2811
  }
2671
2812
  },
2672
2813
  {
@@ -3197,7 +3338,7 @@ var HtmlPreviewPlugin = class {
3197
3338
  }
3198
3339
  async render(ctx) {
3199
3340
  const rawHtml = new TextDecoder("utf-8").decode(ctx.buffer);
3200
- const sanitized = DOMPurify5__default.default.sanitize(rawHtml, {
3341
+ const sanitized = DOMPurify6__default.default.sanitize(rawHtml, {
3201
3342
  WHOLE_DOCUMENT: true,
3202
3343
  ADD_TAGS: ["style", "link"],
3203
3344
  ADD_ATTR: ["target", "rel"]
@@ -3292,35 +3433,27 @@ var OpenDocumentPlugin = class {
3292
3433
  group: "navigation",
3293
3434
  execute: () => instance.toggleThumbnails?.()
3294
3435
  },
3295
- {
3296
- id: "page-prev",
3297
- icon: "page-prev",
3298
- label: "Previous Slide",
3299
- type: "button",
3300
- group: "navigation",
3301
- execute: () => {
3302
- const cur = instance.getCurrentPage?.() ?? 1;
3303
- if (cur > 1) instance.goToPage?.(cur - 1);
3304
- }
3305
- },
3306
3436
  {
3307
3437
  id: "page-nav",
3308
3438
  icon: "",
3309
- label: "Slide Number",
3439
+ label: "Slide Navigation",
3310
3440
  type: "page-nav",
3311
3441
  group: "navigation",
3312
- execute: (p) => instance.goToPage?.(Number(p))
3313
- },
3314
- {
3315
- id: "page-next",
3316
- icon: "page-next",
3317
- label: "Next Slide",
3318
- type: "button",
3319
- group: "navigation",
3320
- execute: () => {
3321
- const cur = instance.getCurrentPage?.() ?? 1;
3322
- const total = instance.getPageCount?.() ?? 1;
3323
- if (cur < total) instance.goToPage?.(cur + 1);
3442
+ value: instance.getCurrentPage?.() ?? 1,
3443
+ max: instance.getPageCount?.() ?? 1,
3444
+ execute: (action, page) => {
3445
+ if (action === "prev") {
3446
+ const cur = instance.getCurrentPage?.() ?? 1;
3447
+ if (cur > 1) instance.goToPage?.(cur - 1);
3448
+ } else if (action === "next") {
3449
+ const cur = instance.getCurrentPage?.() ?? 1;
3450
+ const total = instance.getPageCount?.() ?? 1;
3451
+ if (cur < total) instance.goToPage?.(cur + 1);
3452
+ } else if (typeof page === "number") {
3453
+ instance.goToPage?.(page);
3454
+ } else if (typeof action === "number") {
3455
+ instance.goToPage?.(action);
3456
+ }
3324
3457
  }
3325
3458
  }
3326
3459
  );
@@ -3448,7 +3581,7 @@ var OpenDocumentPlugin = class {
3448
3581
  wrapper.style.padding = "48px";
3449
3582
  wrapper.style.minHeight = "100%";
3450
3583
  const bodyHtml = this.renderOdfBody(contentDoc, styleMap, imageUrls);
3451
- wrapper.innerHTML = DOMPurify5__default.default.sanitize(bodyHtml, {
3584
+ wrapper.innerHTML = DOMPurify6__default.default.sanitize(bodyHtml, {
3452
3585
  ADD_TAGS: ["math", "semantics", "mrow", "mi", "mo", "mn", "msup", "msub"],
3453
3586
  ADD_ATTR: ["style", "colspan", "rowspan"]
3454
3587
  });
@@ -3968,24 +4101,24 @@ var DocPlugin = class {
3968
4101
  html += "</ul>";
3969
4102
  inList = false;
3970
4103
  }
3971
- html += `<h2 style="font-size: 18px; font-weight: 700; color: #1e3a8a; margin: 20px 0 8px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px;">${DOMPurify5__default.default.sanitize(line)}</h2>`;
4104
+ html += `<h2 style="font-size: 18px; font-weight: 700; color: #1e3a8a; margin: 20px 0 8px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px;">${DOMPurify6__default.default.sanitize(line)}</h2>`;
3972
4105
  } else if (line.startsWith("\u2022") || line.startsWith("-") || line.startsWith("*")) {
3973
4106
  if (!inList) {
3974
4107
  html += '<ul style="margin: 8px 0; padding-left: 24px;">';
3975
4108
  inList = true;
3976
4109
  }
3977
4110
  const bulletText = line.replace(/^[•\-\*]\s*/, "");
3978
- html += `<li style="margin: 4px 0; line-height: 1.6;">${DOMPurify5__default.default.sanitize(bulletText)}</li>`;
4111
+ html += `<li style="margin: 4px 0; line-height: 1.6;">${DOMPurify6__default.default.sanitize(bulletText)}</li>`;
3979
4112
  } else {
3980
4113
  if (inList) {
3981
4114
  html += "</ul>";
3982
4115
  inList = false;
3983
4116
  }
3984
- html += `<p style="line-height: 1.7; margin: 10px 0; font-size: 14px; text-align: justify;">${DOMPurify5__default.default.sanitize(line)}</p>`;
4117
+ html += `<p style="line-height: 1.7; margin: 10px 0; font-size: 14px; text-align: justify;">${DOMPurify6__default.default.sanitize(line)}</p>`;
3985
4118
  }
3986
4119
  }
3987
4120
  if (inList) html += "</ul>";
3988
- return html || `<p style="color: #64748b; font-style: italic;">(No readable text found in ${DOMPurify5__default.default.sanitize(filename)})</p>`;
4121
+ return html || `<p style="color: #64748b; font-style: italic;">(No readable text found in ${DOMPurify6__default.default.sanitize(filename)})</p>`;
3989
4122
  }
3990
4123
  };
3991
4124
  function docPlugin() {
@@ -4012,35 +4145,27 @@ var PptPlugin = class {
4012
4145
  group: "navigation",
4013
4146
  execute: () => instance.toggleThumbnails?.()
4014
4147
  },
4015
- {
4016
- id: "page-prev",
4017
- icon: "page-prev",
4018
- label: "Previous Slide",
4019
- type: "button",
4020
- group: "navigation",
4021
- execute: () => {
4022
- const cur = instance.getCurrentPage?.() ?? 1;
4023
- if (cur > 1) instance.goToPage?.(cur - 1);
4024
- }
4025
- },
4026
4148
  {
4027
4149
  id: "page-nav",
4028
4150
  icon: "",
4029
- label: "Slide Number",
4151
+ label: "Slide Navigation",
4030
4152
  type: "page-nav",
4031
4153
  group: "navigation",
4032
- execute: (p) => instance.goToPage?.(Number(p))
4033
- },
4034
- {
4035
- id: "page-next",
4036
- icon: "page-next",
4037
- label: "Next Slide",
4038
- type: "button",
4039
- group: "navigation",
4040
- execute: () => {
4041
- const cur = instance.getCurrentPage?.() ?? 1;
4042
- const total = instance.getPageCount?.() ?? 1;
4043
- if (cur < total) instance.goToPage?.(cur + 1);
4154
+ value: instance.getCurrentPage?.() ?? 1,
4155
+ max: instance.getPageCount?.() ?? 1,
4156
+ execute: (action, page) => {
4157
+ if (action === "prev") {
4158
+ const cur = instance.getCurrentPage?.() ?? 1;
4159
+ if (cur > 1) instance.goToPage?.(cur - 1);
4160
+ } else if (action === "next") {
4161
+ const cur = instance.getCurrentPage?.() ?? 1;
4162
+ const total = instance.getPageCount?.() ?? 1;
4163
+ if (cur < total) instance.goToPage?.(cur + 1);
4164
+ } else if (typeof page === "number") {
4165
+ instance.goToPage?.(page);
4166
+ } else if (typeof action === "number") {
4167
+ instance.goToPage?.(action);
4168
+ }
4044
4169
  }
4045
4170
  },
4046
4171
  {
@@ -4148,10 +4273,10 @@ var PptPlugin = class {
4148
4273
  </div>
4149
4274
  <div style="text-align: center; width: 100%;">
4150
4275
  <h1 style="font-size: ${idx === 1 ? "36px" : "28px"}; color: #1e3a8a; margin: 0 0 24px; font-family: -apple-system, BlinkMacSystemFont, sans-serif; font-weight: 700;">
4151
- ${DOMPurify5__default.default.sanitize(s.title || `Slide ${idx}`)}
4276
+ ${DOMPurify6__default.default.sanitize(s.title || `Slide ${idx}`)}
4152
4277
  </h1>
4153
4278
  <div style="display: flex; flex-direction: column; gap: 12px; max-width: 80%; margin: 0 auto; text-align: ${idx === 1 ? "center" : "left"};">
4154
- ${s.texts.map((t) => `<div style="font-size: 18px; color: #334155; line-height: 1.5; font-family: -apple-system, BlinkMacSystemFont, sans-serif;">${DOMPurify5__default.default.sanitize(t)}</div>`).join("")}
4279
+ ${s.texts.map((t) => `<div style="font-size: 18px; color: #334155; line-height: 1.5; font-family: -apple-system, BlinkMacSystemFont, sans-serif;">${DOMPurify6__default.default.sanitize(t)}</div>`).join("")}
4155
4280
  </div>
4156
4281
  </div>
4157
4282
  `;