@files-preview-app/preview-file 1.2.2 → 1.2.3
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 +232 -28
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.js +231 -27
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +233 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +232 -28
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +232 -28
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +231 -27
- package/dist/react.js.map +1 -1
- package/dist/vue.cjs +232 -28
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +231 -27
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var DOMPurify2 = require('dompurify');
|
|
4
4
|
var docx = require('docx-preview');
|
|
5
5
|
var fflate = require('fflate');
|
|
6
6
|
var XLSX = require('xlsx');
|
|
@@ -33,7 +33,7 @@ function _interopNamespace(e) {
|
|
|
33
33
|
return Object.freeze(n);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
var
|
|
36
|
+
var DOMPurify2__default = /*#__PURE__*/_interopDefault(DOMPurify2);
|
|
37
37
|
var docx__namespace = /*#__PURE__*/_interopNamespace(docx);
|
|
38
38
|
var XLSX__namespace = /*#__PURE__*/_interopNamespace(XLSX);
|
|
39
39
|
var hljs__default = /*#__PURE__*/_interopDefault(hljs);
|
|
@@ -367,12 +367,12 @@ async function sourceToArrayBuffer(source, signal) {
|
|
|
367
367
|
return { buffer, metadata };
|
|
368
368
|
}
|
|
369
369
|
function sanitizeHTML(html) {
|
|
370
|
-
return
|
|
370
|
+
return DOMPurify2__default.default.sanitize(html, {
|
|
371
371
|
USE_PROFILES: { html: true }
|
|
372
372
|
});
|
|
373
373
|
}
|
|
374
374
|
function sanitizeSVG(svg) {
|
|
375
|
-
return
|
|
375
|
+
return DOMPurify2__default.default.sanitize(svg, {
|
|
376
376
|
USE_PROFILES: { svg: true, svgFilters: true }
|
|
377
377
|
});
|
|
378
378
|
}
|
|
@@ -471,6 +471,9 @@ var ICON_THUMBNAILS = `<svg width="24" height="24" viewBox="0 0 24 24" fill="non
|
|
|
471
471
|
var ICON_CLOSE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`;
|
|
472
472
|
var ICON_FULLSCREEN = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"></path></svg>`;
|
|
473
473
|
var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>`;
|
|
474
|
+
var ICON_FAST_FORWARD = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 19 22 12 13 5 13 19"></polygon><polygon points="2 19 11 12 2 5 2 19"></polygon></svg>`;
|
|
475
|
+
var ICON_REWIND = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 19 2 12 11 5 11 19"></polygon><polygon points="22 19 13 12 22 5 22 19"></polygon></svg>`;
|
|
476
|
+
var ICON_SPEED = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`;
|
|
474
477
|
var ICON_MAP = {
|
|
475
478
|
"zoom-in": ICON_ZOOM_IN,
|
|
476
479
|
"zoom-out": ICON_ZOOM_OUT,
|
|
@@ -491,7 +494,12 @@ var ICON_MAP = {
|
|
|
491
494
|
"page-prev": ICON_PAGE_PREV,
|
|
492
495
|
"page-next": ICON_PAGE_NEXT,
|
|
493
496
|
"chevron-left": ICON_PAGE_PREV,
|
|
494
|
-
"chevron-right": ICON_PAGE_NEXT
|
|
497
|
+
"chevron-right": ICON_PAGE_NEXT,
|
|
498
|
+
"fast-forward": ICON_FAST_FORWARD,
|
|
499
|
+
"forward-10": ICON_FAST_FORWARD,
|
|
500
|
+
"rewind": ICON_REWIND,
|
|
501
|
+
"replay-10": ICON_REWIND,
|
|
502
|
+
"speed": ICON_SPEED
|
|
495
503
|
};
|
|
496
504
|
var ToolbarController = class {
|
|
497
505
|
el;
|
|
@@ -1459,6 +1467,16 @@ var MediaPlugin = class {
|
|
|
1459
1467
|
}
|
|
1460
1468
|
if (instance.play) {
|
|
1461
1469
|
actions.push(
|
|
1470
|
+
{
|
|
1471
|
+
id: "replay-10",
|
|
1472
|
+
icon: "replay-10",
|
|
1473
|
+
label: "Rewind 10s",
|
|
1474
|
+
type: "button",
|
|
1475
|
+
group: "actions",
|
|
1476
|
+
execute: () => {
|
|
1477
|
+
instance.rewind?.(10);
|
|
1478
|
+
}
|
|
1479
|
+
},
|
|
1462
1480
|
{
|
|
1463
1481
|
id: "play",
|
|
1464
1482
|
icon: "play",
|
|
@@ -1478,6 +1496,26 @@ var MediaPlugin = class {
|
|
|
1478
1496
|
execute: () => {
|
|
1479
1497
|
instance.pause?.();
|
|
1480
1498
|
}
|
|
1499
|
+
},
|
|
1500
|
+
{
|
|
1501
|
+
id: "forward-10",
|
|
1502
|
+
icon: "forward-10",
|
|
1503
|
+
label: "Fast Forward 10s",
|
|
1504
|
+
type: "button",
|
|
1505
|
+
group: "actions",
|
|
1506
|
+
execute: () => {
|
|
1507
|
+
instance.fastForward?.(10);
|
|
1508
|
+
}
|
|
1509
|
+
},
|
|
1510
|
+
{
|
|
1511
|
+
id: "speed",
|
|
1512
|
+
icon: "speed",
|
|
1513
|
+
label: "Playback Speed",
|
|
1514
|
+
type: "button",
|
|
1515
|
+
group: "actions",
|
|
1516
|
+
execute: () => {
|
|
1517
|
+
instance.cycleSpeed?.();
|
|
1518
|
+
}
|
|
1481
1519
|
}
|
|
1482
1520
|
);
|
|
1483
1521
|
}
|
|
@@ -1600,6 +1638,28 @@ var MediaPlugin = class {
|
|
|
1600
1638
|
play: mediaElement ? () => mediaElement?.play() : void 0,
|
|
1601
1639
|
pause: mediaElement ? () => mediaElement?.pause() : void 0,
|
|
1602
1640
|
isPlaying: mediaElement ? () => !mediaElement?.paused : void 0,
|
|
1641
|
+
fastForward: mediaElement ? (seconds = 10) => {
|
|
1642
|
+
if (mediaElement) {
|
|
1643
|
+
mediaElement.currentTime = Math.min(mediaElement.duration || Infinity, mediaElement.currentTime + seconds);
|
|
1644
|
+
}
|
|
1645
|
+
} : void 0,
|
|
1646
|
+
rewind: mediaElement ? (seconds = 10) => {
|
|
1647
|
+
if (mediaElement) {
|
|
1648
|
+
mediaElement.currentTime = Math.max(0, mediaElement.currentTime - seconds);
|
|
1649
|
+
}
|
|
1650
|
+
} : void 0,
|
|
1651
|
+
cycleSpeed: mediaElement ? () => {
|
|
1652
|
+
if (mediaElement) {
|
|
1653
|
+
const speeds = [1, 1.25, 1.5, 2, 0.5];
|
|
1654
|
+
const curIndex = speeds.indexOf(mediaElement.playbackRate);
|
|
1655
|
+
const nextIndex = curIndex === -1 ? 0 : (curIndex + 1) % speeds.length;
|
|
1656
|
+
mediaElement.playbackRate = speeds[nextIndex];
|
|
1657
|
+
}
|
|
1658
|
+
} : void 0,
|
|
1659
|
+
setPlaybackRate: mediaElement ? (rate) => {
|
|
1660
|
+
if (mediaElement) mediaElement.playbackRate = rate;
|
|
1661
|
+
} : void 0,
|
|
1662
|
+
getPlaybackRate: mediaElement ? () => mediaElement?.playbackRate ?? 1 : void 0,
|
|
1603
1663
|
download: () => {
|
|
1604
1664
|
const a = document.createElement("a");
|
|
1605
1665
|
a.href = url;
|
|
@@ -1681,16 +1741,35 @@ var DocxPlugin = class {
|
|
|
1681
1741
|
wrapper.style.transformOrigin = "top center";
|
|
1682
1742
|
wrapper.style.transition = "transform 0.2s ease";
|
|
1683
1743
|
wrapper.style.padding = "24px 16px";
|
|
1684
|
-
wrapper.style.maxWidth = "
|
|
1744
|
+
wrapper.style.maxWidth = "950px";
|
|
1685
1745
|
wrapper.style.margin = "0 auto";
|
|
1686
1746
|
wrapper.style.boxSizing = "border-box";
|
|
1687
1747
|
ctx.container.style.overflow = "auto";
|
|
1688
1748
|
ctx.container.style.backgroundColor = "#f1f5f9";
|
|
1689
1749
|
ctx.container.appendChild(wrapper);
|
|
1750
|
+
const styleOverride = document.createElement("style");
|
|
1751
|
+
styleOverride.textContent = `
|
|
1752
|
+
.fp-docx-wrapper .docx-wrapper {
|
|
1753
|
+
background: transparent !important;
|
|
1754
|
+
padding: 0 !important;
|
|
1755
|
+
display: flex !important;
|
|
1756
|
+
flex-direction: column !important;
|
|
1757
|
+
align-items: center !important;
|
|
1758
|
+
box-sizing: border-box !important;
|
|
1759
|
+
}
|
|
1760
|
+
.fp-docx-wrapper section.docx {
|
|
1761
|
+
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08) !important;
|
|
1762
|
+
border-radius: 4px !important;
|
|
1763
|
+
margin-bottom: 24px !important;
|
|
1764
|
+
background-color: #ffffff !important;
|
|
1765
|
+
}
|
|
1766
|
+
`;
|
|
1767
|
+
ctx.container.appendChild(styleOverride);
|
|
1690
1768
|
let scale = 1;
|
|
1691
1769
|
let renderedSuccessfully = false;
|
|
1770
|
+
const createdBlobUrls = [];
|
|
1692
1771
|
try {
|
|
1693
|
-
await docx__namespace.renderAsync(ctx.buffer, wrapper,
|
|
1772
|
+
await docx__namespace.renderAsync(ctx.buffer, wrapper, wrapper, {
|
|
1694
1773
|
inWrapper: true,
|
|
1695
1774
|
ignoreWidth: false,
|
|
1696
1775
|
ignoreHeight: false,
|
|
@@ -1699,19 +1778,25 @@ var DocxPlugin = class {
|
|
|
1699
1778
|
breakPages: true,
|
|
1700
1779
|
experimental: true
|
|
1701
1780
|
});
|
|
1781
|
+
if (!ctx.container.contains(wrapper)) {
|
|
1782
|
+
ctx.container.appendChild(wrapper);
|
|
1783
|
+
}
|
|
1702
1784
|
if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
|
|
1703
1785
|
renderedSuccessfully = true;
|
|
1704
1786
|
}
|
|
1705
1787
|
} catch (err) {
|
|
1706
|
-
console.warn("[DocxPlugin] docx-preview failed, triggering native
|
|
1788
|
+
console.warn("[DocxPlugin] docx-preview failed, triggering native fallback:", err);
|
|
1707
1789
|
}
|
|
1708
1790
|
if (!renderedSuccessfully) {
|
|
1709
1791
|
try {
|
|
1710
1792
|
wrapper.innerHTML = "";
|
|
1711
|
-
this.renderXmlFallback(ctx, wrapper);
|
|
1793
|
+
this.renderXmlFallback(ctx, wrapper, createdBlobUrls);
|
|
1794
|
+
if (!ctx.container.contains(wrapper)) {
|
|
1795
|
+
ctx.container.appendChild(wrapper);
|
|
1796
|
+
}
|
|
1712
1797
|
renderedSuccessfully = true;
|
|
1713
1798
|
} catch (fallbackErr) {
|
|
1714
|
-
console.error("[DocxPlugin]
|
|
1799
|
+
console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
|
|
1715
1800
|
wrapper.innerHTML = `
|
|
1716
1801
|
<div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
|
|
1717
1802
|
<div style="font-size:48px; margin-bottom: 16px;">\u{1F4C4}</div>
|
|
@@ -1719,10 +1804,17 @@ var DocxPlugin = class {
|
|
|
1719
1804
|
<p style="color: #64748b; margin: 0;">Could not parse document content</p>
|
|
1720
1805
|
</div>
|
|
1721
1806
|
`;
|
|
1807
|
+
if (!ctx.container.contains(wrapper)) {
|
|
1808
|
+
ctx.container.appendChild(wrapper);
|
|
1809
|
+
}
|
|
1722
1810
|
}
|
|
1723
1811
|
}
|
|
1724
1812
|
const cleanup = () => {
|
|
1813
|
+
for (const url of createdBlobUrls) {
|
|
1814
|
+
URL.revokeObjectURL(url);
|
|
1815
|
+
}
|
|
1725
1816
|
wrapper.remove();
|
|
1817
|
+
styleOverride.remove();
|
|
1726
1818
|
ctx.container.innerHTML = "";
|
|
1727
1819
|
};
|
|
1728
1820
|
ctx.signal.addEventListener("abort", cleanup);
|
|
@@ -1759,13 +1851,50 @@ var DocxPlugin = class {
|
|
|
1759
1851
|
}
|
|
1760
1852
|
};
|
|
1761
1853
|
}
|
|
1762
|
-
renderXmlFallback(ctx, wrapper) {
|
|
1854
|
+
renderXmlFallback(ctx, wrapper, createdBlobUrls) {
|
|
1855
|
+
const magic = new Uint8Array(ctx.buffer.slice(0, 8));
|
|
1856
|
+
if (magic[0] === 208 && magic[1] === 207 && magic[2] === 17 && magic[3] === 224) {
|
|
1857
|
+
this.renderBinaryDocFallback(ctx, wrapper);
|
|
1858
|
+
return;
|
|
1859
|
+
}
|
|
1763
1860
|
const unzipped = fflate.unzipSync(new Uint8Array(ctx.buffer));
|
|
1764
|
-
const
|
|
1861
|
+
const docKey = Object.keys(unzipped).find((k) => k.replace(/^[./\\]+/, "").toLowerCase() === "word/document.xml");
|
|
1862
|
+
const docXmlEntry = docKey ? unzipped[docKey] : void 0;
|
|
1765
1863
|
if (!docXmlEntry) throw new Error("Missing word/document.xml in DOCX package");
|
|
1766
1864
|
const xmlStr = fflate.strFromU8(docXmlEntry);
|
|
1767
1865
|
const parser = new DOMParser();
|
|
1768
1866
|
const doc = parser.parseFromString(xmlStr, "application/xml");
|
|
1867
|
+
const imageMap = {};
|
|
1868
|
+
const relsKey = Object.keys(unzipped).find((k) => k.replace(/^[./\\]+/, "").toLowerCase() === "word/_rels/document.xml.rels");
|
|
1869
|
+
if (relsKey && unzipped[relsKey]) {
|
|
1870
|
+
try {
|
|
1871
|
+
const relsXml = fflate.strFromU8(unzipped[relsKey]);
|
|
1872
|
+
const relsDoc = parser.parseFromString(relsXml, "application/xml");
|
|
1873
|
+
const relEls = Array.from(relsDoc.getElementsByTagName("Relationship"));
|
|
1874
|
+
for (const rel of relEls) {
|
|
1875
|
+
const rId = rel.getAttribute("Id");
|
|
1876
|
+
const target = rel.getAttribute("Target");
|
|
1877
|
+
if (rId && target) {
|
|
1878
|
+
const cleanTarget = target.replace(/^\.\.\//, "").replace(/^\//, "");
|
|
1879
|
+
const fullTargetKey = Object.keys(unzipped).find((k) => {
|
|
1880
|
+
const norm = k.replace(/^[./\\]+/, "").toLowerCase();
|
|
1881
|
+
return norm === ("word/" + cleanTarget).toLowerCase() || norm === cleanTarget.toLowerCase();
|
|
1882
|
+
});
|
|
1883
|
+
if (fullTargetKey && unzipped[fullTargetKey]) {
|
|
1884
|
+
const bytes = unzipped[fullTargetKey];
|
|
1885
|
+
const ext = cleanTarget.split(".").pop()?.toLowerCase() || "png";
|
|
1886
|
+
const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "gif" ? "image/gif" : ext === "svg" ? "image/svg+xml" : "image/png";
|
|
1887
|
+
const blob = new Blob([bytes], { type: mime });
|
|
1888
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
1889
|
+
imageMap[rId] = blobUrl;
|
|
1890
|
+
createdBlobUrls.push(blobUrl);
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
} catch (relsErr) {
|
|
1895
|
+
console.warn("[DocxPlugin] Error parsing relationships:", relsErr);
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1769
1898
|
const card = document.createElement("div");
|
|
1770
1899
|
card.className = "fp-docx-page-card";
|
|
1771
1900
|
card.style.backgroundColor = "#ffffff";
|
|
@@ -1783,7 +1912,7 @@ var DocxPlugin = class {
|
|
|
1783
1912
|
const pStyle = child.getElementsByTagNameNS("*", "pStyle")[0];
|
|
1784
1913
|
const styleVal = pStyle?.getAttribute("w:val") || pStyle?.getAttribute("val") || "";
|
|
1785
1914
|
const numPr = child.getElementsByTagNameNS("*", "numPr")[0];
|
|
1786
|
-
const textContent = this.extractParagraphHtml(child);
|
|
1915
|
+
const textContent = this.extractParagraphHtml(child, imageMap);
|
|
1787
1916
|
if (!textContent.trim()) {
|
|
1788
1917
|
html += '<div style="height: 10px;"></div>';
|
|
1789
1918
|
continue;
|
|
@@ -1809,7 +1938,7 @@ var DocxPlugin = class {
|
|
|
1809
1938
|
html += `<tr style="${rIdx === 0 ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
|
|
1810
1939
|
const cells = Array.from(tr.getElementsByTagNameNS("*", "tc"));
|
|
1811
1940
|
cells.forEach((tc) => {
|
|
1812
|
-
const cellText = this.extractParagraphHtml(tc);
|
|
1941
|
+
const cellText = this.extractParagraphHtml(tc, imageMap);
|
|
1813
1942
|
html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px; font-size: 13px;">${cellText || " "}</td>`;
|
|
1814
1943
|
});
|
|
1815
1944
|
html += "</tr>";
|
|
@@ -1817,34 +1946,63 @@ var DocxPlugin = class {
|
|
|
1817
1946
|
html += "</table>";
|
|
1818
1947
|
}
|
|
1819
1948
|
}
|
|
1820
|
-
card.innerHTML =
|
|
1821
|
-
ADD_TAGS: ["h1", "h2", "h3", "h4", "p", "table", "tr", "td", "span", "b", "i", "u", "img", "div"],
|
|
1949
|
+
card.innerHTML = DOMPurify2__default.default.sanitize(html, {
|
|
1950
|
+
ADD_TAGS: ["h1", "h2", "h3", "h4", "p", "table", "tr", "td", "span", "b", "i", "u", "s", "strike", "img", "div", "br"],
|
|
1822
1951
|
ADD_ATTR: ["style", "src", "alt", "colspan", "rowspan"]
|
|
1823
1952
|
});
|
|
1824
1953
|
wrapper.appendChild(card);
|
|
1825
1954
|
}
|
|
1826
|
-
extractParagraphHtml(pElement) {
|
|
1955
|
+
extractParagraphHtml(pElement, imageMap = {}) {
|
|
1827
1956
|
let result = "";
|
|
1957
|
+
const drawings = Array.from(pElement.getElementsByTagNameNS("*", "drawing"));
|
|
1958
|
+
for (const drawing of drawings) {
|
|
1959
|
+
const blip = drawing.getElementsByTagNameNS("*", "blip")[0];
|
|
1960
|
+
const rId = blip?.getAttribute("r:embed") || blip?.getAttribute("r:id");
|
|
1961
|
+
if (rId && imageMap[rId]) {
|
|
1962
|
+
result += `<div style="text-align:center; margin: 12px 0;"><img src="${imageMap[rId]}" style="max-width: 100%; height: auto; border-radius: 4px;" /></div>`;
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1828
1965
|
const runs = Array.from(pElement.getElementsByTagNameNS("*", "r"));
|
|
1829
|
-
if (runs.length === 0) {
|
|
1830
|
-
return
|
|
1966
|
+
if (runs.length === 0 && !result) {
|
|
1967
|
+
return DOMPurify2__default.default.sanitize(pElement.textContent || "");
|
|
1831
1968
|
}
|
|
1832
1969
|
for (const r of runs) {
|
|
1970
|
+
const blip = r.getElementsByTagNameNS("*", "blip")[0] || r.getElementsByTagNameNS("*", "imagedata")[0];
|
|
1971
|
+
const rId = blip?.getAttribute("r:embed") || blip?.getAttribute("r:id");
|
|
1972
|
+
if (rId && imageMap[rId]) {
|
|
1973
|
+
result += `<img src="${imageMap[rId]}" style="max-width: 100%; height: auto; display: inline-block; margin: 4px;" />`;
|
|
1974
|
+
}
|
|
1975
|
+
const brs = r.getElementsByTagNameNS("*", "br");
|
|
1976
|
+
for (let i = 0; i < brs.length; i++) {
|
|
1977
|
+
result += "<br/>";
|
|
1978
|
+
}
|
|
1979
|
+
const tabs = r.getElementsByTagNameNS("*", "tab");
|
|
1980
|
+
if (tabs.length > 0) {
|
|
1981
|
+
result += " ";
|
|
1982
|
+
}
|
|
1833
1983
|
const rPr = r.getElementsByTagNameNS("*", "rPr")[0];
|
|
1834
1984
|
const isBold = !!rPr?.getElementsByTagNameNS("*", "b")[0];
|
|
1835
1985
|
const isItalic = !!rPr?.getElementsByTagNameNS("*", "i")[0];
|
|
1836
1986
|
const isUnderline = !!rPr?.getElementsByTagNameNS("*", "u")[0];
|
|
1987
|
+
const isStrike = !!rPr?.getElementsByTagNameNS("*", "strike")[0];
|
|
1837
1988
|
const colorNode = rPr?.getElementsByTagNameNS("*", "color")[0];
|
|
1838
1989
|
const colorVal = colorNode?.getAttribute("w:val") || colorNode?.getAttribute("val");
|
|
1990
|
+
const szNode = rPr?.getElementsByTagNameNS("*", "sz")[0];
|
|
1991
|
+
const szVal = szNode?.getAttribute("w:val") || szNode?.getAttribute("val");
|
|
1839
1992
|
const texts = Array.from(r.getElementsByTagNameNS("*", "t"));
|
|
1840
1993
|
let text = texts.map((t) => t.textContent || "").join("");
|
|
1841
1994
|
if (!text) continue;
|
|
1842
|
-
text =
|
|
1995
|
+
text = DOMPurify2__default.default.sanitize(text);
|
|
1843
1996
|
let styles = "";
|
|
1844
1997
|
if (isBold) styles += "font-weight: bold; ";
|
|
1845
1998
|
if (isItalic) styles += "font-style: italic; ";
|
|
1846
1999
|
if (isUnderline) styles += "text-decoration: underline; ";
|
|
2000
|
+
if (isStrike) styles += "text-decoration: line-through; ";
|
|
1847
2001
|
if (colorVal && colorVal !== "auto") styles += `color: #${colorVal}; `;
|
|
2002
|
+
if (szVal) {
|
|
2003
|
+
const pt = parseInt(szVal, 10) / 2;
|
|
2004
|
+
if (!isNaN(pt) && pt > 0) styles += `font-size: ${pt}pt; `;
|
|
2005
|
+
}
|
|
1848
2006
|
if (styles) {
|
|
1849
2007
|
result += `<span style="${styles}">${text}</span>`;
|
|
1850
2008
|
} else {
|
|
@@ -1853,6 +2011,52 @@ var DocxPlugin = class {
|
|
|
1853
2011
|
}
|
|
1854
2012
|
return result;
|
|
1855
2013
|
}
|
|
2014
|
+
renderBinaryDocFallback(ctx, wrapper) {
|
|
2015
|
+
const card = document.createElement("div");
|
|
2016
|
+
card.className = "fp-docx-page-card";
|
|
2017
|
+
card.style.backgroundColor = "#ffffff";
|
|
2018
|
+
card.style.borderRadius = "6px";
|
|
2019
|
+
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
2020
|
+
card.style.padding = "48px 56px";
|
|
2021
|
+
card.style.fontFamily = 'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
2022
|
+
card.style.color = "#1e293b";
|
|
2023
|
+
card.style.lineHeight = "1.6";
|
|
2024
|
+
try {
|
|
2025
|
+
const cfbf = new CfbfReader(ctx.buffer);
|
|
2026
|
+
const wordDocStream = cfbf.readStream("WordDocument");
|
|
2027
|
+
if (wordDocStream && wordDocStream.length >= 512) {
|
|
2028
|
+
const text2 = this.extractReadableStrings(wordDocStream);
|
|
2029
|
+
card.innerHTML = `<div style="white-space: pre-wrap;">${DOMPurify2__default.default.sanitize(text2)}</div>`;
|
|
2030
|
+
wrapper.appendChild(card);
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
} catch {
|
|
2034
|
+
}
|
|
2035
|
+
const text = this.extractReadableStrings(new Uint8Array(ctx.buffer));
|
|
2036
|
+
card.innerHTML = `<div style="white-space: pre-wrap;">${DOMPurify2__default.default.sanitize(text)}</div>`;
|
|
2037
|
+
wrapper.appendChild(card);
|
|
2038
|
+
}
|
|
2039
|
+
extractReadableStrings(bytes) {
|
|
2040
|
+
let result = "";
|
|
2041
|
+
let current = "";
|
|
2042
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
2043
|
+
const b = bytes[i];
|
|
2044
|
+
if (b >= 32 && b <= 126 || b === 10 || b === 13 || b === 9) {
|
|
2045
|
+
current += String.fromCharCode(b);
|
|
2046
|
+
} else if (b === 0 && i + 1 < bytes.length && bytes[i + 1] >= 32 && bytes[i + 1] <= 126) {
|
|
2047
|
+
continue;
|
|
2048
|
+
} else {
|
|
2049
|
+
if (current.trim().length > 3) {
|
|
2050
|
+
result += current.trim() + "\n\n";
|
|
2051
|
+
}
|
|
2052
|
+
current = "";
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
if (current.trim().length > 3) {
|
|
2056
|
+
result += current.trim();
|
|
2057
|
+
}
|
|
2058
|
+
return result;
|
|
2059
|
+
}
|
|
1856
2060
|
};
|
|
1857
2061
|
function docxPlugin() {
|
|
1858
2062
|
return new DocxPlugin();
|
|
@@ -2664,7 +2868,7 @@ var MarkdownPlugin = class {
|
|
|
2664
2868
|
gfm: true,
|
|
2665
2869
|
breaks: true
|
|
2666
2870
|
});
|
|
2667
|
-
const cleanHtml =
|
|
2871
|
+
const cleanHtml = DOMPurify2__default.default.sanitize(rawHtml, {
|
|
2668
2872
|
USE_PROFILES: { html: true }
|
|
2669
2873
|
});
|
|
2670
2874
|
const wrapper = document.createElement("div");
|
|
@@ -3379,7 +3583,7 @@ var HtmlPreviewPlugin = class {
|
|
|
3379
3583
|
}
|
|
3380
3584
|
async render(ctx) {
|
|
3381
3585
|
const rawHtml = new TextDecoder("utf-8").decode(ctx.buffer);
|
|
3382
|
-
const sanitized =
|
|
3586
|
+
const sanitized = DOMPurify2__default.default.sanitize(rawHtml, {
|
|
3383
3587
|
WHOLE_DOCUMENT: true,
|
|
3384
3588
|
ADD_TAGS: ["style", "link"],
|
|
3385
3589
|
ADD_ATTR: ["target", "rel"]
|
|
@@ -3622,7 +3826,7 @@ var OpenDocumentPlugin = class {
|
|
|
3622
3826
|
wrapper.style.padding = "48px";
|
|
3623
3827
|
wrapper.style.minHeight = "100%";
|
|
3624
3828
|
const bodyHtml = this.renderOdfBody(contentDoc, styleMap, imageUrls);
|
|
3625
|
-
wrapper.innerHTML =
|
|
3829
|
+
wrapper.innerHTML = DOMPurify2__default.default.sanitize(bodyHtml, {
|
|
3626
3830
|
ADD_TAGS: ["math", "semantics", "mrow", "mi", "mo", "mn", "msup", "msub"],
|
|
3627
3831
|
ADD_ATTR: ["style", "colspan", "rowspan"]
|
|
3628
3832
|
});
|
|
@@ -4142,24 +4346,24 @@ var DocPlugin = class {
|
|
|
4142
4346
|
html += "</ul>";
|
|
4143
4347
|
inList = false;
|
|
4144
4348
|
}
|
|
4145
|
-
html += `<h2 style="font-size: 18px; font-weight: 700; color: #1e3a8a; margin: 20px 0 8px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px;">${
|
|
4349
|
+
html += `<h2 style="font-size: 18px; font-weight: 700; color: #1e3a8a; margin: 20px 0 8px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px;">${DOMPurify2__default.default.sanitize(line)}</h2>`;
|
|
4146
4350
|
} else if (line.startsWith("\u2022") || line.startsWith("-") || line.startsWith("*")) {
|
|
4147
4351
|
if (!inList) {
|
|
4148
4352
|
html += '<ul style="margin: 8px 0; padding-left: 24px;">';
|
|
4149
4353
|
inList = true;
|
|
4150
4354
|
}
|
|
4151
4355
|
const bulletText = line.replace(/^[•\-\*]\s*/, "");
|
|
4152
|
-
html += `<li style="margin: 4px 0; line-height: 1.6;">${
|
|
4356
|
+
html += `<li style="margin: 4px 0; line-height: 1.6;">${DOMPurify2__default.default.sanitize(bulletText)}</li>`;
|
|
4153
4357
|
} else {
|
|
4154
4358
|
if (inList) {
|
|
4155
4359
|
html += "</ul>";
|
|
4156
4360
|
inList = false;
|
|
4157
4361
|
}
|
|
4158
|
-
html += `<p style="line-height: 1.7; margin: 10px 0; font-size: 14px; text-align: justify;">${
|
|
4362
|
+
html += `<p style="line-height: 1.7; margin: 10px 0; font-size: 14px; text-align: justify;">${DOMPurify2__default.default.sanitize(line)}</p>`;
|
|
4159
4363
|
}
|
|
4160
4364
|
}
|
|
4161
4365
|
if (inList) html += "</ul>";
|
|
4162
|
-
return html || `<p style="color: #64748b; font-style: italic;">(No readable text found in ${
|
|
4366
|
+
return html || `<p style="color: #64748b; font-style: italic;">(No readable text found in ${DOMPurify2__default.default.sanitize(filename)})</p>`;
|
|
4163
4367
|
}
|
|
4164
4368
|
};
|
|
4165
4369
|
function docPlugin() {
|
|
@@ -4314,10 +4518,10 @@ var PptPlugin = class {
|
|
|
4314
4518
|
</div>
|
|
4315
4519
|
<div style="text-align: center; width: 100%;">
|
|
4316
4520
|
<h1 style="font-size: ${idx === 1 ? "36px" : "28px"}; color: #1e3a8a; margin: 0 0 24px; font-family: -apple-system, BlinkMacSystemFont, sans-serif; font-weight: 700;">
|
|
4317
|
-
${
|
|
4521
|
+
${DOMPurify2__default.default.sanitize(s.title || `Slide ${idx}`)}
|
|
4318
4522
|
</h1>
|
|
4319
4523
|
<div style="display: flex; flex-direction: column; gap: 12px; max-width: 80%; margin: 0 auto; text-align: ${idx === 1 ? "center" : "left"};">
|
|
4320
|
-
${s.texts.map((t) => `<div style="font-size: 18px; color: #334155; line-height: 1.5; font-family: -apple-system, BlinkMacSystemFont, sans-serif;">${
|
|
4524
|
+
${s.texts.map((t) => `<div style="font-size: 18px; color: #334155; line-height: 1.5; font-family: -apple-system, BlinkMacSystemFont, sans-serif;">${DOMPurify2__default.default.sanitize(t)}</div>`).join("")}
|
|
4321
4525
|
</div>
|
|
4322
4526
|
</div>
|
|
4323
4527
|
`;
|