@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/angular.cjs +252 -127
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.js +251 -126
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +253 -128
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +252 -127
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +252 -127
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +251 -126
- package/dist/react.js.map +1 -1
- package/dist/vue.cjs +252 -127
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +251 -126
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
() =>
|
|
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
|
-
() =>
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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.
|
|
1460
|
-
video.style.
|
|
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
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
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 =
|
|
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 || " "}</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 =
|
|
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
|
|
2793
|
+
label: "Slide Navigation",
|
|
2656
2794
|
type: "page-nav",
|
|
2657
2795
|
group: "navigation",
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
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 =
|
|
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
|
|
3439
|
+
label: "Slide Navigation",
|
|
3310
3440
|
type: "page-nav",
|
|
3311
3441
|
group: "navigation",
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
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 =
|
|
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;">${
|
|
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;">${
|
|
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;">${
|
|
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 ${
|
|
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
|
|
4151
|
+
label: "Slide Navigation",
|
|
4030
4152
|
type: "page-nav",
|
|
4031
4153
|
group: "navigation",
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
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
|
-
${
|
|
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;">${
|
|
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
|
`;
|