@files-preview-app/preview-file 1.2.7 → 1.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/angular.cjs +269 -90
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.js +269 -90
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +269 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +269 -90
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +269 -90
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +269 -90
- package/dist/react.js.map +1 -1
- package/dist/vue.cjs +269 -90
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +269 -90
- package/dist/vue.js.map +1 -1
- package/package.json +169 -179
package/dist/index.js
CHANGED
|
@@ -476,7 +476,8 @@ function createElement(tag, attrs, ...children) {
|
|
|
476
476
|
}
|
|
477
477
|
var ICON_ZOOM_IN = `<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="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
|
|
478
478
|
var ICON_ZOOM_OUT = `<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="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
|
|
479
|
-
var ICON_FIT_PAGE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><
|
|
479
|
+
var ICON_FIT_PAGE = `<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="3" y="3" width="18" height="18" rx="2"></rect><line x1="8" y1="12" x2="16" y2="12"></line><polyline points="11 9 8 12 11 15"></polyline><polyline points="13 9 16 12 13 15"></polyline></svg>`;
|
|
480
|
+
var ICON_FIT_WIDTH = `<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="2" y1="12" x2="22" y2="12"></line><polyline points="5 9 2 12 5 15"></polyline><polyline points="19 9 22 12 19 15"></polyline><line x1="2" y1="5" x2="2" y2="19"></line><line x1="22" y1="5" x2="22" y2="19"></line></svg>`;
|
|
480
481
|
var ICON_ROTATE_CW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>`;
|
|
481
482
|
var ICON_ROTATE_CCW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg>`;
|
|
482
483
|
var ICON_DOWNLOAD = `<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="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>`;
|
|
@@ -496,6 +497,7 @@ var ICON_MAP = {
|
|
|
496
497
|
"zoom-in": ICON_ZOOM_IN,
|
|
497
498
|
"zoom-out": ICON_ZOOM_OUT,
|
|
498
499
|
"fit-page": ICON_FIT_PAGE,
|
|
500
|
+
"fit-width": ICON_FIT_WIDTH,
|
|
499
501
|
"fit-slide": ICON_FIT_PAGE,
|
|
500
502
|
"rotate-cw": ICON_ROTATE_CW,
|
|
501
503
|
"rotate-ccw": ICON_ROTATE_CCW,
|
|
@@ -1442,6 +1444,7 @@ var PdfPlugin = class {
|
|
|
1442
1444
|
let currentPage = 1;
|
|
1443
1445
|
let zoomScale = 1;
|
|
1444
1446
|
let rotation = 0;
|
|
1447
|
+
let fitMode = "width";
|
|
1445
1448
|
let currentRenderTask = null;
|
|
1446
1449
|
const renderPage = async (pageNum) => {
|
|
1447
1450
|
if (currentRenderTask) {
|
|
@@ -1461,11 +1464,16 @@ var PdfPlugin = class {
|
|
|
1461
1464
|
const containerWidth = container.clientWidth || 900;
|
|
1462
1465
|
const containerHeight = container.clientHeight || 700;
|
|
1463
1466
|
const unscaledVp = page.getViewport({ scale: 1, rotation });
|
|
1464
|
-
const availWidth = Math.max(
|
|
1465
|
-
const availHeight = Math.max(
|
|
1467
|
+
const availWidth = Math.max(280, containerWidth - 48);
|
|
1468
|
+
const availHeight = Math.max(280, containerHeight - 88);
|
|
1466
1469
|
const scaleW = availWidth / unscaledVp.width;
|
|
1467
1470
|
const scaleH = availHeight / unscaledVp.height;
|
|
1468
|
-
|
|
1471
|
+
let fitScale;
|
|
1472
|
+
if (fitMode === "page") {
|
|
1473
|
+
fitScale = Math.max(0.5, Math.min(scaleW, scaleH));
|
|
1474
|
+
} else {
|
|
1475
|
+
fitScale = Math.max(0.65, Math.min(1.15, scaleW));
|
|
1476
|
+
}
|
|
1469
1477
|
const effectiveScale = (fitScale > 0 ? fitScale : 1) * zoomScale;
|
|
1470
1478
|
const pixelRatio = window.devicePixelRatio || 1;
|
|
1471
1479
|
const viewport = page.getViewport({ scale: effectiveScale, rotation });
|
|
@@ -1534,6 +1542,7 @@ var PdfPlugin = class {
|
|
|
1534
1542
|
renderPage(currentPage);
|
|
1535
1543
|
},
|
|
1536
1544
|
fitToPage: () => {
|
|
1545
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
1537
1546
|
zoomScale = 1;
|
|
1538
1547
|
rotation = 0;
|
|
1539
1548
|
renderPage(currentPage);
|
|
@@ -1550,6 +1559,7 @@ var PdfPlugin = class {
|
|
|
1550
1559
|
getPageCount: () => totalPages,
|
|
1551
1560
|
getCurrentPage: () => currentPage,
|
|
1552
1561
|
goToPage: (page) => {
|
|
1562
|
+
container.scrollTop = 0;
|
|
1553
1563
|
renderPage(page);
|
|
1554
1564
|
},
|
|
1555
1565
|
download: () => {
|
|
@@ -2054,7 +2064,14 @@ var DocxPlugin = class {
|
|
|
2054
2064
|
ignoreFonts: true,
|
|
2055
2065
|
// Avoid crashes on embedded obfuscated fonts
|
|
2056
2066
|
breakPages: true,
|
|
2057
|
-
experimental: true
|
|
2067
|
+
experimental: true,
|
|
2068
|
+
ignoreLastRenderedPageBreak: false,
|
|
2069
|
+
// Honor Word's exact page breaks!
|
|
2070
|
+
renderHeaders: true,
|
|
2071
|
+
renderFooters: true,
|
|
2072
|
+
renderFootnotes: true,
|
|
2073
|
+
renderEndnotes: true,
|
|
2074
|
+
useBase64URL: true
|
|
2058
2075
|
});
|
|
2059
2076
|
if (!ctx.container.contains(wrapper)) {
|
|
2060
2077
|
ctx.container.appendChild(wrapper);
|
|
@@ -2075,11 +2092,14 @@ var DocxPlugin = class {
|
|
|
2075
2092
|
renderedSuccessfully = true;
|
|
2076
2093
|
} catch (fallbackErr) {
|
|
2077
2094
|
console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
|
|
2095
|
+
const isCorrupt = fallbackErr?.message?.includes("invalid zip") || fallbackErr?.message?.includes("corrupted");
|
|
2078
2096
|
wrapper.innerHTML = `
|
|
2079
|
-
<div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
|
|
2080
|
-
<div style="font-size:48px; margin-bottom: 16px;"
|
|
2081
|
-
<h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
|
|
2082
|
-
<p style="color: #64748b; margin: 0;
|
|
2097
|
+
<div style="text-align:center; padding: 48px 32px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06); max-width: 600px; margin: 40px auto;">
|
|
2098
|
+
<div style="font-size:48px; margin-bottom: 16px;">${isCorrupt ? "\u26A0\uFE0F" : "\u{1F4C4}"}</div>
|
|
2099
|
+
<h3 style="margin: 0 0 8px; color: #1e293b; font-size: 18px;">${ctx.metadata.name || "Word Document"}</h3>
|
|
2100
|
+
<p style="color: #64748b; margin: 0 0 16px; font-size: 14px; line-height: 1.5;">
|
|
2101
|
+
${isCorrupt ? "This document appears to be corrupted or contains invalid archive data and cannot be opened (matches Microsoft Word on Windows)." : "Could not render document content. The file structure may be damaged."}
|
|
2102
|
+
</p>
|
|
2083
2103
|
</div>
|
|
2084
2104
|
`;
|
|
2085
2105
|
if (!ctx.container.contains(wrapper)) {
|
|
@@ -2087,8 +2107,67 @@ var DocxPlugin = class {
|
|
|
2087
2107
|
}
|
|
2088
2108
|
}
|
|
2089
2109
|
}
|
|
2090
|
-
|
|
2091
|
-
const cards = wrapper.querySelectorAll(".fp-docx-page-card");
|
|
2110
|
+
let sections = Array.from(wrapper.querySelectorAll("section.docx"));
|
|
2111
|
+
const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
|
|
2112
|
+
if (sections.length === 1 && cards.length === 0) {
|
|
2113
|
+
const singleSec = sections[0];
|
|
2114
|
+
const contentContainer = singleSec.querySelector("article") || singleSec;
|
|
2115
|
+
const children = Array.from(contentContainer.children);
|
|
2116
|
+
const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
|
|
2117
|
+
const secH = singleSec.offsetHeight || singleSec.scrollHeight;
|
|
2118
|
+
if (secH > pageH * 1.25 && children.length > 1) {
|
|
2119
|
+
const childHeights = children.map((c) => {
|
|
2120
|
+
const rectH = c.getBoundingClientRect().height;
|
|
2121
|
+
const offH = c.offsetHeight;
|
|
2122
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
2123
|
+
const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
|
|
2124
|
+
return Math.max(rectH, offH, estH);
|
|
2125
|
+
});
|
|
2126
|
+
const parent = singleSec.parentElement || wrapper;
|
|
2127
|
+
const newSections = [singleSec];
|
|
2128
|
+
const headerEl = singleSec.querySelector("header");
|
|
2129
|
+
const footerEl = singleSec.querySelector("footer");
|
|
2130
|
+
contentContainer.innerHTML = "";
|
|
2131
|
+
singleSec.style.minHeight = `${pageH}px`;
|
|
2132
|
+
singleSec.style.boxSizing = "border-box";
|
|
2133
|
+
let curContent = contentContainer;
|
|
2134
|
+
let curH = 0;
|
|
2135
|
+
const maxH = pageH - 140;
|
|
2136
|
+
for (let i = 0; i < children.length; i++) {
|
|
2137
|
+
const child = children[i];
|
|
2138
|
+
const chH = childHeights[i];
|
|
2139
|
+
curContent.appendChild(child);
|
|
2140
|
+
curH += chH;
|
|
2141
|
+
if (curH >= maxH && i < children.length - 1) {
|
|
2142
|
+
const nextSec = document.createElement("section");
|
|
2143
|
+
nextSec.className = singleSec.className;
|
|
2144
|
+
nextSec.style.cssText = singleSec.style.cssText;
|
|
2145
|
+
nextSec.style.minHeight = `${pageH}px`;
|
|
2146
|
+
nextSec.style.boxSizing = "border-box";
|
|
2147
|
+
nextSec.style.backgroundColor = "#ffffff";
|
|
2148
|
+
nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
|
|
2149
|
+
nextSec.style.borderRadius = "4px";
|
|
2150
|
+
nextSec.style.marginBottom = "24px";
|
|
2151
|
+
if (headerEl) {
|
|
2152
|
+
nextSec.appendChild(headerEl.cloneNode(true));
|
|
2153
|
+
}
|
|
2154
|
+
const nextArticle = document.createElement("article");
|
|
2155
|
+
if (contentContainer.tagName.toLowerCase() === "article") {
|
|
2156
|
+
nextArticle.style.cssText = contentContainer.style.cssText;
|
|
2157
|
+
}
|
|
2158
|
+
nextSec.appendChild(nextArticle);
|
|
2159
|
+
if (footerEl) {
|
|
2160
|
+
nextSec.appendChild(footerEl.cloneNode(true));
|
|
2161
|
+
}
|
|
2162
|
+
parent.appendChild(nextSec);
|
|
2163
|
+
newSections.push(nextSec);
|
|
2164
|
+
curContent = nextArticle;
|
|
2165
|
+
curH = 0;
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
sections = newSections;
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2092
2171
|
const pageElements = sections.length > 0 ? sections : cards;
|
|
2093
2172
|
const totalPages = Math.max(1, pageElements.length);
|
|
2094
2173
|
let currentPage = 1;
|
|
@@ -2125,6 +2204,7 @@ var DocxPlugin = class {
|
|
|
2125
2204
|
if (indicator) {
|
|
2126
2205
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
2127
2206
|
}
|
|
2207
|
+
ctx.container.scrollTop = 0;
|
|
2128
2208
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
2129
2209
|
};
|
|
2130
2210
|
if (totalPages > 1) {
|
|
@@ -2132,22 +2212,27 @@ var DocxPlugin = class {
|
|
|
2132
2212
|
}
|
|
2133
2213
|
scale = 1;
|
|
2134
2214
|
let rotation = 0;
|
|
2135
|
-
|
|
2215
|
+
let fitMode = "width";
|
|
2216
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
2136
2217
|
const activeEl = pageElements[currentPage - 1] || wrapper.firstElementChild || wrapper;
|
|
2137
2218
|
const elW = activeEl.offsetWidth || 816;
|
|
2138
|
-
const
|
|
2139
|
-
const availW = Math.max(
|
|
2140
|
-
const availH = Math.max(
|
|
2219
|
+
const singlePageH = Math.min(activeEl.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
2220
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
2221
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
2141
2222
|
const sW = availW / elW;
|
|
2142
|
-
const sH = availH /
|
|
2143
|
-
|
|
2223
|
+
const sH = availH / singlePageH;
|
|
2224
|
+
if (mode === "page") {
|
|
2225
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
2226
|
+
}
|
|
2227
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
2144
2228
|
};
|
|
2145
2229
|
const applyTransform = () => {
|
|
2146
2230
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
2147
2231
|
wrapper.style.transformOrigin = "top center";
|
|
2148
2232
|
};
|
|
2149
2233
|
setTimeout(() => {
|
|
2150
|
-
|
|
2234
|
+
fitMode = "width";
|
|
2235
|
+
scale = calculateFitScale("width");
|
|
2151
2236
|
applyTransform();
|
|
2152
2237
|
}, 60);
|
|
2153
2238
|
const cleanup = () => {
|
|
@@ -2181,7 +2266,8 @@ var DocxPlugin = class {
|
|
|
2181
2266
|
applyTransform();
|
|
2182
2267
|
},
|
|
2183
2268
|
fitToPage: () => {
|
|
2184
|
-
|
|
2269
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
2270
|
+
scale = calculateFitScale(fitMode);
|
|
2185
2271
|
rotation = 0;
|
|
2186
2272
|
applyTransform();
|
|
2187
2273
|
},
|
|
@@ -2625,11 +2711,9 @@ var ExcelPlugin = class {
|
|
|
2625
2711
|
const calculateFitScale = () => {
|
|
2626
2712
|
const table = contentArea.querySelector("table");
|
|
2627
2713
|
if (!table) return 1;
|
|
2628
|
-
const availW = Math.max(
|
|
2629
|
-
const availH = Math.max(200, container.clientHeight - 80);
|
|
2714
|
+
const availW = Math.max(280, container.clientWidth - 48);
|
|
2630
2715
|
const tW = table.offsetWidth || 800;
|
|
2631
|
-
|
|
2632
|
-
return Math.min(1, Math.min(availW / tW, availH / tH));
|
|
2716
|
+
return Math.max(0.65, Math.min(1, availW / tW));
|
|
2633
2717
|
};
|
|
2634
2718
|
try {
|
|
2635
2719
|
wb = XLSX.read(new Uint8Array(ctx.buffer), { type: "array", cellDates: true });
|
|
@@ -3053,17 +3137,39 @@ var CodePlugin = class {
|
|
|
3053
3137
|
let rawPages = [];
|
|
3054
3138
|
if (isTxt) {
|
|
3055
3139
|
const explicitPages = fullText.split(/(?:\f|\x0C)/);
|
|
3140
|
+
const charsPerLine = 85;
|
|
3141
|
+
const maxVisualLines = 45;
|
|
3142
|
+
const charsPerPage = charsPerLine * maxVisualLines;
|
|
3056
3143
|
for (const ep of explicitPages) {
|
|
3057
3144
|
const lines = ep.split(/\r?\n/);
|
|
3058
3145
|
let currentChunk = [];
|
|
3146
|
+
let currentLines = 0;
|
|
3059
3147
|
for (let i = 0; i < lines.length; i++) {
|
|
3060
|
-
|
|
3061
|
-
|
|
3148
|
+
const line = lines[i];
|
|
3149
|
+
const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
|
|
3150
|
+
if (currentLines + vLines > maxVisualLines && currentChunk.length > 0) {
|
|
3062
3151
|
rawPages.push(currentChunk.join("\n"));
|
|
3063
3152
|
currentChunk = [];
|
|
3153
|
+
currentLines = 0;
|
|
3154
|
+
}
|
|
3155
|
+
if (vLines > maxVisualLines) {
|
|
3156
|
+
let remaining = line;
|
|
3157
|
+
while (remaining.length > charsPerPage) {
|
|
3158
|
+
let splitIdx = remaining.lastIndexOf(" ", charsPerPage);
|
|
3159
|
+
if (splitIdx < charsPerPage * 0.75) splitIdx = charsPerPage;
|
|
3160
|
+
rawPages.push(remaining.slice(0, splitIdx));
|
|
3161
|
+
remaining = remaining.slice(splitIdx).trimStart();
|
|
3162
|
+
}
|
|
3163
|
+
if (remaining.length > 0) {
|
|
3164
|
+
currentChunk.push(remaining);
|
|
3165
|
+
currentLines = Math.ceil(remaining.length / charsPerLine);
|
|
3166
|
+
}
|
|
3167
|
+
} else {
|
|
3168
|
+
currentChunk.push(line);
|
|
3169
|
+
currentLines += vLines;
|
|
3064
3170
|
}
|
|
3065
3171
|
}
|
|
3066
|
-
if (currentChunk.length > 0
|
|
3172
|
+
if (currentChunk.length > 0) {
|
|
3067
3173
|
rawPages.push(currentChunk.join("\n"));
|
|
3068
3174
|
}
|
|
3069
3175
|
}
|
|
@@ -3173,6 +3279,7 @@ var CodePlugin = class {
|
|
|
3173
3279
|
if (indicator) {
|
|
3174
3280
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
3175
3281
|
}
|
|
3282
|
+
container.scrollTop = 0;
|
|
3176
3283
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
3177
3284
|
};
|
|
3178
3285
|
if (totalPages > 1) {
|
|
@@ -3226,7 +3333,7 @@ var CodePlugin = class {
|
|
|
3226
3333
|
fitToPage: () => {
|
|
3227
3334
|
fontSize = 13;
|
|
3228
3335
|
rotation = 0;
|
|
3229
|
-
zoomLevel = 1;
|
|
3336
|
+
zoomLevel = isTxt ? Math.max(0.65, Math.min(1.05, (container.clientWidth - 48) / 816)) : 1;
|
|
3230
3337
|
updateTransform();
|
|
3231
3338
|
},
|
|
3232
3339
|
rotateCW: () => {
|
|
@@ -4208,20 +4315,27 @@ var RtfPlugin = class {
|
|
|
4208
4315
|
let scale = 1;
|
|
4209
4316
|
let rotation = 0;
|
|
4210
4317
|
let pageElements = [];
|
|
4211
|
-
|
|
4318
|
+
let fitMode = "width";
|
|
4319
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
4212
4320
|
const activeEl = pageElements[currentPage - 1] || wrapper;
|
|
4213
4321
|
const elW = activeEl.offsetWidth || 850;
|
|
4214
|
-
const
|
|
4215
|
-
const availW = Math.max(
|
|
4216
|
-
const availH = Math.max(
|
|
4217
|
-
|
|
4322
|
+
const singlePageH = Math.min(activeEl.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
4323
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
4324
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
4325
|
+
const sW = availW / elW;
|
|
4326
|
+
const sH = availH / singlePageH;
|
|
4327
|
+
if (mode === "page") {
|
|
4328
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
4329
|
+
}
|
|
4330
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
4218
4331
|
};
|
|
4219
4332
|
const applyTransform = () => {
|
|
4220
4333
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
4221
4334
|
wrapper.style.transformOrigin = "top center";
|
|
4222
4335
|
};
|
|
4223
4336
|
setTimeout(() => {
|
|
4224
|
-
|
|
4337
|
+
fitMode = "width";
|
|
4338
|
+
scale = calculateFitScale("width");
|
|
4225
4339
|
applyTransform();
|
|
4226
4340
|
}, 60);
|
|
4227
4341
|
try {
|
|
@@ -4230,11 +4344,60 @@ var RtfPlugin = class {
|
|
|
4230
4344
|
}
|
|
4231
4345
|
const doc = new RTFJS.Document(ctx.buffer, {});
|
|
4232
4346
|
const htmlElements = await doc.render();
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4347
|
+
if (htmlElements.length === 1) {
|
|
4348
|
+
const singleEl = htmlElements[0];
|
|
4349
|
+
wrapper.appendChild(singleEl);
|
|
4350
|
+
const children = Array.from(singleEl.children);
|
|
4351
|
+
const secH = singleEl.offsetHeight || singleEl.scrollHeight;
|
|
4352
|
+
if (secH > 1300 && children.length > 1) {
|
|
4353
|
+
const childHeights = children.map((c) => {
|
|
4354
|
+
const rectH = c.getBoundingClientRect().height;
|
|
4355
|
+
const offH = c.offsetHeight;
|
|
4356
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
4357
|
+
const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
|
|
4358
|
+
return Math.max(rectH, offH, estH);
|
|
4359
|
+
});
|
|
4360
|
+
wrapper.innerHTML = "";
|
|
4361
|
+
const createRtfCard = () => {
|
|
4362
|
+
const card = document.createElement("div");
|
|
4363
|
+
card.className = "fp-rtf-page-card";
|
|
4364
|
+
card.style.backgroundColor = "#ffffff";
|
|
4365
|
+
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
4366
|
+
card.style.borderRadius = "4px";
|
|
4367
|
+
card.style.padding = "72px 56px";
|
|
4368
|
+
card.style.width = "816px";
|
|
4369
|
+
card.style.minHeight = "1056px";
|
|
4370
|
+
card.style.boxSizing = "border-box";
|
|
4371
|
+
card.style.marginBottom = "24px";
|
|
4372
|
+
return card;
|
|
4373
|
+
};
|
|
4374
|
+
let curCard = createRtfCard();
|
|
4375
|
+
wrapper.appendChild(curCard);
|
|
4376
|
+
pageElements = [curCard];
|
|
4377
|
+
let curH = 0;
|
|
4378
|
+
const maxH = 920;
|
|
4379
|
+
for (let i = 0; i < children.length; i++) {
|
|
4380
|
+
const child = children[i];
|
|
4381
|
+
const chH = childHeights[i];
|
|
4382
|
+
curCard.appendChild(child);
|
|
4383
|
+
curH += chH;
|
|
4384
|
+
if (curH >= maxH && i < children.length - 1) {
|
|
4385
|
+
curCard = createRtfCard();
|
|
4386
|
+
wrapper.appendChild(curCard);
|
|
4387
|
+
pageElements.push(curCard);
|
|
4388
|
+
curH = 0;
|
|
4389
|
+
}
|
|
4390
|
+
}
|
|
4391
|
+
} else {
|
|
4392
|
+
pageElements = [singleEl];
|
|
4393
|
+
}
|
|
4394
|
+
} else {
|
|
4395
|
+
pageElements = htmlElements;
|
|
4396
|
+
for (let i = 0; i < htmlElements.length; i++) {
|
|
4397
|
+
const el = htmlElements[i];
|
|
4398
|
+
el.style.display = i === 0 ? "block" : "none";
|
|
4399
|
+
wrapper.appendChild(el);
|
|
4400
|
+
}
|
|
4238
4401
|
}
|
|
4239
4402
|
} catch (err) {
|
|
4240
4403
|
console.warn("[RtfPlugin] RTF render error, fallback text:", err);
|
|
@@ -4300,6 +4463,7 @@ var RtfPlugin = class {
|
|
|
4300
4463
|
if (indicator) {
|
|
4301
4464
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
4302
4465
|
}
|
|
4466
|
+
ctx.container.scrollTop = 0;
|
|
4303
4467
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
4304
4468
|
};
|
|
4305
4469
|
if (totalPages > 1) {
|
|
@@ -4330,7 +4494,8 @@ var RtfPlugin = class {
|
|
|
4330
4494
|
applyTransform();
|
|
4331
4495
|
},
|
|
4332
4496
|
fitToPage: () => {
|
|
4333
|
-
|
|
4497
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
4498
|
+
scale = calculateFitScale(fitMode);
|
|
4334
4499
|
rotation = 0;
|
|
4335
4500
|
applyTransform();
|
|
4336
4501
|
},
|
|
@@ -4649,19 +4814,29 @@ var OpenDocumentPlugin = class {
|
|
|
4649
4814
|
ctx.container.appendChild(container);
|
|
4650
4815
|
let scale = 1;
|
|
4651
4816
|
let rotation = 0;
|
|
4652
|
-
|
|
4817
|
+
let fitMode = "width";
|
|
4818
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
4653
4819
|
const elW = wrapper.offsetWidth || 850;
|
|
4654
|
-
const
|
|
4655
|
-
const availW = Math.max(
|
|
4656
|
-
const availH = Math.max(
|
|
4657
|
-
|
|
4820
|
+
const singlePageH = Math.min(wrapper.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
4821
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
4822
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
4823
|
+
const sW = availW / elW;
|
|
4824
|
+
const sH = availH / (isPresentation ? 540 : singlePageH);
|
|
4825
|
+
if (isPresentation) {
|
|
4826
|
+
return Math.min(1, Math.min(sW, sH));
|
|
4827
|
+
}
|
|
4828
|
+
if (mode === "page") {
|
|
4829
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
4830
|
+
}
|
|
4831
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
4658
4832
|
};
|
|
4659
4833
|
const applyTransform = () => {
|
|
4660
4834
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
4661
4835
|
wrapper.style.transformOrigin = "top center";
|
|
4662
4836
|
};
|
|
4663
4837
|
setTimeout(() => {
|
|
4664
|
-
|
|
4838
|
+
fitMode = "width";
|
|
4839
|
+
scale = calculateFitScale("width");
|
|
4665
4840
|
applyTransform();
|
|
4666
4841
|
}, 60);
|
|
4667
4842
|
let currentPage = 1;
|
|
@@ -4760,12 +4935,9 @@ var OpenDocumentPlugin = class {
|
|
|
4760
4935
|
page.style.backgroundColor = "#ffffff";
|
|
4761
4936
|
page.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
|
|
4762
4937
|
page.style.borderRadius = "4px";
|
|
4763
|
-
page.style.boxSizing = "border-box";
|
|
4764
4938
|
page.style.display = idx === 0 ? "block" : "none";
|
|
4765
|
-
page.style.
|
|
4766
|
-
page.style.
|
|
4767
|
-
page.style.left = "50%";
|
|
4768
|
-
page.style.transform = "translateX(-50%)";
|
|
4939
|
+
page.style.margin = "0 auto 24px";
|
|
4940
|
+
page.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
|
|
4769
4941
|
elements.forEach((el) => page.appendChild(el));
|
|
4770
4942
|
wrapper.appendChild(page);
|
|
4771
4943
|
slides.push(page);
|
|
@@ -4803,6 +4975,7 @@ var OpenDocumentPlugin = class {
|
|
|
4803
4975
|
if (indicator) {
|
|
4804
4976
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
4805
4977
|
}
|
|
4978
|
+
container.scrollTop = 0;
|
|
4806
4979
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
4807
4980
|
};
|
|
4808
4981
|
return {
|
|
@@ -4822,7 +4995,8 @@ var OpenDocumentPlugin = class {
|
|
|
4822
4995
|
applyTransform();
|
|
4823
4996
|
},
|
|
4824
4997
|
fitToPage: () => {
|
|
4825
|
-
|
|
4998
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
4999
|
+
scale = calculateFitScale(fitMode);
|
|
4826
5000
|
rotation = 0;
|
|
4827
5001
|
applyTransform();
|
|
4828
5002
|
},
|
|
@@ -5294,20 +5468,28 @@ var DocPlugin = class {
|
|
|
5294
5468
|
if (indicator) {
|
|
5295
5469
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
5296
5470
|
}
|
|
5471
|
+
container.scrollTop = 0;
|
|
5297
5472
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
5298
5473
|
};
|
|
5299
5474
|
if (totalPages > 1) {
|
|
5300
5475
|
showPage(1);
|
|
5301
5476
|
}
|
|
5302
|
-
|
|
5477
|
+
let fitMode = "width";
|
|
5478
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
5303
5479
|
const elW = 816;
|
|
5304
5480
|
const elH = 1056;
|
|
5305
|
-
const availW = Math.max(
|
|
5306
|
-
const availH = Math.max(
|
|
5307
|
-
|
|
5481
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
5482
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
5483
|
+
const sW = availW / elW;
|
|
5484
|
+
const sH = availH / elH;
|
|
5485
|
+
if (mode === "page") {
|
|
5486
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
5487
|
+
}
|
|
5488
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
5308
5489
|
};
|
|
5309
5490
|
setTimeout(() => {
|
|
5310
|
-
|
|
5491
|
+
fitMode = "width";
|
|
5492
|
+
scale = calculateFitScale("width");
|
|
5311
5493
|
applyTransform();
|
|
5312
5494
|
}, 60);
|
|
5313
5495
|
const cleanup = () => {
|
|
@@ -5335,7 +5517,8 @@ var DocPlugin = class {
|
|
|
5335
5517
|
applyTransform();
|
|
5336
5518
|
},
|
|
5337
5519
|
fitToPage: () => {
|
|
5338
|
-
|
|
5520
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
5521
|
+
scale = calculateFitScale(fitMode);
|
|
5339
5522
|
rotation = 0;
|
|
5340
5523
|
applyTransform();
|
|
5341
5524
|
},
|
|
@@ -5463,45 +5646,50 @@ var DocPlugin = class {
|
|
|
5463
5646
|
}
|
|
5464
5647
|
splitIntoPages(text) {
|
|
5465
5648
|
if (!text) return [""];
|
|
5466
|
-
const
|
|
5467
|
-
|
|
5468
|
-
|
|
5649
|
+
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
|
|
5650
|
+
const explicitParts = normalized.split(/[\x0C\f]|\n\s*[-=_]{3,}\s*(?:PAGE|Page|page break)[\s\d\w-]*[-=_]{3,}\s*\n/i).map((p) => p.trim()).filter((p) => p.length > 0);
|
|
5651
|
+
if (explicitParts.length === 0) explicitParts.push(normalized);
|
|
5652
|
+
const maxLinesPerPage = 32;
|
|
5653
|
+
const charsPerLine = 80;
|
|
5469
5654
|
const finalPages = [];
|
|
5470
5655
|
for (const part of explicitParts) {
|
|
5471
|
-
const lines = part.split(
|
|
5656
|
+
const lines = part.split("\n");
|
|
5472
5657
|
let currentLines = [];
|
|
5473
5658
|
let count = 0;
|
|
5474
5659
|
for (const line of lines) {
|
|
5475
|
-
|
|
5476
|
-
count
|
|
5477
|
-
if (count >= maxLinesPerPage) {
|
|
5660
|
+
const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
|
|
5661
|
+
if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
|
|
5478
5662
|
finalPages.push(currentLines.join("\n"));
|
|
5479
5663
|
currentLines = [];
|
|
5480
5664
|
count = 0;
|
|
5481
5665
|
}
|
|
5666
|
+
currentLines.push(line);
|
|
5667
|
+
count += vLines;
|
|
5482
5668
|
}
|
|
5483
5669
|
if (currentLines.length > 0) {
|
|
5484
5670
|
finalPages.push(currentLines.join("\n"));
|
|
5485
5671
|
}
|
|
5486
5672
|
}
|
|
5487
|
-
return finalPages.length > 0 ? finalPages : [
|
|
5673
|
+
return finalPages.length > 0 ? finalPages : [normalized];
|
|
5488
5674
|
}
|
|
5489
5675
|
/**
|
|
5490
5676
|
* Format cleaned extracted text into attractive HTML paragraphs, headings, and lists
|
|
5491
5677
|
*/
|
|
5492
5678
|
formatDocToHtml(text, filename) {
|
|
5493
|
-
const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").split("\n");
|
|
5679
|
+
const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ").split("\n");
|
|
5494
5680
|
let html = "";
|
|
5495
5681
|
let inList = false;
|
|
5496
5682
|
let tableLines = [];
|
|
5497
5683
|
const flushTable = () => {
|
|
5498
5684
|
if (tableLines.length > 0) {
|
|
5499
|
-
html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size:
|
|
5500
|
-
for (
|
|
5501
|
-
|
|
5502
|
-
const
|
|
5685
|
+
html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px; font-family: Calibri, sans-serif;">';
|
|
5686
|
+
for (let rIdx = 0; rIdx < tableLines.length; rIdx++) {
|
|
5687
|
+
const tLine = tableLines[rIdx];
|
|
5688
|
+
const isHeader = rIdx === 0;
|
|
5689
|
+
html += `<tr style="${isHeader ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
|
|
5690
|
+
const cols = tLine.split(" ").filter((c) => c.trim().length > 0);
|
|
5503
5691
|
for (const col of cols) {
|
|
5504
|
-
html += `<td style="border: 1px solid #cbd5e1; padding:
|
|
5692
|
+
html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px;">${DOMPurify6.sanitize(col.trim())}</td>`;
|
|
5505
5693
|
}
|
|
5506
5694
|
html += "</tr>";
|
|
5507
5695
|
}
|
|
@@ -5514,27 +5702,18 @@ var DocPlugin = class {
|
|
|
5514
5702
|
let line = lines[i];
|
|
5515
5703
|
let tabCount = (line.match(/\t/g) || []).length;
|
|
5516
5704
|
if (tabCount > 0) {
|
|
5517
|
-
let
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
const nextTabCount = (lines[j].match(/\t/g) || []).length;
|
|
5521
|
-
if (nextTabCount === tabCount) {
|
|
5522
|
-
consecutiveTableLines++;
|
|
5523
|
-
j++;
|
|
5524
|
-
} else {
|
|
5525
|
-
break;
|
|
5526
|
-
}
|
|
5705
|
+
let j = i;
|
|
5706
|
+
while (j < lines.length && (lines[j].match(/\t/g) || []).length > 0) {
|
|
5707
|
+
j++;
|
|
5527
5708
|
}
|
|
5528
|
-
if (
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
inList = false;
|
|
5532
|
-
}
|
|
5533
|
-
tableLines = lines.slice(i, j);
|
|
5534
|
-
flushTable();
|
|
5535
|
-
i = j;
|
|
5536
|
-
continue;
|
|
5709
|
+
if (inList) {
|
|
5710
|
+
html += "</ul>";
|
|
5711
|
+
inList = false;
|
|
5537
5712
|
}
|
|
5713
|
+
tableLines = lines.slice(i, j);
|
|
5714
|
+
flushTable();
|
|
5715
|
+
i = j;
|
|
5716
|
+
continue;
|
|
5538
5717
|
}
|
|
5539
5718
|
line = line.trim();
|
|
5540
5719
|
if (!line) {
|