@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.js CHANGED
@@ -1516,6 +1516,7 @@ var PdfPlugin = class {
1516
1516
  getPageCount: () => totalPages,
1517
1517
  getCurrentPage: () => currentPage,
1518
1518
  goToPage: (page) => {
1519
+ container.scrollTop = 0;
1519
1520
  renderPage(page);
1520
1521
  },
1521
1522
  download: () => {
@@ -2020,7 +2021,14 @@ var DocxPlugin = class {
2020
2021
  ignoreFonts: true,
2021
2022
  // Avoid crashes on embedded obfuscated fonts
2022
2023
  breakPages: true,
2023
- experimental: true
2024
+ experimental: true,
2025
+ ignoreLastRenderedPageBreak: false,
2026
+ // Honor Word's exact page breaks!
2027
+ renderHeaders: true,
2028
+ renderFooters: true,
2029
+ renderFootnotes: true,
2030
+ renderEndnotes: true,
2031
+ useBase64URL: true
2024
2032
  });
2025
2033
  if (!ctx.container.contains(wrapper)) {
2026
2034
  ctx.container.appendChild(wrapper);
@@ -2041,11 +2049,14 @@ var DocxPlugin = class {
2041
2049
  renderedSuccessfully = true;
2042
2050
  } catch (fallbackErr) {
2043
2051
  console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
2052
+ const isCorrupt = fallbackErr?.message?.includes("invalid zip") || fallbackErr?.message?.includes("corrupted");
2044
2053
  wrapper.innerHTML = `
2045
- <div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
2046
- <div style="font-size:48px; margin-bottom: 16px;">\u{1F4C4}</div>
2047
- <h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
2048
- <p style="color: #64748b; margin: 0;">Could not parse document content</p>
2054
+ <div style="text-align:center; padding: 48px 32px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06); max-width: 600px; margin: 40px auto;">
2055
+ <div style="font-size:48px; margin-bottom: 16px;">${isCorrupt ? "\u26A0\uFE0F" : "\u{1F4C4}"}</div>
2056
+ <h3 style="margin: 0 0 8px; color: #1e293b; font-size: 18px;">${ctx.metadata.name || "Word Document"}</h3>
2057
+ <p style="color: #64748b; margin: 0 0 16px; font-size: 14px; line-height: 1.5;">
2058
+ ${isCorrupt ? "This document appears to be corrupted or contains invalid archive data and cannot be opened (matches Microsoft Word on Windows)." : "Could not render document content. The file structure may be damaged."}
2059
+ </p>
2049
2060
  </div>
2050
2061
  `;
2051
2062
  if (!ctx.container.contains(wrapper)) {
@@ -2057,47 +2068,61 @@ var DocxPlugin = class {
2057
2068
  const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
2058
2069
  if (sections.length === 1 && cards.length === 0) {
2059
2070
  const singleSec = sections[0];
2060
- const pageH = 1056;
2071
+ const contentContainer = singleSec.querySelector("article") || singleSec;
2072
+ const children = Array.from(contentContainer.children);
2073
+ const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
2061
2074
  const secH = singleSec.offsetHeight || singleSec.scrollHeight;
2062
- if (secH > pageH * 1.25) {
2063
- const children = Array.from(singleSec.children);
2064
- if (children.length > 1) {
2065
- const parent = singleSec.parentElement || wrapper;
2066
- const newSections = [singleSec];
2067
- singleSec.innerHTML = "";
2068
- singleSec.style.minHeight = `${pageH}px`;
2069
- singleSec.style.maxHeight = `${pageH}px`;
2070
- singleSec.style.overflow = "hidden";
2071
- singleSec.style.boxSizing = "border-box";
2072
- let curSec = singleSec;
2073
- let curH = 0;
2074
- const maxH = pageH - 96;
2075
- for (let i = 0; i < children.length; i++) {
2076
- const child = children[i];
2077
- curSec.appendChild(child);
2078
- const chH = child.offsetHeight || 28;
2079
- curH += chH;
2080
- if (curH >= maxH && i < children.length - 1) {
2081
- const nextSec = document.createElement("section");
2082
- nextSec.className = singleSec.className;
2083
- nextSec.style.cssText = singleSec.style.cssText;
2084
- nextSec.style.width = singleSec.style.width || "816px";
2085
- nextSec.style.minHeight = `${pageH}px`;
2086
- nextSec.style.maxHeight = `${pageH}px`;
2087
- nextSec.style.overflow = "hidden";
2088
- nextSec.style.boxSizing = "border-box";
2089
- nextSec.style.backgroundColor = "#ffffff";
2090
- nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2091
- nextSec.style.borderRadius = "4px";
2092
- nextSec.style.marginBottom = "24px";
2093
- parent.appendChild(nextSec);
2094
- newSections.push(nextSec);
2095
- curSec = nextSec;
2096
- curH = 0;
2075
+ if (secH > pageH * 1.25 && children.length > 1) {
2076
+ const childHeights = children.map((c) => {
2077
+ const rectH = c.getBoundingClientRect().height;
2078
+ const offH = c.offsetHeight;
2079
+ const textLen = c.textContent?.trim().length || 0;
2080
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
2081
+ return Math.max(rectH, offH, estH);
2082
+ });
2083
+ const parent = singleSec.parentElement || wrapper;
2084
+ const newSections = [singleSec];
2085
+ const headerEl = singleSec.querySelector("header");
2086
+ const footerEl = singleSec.querySelector("footer");
2087
+ contentContainer.innerHTML = "";
2088
+ singleSec.style.minHeight = `${pageH}px`;
2089
+ singleSec.style.boxSizing = "border-box";
2090
+ let curContent = contentContainer;
2091
+ let curH = 0;
2092
+ const maxH = pageH - 140;
2093
+ for (let i = 0; i < children.length; i++) {
2094
+ const child = children[i];
2095
+ const chH = childHeights[i];
2096
+ curContent.appendChild(child);
2097
+ curH += chH;
2098
+ if (curH >= maxH && i < children.length - 1) {
2099
+ const nextSec = document.createElement("section");
2100
+ nextSec.className = singleSec.className;
2101
+ nextSec.style.cssText = singleSec.style.cssText;
2102
+ nextSec.style.minHeight = `${pageH}px`;
2103
+ nextSec.style.boxSizing = "border-box";
2104
+ nextSec.style.backgroundColor = "#ffffff";
2105
+ nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2106
+ nextSec.style.borderRadius = "4px";
2107
+ nextSec.style.marginBottom = "24px";
2108
+ if (headerEl) {
2109
+ nextSec.appendChild(headerEl.cloneNode(true));
2110
+ }
2111
+ const nextArticle = document.createElement("article");
2112
+ if (contentContainer.tagName.toLowerCase() === "article") {
2113
+ nextArticle.style.cssText = contentContainer.style.cssText;
2097
2114
  }
2115
+ nextSec.appendChild(nextArticle);
2116
+ if (footerEl) {
2117
+ nextSec.appendChild(footerEl.cloneNode(true));
2118
+ }
2119
+ parent.appendChild(nextSec);
2120
+ newSections.push(nextSec);
2121
+ curContent = nextArticle;
2122
+ curH = 0;
2098
2123
  }
2099
- sections = newSections;
2100
2124
  }
2125
+ sections = newSections;
2101
2126
  }
2102
2127
  }
2103
2128
  const pageElements = sections.length > 0 ? sections : cards;
@@ -2136,6 +2161,7 @@ var DocxPlugin = class {
2136
2161
  if (indicator) {
2137
2162
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
2138
2163
  }
2164
+ ctx.container.scrollTop = 0;
2139
2165
  ctx.emit("page-change", { page: currentPage, total: totalPages });
2140
2166
  };
2141
2167
  if (totalPages > 1) {
@@ -3068,17 +3094,39 @@ var CodePlugin = class {
3068
3094
  let rawPages = [];
3069
3095
  if (isTxt) {
3070
3096
  const explicitPages = fullText.split(/(?:\f|\x0C)/);
3097
+ const charsPerLine = 85;
3098
+ const maxVisualLines = 45;
3099
+ const charsPerPage = charsPerLine * maxVisualLines;
3071
3100
  for (const ep of explicitPages) {
3072
3101
  const lines = ep.split(/\r?\n/);
3073
3102
  let currentChunk = [];
3103
+ let currentLines = 0;
3074
3104
  for (let i = 0; i < lines.length; i++) {
3075
- currentChunk.push(lines[i]);
3076
- if (currentChunk.length >= 46) {
3105
+ const line = lines[i];
3106
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
3107
+ if (currentLines + vLines > maxVisualLines && currentChunk.length > 0) {
3077
3108
  rawPages.push(currentChunk.join("\n"));
3078
3109
  currentChunk = [];
3110
+ currentLines = 0;
3111
+ }
3112
+ if (vLines > maxVisualLines) {
3113
+ let remaining = line;
3114
+ while (remaining.length > charsPerPage) {
3115
+ let splitIdx = remaining.lastIndexOf(" ", charsPerPage);
3116
+ if (splitIdx < charsPerPage * 0.75) splitIdx = charsPerPage;
3117
+ rawPages.push(remaining.slice(0, splitIdx));
3118
+ remaining = remaining.slice(splitIdx).trimStart();
3119
+ }
3120
+ if (remaining.length > 0) {
3121
+ currentChunk.push(remaining);
3122
+ currentLines = Math.ceil(remaining.length / charsPerLine);
3123
+ }
3124
+ } else {
3125
+ currentChunk.push(line);
3126
+ currentLines += vLines;
3079
3127
  }
3080
3128
  }
3081
- if (currentChunk.length > 0 || lines.length === 0) {
3129
+ if (currentChunk.length > 0) {
3082
3130
  rawPages.push(currentChunk.join("\n"));
3083
3131
  }
3084
3132
  }
@@ -3188,6 +3236,7 @@ var CodePlugin = class {
3188
3236
  if (indicator) {
3189
3237
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
3190
3238
  }
3239
+ container.scrollTop = 0;
3191
3240
  ctx.emit("page-change", { page: currentPage, total: totalPages });
3192
3241
  };
3193
3242
  if (totalPages > 1) {
@@ -4252,11 +4301,60 @@ var RtfPlugin = class {
4252
4301
  }
4253
4302
  const doc = new RTFJS.Document(ctx.buffer, {});
4254
4303
  const htmlElements = await doc.render();
4255
- pageElements = htmlElements;
4256
- for (let i = 0; i < htmlElements.length; i++) {
4257
- const el = htmlElements[i];
4258
- el.style.display = i === 0 ? "block" : "none";
4259
- wrapper.appendChild(el);
4304
+ if (htmlElements.length === 1) {
4305
+ const singleEl = htmlElements[0];
4306
+ wrapper.appendChild(singleEl);
4307
+ const children = Array.from(singleEl.children);
4308
+ const secH = singleEl.offsetHeight || singleEl.scrollHeight;
4309
+ if (secH > 1300 && children.length > 1) {
4310
+ const childHeights = children.map((c) => {
4311
+ const rectH = c.getBoundingClientRect().height;
4312
+ const offH = c.offsetHeight;
4313
+ const textLen = c.textContent?.trim().length || 0;
4314
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
4315
+ return Math.max(rectH, offH, estH);
4316
+ });
4317
+ wrapper.innerHTML = "";
4318
+ const createRtfCard = () => {
4319
+ const card = document.createElement("div");
4320
+ card.className = "fp-rtf-page-card";
4321
+ card.style.backgroundColor = "#ffffff";
4322
+ card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
4323
+ card.style.borderRadius = "4px";
4324
+ card.style.padding = "72px 56px";
4325
+ card.style.width = "816px";
4326
+ card.style.minHeight = "1056px";
4327
+ card.style.boxSizing = "border-box";
4328
+ card.style.marginBottom = "24px";
4329
+ return card;
4330
+ };
4331
+ let curCard = createRtfCard();
4332
+ wrapper.appendChild(curCard);
4333
+ pageElements = [curCard];
4334
+ let curH = 0;
4335
+ const maxH = 920;
4336
+ for (let i = 0; i < children.length; i++) {
4337
+ const child = children[i];
4338
+ const chH = childHeights[i];
4339
+ curCard.appendChild(child);
4340
+ curH += chH;
4341
+ if (curH >= maxH && i < children.length - 1) {
4342
+ curCard = createRtfCard();
4343
+ wrapper.appendChild(curCard);
4344
+ pageElements.push(curCard);
4345
+ curH = 0;
4346
+ }
4347
+ }
4348
+ } else {
4349
+ pageElements = [singleEl];
4350
+ }
4351
+ } else {
4352
+ pageElements = htmlElements;
4353
+ for (let i = 0; i < htmlElements.length; i++) {
4354
+ const el = htmlElements[i];
4355
+ el.style.display = i === 0 ? "block" : "none";
4356
+ wrapper.appendChild(el);
4357
+ }
4260
4358
  }
4261
4359
  } catch (err) {
4262
4360
  console.warn("[RtfPlugin] RTF render error, fallback text:", err);
@@ -4322,6 +4420,7 @@ var RtfPlugin = class {
4322
4420
  if (indicator) {
4323
4421
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4324
4422
  }
4423
+ ctx.container.scrollTop = 0;
4325
4424
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4326
4425
  };
4327
4426
  if (totalPages > 1) {
@@ -4793,12 +4892,9 @@ var OpenDocumentPlugin = class {
4793
4892
  page.style.backgroundColor = "#ffffff";
4794
4893
  page.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
4795
4894
  page.style.borderRadius = "4px";
4796
- page.style.boxSizing = "border-box";
4797
4895
  page.style.display = idx === 0 ? "block" : "none";
4798
- page.style.position = "absolute";
4799
- page.style.top = "0";
4800
- page.style.left = "50%";
4801
- page.style.transform = "translateX(-50%)";
4896
+ page.style.margin = "0 auto 24px";
4897
+ page.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4802
4898
  elements.forEach((el) => page.appendChild(el));
4803
4899
  wrapper.appendChild(page);
4804
4900
  slides.push(page);
@@ -4836,6 +4932,7 @@ var OpenDocumentPlugin = class {
4836
4932
  if (indicator) {
4837
4933
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4838
4934
  }
4935
+ container.scrollTop = 0;
4839
4936
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4840
4937
  };
4841
4938
  return {
@@ -5328,6 +5425,7 @@ var DocPlugin = class {
5328
5425
  if (indicator) {
5329
5426
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
5330
5427
  }
5428
+ container.scrollTop = 0;
5331
5429
  ctx.emit("page-change", { page: currentPage, total: totalPages });
5332
5430
  };
5333
5431
  if (totalPages > 1) {
@@ -5505,45 +5603,50 @@ var DocPlugin = class {
5505
5603
  }
5506
5604
  splitIntoPages(text) {
5507
5605
  if (!text) return [""];
5508
- 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);
5509
- if (explicitParts.length === 0) explicitParts.push(text);
5510
- const maxLinesPerPage = 48;
5606
+ const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
5607
+ const explicitParts = normalized.split(/[\x0C\f]|\n\s*[-=_]{3,}\s*(?:PAGE|Page|page break)[\s\d\w-]*[-=_]{3,}\s*\n/i).map((p) => p.trim()).filter((p) => p.length > 0);
5608
+ if (explicitParts.length === 0) explicitParts.push(normalized);
5609
+ const maxLinesPerPage = 32;
5610
+ const charsPerLine = 80;
5511
5611
  const finalPages = [];
5512
5612
  for (const part of explicitParts) {
5513
- const lines = part.split(/\r?\n/);
5613
+ const lines = part.split("\n");
5514
5614
  let currentLines = [];
5515
5615
  let count = 0;
5516
5616
  for (const line of lines) {
5517
- currentLines.push(line);
5518
- count++;
5519
- if (count >= maxLinesPerPage) {
5617
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
5618
+ if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
5520
5619
  finalPages.push(currentLines.join("\n"));
5521
5620
  currentLines = [];
5522
5621
  count = 0;
5523
5622
  }
5623
+ currentLines.push(line);
5624
+ count += vLines;
5524
5625
  }
5525
5626
  if (currentLines.length > 0) {
5526
5627
  finalPages.push(currentLines.join("\n"));
5527
5628
  }
5528
5629
  }
5529
- return finalPages.length > 0 ? finalPages : [text];
5630
+ return finalPages.length > 0 ? finalPages : [normalized];
5530
5631
  }
5531
5632
  /**
5532
5633
  * Format cleaned extracted text into attractive HTML paragraphs, headings, and lists
5533
5634
  */
5534
5635
  formatDocToHtml(text, filename) {
5535
- const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").split("\n");
5636
+ const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ").split("\n");
5536
5637
  let html = "";
5537
5638
  let inList = false;
5538
5639
  let tableLines = [];
5539
5640
  const flushTable = () => {
5540
5641
  if (tableLines.length > 0) {
5541
- html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12px;">';
5542
- for (const tLine of tableLines) {
5543
- html += "<tr>";
5544
- const cols = tLine.split(" ");
5642
+ html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px; font-family: Calibri, sans-serif;">';
5643
+ for (let rIdx = 0; rIdx < tableLines.length; rIdx++) {
5644
+ const tLine = tableLines[rIdx];
5645
+ const isHeader = rIdx === 0;
5646
+ html += `<tr style="${isHeader ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
5647
+ const cols = tLine.split(" ").filter((c) => c.trim().length > 0);
5545
5648
  for (const col of cols) {
5546
- html += `<td style="border: 1px solid #cbd5e1; padding: 6px 8px;">${DOMPurify6.sanitize(col.trim())}</td>`;
5649
+ html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px;">${DOMPurify6.sanitize(col.trim())}</td>`;
5547
5650
  }
5548
5651
  html += "</tr>";
5549
5652
  }
@@ -5556,27 +5659,18 @@ var DocPlugin = class {
5556
5659
  let line = lines[i];
5557
5660
  let tabCount = (line.match(/\t/g) || []).length;
5558
5661
  if (tabCount > 0) {
5559
- let consecutiveTableLines = 1;
5560
- let j = i + 1;
5561
- while (j < lines.length) {
5562
- const nextTabCount = (lines[j].match(/\t/g) || []).length;
5563
- if (nextTabCount === tabCount) {
5564
- consecutiveTableLines++;
5565
- j++;
5566
- } else {
5567
- break;
5568
- }
5662
+ let j = i;
5663
+ while (j < lines.length && (lines[j].match(/\t/g) || []).length > 0) {
5664
+ j++;
5569
5665
  }
5570
- if (consecutiveTableLines >= 3) {
5571
- if (inList) {
5572
- html += "</ul>";
5573
- inList = false;
5574
- }
5575
- tableLines = lines.slice(i, j);
5576
- flushTable();
5577
- i = j;
5578
- continue;
5666
+ if (inList) {
5667
+ html += "</ul>";
5668
+ inList = false;
5579
5669
  }
5670
+ tableLines = lines.slice(i, j);
5671
+ flushTable();
5672
+ i = j;
5673
+ continue;
5580
5674
  }
5581
5675
  line = line.trim();
5582
5676
  if (!line) {