@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/vue.js
CHANGED
|
@@ -433,7 +433,8 @@ function createElement(tag, attrs, ...children) {
|
|
|
433
433
|
}
|
|
434
434
|
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>`;
|
|
435
435
|
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>`;
|
|
436
|
-
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"><
|
|
436
|
+
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>`;
|
|
437
|
+
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>`;
|
|
437
438
|
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>`;
|
|
438
439
|
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>`;
|
|
439
440
|
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>`;
|
|
@@ -453,6 +454,7 @@ var ICON_MAP = {
|
|
|
453
454
|
"zoom-in": ICON_ZOOM_IN,
|
|
454
455
|
"zoom-out": ICON_ZOOM_OUT,
|
|
455
456
|
"fit-page": ICON_FIT_PAGE,
|
|
457
|
+
"fit-width": ICON_FIT_WIDTH,
|
|
456
458
|
"fit-slide": ICON_FIT_PAGE,
|
|
457
459
|
"rotate-cw": ICON_ROTATE_CW,
|
|
458
460
|
"rotate-ccw": ICON_ROTATE_CCW,
|
|
@@ -1399,6 +1401,7 @@ var PdfPlugin = class {
|
|
|
1399
1401
|
let currentPage = 1;
|
|
1400
1402
|
let zoomScale = 1;
|
|
1401
1403
|
let rotation = 0;
|
|
1404
|
+
let fitMode = "width";
|
|
1402
1405
|
let currentRenderTask = null;
|
|
1403
1406
|
const renderPage = async (pageNum) => {
|
|
1404
1407
|
if (currentRenderTask) {
|
|
@@ -1418,11 +1421,16 @@ var PdfPlugin = class {
|
|
|
1418
1421
|
const containerWidth = container.clientWidth || 900;
|
|
1419
1422
|
const containerHeight = container.clientHeight || 700;
|
|
1420
1423
|
const unscaledVp = page.getViewport({ scale: 1, rotation });
|
|
1421
|
-
const availWidth = Math.max(
|
|
1422
|
-
const availHeight = Math.max(
|
|
1424
|
+
const availWidth = Math.max(280, containerWidth - 48);
|
|
1425
|
+
const availHeight = Math.max(280, containerHeight - 88);
|
|
1423
1426
|
const scaleW = availWidth / unscaledVp.width;
|
|
1424
1427
|
const scaleH = availHeight / unscaledVp.height;
|
|
1425
|
-
|
|
1428
|
+
let fitScale;
|
|
1429
|
+
if (fitMode === "page") {
|
|
1430
|
+
fitScale = Math.max(0.5, Math.min(scaleW, scaleH));
|
|
1431
|
+
} else {
|
|
1432
|
+
fitScale = Math.max(0.65, Math.min(1.15, scaleW));
|
|
1433
|
+
}
|
|
1426
1434
|
const effectiveScale = (fitScale > 0 ? fitScale : 1) * zoomScale;
|
|
1427
1435
|
const pixelRatio = window.devicePixelRatio || 1;
|
|
1428
1436
|
const viewport = page.getViewport({ scale: effectiveScale, rotation });
|
|
@@ -1491,6 +1499,7 @@ var PdfPlugin = class {
|
|
|
1491
1499
|
renderPage(currentPage);
|
|
1492
1500
|
},
|
|
1493
1501
|
fitToPage: () => {
|
|
1502
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
1494
1503
|
zoomScale = 1;
|
|
1495
1504
|
rotation = 0;
|
|
1496
1505
|
renderPage(currentPage);
|
|
@@ -1507,6 +1516,7 @@ var PdfPlugin = class {
|
|
|
1507
1516
|
getPageCount: () => totalPages,
|
|
1508
1517
|
getCurrentPage: () => currentPage,
|
|
1509
1518
|
goToPage: (page) => {
|
|
1519
|
+
container.scrollTop = 0;
|
|
1510
1520
|
renderPage(page);
|
|
1511
1521
|
},
|
|
1512
1522
|
download: () => {
|
|
@@ -2011,7 +2021,14 @@ var DocxPlugin = class {
|
|
|
2011
2021
|
ignoreFonts: true,
|
|
2012
2022
|
// Avoid crashes on embedded obfuscated fonts
|
|
2013
2023
|
breakPages: true,
|
|
2014
|
-
experimental: true
|
|
2024
|
+
experimental: true,
|
|
2025
|
+
ignoreLastRenderedPageBreak: false,
|
|
2026
|
+
// Honor Word's exact page breaks!
|
|
2027
|
+
renderHeaders: true,
|
|
2028
|
+
renderFooters: true,
|
|
2029
|
+
renderFootnotes: true,
|
|
2030
|
+
renderEndnotes: true,
|
|
2031
|
+
useBase64URL: true
|
|
2015
2032
|
});
|
|
2016
2033
|
if (!ctx.container.contains(wrapper)) {
|
|
2017
2034
|
ctx.container.appendChild(wrapper);
|
|
@@ -2032,11 +2049,14 @@ var DocxPlugin = class {
|
|
|
2032
2049
|
renderedSuccessfully = true;
|
|
2033
2050
|
} catch (fallbackErr) {
|
|
2034
2051
|
console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
|
|
2052
|
+
const isCorrupt = fallbackErr?.message?.includes("invalid zip") || fallbackErr?.message?.includes("corrupted");
|
|
2035
2053
|
wrapper.innerHTML = `
|
|
2036
|
-
<div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
|
|
2037
|
-
<div style="font-size:48px; margin-bottom: 16px;"
|
|
2038
|
-
<h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
|
|
2039
|
-
<p style="color: #64748b; margin: 0;
|
|
2054
|
+
<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;">
|
|
2055
|
+
<div style="font-size:48px; margin-bottom: 16px;">${isCorrupt ? "\u26A0\uFE0F" : "\u{1F4C4}"}</div>
|
|
2056
|
+
<h3 style="margin: 0 0 8px; color: #1e293b; font-size: 18px;">${ctx.metadata.name || "Word Document"}</h3>
|
|
2057
|
+
<p style="color: #64748b; margin: 0 0 16px; font-size: 14px; line-height: 1.5;">
|
|
2058
|
+
${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."}
|
|
2059
|
+
</p>
|
|
2040
2060
|
</div>
|
|
2041
2061
|
`;
|
|
2042
2062
|
if (!ctx.container.contains(wrapper)) {
|
|
@@ -2044,8 +2064,67 @@ var DocxPlugin = class {
|
|
|
2044
2064
|
}
|
|
2045
2065
|
}
|
|
2046
2066
|
}
|
|
2047
|
-
|
|
2048
|
-
const cards = wrapper.querySelectorAll(".fp-docx-page-card");
|
|
2067
|
+
let sections = Array.from(wrapper.querySelectorAll("section.docx"));
|
|
2068
|
+
const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
|
|
2069
|
+
if (sections.length === 1 && cards.length === 0) {
|
|
2070
|
+
const singleSec = sections[0];
|
|
2071
|
+
const contentContainer = singleSec.querySelector("article") || singleSec;
|
|
2072
|
+
const children = Array.from(contentContainer.children);
|
|
2073
|
+
const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
|
|
2074
|
+
const secH = singleSec.offsetHeight || singleSec.scrollHeight;
|
|
2075
|
+
if (secH > pageH * 1.25 && children.length > 1) {
|
|
2076
|
+
const childHeights = children.map((c) => {
|
|
2077
|
+
const rectH = c.getBoundingClientRect().height;
|
|
2078
|
+
const offH = c.offsetHeight;
|
|
2079
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
2080
|
+
const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
|
|
2081
|
+
return Math.max(rectH, offH, estH);
|
|
2082
|
+
});
|
|
2083
|
+
const parent = singleSec.parentElement || wrapper;
|
|
2084
|
+
const newSections = [singleSec];
|
|
2085
|
+
const headerEl = singleSec.querySelector("header");
|
|
2086
|
+
const footerEl = singleSec.querySelector("footer");
|
|
2087
|
+
contentContainer.innerHTML = "";
|
|
2088
|
+
singleSec.style.minHeight = `${pageH}px`;
|
|
2089
|
+
singleSec.style.boxSizing = "border-box";
|
|
2090
|
+
let curContent = contentContainer;
|
|
2091
|
+
let curH = 0;
|
|
2092
|
+
const maxH = pageH - 140;
|
|
2093
|
+
for (let i = 0; i < children.length; i++) {
|
|
2094
|
+
const child = children[i];
|
|
2095
|
+
const chH = childHeights[i];
|
|
2096
|
+
curContent.appendChild(child);
|
|
2097
|
+
curH += chH;
|
|
2098
|
+
if (curH >= maxH && i < children.length - 1) {
|
|
2099
|
+
const nextSec = document.createElement("section");
|
|
2100
|
+
nextSec.className = singleSec.className;
|
|
2101
|
+
nextSec.style.cssText = singleSec.style.cssText;
|
|
2102
|
+
nextSec.style.minHeight = `${pageH}px`;
|
|
2103
|
+
nextSec.style.boxSizing = "border-box";
|
|
2104
|
+
nextSec.style.backgroundColor = "#ffffff";
|
|
2105
|
+
nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
|
|
2106
|
+
nextSec.style.borderRadius = "4px";
|
|
2107
|
+
nextSec.style.marginBottom = "24px";
|
|
2108
|
+
if (headerEl) {
|
|
2109
|
+
nextSec.appendChild(headerEl.cloneNode(true));
|
|
2110
|
+
}
|
|
2111
|
+
const nextArticle = document.createElement("article");
|
|
2112
|
+
if (contentContainer.tagName.toLowerCase() === "article") {
|
|
2113
|
+
nextArticle.style.cssText = contentContainer.style.cssText;
|
|
2114
|
+
}
|
|
2115
|
+
nextSec.appendChild(nextArticle);
|
|
2116
|
+
if (footerEl) {
|
|
2117
|
+
nextSec.appendChild(footerEl.cloneNode(true));
|
|
2118
|
+
}
|
|
2119
|
+
parent.appendChild(nextSec);
|
|
2120
|
+
newSections.push(nextSec);
|
|
2121
|
+
curContent = nextArticle;
|
|
2122
|
+
curH = 0;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
sections = newSections;
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2049
2128
|
const pageElements = sections.length > 0 ? sections : cards;
|
|
2050
2129
|
const totalPages = Math.max(1, pageElements.length);
|
|
2051
2130
|
let currentPage = 1;
|
|
@@ -2082,6 +2161,7 @@ var DocxPlugin = class {
|
|
|
2082
2161
|
if (indicator) {
|
|
2083
2162
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
2084
2163
|
}
|
|
2164
|
+
ctx.container.scrollTop = 0;
|
|
2085
2165
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
2086
2166
|
};
|
|
2087
2167
|
if (totalPages > 1) {
|
|
@@ -2089,22 +2169,27 @@ var DocxPlugin = class {
|
|
|
2089
2169
|
}
|
|
2090
2170
|
scale = 1;
|
|
2091
2171
|
let rotation = 0;
|
|
2092
|
-
|
|
2172
|
+
let fitMode = "width";
|
|
2173
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
2093
2174
|
const activeEl = pageElements[currentPage - 1] || wrapper.firstElementChild || wrapper;
|
|
2094
2175
|
const elW = activeEl.offsetWidth || 816;
|
|
2095
|
-
const
|
|
2096
|
-
const availW = Math.max(
|
|
2097
|
-
const availH = Math.max(
|
|
2176
|
+
const singlePageH = Math.min(activeEl.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
2177
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
2178
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
2098
2179
|
const sW = availW / elW;
|
|
2099
|
-
const sH = availH /
|
|
2100
|
-
|
|
2180
|
+
const sH = availH / singlePageH;
|
|
2181
|
+
if (mode === "page") {
|
|
2182
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
2183
|
+
}
|
|
2184
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
2101
2185
|
};
|
|
2102
2186
|
const applyTransform = () => {
|
|
2103
2187
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
2104
2188
|
wrapper.style.transformOrigin = "top center";
|
|
2105
2189
|
};
|
|
2106
2190
|
setTimeout(() => {
|
|
2107
|
-
|
|
2191
|
+
fitMode = "width";
|
|
2192
|
+
scale = calculateFitScale("width");
|
|
2108
2193
|
applyTransform();
|
|
2109
2194
|
}, 60);
|
|
2110
2195
|
const cleanup = () => {
|
|
@@ -2138,7 +2223,8 @@ var DocxPlugin = class {
|
|
|
2138
2223
|
applyTransform();
|
|
2139
2224
|
},
|
|
2140
2225
|
fitToPage: () => {
|
|
2141
|
-
|
|
2226
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
2227
|
+
scale = calculateFitScale(fitMode);
|
|
2142
2228
|
rotation = 0;
|
|
2143
2229
|
applyTransform();
|
|
2144
2230
|
},
|
|
@@ -2582,11 +2668,9 @@ var ExcelPlugin = class {
|
|
|
2582
2668
|
const calculateFitScale = () => {
|
|
2583
2669
|
const table = contentArea.querySelector("table");
|
|
2584
2670
|
if (!table) return 1;
|
|
2585
|
-
const availW = Math.max(
|
|
2586
|
-
const availH = Math.max(200, container.clientHeight - 80);
|
|
2671
|
+
const availW = Math.max(280, container.clientWidth - 48);
|
|
2587
2672
|
const tW = table.offsetWidth || 800;
|
|
2588
|
-
|
|
2589
|
-
return Math.min(1, Math.min(availW / tW, availH / tH));
|
|
2673
|
+
return Math.max(0.65, Math.min(1, availW / tW));
|
|
2590
2674
|
};
|
|
2591
2675
|
try {
|
|
2592
2676
|
wb = XLSX.read(new Uint8Array(ctx.buffer), { type: "array", cellDates: true });
|
|
@@ -3010,17 +3094,39 @@ var CodePlugin = class {
|
|
|
3010
3094
|
let rawPages = [];
|
|
3011
3095
|
if (isTxt) {
|
|
3012
3096
|
const explicitPages = fullText.split(/(?:\f|\x0C)/);
|
|
3097
|
+
const charsPerLine = 85;
|
|
3098
|
+
const maxVisualLines = 45;
|
|
3099
|
+
const charsPerPage = charsPerLine * maxVisualLines;
|
|
3013
3100
|
for (const ep of explicitPages) {
|
|
3014
3101
|
const lines = ep.split(/\r?\n/);
|
|
3015
3102
|
let currentChunk = [];
|
|
3103
|
+
let currentLines = 0;
|
|
3016
3104
|
for (let i = 0; i < lines.length; i++) {
|
|
3017
|
-
|
|
3018
|
-
|
|
3105
|
+
const line = lines[i];
|
|
3106
|
+
const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
|
|
3107
|
+
if (currentLines + vLines > maxVisualLines && currentChunk.length > 0) {
|
|
3019
3108
|
rawPages.push(currentChunk.join("\n"));
|
|
3020
3109
|
currentChunk = [];
|
|
3110
|
+
currentLines = 0;
|
|
3111
|
+
}
|
|
3112
|
+
if (vLines > maxVisualLines) {
|
|
3113
|
+
let remaining = line;
|
|
3114
|
+
while (remaining.length > charsPerPage) {
|
|
3115
|
+
let splitIdx = remaining.lastIndexOf(" ", charsPerPage);
|
|
3116
|
+
if (splitIdx < charsPerPage * 0.75) splitIdx = charsPerPage;
|
|
3117
|
+
rawPages.push(remaining.slice(0, splitIdx));
|
|
3118
|
+
remaining = remaining.slice(splitIdx).trimStart();
|
|
3119
|
+
}
|
|
3120
|
+
if (remaining.length > 0) {
|
|
3121
|
+
currentChunk.push(remaining);
|
|
3122
|
+
currentLines = Math.ceil(remaining.length / charsPerLine);
|
|
3123
|
+
}
|
|
3124
|
+
} else {
|
|
3125
|
+
currentChunk.push(line);
|
|
3126
|
+
currentLines += vLines;
|
|
3021
3127
|
}
|
|
3022
3128
|
}
|
|
3023
|
-
if (currentChunk.length > 0
|
|
3129
|
+
if (currentChunk.length > 0) {
|
|
3024
3130
|
rawPages.push(currentChunk.join("\n"));
|
|
3025
3131
|
}
|
|
3026
3132
|
}
|
|
@@ -3130,6 +3236,7 @@ var CodePlugin = class {
|
|
|
3130
3236
|
if (indicator) {
|
|
3131
3237
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
3132
3238
|
}
|
|
3239
|
+
container.scrollTop = 0;
|
|
3133
3240
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
3134
3241
|
};
|
|
3135
3242
|
if (totalPages > 1) {
|
|
@@ -3183,7 +3290,7 @@ var CodePlugin = class {
|
|
|
3183
3290
|
fitToPage: () => {
|
|
3184
3291
|
fontSize = 13;
|
|
3185
3292
|
rotation = 0;
|
|
3186
|
-
zoomLevel = 1;
|
|
3293
|
+
zoomLevel = isTxt ? Math.max(0.65, Math.min(1.05, (container.clientWidth - 48) / 816)) : 1;
|
|
3187
3294
|
updateTransform();
|
|
3188
3295
|
},
|
|
3189
3296
|
rotateCW: () => {
|
|
@@ -4165,20 +4272,27 @@ var RtfPlugin = class {
|
|
|
4165
4272
|
let scale = 1;
|
|
4166
4273
|
let rotation = 0;
|
|
4167
4274
|
let pageElements = [];
|
|
4168
|
-
|
|
4275
|
+
let fitMode = "width";
|
|
4276
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
4169
4277
|
const activeEl = pageElements[currentPage - 1] || wrapper;
|
|
4170
4278
|
const elW = activeEl.offsetWidth || 850;
|
|
4171
|
-
const
|
|
4172
|
-
const availW = Math.max(
|
|
4173
|
-
const availH = Math.max(
|
|
4174
|
-
|
|
4279
|
+
const singlePageH = Math.min(activeEl.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
4280
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
4281
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
4282
|
+
const sW = availW / elW;
|
|
4283
|
+
const sH = availH / singlePageH;
|
|
4284
|
+
if (mode === "page") {
|
|
4285
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
4286
|
+
}
|
|
4287
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
4175
4288
|
};
|
|
4176
4289
|
const applyTransform = () => {
|
|
4177
4290
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
4178
4291
|
wrapper.style.transformOrigin = "top center";
|
|
4179
4292
|
};
|
|
4180
4293
|
setTimeout(() => {
|
|
4181
|
-
|
|
4294
|
+
fitMode = "width";
|
|
4295
|
+
scale = calculateFitScale("width");
|
|
4182
4296
|
applyTransform();
|
|
4183
4297
|
}, 60);
|
|
4184
4298
|
try {
|
|
@@ -4187,11 +4301,60 @@ var RtfPlugin = class {
|
|
|
4187
4301
|
}
|
|
4188
4302
|
const doc = new RTFJS.Document(ctx.buffer, {});
|
|
4189
4303
|
const htmlElements = await doc.render();
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4304
|
+
if (htmlElements.length === 1) {
|
|
4305
|
+
const singleEl = htmlElements[0];
|
|
4306
|
+
wrapper.appendChild(singleEl);
|
|
4307
|
+
const children = Array.from(singleEl.children);
|
|
4308
|
+
const secH = singleEl.offsetHeight || singleEl.scrollHeight;
|
|
4309
|
+
if (secH > 1300 && children.length > 1) {
|
|
4310
|
+
const childHeights = children.map((c) => {
|
|
4311
|
+
const rectH = c.getBoundingClientRect().height;
|
|
4312
|
+
const offH = c.offsetHeight;
|
|
4313
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
4314
|
+
const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
|
|
4315
|
+
return Math.max(rectH, offH, estH);
|
|
4316
|
+
});
|
|
4317
|
+
wrapper.innerHTML = "";
|
|
4318
|
+
const createRtfCard = () => {
|
|
4319
|
+
const card = document.createElement("div");
|
|
4320
|
+
card.className = "fp-rtf-page-card";
|
|
4321
|
+
card.style.backgroundColor = "#ffffff";
|
|
4322
|
+
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
4323
|
+
card.style.borderRadius = "4px";
|
|
4324
|
+
card.style.padding = "72px 56px";
|
|
4325
|
+
card.style.width = "816px";
|
|
4326
|
+
card.style.minHeight = "1056px";
|
|
4327
|
+
card.style.boxSizing = "border-box";
|
|
4328
|
+
card.style.marginBottom = "24px";
|
|
4329
|
+
return card;
|
|
4330
|
+
};
|
|
4331
|
+
let curCard = createRtfCard();
|
|
4332
|
+
wrapper.appendChild(curCard);
|
|
4333
|
+
pageElements = [curCard];
|
|
4334
|
+
let curH = 0;
|
|
4335
|
+
const maxH = 920;
|
|
4336
|
+
for (let i = 0; i < children.length; i++) {
|
|
4337
|
+
const child = children[i];
|
|
4338
|
+
const chH = childHeights[i];
|
|
4339
|
+
curCard.appendChild(child);
|
|
4340
|
+
curH += chH;
|
|
4341
|
+
if (curH >= maxH && i < children.length - 1) {
|
|
4342
|
+
curCard = createRtfCard();
|
|
4343
|
+
wrapper.appendChild(curCard);
|
|
4344
|
+
pageElements.push(curCard);
|
|
4345
|
+
curH = 0;
|
|
4346
|
+
}
|
|
4347
|
+
}
|
|
4348
|
+
} else {
|
|
4349
|
+
pageElements = [singleEl];
|
|
4350
|
+
}
|
|
4351
|
+
} else {
|
|
4352
|
+
pageElements = htmlElements;
|
|
4353
|
+
for (let i = 0; i < htmlElements.length; i++) {
|
|
4354
|
+
const el = htmlElements[i];
|
|
4355
|
+
el.style.display = i === 0 ? "block" : "none";
|
|
4356
|
+
wrapper.appendChild(el);
|
|
4357
|
+
}
|
|
4195
4358
|
}
|
|
4196
4359
|
} catch (err) {
|
|
4197
4360
|
console.warn("[RtfPlugin] RTF render error, fallback text:", err);
|
|
@@ -4257,6 +4420,7 @@ var RtfPlugin = class {
|
|
|
4257
4420
|
if (indicator) {
|
|
4258
4421
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
4259
4422
|
}
|
|
4423
|
+
ctx.container.scrollTop = 0;
|
|
4260
4424
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
4261
4425
|
};
|
|
4262
4426
|
if (totalPages > 1) {
|
|
@@ -4287,7 +4451,8 @@ var RtfPlugin = class {
|
|
|
4287
4451
|
applyTransform();
|
|
4288
4452
|
},
|
|
4289
4453
|
fitToPage: () => {
|
|
4290
|
-
|
|
4454
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
4455
|
+
scale = calculateFitScale(fitMode);
|
|
4291
4456
|
rotation = 0;
|
|
4292
4457
|
applyTransform();
|
|
4293
4458
|
},
|
|
@@ -4606,19 +4771,29 @@ var OpenDocumentPlugin = class {
|
|
|
4606
4771
|
ctx.container.appendChild(container);
|
|
4607
4772
|
let scale = 1;
|
|
4608
4773
|
let rotation = 0;
|
|
4609
|
-
|
|
4774
|
+
let fitMode = "width";
|
|
4775
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
4610
4776
|
const elW = wrapper.offsetWidth || 850;
|
|
4611
|
-
const
|
|
4612
|
-
const availW = Math.max(
|
|
4613
|
-
const availH = Math.max(
|
|
4614
|
-
|
|
4777
|
+
const singlePageH = Math.min(wrapper.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
4778
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
4779
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
4780
|
+
const sW = availW / elW;
|
|
4781
|
+
const sH = availH / (isPresentation ? 540 : singlePageH);
|
|
4782
|
+
if (isPresentation) {
|
|
4783
|
+
return Math.min(1, Math.min(sW, sH));
|
|
4784
|
+
}
|
|
4785
|
+
if (mode === "page") {
|
|
4786
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
4787
|
+
}
|
|
4788
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
4615
4789
|
};
|
|
4616
4790
|
const applyTransform = () => {
|
|
4617
4791
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
4618
4792
|
wrapper.style.transformOrigin = "top center";
|
|
4619
4793
|
};
|
|
4620
4794
|
setTimeout(() => {
|
|
4621
|
-
|
|
4795
|
+
fitMode = "width";
|
|
4796
|
+
scale = calculateFitScale("width");
|
|
4622
4797
|
applyTransform();
|
|
4623
4798
|
}, 60);
|
|
4624
4799
|
let currentPage = 1;
|
|
@@ -4717,12 +4892,9 @@ var OpenDocumentPlugin = class {
|
|
|
4717
4892
|
page.style.backgroundColor = "#ffffff";
|
|
4718
4893
|
page.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
|
|
4719
4894
|
page.style.borderRadius = "4px";
|
|
4720
|
-
page.style.boxSizing = "border-box";
|
|
4721
4895
|
page.style.display = idx === 0 ? "block" : "none";
|
|
4722
|
-
page.style.
|
|
4723
|
-
page.style.
|
|
4724
|
-
page.style.left = "50%";
|
|
4725
|
-
page.style.transform = "translateX(-50%)";
|
|
4896
|
+
page.style.margin = "0 auto 24px";
|
|
4897
|
+
page.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
|
|
4726
4898
|
elements.forEach((el) => page.appendChild(el));
|
|
4727
4899
|
wrapper.appendChild(page);
|
|
4728
4900
|
slides.push(page);
|
|
@@ -4760,6 +4932,7 @@ var OpenDocumentPlugin = class {
|
|
|
4760
4932
|
if (indicator) {
|
|
4761
4933
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
4762
4934
|
}
|
|
4935
|
+
container.scrollTop = 0;
|
|
4763
4936
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
4764
4937
|
};
|
|
4765
4938
|
return {
|
|
@@ -4779,7 +4952,8 @@ var OpenDocumentPlugin = class {
|
|
|
4779
4952
|
applyTransform();
|
|
4780
4953
|
},
|
|
4781
4954
|
fitToPage: () => {
|
|
4782
|
-
|
|
4955
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
4956
|
+
scale = calculateFitScale(fitMode);
|
|
4783
4957
|
rotation = 0;
|
|
4784
4958
|
applyTransform();
|
|
4785
4959
|
},
|
|
@@ -5251,20 +5425,28 @@ var DocPlugin = class {
|
|
|
5251
5425
|
if (indicator) {
|
|
5252
5426
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
5253
5427
|
}
|
|
5428
|
+
container.scrollTop = 0;
|
|
5254
5429
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
5255
5430
|
};
|
|
5256
5431
|
if (totalPages > 1) {
|
|
5257
5432
|
showPage(1);
|
|
5258
5433
|
}
|
|
5259
|
-
|
|
5434
|
+
let fitMode = "width";
|
|
5435
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
5260
5436
|
const elW = 816;
|
|
5261
5437
|
const elH = 1056;
|
|
5262
|
-
const availW = Math.max(
|
|
5263
|
-
const availH = Math.max(
|
|
5264
|
-
|
|
5438
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
5439
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
5440
|
+
const sW = availW / elW;
|
|
5441
|
+
const sH = availH / elH;
|
|
5442
|
+
if (mode === "page") {
|
|
5443
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
5444
|
+
}
|
|
5445
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
5265
5446
|
};
|
|
5266
5447
|
setTimeout(() => {
|
|
5267
|
-
|
|
5448
|
+
fitMode = "width";
|
|
5449
|
+
scale = calculateFitScale("width");
|
|
5268
5450
|
applyTransform();
|
|
5269
5451
|
}, 60);
|
|
5270
5452
|
const cleanup = () => {
|
|
@@ -5292,7 +5474,8 @@ var DocPlugin = class {
|
|
|
5292
5474
|
applyTransform();
|
|
5293
5475
|
},
|
|
5294
5476
|
fitToPage: () => {
|
|
5295
|
-
|
|
5477
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
5478
|
+
scale = calculateFitScale(fitMode);
|
|
5296
5479
|
rotation = 0;
|
|
5297
5480
|
applyTransform();
|
|
5298
5481
|
},
|
|
@@ -5420,45 +5603,50 @@ var DocPlugin = class {
|
|
|
5420
5603
|
}
|
|
5421
5604
|
splitIntoPages(text) {
|
|
5422
5605
|
if (!text) return [""];
|
|
5423
|
-
const
|
|
5424
|
-
|
|
5425
|
-
|
|
5606
|
+
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
|
|
5607
|
+
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);
|
|
5608
|
+
if (explicitParts.length === 0) explicitParts.push(normalized);
|
|
5609
|
+
const maxLinesPerPage = 32;
|
|
5610
|
+
const charsPerLine = 80;
|
|
5426
5611
|
const finalPages = [];
|
|
5427
5612
|
for (const part of explicitParts) {
|
|
5428
|
-
const lines = part.split(
|
|
5613
|
+
const lines = part.split("\n");
|
|
5429
5614
|
let currentLines = [];
|
|
5430
5615
|
let count = 0;
|
|
5431
5616
|
for (const line of lines) {
|
|
5432
|
-
|
|
5433
|
-
count
|
|
5434
|
-
if (count >= maxLinesPerPage) {
|
|
5617
|
+
const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
|
|
5618
|
+
if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
|
|
5435
5619
|
finalPages.push(currentLines.join("\n"));
|
|
5436
5620
|
currentLines = [];
|
|
5437
5621
|
count = 0;
|
|
5438
5622
|
}
|
|
5623
|
+
currentLines.push(line);
|
|
5624
|
+
count += vLines;
|
|
5439
5625
|
}
|
|
5440
5626
|
if (currentLines.length > 0) {
|
|
5441
5627
|
finalPages.push(currentLines.join("\n"));
|
|
5442
5628
|
}
|
|
5443
5629
|
}
|
|
5444
|
-
return finalPages.length > 0 ? finalPages : [
|
|
5630
|
+
return finalPages.length > 0 ? finalPages : [normalized];
|
|
5445
5631
|
}
|
|
5446
5632
|
/**
|
|
5447
5633
|
* Format cleaned extracted text into attractive HTML paragraphs, headings, and lists
|
|
5448
5634
|
*/
|
|
5449
5635
|
formatDocToHtml(text, filename) {
|
|
5450
|
-
const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").split("\n");
|
|
5636
|
+
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");
|
|
5451
5637
|
let html = "";
|
|
5452
5638
|
let inList = false;
|
|
5453
5639
|
let tableLines = [];
|
|
5454
5640
|
const flushTable = () => {
|
|
5455
5641
|
if (tableLines.length > 0) {
|
|
5456
|
-
html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size:
|
|
5457
|
-
for (
|
|
5458
|
-
|
|
5459
|
-
const
|
|
5642
|
+
html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px; font-family: Calibri, sans-serif;">';
|
|
5643
|
+
for (let rIdx = 0; rIdx < tableLines.length; rIdx++) {
|
|
5644
|
+
const tLine = tableLines[rIdx];
|
|
5645
|
+
const isHeader = rIdx === 0;
|
|
5646
|
+
html += `<tr style="${isHeader ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
|
|
5647
|
+
const cols = tLine.split(" ").filter((c) => c.trim().length > 0);
|
|
5460
5648
|
for (const col of cols) {
|
|
5461
|
-
html += `<td style="border: 1px solid #cbd5e1; padding:
|
|
5649
|
+
html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px;">${DOMPurify6.sanitize(col.trim())}</td>`;
|
|
5462
5650
|
}
|
|
5463
5651
|
html += "</tr>";
|
|
5464
5652
|
}
|
|
@@ -5471,27 +5659,18 @@ var DocPlugin = class {
|
|
|
5471
5659
|
let line = lines[i];
|
|
5472
5660
|
let tabCount = (line.match(/\t/g) || []).length;
|
|
5473
5661
|
if (tabCount > 0) {
|
|
5474
|
-
let
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
const nextTabCount = (lines[j].match(/\t/g) || []).length;
|
|
5478
|
-
if (nextTabCount === tabCount) {
|
|
5479
|
-
consecutiveTableLines++;
|
|
5480
|
-
j++;
|
|
5481
|
-
} else {
|
|
5482
|
-
break;
|
|
5483
|
-
}
|
|
5662
|
+
let j = i;
|
|
5663
|
+
while (j < lines.length && (lines[j].match(/\t/g) || []).length > 0) {
|
|
5664
|
+
j++;
|
|
5484
5665
|
}
|
|
5485
|
-
if (
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
inList = false;
|
|
5489
|
-
}
|
|
5490
|
-
tableLines = lines.slice(i, j);
|
|
5491
|
-
flushTable();
|
|
5492
|
-
i = j;
|
|
5493
|
-
continue;
|
|
5666
|
+
if (inList) {
|
|
5667
|
+
html += "</ul>";
|
|
5668
|
+
inList = false;
|
|
5494
5669
|
}
|
|
5670
|
+
tableLines = lines.slice(i, j);
|
|
5671
|
+
flushTable();
|
|
5672
|
+
i = j;
|
|
5673
|
+
continue;
|
|
5495
5674
|
}
|
|
5496
5675
|
line = line.trim();
|
|
5497
5676
|
if (!line) {
|