@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/angular.js
CHANGED
|
@@ -481,7 +481,8 @@ function createElement(tag, attrs, ...children) {
|
|
|
481
481
|
}
|
|
482
482
|
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>`;
|
|
483
483
|
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>`;
|
|
484
|
-
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"><
|
|
484
|
+
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>`;
|
|
485
|
+
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>`;
|
|
485
486
|
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>`;
|
|
486
487
|
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>`;
|
|
487
488
|
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>`;
|
|
@@ -501,6 +502,7 @@ var ICON_MAP = {
|
|
|
501
502
|
"zoom-in": ICON_ZOOM_IN,
|
|
502
503
|
"zoom-out": ICON_ZOOM_OUT,
|
|
503
504
|
"fit-page": ICON_FIT_PAGE,
|
|
505
|
+
"fit-width": ICON_FIT_WIDTH,
|
|
504
506
|
"fit-slide": ICON_FIT_PAGE,
|
|
505
507
|
"rotate-cw": ICON_ROTATE_CW,
|
|
506
508
|
"rotate-ccw": ICON_ROTATE_CCW,
|
|
@@ -1447,6 +1449,7 @@ var PdfPlugin = class {
|
|
|
1447
1449
|
let currentPage = 1;
|
|
1448
1450
|
let zoomScale = 1;
|
|
1449
1451
|
let rotation = 0;
|
|
1452
|
+
let fitMode = "width";
|
|
1450
1453
|
let currentRenderTask = null;
|
|
1451
1454
|
const renderPage = async (pageNum) => {
|
|
1452
1455
|
if (currentRenderTask) {
|
|
@@ -1466,11 +1469,16 @@ var PdfPlugin = class {
|
|
|
1466
1469
|
const containerWidth = container.clientWidth || 900;
|
|
1467
1470
|
const containerHeight = container.clientHeight || 700;
|
|
1468
1471
|
const unscaledVp = page.getViewport({ scale: 1, rotation });
|
|
1469
|
-
const availWidth = Math.max(
|
|
1470
|
-
const availHeight = Math.max(
|
|
1472
|
+
const availWidth = Math.max(280, containerWidth - 48);
|
|
1473
|
+
const availHeight = Math.max(280, containerHeight - 88);
|
|
1471
1474
|
const scaleW = availWidth / unscaledVp.width;
|
|
1472
1475
|
const scaleH = availHeight / unscaledVp.height;
|
|
1473
|
-
|
|
1476
|
+
let fitScale;
|
|
1477
|
+
if (fitMode === "page") {
|
|
1478
|
+
fitScale = Math.max(0.5, Math.min(scaleW, scaleH));
|
|
1479
|
+
} else {
|
|
1480
|
+
fitScale = Math.max(0.65, Math.min(1.15, scaleW));
|
|
1481
|
+
}
|
|
1474
1482
|
const effectiveScale = (fitScale > 0 ? fitScale : 1) * zoomScale;
|
|
1475
1483
|
const pixelRatio = window.devicePixelRatio || 1;
|
|
1476
1484
|
const viewport = page.getViewport({ scale: effectiveScale, rotation });
|
|
@@ -1539,6 +1547,7 @@ var PdfPlugin = class {
|
|
|
1539
1547
|
renderPage(currentPage);
|
|
1540
1548
|
},
|
|
1541
1549
|
fitToPage: () => {
|
|
1550
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
1542
1551
|
zoomScale = 1;
|
|
1543
1552
|
rotation = 0;
|
|
1544
1553
|
renderPage(currentPage);
|
|
@@ -1555,6 +1564,7 @@ var PdfPlugin = class {
|
|
|
1555
1564
|
getPageCount: () => totalPages,
|
|
1556
1565
|
getCurrentPage: () => currentPage,
|
|
1557
1566
|
goToPage: (page) => {
|
|
1567
|
+
container.scrollTop = 0;
|
|
1558
1568
|
renderPage(page);
|
|
1559
1569
|
},
|
|
1560
1570
|
download: () => {
|
|
@@ -2059,7 +2069,14 @@ var DocxPlugin = class {
|
|
|
2059
2069
|
ignoreFonts: true,
|
|
2060
2070
|
// Avoid crashes on embedded obfuscated fonts
|
|
2061
2071
|
breakPages: true,
|
|
2062
|
-
experimental: true
|
|
2072
|
+
experimental: true,
|
|
2073
|
+
ignoreLastRenderedPageBreak: false,
|
|
2074
|
+
// Honor Word's exact page breaks!
|
|
2075
|
+
renderHeaders: true,
|
|
2076
|
+
renderFooters: true,
|
|
2077
|
+
renderFootnotes: true,
|
|
2078
|
+
renderEndnotes: true,
|
|
2079
|
+
useBase64URL: true
|
|
2063
2080
|
});
|
|
2064
2081
|
if (!ctx.container.contains(wrapper)) {
|
|
2065
2082
|
ctx.container.appendChild(wrapper);
|
|
@@ -2080,11 +2097,14 @@ var DocxPlugin = class {
|
|
|
2080
2097
|
renderedSuccessfully = true;
|
|
2081
2098
|
} catch (fallbackErr) {
|
|
2082
2099
|
console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
|
|
2100
|
+
const isCorrupt = fallbackErr?.message?.includes("invalid zip") || fallbackErr?.message?.includes("corrupted");
|
|
2083
2101
|
wrapper.innerHTML = `
|
|
2084
|
-
<div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
|
|
2085
|
-
<div style="font-size:48px; margin-bottom: 16px;"
|
|
2086
|
-
<h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
|
|
2087
|
-
<p style="color: #64748b; margin: 0;
|
|
2102
|
+
<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;">
|
|
2103
|
+
<div style="font-size:48px; margin-bottom: 16px;">${isCorrupt ? "\u26A0\uFE0F" : "\u{1F4C4}"}</div>
|
|
2104
|
+
<h3 style="margin: 0 0 8px; color: #1e293b; font-size: 18px;">${ctx.metadata.name || "Word Document"}</h3>
|
|
2105
|
+
<p style="color: #64748b; margin: 0 0 16px; font-size: 14px; line-height: 1.5;">
|
|
2106
|
+
${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."}
|
|
2107
|
+
</p>
|
|
2088
2108
|
</div>
|
|
2089
2109
|
`;
|
|
2090
2110
|
if (!ctx.container.contains(wrapper)) {
|
|
@@ -2092,8 +2112,67 @@ var DocxPlugin = class {
|
|
|
2092
2112
|
}
|
|
2093
2113
|
}
|
|
2094
2114
|
}
|
|
2095
|
-
|
|
2096
|
-
const cards = wrapper.querySelectorAll(".fp-docx-page-card");
|
|
2115
|
+
let sections = Array.from(wrapper.querySelectorAll("section.docx"));
|
|
2116
|
+
const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
|
|
2117
|
+
if (sections.length === 1 && cards.length === 0) {
|
|
2118
|
+
const singleSec = sections[0];
|
|
2119
|
+
const contentContainer = singleSec.querySelector("article") || singleSec;
|
|
2120
|
+
const children = Array.from(contentContainer.children);
|
|
2121
|
+
const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
|
|
2122
|
+
const secH = singleSec.offsetHeight || singleSec.scrollHeight;
|
|
2123
|
+
if (secH > pageH * 1.25 && children.length > 1) {
|
|
2124
|
+
const childHeights = children.map((c) => {
|
|
2125
|
+
const rectH = c.getBoundingClientRect().height;
|
|
2126
|
+
const offH = c.offsetHeight;
|
|
2127
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
2128
|
+
const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
|
|
2129
|
+
return Math.max(rectH, offH, estH);
|
|
2130
|
+
});
|
|
2131
|
+
const parent = singleSec.parentElement || wrapper;
|
|
2132
|
+
const newSections = [singleSec];
|
|
2133
|
+
const headerEl = singleSec.querySelector("header");
|
|
2134
|
+
const footerEl = singleSec.querySelector("footer");
|
|
2135
|
+
contentContainer.innerHTML = "";
|
|
2136
|
+
singleSec.style.minHeight = `${pageH}px`;
|
|
2137
|
+
singleSec.style.boxSizing = "border-box";
|
|
2138
|
+
let curContent = contentContainer;
|
|
2139
|
+
let curH = 0;
|
|
2140
|
+
const maxH = pageH - 140;
|
|
2141
|
+
for (let i = 0; i < children.length; i++) {
|
|
2142
|
+
const child = children[i];
|
|
2143
|
+
const chH = childHeights[i];
|
|
2144
|
+
curContent.appendChild(child);
|
|
2145
|
+
curH += chH;
|
|
2146
|
+
if (curH >= maxH && i < children.length - 1) {
|
|
2147
|
+
const nextSec = document.createElement("section");
|
|
2148
|
+
nextSec.className = singleSec.className;
|
|
2149
|
+
nextSec.style.cssText = singleSec.style.cssText;
|
|
2150
|
+
nextSec.style.minHeight = `${pageH}px`;
|
|
2151
|
+
nextSec.style.boxSizing = "border-box";
|
|
2152
|
+
nextSec.style.backgroundColor = "#ffffff";
|
|
2153
|
+
nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
|
|
2154
|
+
nextSec.style.borderRadius = "4px";
|
|
2155
|
+
nextSec.style.marginBottom = "24px";
|
|
2156
|
+
if (headerEl) {
|
|
2157
|
+
nextSec.appendChild(headerEl.cloneNode(true));
|
|
2158
|
+
}
|
|
2159
|
+
const nextArticle = document.createElement("article");
|
|
2160
|
+
if (contentContainer.tagName.toLowerCase() === "article") {
|
|
2161
|
+
nextArticle.style.cssText = contentContainer.style.cssText;
|
|
2162
|
+
}
|
|
2163
|
+
nextSec.appendChild(nextArticle);
|
|
2164
|
+
if (footerEl) {
|
|
2165
|
+
nextSec.appendChild(footerEl.cloneNode(true));
|
|
2166
|
+
}
|
|
2167
|
+
parent.appendChild(nextSec);
|
|
2168
|
+
newSections.push(nextSec);
|
|
2169
|
+
curContent = nextArticle;
|
|
2170
|
+
curH = 0;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
sections = newSections;
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2097
2176
|
const pageElements = sections.length > 0 ? sections : cards;
|
|
2098
2177
|
const totalPages = Math.max(1, pageElements.length);
|
|
2099
2178
|
let currentPage = 1;
|
|
@@ -2130,6 +2209,7 @@ var DocxPlugin = class {
|
|
|
2130
2209
|
if (indicator) {
|
|
2131
2210
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
2132
2211
|
}
|
|
2212
|
+
ctx.container.scrollTop = 0;
|
|
2133
2213
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
2134
2214
|
};
|
|
2135
2215
|
if (totalPages > 1) {
|
|
@@ -2137,22 +2217,27 @@ var DocxPlugin = class {
|
|
|
2137
2217
|
}
|
|
2138
2218
|
scale = 1;
|
|
2139
2219
|
let rotation = 0;
|
|
2140
|
-
|
|
2220
|
+
let fitMode = "width";
|
|
2221
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
2141
2222
|
const activeEl = pageElements[currentPage - 1] || wrapper.firstElementChild || wrapper;
|
|
2142
2223
|
const elW = activeEl.offsetWidth || 816;
|
|
2143
|
-
const
|
|
2144
|
-
const availW = Math.max(
|
|
2145
|
-
const availH = Math.max(
|
|
2224
|
+
const singlePageH = Math.min(activeEl.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
2225
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
2226
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
2146
2227
|
const sW = availW / elW;
|
|
2147
|
-
const sH = availH /
|
|
2148
|
-
|
|
2228
|
+
const sH = availH / singlePageH;
|
|
2229
|
+
if (mode === "page") {
|
|
2230
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
2231
|
+
}
|
|
2232
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
2149
2233
|
};
|
|
2150
2234
|
const applyTransform = () => {
|
|
2151
2235
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
2152
2236
|
wrapper.style.transformOrigin = "top center";
|
|
2153
2237
|
};
|
|
2154
2238
|
setTimeout(() => {
|
|
2155
|
-
|
|
2239
|
+
fitMode = "width";
|
|
2240
|
+
scale = calculateFitScale("width");
|
|
2156
2241
|
applyTransform();
|
|
2157
2242
|
}, 60);
|
|
2158
2243
|
const cleanup = () => {
|
|
@@ -2186,7 +2271,8 @@ var DocxPlugin = class {
|
|
|
2186
2271
|
applyTransform();
|
|
2187
2272
|
},
|
|
2188
2273
|
fitToPage: () => {
|
|
2189
|
-
|
|
2274
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
2275
|
+
scale = calculateFitScale(fitMode);
|
|
2190
2276
|
rotation = 0;
|
|
2191
2277
|
applyTransform();
|
|
2192
2278
|
},
|
|
@@ -2630,11 +2716,9 @@ var ExcelPlugin = class {
|
|
|
2630
2716
|
const calculateFitScale = () => {
|
|
2631
2717
|
const table = contentArea.querySelector("table");
|
|
2632
2718
|
if (!table) return 1;
|
|
2633
|
-
const availW = Math.max(
|
|
2634
|
-
const availH = Math.max(200, container.clientHeight - 80);
|
|
2719
|
+
const availW = Math.max(280, container.clientWidth - 48);
|
|
2635
2720
|
const tW = table.offsetWidth || 800;
|
|
2636
|
-
|
|
2637
|
-
return Math.min(1, Math.min(availW / tW, availH / tH));
|
|
2721
|
+
return Math.max(0.65, Math.min(1, availW / tW));
|
|
2638
2722
|
};
|
|
2639
2723
|
try {
|
|
2640
2724
|
wb = XLSX.read(new Uint8Array(ctx.buffer), { type: "array", cellDates: true });
|
|
@@ -3058,17 +3142,39 @@ var CodePlugin = class {
|
|
|
3058
3142
|
let rawPages = [];
|
|
3059
3143
|
if (isTxt) {
|
|
3060
3144
|
const explicitPages = fullText.split(/(?:\f|\x0C)/);
|
|
3145
|
+
const charsPerLine = 85;
|
|
3146
|
+
const maxVisualLines = 45;
|
|
3147
|
+
const charsPerPage = charsPerLine * maxVisualLines;
|
|
3061
3148
|
for (const ep of explicitPages) {
|
|
3062
3149
|
const lines = ep.split(/\r?\n/);
|
|
3063
3150
|
let currentChunk = [];
|
|
3151
|
+
let currentLines = 0;
|
|
3064
3152
|
for (let i = 0; i < lines.length; i++) {
|
|
3065
|
-
|
|
3066
|
-
|
|
3153
|
+
const line = lines[i];
|
|
3154
|
+
const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
|
|
3155
|
+
if (currentLines + vLines > maxVisualLines && currentChunk.length > 0) {
|
|
3067
3156
|
rawPages.push(currentChunk.join("\n"));
|
|
3068
3157
|
currentChunk = [];
|
|
3158
|
+
currentLines = 0;
|
|
3159
|
+
}
|
|
3160
|
+
if (vLines > maxVisualLines) {
|
|
3161
|
+
let remaining = line;
|
|
3162
|
+
while (remaining.length > charsPerPage) {
|
|
3163
|
+
let splitIdx = remaining.lastIndexOf(" ", charsPerPage);
|
|
3164
|
+
if (splitIdx < charsPerPage * 0.75) splitIdx = charsPerPage;
|
|
3165
|
+
rawPages.push(remaining.slice(0, splitIdx));
|
|
3166
|
+
remaining = remaining.slice(splitIdx).trimStart();
|
|
3167
|
+
}
|
|
3168
|
+
if (remaining.length > 0) {
|
|
3169
|
+
currentChunk.push(remaining);
|
|
3170
|
+
currentLines = Math.ceil(remaining.length / charsPerLine);
|
|
3171
|
+
}
|
|
3172
|
+
} else {
|
|
3173
|
+
currentChunk.push(line);
|
|
3174
|
+
currentLines += vLines;
|
|
3069
3175
|
}
|
|
3070
3176
|
}
|
|
3071
|
-
if (currentChunk.length > 0
|
|
3177
|
+
if (currentChunk.length > 0) {
|
|
3072
3178
|
rawPages.push(currentChunk.join("\n"));
|
|
3073
3179
|
}
|
|
3074
3180
|
}
|
|
@@ -3178,6 +3284,7 @@ var CodePlugin = class {
|
|
|
3178
3284
|
if (indicator) {
|
|
3179
3285
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
3180
3286
|
}
|
|
3287
|
+
container.scrollTop = 0;
|
|
3181
3288
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
3182
3289
|
};
|
|
3183
3290
|
if (totalPages > 1) {
|
|
@@ -3231,7 +3338,7 @@ var CodePlugin = class {
|
|
|
3231
3338
|
fitToPage: () => {
|
|
3232
3339
|
fontSize = 13;
|
|
3233
3340
|
rotation = 0;
|
|
3234
|
-
zoomLevel = 1;
|
|
3341
|
+
zoomLevel = isTxt ? Math.max(0.65, Math.min(1.05, (container.clientWidth - 48) / 816)) : 1;
|
|
3235
3342
|
updateTransform();
|
|
3236
3343
|
},
|
|
3237
3344
|
rotateCW: () => {
|
|
@@ -4213,20 +4320,27 @@ var RtfPlugin = class {
|
|
|
4213
4320
|
let scale = 1;
|
|
4214
4321
|
let rotation = 0;
|
|
4215
4322
|
let pageElements = [];
|
|
4216
|
-
|
|
4323
|
+
let fitMode = "width";
|
|
4324
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
4217
4325
|
const activeEl = pageElements[currentPage - 1] || wrapper;
|
|
4218
4326
|
const elW = activeEl.offsetWidth || 850;
|
|
4219
|
-
const
|
|
4220
|
-
const availW = Math.max(
|
|
4221
|
-
const availH = Math.max(
|
|
4222
|
-
|
|
4327
|
+
const singlePageH = Math.min(activeEl.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
4328
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
4329
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
4330
|
+
const sW = availW / elW;
|
|
4331
|
+
const sH = availH / singlePageH;
|
|
4332
|
+
if (mode === "page") {
|
|
4333
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
4334
|
+
}
|
|
4335
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
4223
4336
|
};
|
|
4224
4337
|
const applyTransform = () => {
|
|
4225
4338
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
4226
4339
|
wrapper.style.transformOrigin = "top center";
|
|
4227
4340
|
};
|
|
4228
4341
|
setTimeout(() => {
|
|
4229
|
-
|
|
4342
|
+
fitMode = "width";
|
|
4343
|
+
scale = calculateFitScale("width");
|
|
4230
4344
|
applyTransform();
|
|
4231
4345
|
}, 60);
|
|
4232
4346
|
try {
|
|
@@ -4235,11 +4349,60 @@ var RtfPlugin = class {
|
|
|
4235
4349
|
}
|
|
4236
4350
|
const doc = new RTFJS.Document(ctx.buffer, {});
|
|
4237
4351
|
const htmlElements = await doc.render();
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4352
|
+
if (htmlElements.length === 1) {
|
|
4353
|
+
const singleEl = htmlElements[0];
|
|
4354
|
+
wrapper.appendChild(singleEl);
|
|
4355
|
+
const children = Array.from(singleEl.children);
|
|
4356
|
+
const secH = singleEl.offsetHeight || singleEl.scrollHeight;
|
|
4357
|
+
if (secH > 1300 && children.length > 1) {
|
|
4358
|
+
const childHeights = children.map((c) => {
|
|
4359
|
+
const rectH = c.getBoundingClientRect().height;
|
|
4360
|
+
const offH = c.offsetHeight;
|
|
4361
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
4362
|
+
const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
|
|
4363
|
+
return Math.max(rectH, offH, estH);
|
|
4364
|
+
});
|
|
4365
|
+
wrapper.innerHTML = "";
|
|
4366
|
+
const createRtfCard = () => {
|
|
4367
|
+
const card = document.createElement("div");
|
|
4368
|
+
card.className = "fp-rtf-page-card";
|
|
4369
|
+
card.style.backgroundColor = "#ffffff";
|
|
4370
|
+
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
4371
|
+
card.style.borderRadius = "4px";
|
|
4372
|
+
card.style.padding = "72px 56px";
|
|
4373
|
+
card.style.width = "816px";
|
|
4374
|
+
card.style.minHeight = "1056px";
|
|
4375
|
+
card.style.boxSizing = "border-box";
|
|
4376
|
+
card.style.marginBottom = "24px";
|
|
4377
|
+
return card;
|
|
4378
|
+
};
|
|
4379
|
+
let curCard = createRtfCard();
|
|
4380
|
+
wrapper.appendChild(curCard);
|
|
4381
|
+
pageElements = [curCard];
|
|
4382
|
+
let curH = 0;
|
|
4383
|
+
const maxH = 920;
|
|
4384
|
+
for (let i = 0; i < children.length; i++) {
|
|
4385
|
+
const child = children[i];
|
|
4386
|
+
const chH = childHeights[i];
|
|
4387
|
+
curCard.appendChild(child);
|
|
4388
|
+
curH += chH;
|
|
4389
|
+
if (curH >= maxH && i < children.length - 1) {
|
|
4390
|
+
curCard = createRtfCard();
|
|
4391
|
+
wrapper.appendChild(curCard);
|
|
4392
|
+
pageElements.push(curCard);
|
|
4393
|
+
curH = 0;
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
} else {
|
|
4397
|
+
pageElements = [singleEl];
|
|
4398
|
+
}
|
|
4399
|
+
} else {
|
|
4400
|
+
pageElements = htmlElements;
|
|
4401
|
+
for (let i = 0; i < htmlElements.length; i++) {
|
|
4402
|
+
const el = htmlElements[i];
|
|
4403
|
+
el.style.display = i === 0 ? "block" : "none";
|
|
4404
|
+
wrapper.appendChild(el);
|
|
4405
|
+
}
|
|
4243
4406
|
}
|
|
4244
4407
|
} catch (err) {
|
|
4245
4408
|
console.warn("[RtfPlugin] RTF render error, fallback text:", err);
|
|
@@ -4305,6 +4468,7 @@ var RtfPlugin = class {
|
|
|
4305
4468
|
if (indicator) {
|
|
4306
4469
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
4307
4470
|
}
|
|
4471
|
+
ctx.container.scrollTop = 0;
|
|
4308
4472
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
4309
4473
|
};
|
|
4310
4474
|
if (totalPages > 1) {
|
|
@@ -4335,7 +4499,8 @@ var RtfPlugin = class {
|
|
|
4335
4499
|
applyTransform();
|
|
4336
4500
|
},
|
|
4337
4501
|
fitToPage: () => {
|
|
4338
|
-
|
|
4502
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
4503
|
+
scale = calculateFitScale(fitMode);
|
|
4339
4504
|
rotation = 0;
|
|
4340
4505
|
applyTransform();
|
|
4341
4506
|
},
|
|
@@ -4654,19 +4819,29 @@ var OpenDocumentPlugin = class {
|
|
|
4654
4819
|
ctx.container.appendChild(container);
|
|
4655
4820
|
let scale = 1;
|
|
4656
4821
|
let rotation = 0;
|
|
4657
|
-
|
|
4822
|
+
let fitMode = "width";
|
|
4823
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
4658
4824
|
const elW = wrapper.offsetWidth || 850;
|
|
4659
|
-
const
|
|
4660
|
-
const availW = Math.max(
|
|
4661
|
-
const availH = Math.max(
|
|
4662
|
-
|
|
4825
|
+
const singlePageH = Math.min(wrapper.offsetHeight || 1056, Math.round(elW * 1.32));
|
|
4826
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
4827
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
4828
|
+
const sW = availW / elW;
|
|
4829
|
+
const sH = availH / (isPresentation ? 540 : singlePageH);
|
|
4830
|
+
if (isPresentation) {
|
|
4831
|
+
return Math.min(1, Math.min(sW, sH));
|
|
4832
|
+
}
|
|
4833
|
+
if (mode === "page") {
|
|
4834
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
4835
|
+
}
|
|
4836
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
4663
4837
|
};
|
|
4664
4838
|
const applyTransform = () => {
|
|
4665
4839
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
4666
4840
|
wrapper.style.transformOrigin = "top center";
|
|
4667
4841
|
};
|
|
4668
4842
|
setTimeout(() => {
|
|
4669
|
-
|
|
4843
|
+
fitMode = "width";
|
|
4844
|
+
scale = calculateFitScale("width");
|
|
4670
4845
|
applyTransform();
|
|
4671
4846
|
}, 60);
|
|
4672
4847
|
let currentPage = 1;
|
|
@@ -4765,12 +4940,9 @@ var OpenDocumentPlugin = class {
|
|
|
4765
4940
|
page.style.backgroundColor = "#ffffff";
|
|
4766
4941
|
page.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
|
|
4767
4942
|
page.style.borderRadius = "4px";
|
|
4768
|
-
page.style.boxSizing = "border-box";
|
|
4769
4943
|
page.style.display = idx === 0 ? "block" : "none";
|
|
4770
|
-
page.style.
|
|
4771
|
-
page.style.
|
|
4772
|
-
page.style.left = "50%";
|
|
4773
|
-
page.style.transform = "translateX(-50%)";
|
|
4944
|
+
page.style.margin = "0 auto 24px";
|
|
4945
|
+
page.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
|
|
4774
4946
|
elements.forEach((el) => page.appendChild(el));
|
|
4775
4947
|
wrapper.appendChild(page);
|
|
4776
4948
|
slides.push(page);
|
|
@@ -4808,6 +4980,7 @@ var OpenDocumentPlugin = class {
|
|
|
4808
4980
|
if (indicator) {
|
|
4809
4981
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
4810
4982
|
}
|
|
4983
|
+
container.scrollTop = 0;
|
|
4811
4984
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
4812
4985
|
};
|
|
4813
4986
|
return {
|
|
@@ -4827,7 +5000,8 @@ var OpenDocumentPlugin = class {
|
|
|
4827
5000
|
applyTransform();
|
|
4828
5001
|
},
|
|
4829
5002
|
fitToPage: () => {
|
|
4830
|
-
|
|
5003
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
5004
|
+
scale = calculateFitScale(fitMode);
|
|
4831
5005
|
rotation = 0;
|
|
4832
5006
|
applyTransform();
|
|
4833
5007
|
},
|
|
@@ -5299,20 +5473,28 @@ var DocPlugin = class {
|
|
|
5299
5473
|
if (indicator) {
|
|
5300
5474
|
indicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
|
5301
5475
|
}
|
|
5476
|
+
container.scrollTop = 0;
|
|
5302
5477
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
5303
5478
|
};
|
|
5304
5479
|
if (totalPages > 1) {
|
|
5305
5480
|
showPage(1);
|
|
5306
5481
|
}
|
|
5307
|
-
|
|
5482
|
+
let fitMode = "width";
|
|
5483
|
+
const calculateFitScale = (mode = fitMode) => {
|
|
5308
5484
|
const elW = 816;
|
|
5309
5485
|
const elH = 1056;
|
|
5310
|
-
const availW = Math.max(
|
|
5311
|
-
const availH = Math.max(
|
|
5312
|
-
|
|
5486
|
+
const availW = Math.max(280, ctx.container.clientWidth - 48);
|
|
5487
|
+
const availH = Math.max(280, ctx.container.clientHeight - 80);
|
|
5488
|
+
const sW = availW / elW;
|
|
5489
|
+
const sH = availH / elH;
|
|
5490
|
+
if (mode === "page") {
|
|
5491
|
+
return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
|
|
5492
|
+
}
|
|
5493
|
+
return Math.max(0.65, Math.min(1.05, sW));
|
|
5313
5494
|
};
|
|
5314
5495
|
setTimeout(() => {
|
|
5315
|
-
|
|
5496
|
+
fitMode = "width";
|
|
5497
|
+
scale = calculateFitScale("width");
|
|
5316
5498
|
applyTransform();
|
|
5317
5499
|
}, 60);
|
|
5318
5500
|
const cleanup = () => {
|
|
@@ -5340,7 +5522,8 @@ var DocPlugin = class {
|
|
|
5340
5522
|
applyTransform();
|
|
5341
5523
|
},
|
|
5342
5524
|
fitToPage: () => {
|
|
5343
|
-
|
|
5525
|
+
fitMode = fitMode === "width" ? "page" : "width";
|
|
5526
|
+
scale = calculateFitScale(fitMode);
|
|
5344
5527
|
rotation = 0;
|
|
5345
5528
|
applyTransform();
|
|
5346
5529
|
},
|
|
@@ -5468,45 +5651,50 @@ var DocPlugin = class {
|
|
|
5468
5651
|
}
|
|
5469
5652
|
splitIntoPages(text) {
|
|
5470
5653
|
if (!text) return [""];
|
|
5471
|
-
const
|
|
5472
|
-
|
|
5473
|
-
|
|
5654
|
+
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
|
|
5655
|
+
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);
|
|
5656
|
+
if (explicitParts.length === 0) explicitParts.push(normalized);
|
|
5657
|
+
const maxLinesPerPage = 32;
|
|
5658
|
+
const charsPerLine = 80;
|
|
5474
5659
|
const finalPages = [];
|
|
5475
5660
|
for (const part of explicitParts) {
|
|
5476
|
-
const lines = part.split(
|
|
5661
|
+
const lines = part.split("\n");
|
|
5477
5662
|
let currentLines = [];
|
|
5478
5663
|
let count = 0;
|
|
5479
5664
|
for (const line of lines) {
|
|
5480
|
-
|
|
5481
|
-
count
|
|
5482
|
-
if (count >= maxLinesPerPage) {
|
|
5665
|
+
const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
|
|
5666
|
+
if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
|
|
5483
5667
|
finalPages.push(currentLines.join("\n"));
|
|
5484
5668
|
currentLines = [];
|
|
5485
5669
|
count = 0;
|
|
5486
5670
|
}
|
|
5671
|
+
currentLines.push(line);
|
|
5672
|
+
count += vLines;
|
|
5487
5673
|
}
|
|
5488
5674
|
if (currentLines.length > 0) {
|
|
5489
5675
|
finalPages.push(currentLines.join("\n"));
|
|
5490
5676
|
}
|
|
5491
5677
|
}
|
|
5492
|
-
return finalPages.length > 0 ? finalPages : [
|
|
5678
|
+
return finalPages.length > 0 ? finalPages : [normalized];
|
|
5493
5679
|
}
|
|
5494
5680
|
/**
|
|
5495
5681
|
* Format cleaned extracted text into attractive HTML paragraphs, headings, and lists
|
|
5496
5682
|
*/
|
|
5497
5683
|
formatDocToHtml(text, filename) {
|
|
5498
|
-
const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").split("\n");
|
|
5684
|
+
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");
|
|
5499
5685
|
let html = "";
|
|
5500
5686
|
let inList = false;
|
|
5501
5687
|
let tableLines = [];
|
|
5502
5688
|
const flushTable = () => {
|
|
5503
5689
|
if (tableLines.length > 0) {
|
|
5504
|
-
html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size:
|
|
5505
|
-
for (
|
|
5506
|
-
|
|
5507
|
-
const
|
|
5690
|
+
html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px; font-family: Calibri, sans-serif;">';
|
|
5691
|
+
for (let rIdx = 0; rIdx < tableLines.length; rIdx++) {
|
|
5692
|
+
const tLine = tableLines[rIdx];
|
|
5693
|
+
const isHeader = rIdx === 0;
|
|
5694
|
+
html += `<tr style="${isHeader ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
|
|
5695
|
+
const cols = tLine.split(" ").filter((c) => c.trim().length > 0);
|
|
5508
5696
|
for (const col of cols) {
|
|
5509
|
-
html += `<td style="border: 1px solid #cbd5e1; padding:
|
|
5697
|
+
html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px;">${DOMPurify6.sanitize(col.trim())}</td>`;
|
|
5510
5698
|
}
|
|
5511
5699
|
html += "</tr>";
|
|
5512
5700
|
}
|
|
@@ -5519,27 +5707,18 @@ var DocPlugin = class {
|
|
|
5519
5707
|
let line = lines[i];
|
|
5520
5708
|
let tabCount = (line.match(/\t/g) || []).length;
|
|
5521
5709
|
if (tabCount > 0) {
|
|
5522
|
-
let
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
const nextTabCount = (lines[j].match(/\t/g) || []).length;
|
|
5526
|
-
if (nextTabCount === tabCount) {
|
|
5527
|
-
consecutiveTableLines++;
|
|
5528
|
-
j++;
|
|
5529
|
-
} else {
|
|
5530
|
-
break;
|
|
5531
|
-
}
|
|
5710
|
+
let j = i;
|
|
5711
|
+
while (j < lines.length && (lines[j].match(/\t/g) || []).length > 0) {
|
|
5712
|
+
j++;
|
|
5532
5713
|
}
|
|
5533
|
-
if (
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
inList = false;
|
|
5537
|
-
}
|
|
5538
|
-
tableLines = lines.slice(i, j);
|
|
5539
|
-
flushTable();
|
|
5540
|
-
i = j;
|
|
5541
|
-
continue;
|
|
5714
|
+
if (inList) {
|
|
5715
|
+
html += "</ul>";
|
|
5716
|
+
inList = false;
|
|
5542
5717
|
}
|
|
5718
|
+
tableLines = lines.slice(i, j);
|
|
5719
|
+
flushTable();
|
|
5720
|
+
i = j;
|
|
5721
|
+
continue;
|
|
5543
5722
|
}
|
|
5544
5723
|
line = line.trim();
|
|
5545
5724
|
if (!line) {
|