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