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