@files-preview-app/preview-file 1.2.8 → 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/vue.cjs CHANGED
@@ -1548,6 +1548,7 @@ var PdfPlugin = class {
1548
1548
  getPageCount: () => totalPages,
1549
1549
  getCurrentPage: () => currentPage,
1550
1550
  goToPage: (page) => {
1551
+ container.scrollTop = 0;
1551
1552
  renderPage(page);
1552
1553
  },
1553
1554
  download: () => {
@@ -2052,7 +2053,14 @@ var DocxPlugin = class {
2052
2053
  ignoreFonts: true,
2053
2054
  // Avoid crashes on embedded obfuscated fonts
2054
2055
  breakPages: true,
2055
- experimental: true
2056
+ experimental: true,
2057
+ ignoreLastRenderedPageBreak: false,
2058
+ // Honor Word's exact page breaks!
2059
+ renderHeaders: true,
2060
+ renderFooters: true,
2061
+ renderFootnotes: true,
2062
+ renderEndnotes: true,
2063
+ useBase64URL: true
2056
2064
  });
2057
2065
  if (!ctx.container.contains(wrapper)) {
2058
2066
  ctx.container.appendChild(wrapper);
@@ -2073,11 +2081,14 @@ var DocxPlugin = class {
2073
2081
  renderedSuccessfully = true;
2074
2082
  } catch (fallbackErr) {
2075
2083
  console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
2084
+ const isCorrupt = fallbackErr?.message?.includes("invalid zip") || fallbackErr?.message?.includes("corrupted");
2076
2085
  wrapper.innerHTML = `
2077
- <div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
2078
- <div style="font-size:48px; margin-bottom: 16px;">\u{1F4C4}</div>
2079
- <h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
2080
- <p style="color: #64748b; margin: 0;">Could not parse document content</p>
2086
+ <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;">
2087
+ <div style="font-size:48px; margin-bottom: 16px;">${isCorrupt ? "\u26A0\uFE0F" : "\u{1F4C4}"}</div>
2088
+ <h3 style="margin: 0 0 8px; color: #1e293b; font-size: 18px;">${ctx.metadata.name || "Word Document"}</h3>
2089
+ <p style="color: #64748b; margin: 0 0 16px; font-size: 14px; line-height: 1.5;">
2090
+ ${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."}
2091
+ </p>
2081
2092
  </div>
2082
2093
  `;
2083
2094
  if (!ctx.container.contains(wrapper)) {
@@ -2089,47 +2100,61 @@ var DocxPlugin = class {
2089
2100
  const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
2090
2101
  if (sections.length === 1 && cards.length === 0) {
2091
2102
  const singleSec = sections[0];
2092
- const pageH = 1056;
2103
+ const contentContainer = singleSec.querySelector("article") || singleSec;
2104
+ const children = Array.from(contentContainer.children);
2105
+ const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
2093
2106
  const secH = singleSec.offsetHeight || singleSec.scrollHeight;
2094
- if (secH > pageH * 1.25) {
2095
- const children = Array.from(singleSec.children);
2096
- if (children.length > 1) {
2097
- const parent = singleSec.parentElement || wrapper;
2098
- const newSections = [singleSec];
2099
- singleSec.innerHTML = "";
2100
- singleSec.style.minHeight = `${pageH}px`;
2101
- singleSec.style.maxHeight = `${pageH}px`;
2102
- singleSec.style.overflow = "hidden";
2103
- singleSec.style.boxSizing = "border-box";
2104
- let curSec = singleSec;
2105
- let curH = 0;
2106
- const maxH = pageH - 96;
2107
- for (let i = 0; i < children.length; i++) {
2108
- const child = children[i];
2109
- curSec.appendChild(child);
2110
- const chH = child.offsetHeight || 28;
2111
- curH += chH;
2112
- if (curH >= maxH && i < children.length - 1) {
2113
- const nextSec = document.createElement("section");
2114
- nextSec.className = singleSec.className;
2115
- nextSec.style.cssText = singleSec.style.cssText;
2116
- nextSec.style.width = singleSec.style.width || "816px";
2117
- nextSec.style.minHeight = `${pageH}px`;
2118
- nextSec.style.maxHeight = `${pageH}px`;
2119
- nextSec.style.overflow = "hidden";
2120
- nextSec.style.boxSizing = "border-box";
2121
- nextSec.style.backgroundColor = "#ffffff";
2122
- nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2123
- nextSec.style.borderRadius = "4px";
2124
- nextSec.style.marginBottom = "24px";
2125
- parent.appendChild(nextSec);
2126
- newSections.push(nextSec);
2127
- curSec = nextSec;
2128
- curH = 0;
2107
+ if (secH > pageH * 1.25 && children.length > 1) {
2108
+ const childHeights = children.map((c) => {
2109
+ const rectH = c.getBoundingClientRect().height;
2110
+ const offH = c.offsetHeight;
2111
+ const textLen = c.textContent?.trim().length || 0;
2112
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
2113
+ return Math.max(rectH, offH, estH);
2114
+ });
2115
+ const parent = singleSec.parentElement || wrapper;
2116
+ const newSections = [singleSec];
2117
+ const headerEl = singleSec.querySelector("header");
2118
+ const footerEl = singleSec.querySelector("footer");
2119
+ contentContainer.innerHTML = "";
2120
+ singleSec.style.minHeight = `${pageH}px`;
2121
+ singleSec.style.boxSizing = "border-box";
2122
+ let curContent = contentContainer;
2123
+ let curH = 0;
2124
+ const maxH = pageH - 140;
2125
+ for (let i = 0; i < children.length; i++) {
2126
+ const child = children[i];
2127
+ const chH = childHeights[i];
2128
+ curContent.appendChild(child);
2129
+ curH += chH;
2130
+ if (curH >= maxH && i < children.length - 1) {
2131
+ const nextSec = document.createElement("section");
2132
+ nextSec.className = singleSec.className;
2133
+ nextSec.style.cssText = singleSec.style.cssText;
2134
+ nextSec.style.minHeight = `${pageH}px`;
2135
+ nextSec.style.boxSizing = "border-box";
2136
+ nextSec.style.backgroundColor = "#ffffff";
2137
+ nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2138
+ nextSec.style.borderRadius = "4px";
2139
+ nextSec.style.marginBottom = "24px";
2140
+ if (headerEl) {
2141
+ nextSec.appendChild(headerEl.cloneNode(true));
2142
+ }
2143
+ const nextArticle = document.createElement("article");
2144
+ if (contentContainer.tagName.toLowerCase() === "article") {
2145
+ nextArticle.style.cssText = contentContainer.style.cssText;
2129
2146
  }
2147
+ nextSec.appendChild(nextArticle);
2148
+ if (footerEl) {
2149
+ nextSec.appendChild(footerEl.cloneNode(true));
2150
+ }
2151
+ parent.appendChild(nextSec);
2152
+ newSections.push(nextSec);
2153
+ curContent = nextArticle;
2154
+ curH = 0;
2130
2155
  }
2131
- sections = newSections;
2132
2156
  }
2157
+ sections = newSections;
2133
2158
  }
2134
2159
  }
2135
2160
  const pageElements = sections.length > 0 ? sections : cards;
@@ -2168,6 +2193,7 @@ var DocxPlugin = class {
2168
2193
  if (indicator) {
2169
2194
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
2170
2195
  }
2196
+ ctx.container.scrollTop = 0;
2171
2197
  ctx.emit("page-change", { page: currentPage, total: totalPages });
2172
2198
  };
2173
2199
  if (totalPages > 1) {
@@ -3100,17 +3126,39 @@ var CodePlugin = class {
3100
3126
  let rawPages = [];
3101
3127
  if (isTxt) {
3102
3128
  const explicitPages = fullText.split(/(?:\f|\x0C)/);
3129
+ const charsPerLine = 85;
3130
+ const maxVisualLines = 45;
3131
+ const charsPerPage = charsPerLine * maxVisualLines;
3103
3132
  for (const ep of explicitPages) {
3104
3133
  const lines = ep.split(/\r?\n/);
3105
3134
  let currentChunk = [];
3135
+ let currentLines = 0;
3106
3136
  for (let i = 0; i < lines.length; i++) {
3107
- currentChunk.push(lines[i]);
3108
- if (currentChunk.length >= 46) {
3137
+ const line = lines[i];
3138
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
3139
+ if (currentLines + vLines > maxVisualLines && currentChunk.length > 0) {
3109
3140
  rawPages.push(currentChunk.join("\n"));
3110
3141
  currentChunk = [];
3142
+ currentLines = 0;
3143
+ }
3144
+ if (vLines > maxVisualLines) {
3145
+ let remaining = line;
3146
+ while (remaining.length > charsPerPage) {
3147
+ let splitIdx = remaining.lastIndexOf(" ", charsPerPage);
3148
+ if (splitIdx < charsPerPage * 0.75) splitIdx = charsPerPage;
3149
+ rawPages.push(remaining.slice(0, splitIdx));
3150
+ remaining = remaining.slice(splitIdx).trimStart();
3151
+ }
3152
+ if (remaining.length > 0) {
3153
+ currentChunk.push(remaining);
3154
+ currentLines = Math.ceil(remaining.length / charsPerLine);
3155
+ }
3156
+ } else {
3157
+ currentChunk.push(line);
3158
+ currentLines += vLines;
3111
3159
  }
3112
3160
  }
3113
- if (currentChunk.length > 0 || lines.length === 0) {
3161
+ if (currentChunk.length > 0) {
3114
3162
  rawPages.push(currentChunk.join("\n"));
3115
3163
  }
3116
3164
  }
@@ -3220,6 +3268,7 @@ var CodePlugin = class {
3220
3268
  if (indicator) {
3221
3269
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
3222
3270
  }
3271
+ container.scrollTop = 0;
3223
3272
  ctx.emit("page-change", { page: currentPage, total: totalPages });
3224
3273
  };
3225
3274
  if (totalPages > 1) {
@@ -4284,11 +4333,60 @@ var RtfPlugin = class {
4284
4333
  }
4285
4334
  const doc = new RTFJS__namespace.Document(ctx.buffer, {});
4286
4335
  const htmlElements = await doc.render();
4287
- pageElements = htmlElements;
4288
- for (let i = 0; i < htmlElements.length; i++) {
4289
- const el = htmlElements[i];
4290
- el.style.display = i === 0 ? "block" : "none";
4291
- wrapper.appendChild(el);
4336
+ if (htmlElements.length === 1) {
4337
+ const singleEl = htmlElements[0];
4338
+ wrapper.appendChild(singleEl);
4339
+ const children = Array.from(singleEl.children);
4340
+ const secH = singleEl.offsetHeight || singleEl.scrollHeight;
4341
+ if (secH > 1300 && children.length > 1) {
4342
+ const childHeights = children.map((c) => {
4343
+ const rectH = c.getBoundingClientRect().height;
4344
+ const offH = c.offsetHeight;
4345
+ const textLen = c.textContent?.trim().length || 0;
4346
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
4347
+ return Math.max(rectH, offH, estH);
4348
+ });
4349
+ wrapper.innerHTML = "";
4350
+ const createRtfCard = () => {
4351
+ const card = document.createElement("div");
4352
+ card.className = "fp-rtf-page-card";
4353
+ card.style.backgroundColor = "#ffffff";
4354
+ card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
4355
+ card.style.borderRadius = "4px";
4356
+ card.style.padding = "72px 56px";
4357
+ card.style.width = "816px";
4358
+ card.style.minHeight = "1056px";
4359
+ card.style.boxSizing = "border-box";
4360
+ card.style.marginBottom = "24px";
4361
+ return card;
4362
+ };
4363
+ let curCard = createRtfCard();
4364
+ wrapper.appendChild(curCard);
4365
+ pageElements = [curCard];
4366
+ let curH = 0;
4367
+ const maxH = 920;
4368
+ for (let i = 0; i < children.length; i++) {
4369
+ const child = children[i];
4370
+ const chH = childHeights[i];
4371
+ curCard.appendChild(child);
4372
+ curH += chH;
4373
+ if (curH >= maxH && i < children.length - 1) {
4374
+ curCard = createRtfCard();
4375
+ wrapper.appendChild(curCard);
4376
+ pageElements.push(curCard);
4377
+ curH = 0;
4378
+ }
4379
+ }
4380
+ } else {
4381
+ pageElements = [singleEl];
4382
+ }
4383
+ } else {
4384
+ pageElements = htmlElements;
4385
+ for (let i = 0; i < htmlElements.length; i++) {
4386
+ const el = htmlElements[i];
4387
+ el.style.display = i === 0 ? "block" : "none";
4388
+ wrapper.appendChild(el);
4389
+ }
4292
4390
  }
4293
4391
  } catch (err) {
4294
4392
  console.warn("[RtfPlugin] RTF render error, fallback text:", err);
@@ -4354,6 +4452,7 @@ var RtfPlugin = class {
4354
4452
  if (indicator) {
4355
4453
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4356
4454
  }
4455
+ ctx.container.scrollTop = 0;
4357
4456
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4358
4457
  };
4359
4458
  if (totalPages > 1) {
@@ -4825,12 +4924,9 @@ var OpenDocumentPlugin = class {
4825
4924
  page.style.backgroundColor = "#ffffff";
4826
4925
  page.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
4827
4926
  page.style.borderRadius = "4px";
4828
- page.style.boxSizing = "border-box";
4829
4927
  page.style.display = idx === 0 ? "block" : "none";
4830
- page.style.position = "absolute";
4831
- page.style.top = "0";
4832
- page.style.left = "50%";
4833
- page.style.transform = "translateX(-50%)";
4928
+ page.style.margin = "0 auto 24px";
4929
+ page.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4834
4930
  elements.forEach((el) => page.appendChild(el));
4835
4931
  wrapper.appendChild(page);
4836
4932
  slides.push(page);
@@ -4868,6 +4964,7 @@ var OpenDocumentPlugin = class {
4868
4964
  if (indicator) {
4869
4965
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4870
4966
  }
4967
+ container.scrollTop = 0;
4871
4968
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4872
4969
  };
4873
4970
  return {
@@ -5360,6 +5457,7 @@ var DocPlugin = class {
5360
5457
  if (indicator) {
5361
5458
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
5362
5459
  }
5460
+ container.scrollTop = 0;
5363
5461
  ctx.emit("page-change", { page: currentPage, total: totalPages });
5364
5462
  };
5365
5463
  if (totalPages > 1) {
@@ -5537,45 +5635,50 @@ var DocPlugin = class {
5537
5635
  }
5538
5636
  splitIntoPages(text) {
5539
5637
  if (!text) return [""];
5540
- const explicitParts = text.split(/[\x0C\f]|\r?\n\s*[-=_]{3,}\s*(?:PAGE|Page|page break)[\s\d\w-]*[-=_]{3,}\s*\r?\n/i).map((p) => p.trim()).filter((p) => p.length > 0);
5541
- if (explicitParts.length === 0) explicitParts.push(text);
5542
- const maxLinesPerPage = 48;
5638
+ const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
5639
+ 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);
5640
+ if (explicitParts.length === 0) explicitParts.push(normalized);
5641
+ const maxLinesPerPage = 32;
5642
+ const charsPerLine = 80;
5543
5643
  const finalPages = [];
5544
5644
  for (const part of explicitParts) {
5545
- const lines = part.split(/\r?\n/);
5645
+ const lines = part.split("\n");
5546
5646
  let currentLines = [];
5547
5647
  let count = 0;
5548
5648
  for (const line of lines) {
5549
- currentLines.push(line);
5550
- count++;
5551
- if (count >= maxLinesPerPage) {
5649
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
5650
+ if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
5552
5651
  finalPages.push(currentLines.join("\n"));
5553
5652
  currentLines = [];
5554
5653
  count = 0;
5555
5654
  }
5655
+ currentLines.push(line);
5656
+ count += vLines;
5556
5657
  }
5557
5658
  if (currentLines.length > 0) {
5558
5659
  finalPages.push(currentLines.join("\n"));
5559
5660
  }
5560
5661
  }
5561
- return finalPages.length > 0 ? finalPages : [text];
5662
+ return finalPages.length > 0 ? finalPages : [normalized];
5562
5663
  }
5563
5664
  /**
5564
5665
  * Format cleaned extracted text into attractive HTML paragraphs, headings, and lists
5565
5666
  */
5566
5667
  formatDocToHtml(text, filename) {
5567
- const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").split("\n");
5668
+ 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");
5568
5669
  let html = "";
5569
5670
  let inList = false;
5570
5671
  let tableLines = [];
5571
5672
  const flushTable = () => {
5572
5673
  if (tableLines.length > 0) {
5573
- html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12px;">';
5574
- for (const tLine of tableLines) {
5575
- html += "<tr>";
5576
- const cols = tLine.split(" ");
5674
+ html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px; font-family: Calibri, sans-serif;">';
5675
+ for (let rIdx = 0; rIdx < tableLines.length; rIdx++) {
5676
+ const tLine = tableLines[rIdx];
5677
+ const isHeader = rIdx === 0;
5678
+ html += `<tr style="${isHeader ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
5679
+ const cols = tLine.split(" ").filter((c) => c.trim().length > 0);
5577
5680
  for (const col of cols) {
5578
- html += `<td style="border: 1px solid #cbd5e1; padding: 6px 8px;">${DOMPurify6__default.default.sanitize(col.trim())}</td>`;
5681
+ html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px;">${DOMPurify6__default.default.sanitize(col.trim())}</td>`;
5579
5682
  }
5580
5683
  html += "</tr>";
5581
5684
  }
@@ -5588,27 +5691,18 @@ var DocPlugin = class {
5588
5691
  let line = lines[i];
5589
5692
  let tabCount = (line.match(/\t/g) || []).length;
5590
5693
  if (tabCount > 0) {
5591
- let consecutiveTableLines = 1;
5592
- let j = i + 1;
5593
- while (j < lines.length) {
5594
- const nextTabCount = (lines[j].match(/\t/g) || []).length;
5595
- if (nextTabCount === tabCount) {
5596
- consecutiveTableLines++;
5597
- j++;
5598
- } else {
5599
- break;
5600
- }
5694
+ let j = i;
5695
+ while (j < lines.length && (lines[j].match(/\t/g) || []).length > 0) {
5696
+ j++;
5601
5697
  }
5602
- if (consecutiveTableLines >= 3) {
5603
- if (inList) {
5604
- html += "</ul>";
5605
- inList = false;
5606
- }
5607
- tableLines = lines.slice(i, j);
5608
- flushTable();
5609
- i = j;
5610
- continue;
5698
+ if (inList) {
5699
+ html += "</ul>";
5700
+ inList = false;
5611
5701
  }
5702
+ tableLines = lines.slice(i, j);
5703
+ flushTable();
5704
+ i = j;
5705
+ continue;
5612
5706
  }
5613
5707
  line = line.trim();
5614
5708
  if (!line) {