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