@files-preview-app/preview-file 1.3.4 → 1.3.5
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 +261 -210
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.js +261 -210
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +261 -210
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +261 -210
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +261 -210
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +261 -210
- package/dist/react.js.map +1 -1
- package/dist/vue.cjs +261 -210
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +261 -210
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -5247,7 +5247,7 @@ function cleanRtfText(raw) {
|
|
|
5247
5247
|
return String.fromCharCode(num);
|
|
5248
5248
|
}).replace(/\\'([0-9a-fA-F]{2})/g, (_, hex) => {
|
|
5249
5249
|
return String.fromCharCode(parseInt(hex, 16));
|
|
5250
|
-
}).replace(/\\tab\b/g, " ").replace(/\\emdash\b/g, "\u2014").replace(/\\endash\b/g, "\u2013").replace(/\\bullet\b/g, "\u2022").replace(/\\lquote\b/g, "\u2018").replace(/\\rquote\b/g, "\u2019").replace(/\\ldblquote\b/g, "\u201C").replace(/\\rdblquote\b/g, "\u201D").replace(
|
|
5250
|
+
}).replace(/\\tab\b/g, " ").replace(/\\emdash\b/g, "\u2014").replace(/\\endash\b/g, "\u2013").replace(/\\bullet\b/g, "\u2022").replace(/\\lquote\b/g, "\u2018").replace(/\\rquote\b/g, "\u2019").replace(/\\ldblquote\b/g, "\u201C").replace(/\\rdblquote\b/g, "\u201D").replace(/\\[a-zA-Z]+-?\d*\s?/g, " ").replace(/[{}\r\n]/g, " ").replace(/\s+/g, " ").trim();
|
|
5251
5251
|
}
|
|
5252
5252
|
function parseRtfTables(rtfText) {
|
|
5253
5253
|
const rowSegments = rtfText.split(/\\row\b/);
|
|
@@ -5287,17 +5287,12 @@ function parseRtfTables(rtfText) {
|
|
|
5287
5287
|
}
|
|
5288
5288
|
const isNewTable = !currentTable || segmentStart - currentTable.lastEnd > 2500;
|
|
5289
5289
|
if (isNewTable) {
|
|
5290
|
-
const prevTextSlice = rtfText.slice(Math.max(0, segmentStart - 4e3), segmentStart);
|
|
5291
|
-
const cleanPrev = cleanRtfText(prevTextSlice);
|
|
5292
|
-
const anchorBefore = cleanPrev.slice(-80).trim();
|
|
5293
5290
|
currentTable = {
|
|
5294
5291
|
id: `RTF_TABLE_${rawTables.length}`,
|
|
5295
5292
|
startPos: segmentStart,
|
|
5296
5293
|
lastEnd: segmentEnd,
|
|
5297
5294
|
rows: [],
|
|
5298
|
-
columnWidths: cellWidths
|
|
5299
|
-
anchorBefore,
|
|
5300
|
-
anchorAfter: ""
|
|
5295
|
+
columnWidths: cellWidths
|
|
5301
5296
|
};
|
|
5302
5297
|
rawTables.push(currentTable);
|
|
5303
5298
|
}
|
|
@@ -5311,20 +5306,13 @@ function parseRtfTables(rtfText) {
|
|
|
5311
5306
|
}
|
|
5312
5307
|
charOffset += segment.length + 4;
|
|
5313
5308
|
}
|
|
5314
|
-
rawTables.forEach((tbl) => {
|
|
5315
|
-
const afterSlice = rtfText.slice(tbl.lastEnd, Math.min(rtfText.length, tbl.lastEnd + 2e3));
|
|
5316
|
-
const cleanAfter = cleanRtfText(afterSlice);
|
|
5317
|
-
tbl.anchorAfter = cleanAfter.slice(0, 80).trim();
|
|
5318
|
-
});
|
|
5319
5309
|
return rawTables.map((tbl) => {
|
|
5320
5310
|
const totalW = (tbl.columnWidths || []).reduce((a, b) => a + b, 0);
|
|
5321
5311
|
const colPercents = totalW > 0 ? tbl.columnWidths.map((w) => Math.round(w / totalW * 100)) : [];
|
|
5322
5312
|
return {
|
|
5323
5313
|
id: tbl.id,
|
|
5324
5314
|
rows: tbl.rows.map((r) => r.cells),
|
|
5325
|
-
colPercents
|
|
5326
|
-
anchorBefore: tbl.anchorBefore,
|
|
5327
|
-
anchorAfter: tbl.anchorAfter
|
|
5315
|
+
colPercents
|
|
5328
5316
|
};
|
|
5329
5317
|
});
|
|
5330
5318
|
}
|
|
@@ -5337,8 +5325,6 @@ function renderRtfTableElement(table) {
|
|
|
5337
5325
|
tableEl.style.fontSize = "10pt";
|
|
5338
5326
|
tableEl.style.lineHeight = "1.5";
|
|
5339
5327
|
tableEl.style.border = "1px solid #cbd5e1";
|
|
5340
|
-
tableEl.style.borderRadius = "4px";
|
|
5341
|
-
tableEl.style.boxSizing = "border-box";
|
|
5342
5328
|
tableEl.style.backgroundColor = "#ffffff";
|
|
5343
5329
|
const thead = document.createElement("thead");
|
|
5344
5330
|
const tbody = document.createElement("tbody");
|
|
@@ -5347,27 +5333,17 @@ function renderRtfTableElement(table) {
|
|
|
5347
5333
|
const isHeader = rIdx === 0;
|
|
5348
5334
|
if (isHeader) {
|
|
5349
5335
|
tr.style.backgroundColor = "#f8fafc";
|
|
5350
|
-
tr.style.borderBottom = "2px solid #cbd5e1";
|
|
5351
|
-
} else {
|
|
5352
|
-
tr.style.borderBottom = "1px solid #e2e8f0";
|
|
5353
|
-
if (rIdx % 2 === 0) {
|
|
5354
|
-
tr.style.backgroundColor = "#fcfdfe";
|
|
5355
|
-
}
|
|
5356
5336
|
}
|
|
5357
5337
|
rowCells.forEach((cellText, cIdx) => {
|
|
5358
5338
|
const cellEl = document.createElement(isHeader ? "th" : "td");
|
|
5359
5339
|
cellEl.style.padding = "8px 12px";
|
|
5360
5340
|
cellEl.style.border = "1px solid #cbd5e1";
|
|
5361
5341
|
cellEl.style.verticalAlign = "top";
|
|
5362
|
-
cellEl.style.color = isHeader ? "#0f172a" : "#1e293b";
|
|
5363
|
-
cellEl.style.fontWeight = isHeader ? "600" : "normal";
|
|
5364
5342
|
if (table.colPercents && table.colPercents[cIdx]) {
|
|
5365
5343
|
cellEl.style.width = `${table.colPercents[cIdx]}%`;
|
|
5366
5344
|
}
|
|
5367
5345
|
if (/^\d+$/.test(cellText.trim()) || cellText.trim() === "#") {
|
|
5368
5346
|
cellEl.style.textAlign = "center";
|
|
5369
|
-
} else {
|
|
5370
|
-
cellEl.style.textAlign = "left";
|
|
5371
5347
|
}
|
|
5372
5348
|
cellEl.textContent = cellText;
|
|
5373
5349
|
tr.appendChild(cellEl);
|
|
@@ -5382,23 +5358,19 @@ function renderRtfTableElement(table) {
|
|
|
5382
5358
|
tableEl.appendChild(tbody);
|
|
5383
5359
|
return tableEl;
|
|
5384
5360
|
}
|
|
5385
|
-
function
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
const vb = svg.getAttribute("viewBox") || "";
|
|
5399
|
-
return `svg_${vb}_${svg.innerHTML.length}`;
|
|
5400
|
-
}
|
|
5401
|
-
return null;
|
|
5361
|
+
function isHeadingElement(el) {
|
|
5362
|
+
if (["H1", "H2", "H3", "H4"].includes(el.tagName)) return true;
|
|
5363
|
+
const spans = el.querySelectorAll ? Array.from(el.querySelectorAll("span, b, strong, div")) : [];
|
|
5364
|
+
for (const s of spans) {
|
|
5365
|
+
const hEl = s;
|
|
5366
|
+
const fs = parseFloat(hEl.style.fontSize) || 0;
|
|
5367
|
+
const isBold = hEl.style.fontWeight === "bold" || parseInt(hEl.style.fontWeight, 10) >= 600 || ["B", "STRONG"].includes(hEl.tagName);
|
|
5368
|
+
if (isBold && fs >= 14) return true;
|
|
5369
|
+
}
|
|
5370
|
+
const elFs = parseFloat(el.style.fontSize) || 0;
|
|
5371
|
+
const elBold = el.style.fontWeight === "bold" || parseInt(el.style.fontWeight, 10) >= 600;
|
|
5372
|
+
if (elBold && elFs >= 14) return true;
|
|
5373
|
+
return false;
|
|
5402
5374
|
}
|
|
5403
5375
|
var RtfPlugin = class {
|
|
5404
5376
|
id = "rtf";
|
|
@@ -5511,10 +5483,66 @@ var RtfPlugin = class {
|
|
|
5511
5483
|
return actions;
|
|
5512
5484
|
}
|
|
5513
5485
|
async render(ctx) {
|
|
5486
|
+
const rawRtf = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5487
|
+
const paperwMatch = rawRtf.match(/\\paperw(\d+)/);
|
|
5488
|
+
const paperhMatch = rawRtf.match(/\\paperh(\d+)/);
|
|
5489
|
+
const marglMatch = rawRtf.match(/\\margl(\d+)/);
|
|
5490
|
+
const margrMatch = rawRtf.match(/\\margr(\d+)/);
|
|
5491
|
+
const margtMatch = rawRtf.match(/\\margt(\d+)/);
|
|
5492
|
+
const margbMatch = rawRtf.match(/\\margb(\d+)/);
|
|
5493
|
+
const paperwTwips = paperwMatch ? parseInt(paperwMatch[1], 10) : 11906;
|
|
5494
|
+
const paperhTwips = paperhMatch ? parseInt(paperhMatch[1], 10) : 16838;
|
|
5495
|
+
const marglTwips = marglMatch ? parseInt(marglMatch[1], 10) : 1134;
|
|
5496
|
+
const margrTwips = margrMatch ? parseInt(margrMatch[1], 10) : 1134;
|
|
5497
|
+
const margtTwips = margtMatch ? parseInt(margtMatch[1], 10) : 1134;
|
|
5498
|
+
const margbTwips = margbMatch ? parseInt(margbMatch[1], 10) : 1134;
|
|
5499
|
+
const pageWidth = Math.round(paperwTwips / 15);
|
|
5500
|
+
const pageHeight = Math.round(paperhTwips / 15);
|
|
5501
|
+
const padLeft = Math.round(marglTwips / 15);
|
|
5502
|
+
const padRight = Math.round(margrTwips / 15);
|
|
5503
|
+
const padTop = Math.round(margtTwips / 15);
|
|
5504
|
+
const padBottom = Math.round(margbTwips / 15);
|
|
5505
|
+
const printableHeight = pageHeight - padTop - padBottom;
|
|
5506
|
+
const extractedImages = [];
|
|
5507
|
+
let p = 0;
|
|
5508
|
+
while ((p = rawRtf.indexOf("\\pict", p)) !== -1) {
|
|
5509
|
+
const startP = p;
|
|
5510
|
+
p += 5;
|
|
5511
|
+
const header = rawRtf.substring(startP, startP + 600);
|
|
5512
|
+
let mime = "";
|
|
5513
|
+
let magic = "";
|
|
5514
|
+
if (header.includes("\\pngblip")) {
|
|
5515
|
+
mime = "image/png";
|
|
5516
|
+
magic = "89504e47";
|
|
5517
|
+
} else if (header.includes("\\jpegblip")) {
|
|
5518
|
+
mime = "image/jpeg";
|
|
5519
|
+
magic = "ffd8ff";
|
|
5520
|
+
}
|
|
5521
|
+
if (!mime || !magic) continue;
|
|
5522
|
+
const magicPos = rawRtf.indexOf(magic, startP);
|
|
5523
|
+
if (magicPos === -1 || magicPos - startP > 3e3) continue;
|
|
5524
|
+
let endP = magicPos;
|
|
5525
|
+
while (endP < rawRtf.length && /[0-9a-fA-F\r\n\s]/.test(rawRtf[endP])) {
|
|
5526
|
+
endP++;
|
|
5527
|
+
}
|
|
5528
|
+
const cleanHex = rawRtf.substring(magicPos, endP).replace(/[\r\n\s]/g, "");
|
|
5529
|
+
if (cleanHex.length < 100) continue;
|
|
5530
|
+
const hexLen = cleanHex.length / 2;
|
|
5531
|
+
const u8 = new Uint8Array(hexLen);
|
|
5532
|
+
for (let k = 0; k < hexLen; k++) {
|
|
5533
|
+
u8[k] = parseInt(cleanHex.substr(k * 2, 2), 16);
|
|
5534
|
+
}
|
|
5535
|
+
let bStr = "";
|
|
5536
|
+
for (let k = 0; k < u8.length; k += 8192) {
|
|
5537
|
+
bStr += String.fromCharCode.apply(null, Array.from(u8.subarray(k, k + 8192)));
|
|
5538
|
+
}
|
|
5539
|
+
extractedImages.push({ mime, dataUrl: `data:${mime};base64,${btoa(bStr)}`, offset: startP });
|
|
5540
|
+
}
|
|
5541
|
+
const tables = parseRtfTables(rawRtf);
|
|
5514
5542
|
const wrapper = document.createElement("div");
|
|
5515
5543
|
wrapper.className = "fp-rtf-wrapper";
|
|
5516
5544
|
wrapper.style.padding = "0";
|
|
5517
|
-
wrapper.style.width =
|
|
5545
|
+
wrapper.style.width = `${pageWidth}px`;
|
|
5518
5546
|
wrapper.style.margin = "0 auto";
|
|
5519
5547
|
wrapper.style.boxSizing = "border-box";
|
|
5520
5548
|
wrapper.style.display = "flex";
|
|
@@ -5534,9 +5562,8 @@ var RtfPlugin = class {
|
|
|
5534
5562
|
let isUserZoomed = false;
|
|
5535
5563
|
let fitMode = ctx?.options?.fitMode || "width";
|
|
5536
5564
|
const calculateFitScale = (mode = fitMode) => {
|
|
5537
|
-
const
|
|
5538
|
-
const
|
|
5539
|
-
const singlePageH = activeEl?.offsetHeight || 1056;
|
|
5565
|
+
const elW = pageWidth;
|
|
5566
|
+
const singlePageH = pageHeight;
|
|
5540
5567
|
const availW = Math.max(280, ctx.container.clientWidth - 32);
|
|
5541
5568
|
const availH = Math.max(280, ctx.container.clientHeight - 32);
|
|
5542
5569
|
const sW = availW / elW;
|
|
@@ -5549,8 +5576,7 @@ var RtfPlugin = class {
|
|
|
5549
5576
|
const applyTransform = () => {
|
|
5550
5577
|
wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
|
|
5551
5578
|
wrapper.style.transformOrigin = "top center";
|
|
5552
|
-
const
|
|
5553
|
-
const baseH = activeEl?.offsetHeight || 1056;
|
|
5579
|
+
const baseH = pageHeight;
|
|
5554
5580
|
const scaledH = baseH * scale;
|
|
5555
5581
|
const extraH = Math.max(0, scaledH - baseH);
|
|
5556
5582
|
wrapper.style.marginBottom = `${extraH + 32}px`;
|
|
@@ -5570,193 +5596,220 @@ var RtfPlugin = class {
|
|
|
5570
5596
|
if (typeof RTFJS.loggingEnabled === "function") {
|
|
5571
5597
|
RTFJS.loggingEnabled(false);
|
|
5572
5598
|
}
|
|
5573
|
-
const rawText = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5574
|
-
const tables = parseRtfTables(rawText);
|
|
5575
|
-
const seenMediaSignatures = /* @__PURE__ */ new Set();
|
|
5576
5599
|
const doc = new RTFJS.Document(ctx.buffer, {
|
|
5577
5600
|
onPicture: (isLegacy, createPic) => {
|
|
5578
|
-
if (isLegacy === true)
|
|
5579
|
-
|
|
5580
|
-
}
|
|
5581
|
-
const pic = createPic();
|
|
5582
|
-
if (!pic) return null;
|
|
5583
|
-
const fp = extractMediaFingerprint(pic);
|
|
5584
|
-
if (fp) {
|
|
5585
|
-
if (seenMediaSignatures.has(fp)) {
|
|
5586
|
-
return null;
|
|
5587
|
-
}
|
|
5588
|
-
seenMediaSignatures.add(fp);
|
|
5589
|
-
}
|
|
5590
|
-
return pic;
|
|
5601
|
+
if (isLegacy === true) return null;
|
|
5602
|
+
return createPic();
|
|
5591
5603
|
}
|
|
5592
5604
|
});
|
|
5593
|
-
const
|
|
5594
|
-
|
|
5595
|
-
const
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
const
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
seenInContentBlocks.add(fp);
|
|
5613
|
-
}
|
|
5614
|
-
const hasMedia = item.querySelector("img, svg, canvas, table") !== null || ["img", "svg", "table"].includes(tag);
|
|
5615
|
-
const textContent = (item.textContent || "").trim();
|
|
5616
|
-
if (!hasMedia && textContent.length === 0) {
|
|
5617
|
-
continue;
|
|
5618
|
-
}
|
|
5619
|
-
const svgs = item.querySelectorAll("svg, img");
|
|
5620
|
-
svgs.forEach((s) => {
|
|
5621
|
-
const el = s;
|
|
5622
|
-
el.style.maxWidth = "100%";
|
|
5623
|
-
el.style.maxHeight = "360px";
|
|
5624
|
-
el.style.display = "block";
|
|
5625
|
-
el.style.margin = "12px auto";
|
|
5626
|
-
if (s.tagName.toLowerCase() === "svg") {
|
|
5627
|
-
s.removeAttribute("width");
|
|
5628
|
-
s.removeAttribute("height");
|
|
5629
|
-
el.style.width = "100%";
|
|
5630
|
-
el.style.maxHeight = "360px";
|
|
5631
|
-
}
|
|
5632
|
-
});
|
|
5633
|
-
if (tag === "p" || tag === "div") {
|
|
5634
|
-
item.style.display = "block";
|
|
5635
|
-
item.style.marginBottom = "12px";
|
|
5636
|
-
item.style.lineHeight = "1.6";
|
|
5637
|
-
}
|
|
5638
|
-
contentNodes.push(item);
|
|
5605
|
+
const elements = await doc.render();
|
|
5606
|
+
let unsupportedIndex = 1;
|
|
5607
|
+
const usedTables = /* @__PURE__ */ new Set();
|
|
5608
|
+
for (let i = 0; i < elements.length; i++) {
|
|
5609
|
+
const el = elements[i];
|
|
5610
|
+
const text = el.textContent || "";
|
|
5611
|
+
if (text.includes("[Unsupported image format]")) {
|
|
5612
|
+
if (extractedImages[unsupportedIndex]) {
|
|
5613
|
+
const img = document.createElement("img");
|
|
5614
|
+
img.src = extractedImages[unsupportedIndex].dataUrl;
|
|
5615
|
+
img.style.width = "100%";
|
|
5616
|
+
img.style.height = "auto";
|
|
5617
|
+
img.style.maxHeight = "430px";
|
|
5618
|
+
img.style.objectFit = "contain";
|
|
5619
|
+
img.style.display = "block";
|
|
5620
|
+
img.style.margin = "12px auto";
|
|
5621
|
+
el.innerHTML = "";
|
|
5622
|
+
el.appendChild(img);
|
|
5623
|
+
unsupportedIndex++;
|
|
5639
5624
|
}
|
|
5640
5625
|
}
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5626
|
+
if (tables.length > 0) {
|
|
5627
|
+
for (let t = 0; t < tables.length; t++) {
|
|
5628
|
+
if (usedTables.has(t)) continue;
|
|
5629
|
+
const tbl = tables[t];
|
|
5630
|
+
if (tbl.rows.length >= 2) {
|
|
5631
|
+
const sampleCell1 = tbl.rows[1]?.[1] || tbl.rows[0]?.[1] || "";
|
|
5632
|
+
const sampleCell2 = tbl.rows[2]?.[1] || tbl.rows[1]?.[0] || "";
|
|
5633
|
+
const match1 = sampleCell1 && text.includes(sampleCell1.slice(0, 15).trim());
|
|
5634
|
+
const match2 = sampleCell2 && text.includes(sampleCell2.slice(0, 15).trim());
|
|
5635
|
+
if (match1 && match2) {
|
|
5636
|
+
el.innerHTML = "";
|
|
5637
|
+
el.appendChild(renderRtfTableElement(tbl));
|
|
5638
|
+
usedTables.add(t);
|
|
5639
|
+
break;
|
|
5640
|
+
}
|
|
5653
5641
|
}
|
|
5654
5642
|
}
|
|
5655
5643
|
}
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5644
|
+
}
|
|
5645
|
+
elements.forEach((el) => {
|
|
5646
|
+
const svgs = el.querySelectorAll ? Array.from(el.querySelectorAll("svg")) : [];
|
|
5647
|
+
svgs.forEach((svg) => {
|
|
5648
|
+
svg.removeAttribute("width");
|
|
5649
|
+
svg.removeAttribute("height");
|
|
5650
|
+
svg.style.maxWidth = "100%";
|
|
5651
|
+
svg.style.maxHeight = "430px";
|
|
5652
|
+
svg.style.height = "auto";
|
|
5653
|
+
svg.style.display = "block";
|
|
5654
|
+
svg.style.margin = "12px auto";
|
|
5655
|
+
});
|
|
5656
|
+
const imgs = el.querySelectorAll ? Array.from(el.querySelectorAll("img")) : [];
|
|
5657
|
+
imgs.forEach((img) => {
|
|
5658
|
+
img.style.maxWidth = "100%";
|
|
5659
|
+
img.style.maxHeight = "430px";
|
|
5660
|
+
img.style.height = "auto";
|
|
5661
|
+
img.style.objectFit = "contain";
|
|
5662
|
+
img.style.display = "block";
|
|
5663
|
+
img.style.margin = "12px auto";
|
|
5664
|
+
});
|
|
5665
|
+
});
|
|
5666
|
+
const allImgs = Array.from(document.querySelectorAll("img")).concat(
|
|
5667
|
+
elements.flatMap((el) => Array.from(el.querySelectorAll ? el.querySelectorAll("img") : []))
|
|
5668
|
+
);
|
|
5669
|
+
await Promise.all(allImgs.map((img) => {
|
|
5670
|
+
if (img.complete && img.naturalHeight > 0) return Promise.resolve();
|
|
5671
|
+
if (img.decode) return img.decode().catch(() => {
|
|
5672
|
+
});
|
|
5673
|
+
return new Promise((r) => {
|
|
5674
|
+
img.onload = r;
|
|
5675
|
+
img.onerror = r;
|
|
5676
|
+
});
|
|
5677
|
+
}));
|
|
5678
|
+
elements.forEach((el) => {
|
|
5679
|
+
const text = el.textContent || "";
|
|
5680
|
+
if (text.includes("\uF0B7")) {
|
|
5681
|
+
const cleanText = text.replace(/^[\s\uf0b7\t]+/, "");
|
|
5682
|
+
el.style.display = "flex";
|
|
5683
|
+
el.style.alignItems = "flex-start";
|
|
5684
|
+
el.style.margin = "6px 0 6px 28px";
|
|
5685
|
+
el.style.fontSize = "11pt";
|
|
5686
|
+
el.style.lineHeight = "1.5";
|
|
5687
|
+
el.innerHTML = `<span style="margin-right:10px; user-select:none;">□</span><span>${cleanText}</span>`;
|
|
5665
5688
|
}
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5689
|
+
});
|
|
5690
|
+
elements.forEach((el) => {
|
|
5691
|
+
const text = (el.textContent || "").trim();
|
|
5692
|
+
const hasMedia = el.querySelector("img, svg, canvas, table") !== null || ["IMG", "SVG", "TABLE"].includes(el.tagName);
|
|
5693
|
+
if (isHeadingElement(el)) {
|
|
5694
|
+
el.style.marginTop = "20px";
|
|
5695
|
+
el.style.marginBottom = "10px";
|
|
5696
|
+
el.style.lineHeight = "1.25";
|
|
5697
|
+
} else if (text.length > 0 && !hasMedia) {
|
|
5698
|
+
el.style.marginBottom = "12px";
|
|
5699
|
+
el.style.lineHeight = "1.45";
|
|
5672
5700
|
}
|
|
5673
5701
|
});
|
|
5674
|
-
const
|
|
5702
|
+
const measureCard = document.createElement("div");
|
|
5703
|
+
measureCard.style.width = `${pageWidth}px`;
|
|
5704
|
+
measureCard.style.padding = `${padTop}px ${padRight}px ${padBottom}px ${padLeft}px`;
|
|
5705
|
+
measureCard.style.boxSizing = "border-box";
|
|
5706
|
+
measureCard.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
|
|
5707
|
+
measureCard.style.lineHeight = "1.45";
|
|
5708
|
+
measureCard.style.visibility = "hidden";
|
|
5709
|
+
measureCard.style.position = "absolute";
|
|
5710
|
+
measureCard.style.top = "-99999px";
|
|
5711
|
+
document.body.appendChild(measureCard);
|
|
5712
|
+
const createPageCard = (num) => {
|
|
5675
5713
|
const card = document.createElement("div");
|
|
5676
5714
|
card.className = "fp-rtf-page-card";
|
|
5677
|
-
card.setAttribute("data-page-number", String(
|
|
5715
|
+
card.setAttribute("data-page-number", String(num));
|
|
5678
5716
|
card.style.backgroundColor = "#ffffff";
|
|
5679
5717
|
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.04)";
|
|
5680
5718
|
card.style.borderRadius = "4px";
|
|
5681
|
-
card.style.
|
|
5682
|
-
card.style.
|
|
5683
|
-
card.style.
|
|
5684
|
-
card.style.maxHeight = "1056px";
|
|
5685
|
-
card.style.overflow = "hidden";
|
|
5719
|
+
card.style.width = `${pageWidth}px`;
|
|
5720
|
+
card.style.height = `${pageHeight}px`;
|
|
5721
|
+
card.style.padding = `${padTop}px ${padRight}px ${padBottom}px ${padLeft}px`;
|
|
5686
5722
|
card.style.boxSizing = "border-box";
|
|
5723
|
+
card.style.overflow = "hidden";
|
|
5687
5724
|
card.style.marginBottom = "24px";
|
|
5688
|
-
card.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
|
|
5689
|
-
card.style.lineHeight = "1.6";
|
|
5690
5725
|
card.style.color = "#1e293b";
|
|
5726
|
+
card.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
|
|
5727
|
+
card.style.lineHeight = "1.45";
|
|
5691
5728
|
card.style.position = "relative";
|
|
5729
|
+
card.style.textAlign = "left";
|
|
5692
5730
|
return card;
|
|
5693
5731
|
};
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
const
|
|
5702
|
-
const
|
|
5703
|
-
const
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
if (realH > 0) return realH;
|
|
5718
|
-
const textLen = c.textContent?.trim().length || 0;
|
|
5719
|
-
return Math.max(28, Math.ceil(textLen / 75) * 26 + 16);
|
|
5720
|
-
});
|
|
5721
|
-
wrapper.innerHTML = "";
|
|
5722
|
-
let curCard = createRtfCard(1);
|
|
5723
|
-
wrapper.appendChild(curCard);
|
|
5724
|
-
pageElements = [curCard];
|
|
5725
|
-
let curH = 0;
|
|
5726
|
-
const maxH = 860;
|
|
5727
|
-
for (let i = 0; i < contentNodes.length; i++) {
|
|
5728
|
-
const child = contentNodes[i];
|
|
5729
|
-
const chH = childHeights[i];
|
|
5730
|
-
const isChildEmpty = (child.textContent || "").trim().length === 0 && !child.querySelector("table, img, svg, canvas");
|
|
5731
|
-
if (curH === 0 && isChildEmpty) {
|
|
5732
|
+
const pages = [];
|
|
5733
|
+
let curCard = createPageCard(1);
|
|
5734
|
+
pages.push(curCard);
|
|
5735
|
+
let curHeight = 0;
|
|
5736
|
+
for (let i = 0; i < elements.length; i++) {
|
|
5737
|
+
const el = elements[i];
|
|
5738
|
+
if (!el || !(el instanceof HTMLElement)) continue;
|
|
5739
|
+
const text = (el.textContent || "").trim();
|
|
5740
|
+
const hasMedia = el.querySelector("img, svg, canvas, table") !== null || ["IMG", "SVG", "TABLE"].includes(el.tagName);
|
|
5741
|
+
const isEmptyPar = !hasMedia && text.length === 0;
|
|
5742
|
+
if (isEmptyPar) {
|
|
5743
|
+
const emptyH = 35;
|
|
5744
|
+
if (curHeight + emptyH > printableHeight) {
|
|
5745
|
+
if (curCard.childNodes.length > 0) {
|
|
5746
|
+
curCard = createPageCard(pages.length + 1);
|
|
5747
|
+
pages.push(curCard);
|
|
5748
|
+
curHeight = 0;
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
const spacer = document.createElement("div");
|
|
5752
|
+
spacer.style.height = `${emptyH}px`;
|
|
5753
|
+
curCard.appendChild(spacer);
|
|
5754
|
+
curHeight += emptyH;
|
|
5732
5755
|
continue;
|
|
5733
5756
|
}
|
|
5734
|
-
|
|
5735
|
-
const
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5757
|
+
measureCard.innerHTML = "";
|
|
5758
|
+
const clone = el.cloneNode(true);
|
|
5759
|
+
measureCard.appendChild(clone);
|
|
5760
|
+
const compStyle = window.getComputedStyle(clone);
|
|
5761
|
+
const mt = parseFloat(compStyle.marginTop) || 0;
|
|
5762
|
+
const mb = parseFloat(compStyle.marginBottom) || 0;
|
|
5763
|
+
const elH = clone.offsetHeight + mt + mb;
|
|
5764
|
+
const isHeading = isHeadingElement(el);
|
|
5765
|
+
let nextContentH = 0;
|
|
5766
|
+
if (isHeading || hasMedia) {
|
|
5767
|
+
for (let j = i + 1; j < elements.length; j++) {
|
|
5768
|
+
const nextEl = elements[j];
|
|
5769
|
+
if (nextEl && (nextEl.textContent || "").trim().length > 0) {
|
|
5770
|
+
measureCard.innerHTML = "";
|
|
5771
|
+
const nClone = nextEl.cloneNode(true);
|
|
5772
|
+
measureCard.appendChild(nClone);
|
|
5773
|
+
const nStyle = window.getComputedStyle(nClone);
|
|
5774
|
+
nextContentH = nClone.offsetHeight + (parseFloat(nStyle.marginTop) || 0) + (parseFloat(nStyle.marginBottom) || 0);
|
|
5775
|
+
break;
|
|
5776
|
+
}
|
|
5777
|
+
}
|
|
5741
5778
|
}
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5779
|
+
const remainingSpace = printableHeight - curHeight;
|
|
5780
|
+
const isLargeMedia = hasMedia && elH > 300;
|
|
5781
|
+
const keepWithNextOverflow = isHeading && nextContentH > 0 && elH + nextContentH + 20 > remainingSpace;
|
|
5782
|
+
const largeMediaOverflow = isLargeMedia && curHeight > 0 && elH + 80 > remainingSpace;
|
|
5783
|
+
const shouldBreak = (curHeight + elH > printableHeight || keepWithNextOverflow || largeMediaOverflow) && curCard.childNodes.length > 0;
|
|
5784
|
+
if (shouldBreak) {
|
|
5785
|
+
curCard = createPageCard(pages.length + 1);
|
|
5786
|
+
pages.push(curCard);
|
|
5787
|
+
curHeight = 0;
|
|
5788
|
+
}
|
|
5789
|
+
curCard.appendChild(el);
|
|
5790
|
+
curHeight += elH;
|
|
5791
|
+
}
|
|
5792
|
+
measureCard.remove();
|
|
5793
|
+
pageElements = pages.filter((card) => {
|
|
5746
5794
|
const hasText = (card.textContent || "").trim().length > 0;
|
|
5747
|
-
const
|
|
5748
|
-
return hasText ||
|
|
5795
|
+
const hasCardMedia = card.querySelector("table, img, svg, canvas") !== null;
|
|
5796
|
+
return hasText || hasCardMedia;
|
|
5749
5797
|
});
|
|
5750
5798
|
if (pageElements.length === 0) {
|
|
5751
5799
|
pageElements = [curCard];
|
|
5752
5800
|
}
|
|
5801
|
+
wrapper.innerHTML = "";
|
|
5802
|
+
pageElements.forEach((card, idx) => {
|
|
5803
|
+
card.setAttribute("data-page-number", String(idx + 1));
|
|
5804
|
+
card.style.display = idx === 0 ? "block" : "none";
|
|
5805
|
+
wrapper.appendChild(card);
|
|
5806
|
+
});
|
|
5753
5807
|
} catch (err) {
|
|
5754
5808
|
console.warn("[RtfPlugin] RTF render error, fallback text:", err);
|
|
5755
|
-
const text =
|
|
5756
|
-
const tables = parseRtfTables(text);
|
|
5809
|
+
const text = rawRtf;
|
|
5757
5810
|
const rawPages = text.split(/\\page\b/).map((segment) => {
|
|
5758
5811
|
return segment.replace(/\\par[d]?/g, "\n").replace(/\\[a-zA-Z0-9\-]+/g, "").replace(/[{}]/g, "").trim();
|
|
5759
|
-
}).filter((
|
|
5812
|
+
}).filter((p2) => p2.length > 0);
|
|
5760
5813
|
const pages = rawPages.length > 0 ? rawPages : [text.replace(/\\par[d]?/g, "\n").replace(/\\[a-zA-Z0-9\-]+/g, "").replace(/[{}]/g, "").trim()];
|
|
5761
5814
|
for (let i = 0; i < pages.length; i++) {
|
|
5762
5815
|
const pageCard = document.createElement("div");
|
|
@@ -5764,9 +5817,9 @@ var RtfPlugin = class {
|
|
|
5764
5817
|
pageCard.style.backgroundColor = "#ffffff";
|
|
5765
5818
|
pageCard.style.boxShadow = "0 2px 12px rgba(0,0,0,0.08)";
|
|
5766
5819
|
pageCard.style.borderRadius = "4px";
|
|
5767
|
-
pageCard.style.padding =
|
|
5768
|
-
pageCard.style.width =
|
|
5769
|
-
pageCard.style.minHeight =
|
|
5820
|
+
pageCard.style.padding = `${padTop}px ${padRight}px ${padBottom}px ${padLeft}px`;
|
|
5821
|
+
pageCard.style.width = `${pageWidth}px`;
|
|
5822
|
+
pageCard.style.minHeight = `${pageHeight}px`;
|
|
5770
5823
|
pageCard.style.boxSizing = "border-box";
|
|
5771
5824
|
pageCard.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
|
|
5772
5825
|
pageCard.style.fontSize = "12pt";
|
|
@@ -5786,11 +5839,9 @@ var RtfPlugin = class {
|
|
|
5786
5839
|
let currentPage = 1;
|
|
5787
5840
|
const showPage = (pageNum) => {
|
|
5788
5841
|
currentPage = Math.max(1, Math.min(totalPages, pageNum));
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
});
|
|
5793
|
-
}
|
|
5842
|
+
pageElements.forEach((el, idx) => {
|
|
5843
|
+
el.style.display = idx + 1 === currentPage ? "block" : "none";
|
|
5844
|
+
});
|
|
5794
5845
|
ctx.container.scrollTop = 0;
|
|
5795
5846
|
ctx.emit("page-change", { page: currentPage, total: totalPages });
|
|
5796
5847
|
};
|