@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/angular.cjs CHANGED
@@ -1596,6 +1596,7 @@ var PdfPlugin = class {
1596
1596
  getPageCount: () => totalPages,
1597
1597
  getCurrentPage: () => currentPage,
1598
1598
  goToPage: (page) => {
1599
+ container.scrollTop = 0;
1599
1600
  renderPage(page);
1600
1601
  },
1601
1602
  download: () => {
@@ -2100,7 +2101,14 @@ var DocxPlugin = class {
2100
2101
  ignoreFonts: true,
2101
2102
  // Avoid crashes on embedded obfuscated fonts
2102
2103
  breakPages: true,
2103
- experimental: true
2104
+ experimental: true,
2105
+ ignoreLastRenderedPageBreak: false,
2106
+ // Honor Word's exact page breaks!
2107
+ renderHeaders: true,
2108
+ renderFooters: true,
2109
+ renderFootnotes: true,
2110
+ renderEndnotes: true,
2111
+ useBase64URL: true
2104
2112
  });
2105
2113
  if (!ctx.container.contains(wrapper)) {
2106
2114
  ctx.container.appendChild(wrapper);
@@ -2121,11 +2129,14 @@ var DocxPlugin = class {
2121
2129
  renderedSuccessfully = true;
2122
2130
  } catch (fallbackErr) {
2123
2131
  console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
2132
+ const isCorrupt = fallbackErr?.message?.includes("invalid zip") || fallbackErr?.message?.includes("corrupted");
2124
2133
  wrapper.innerHTML = `
2125
- <div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
2126
- <div style="font-size:48px; margin-bottom: 16px;">\u{1F4C4}</div>
2127
- <h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
2128
- <p style="color: #64748b; margin: 0;">Could not parse document content</p>
2134
+ <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;">
2135
+ <div style="font-size:48px; margin-bottom: 16px;">${isCorrupt ? "\u26A0\uFE0F" : "\u{1F4C4}"}</div>
2136
+ <h3 style="margin: 0 0 8px; color: #1e293b; font-size: 18px;">${ctx.metadata.name || "Word Document"}</h3>
2137
+ <p style="color: #64748b; margin: 0 0 16px; font-size: 14px; line-height: 1.5;">
2138
+ ${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."}
2139
+ </p>
2129
2140
  </div>
2130
2141
  `;
2131
2142
  if (!ctx.container.contains(wrapper)) {
@@ -2137,47 +2148,61 @@ var DocxPlugin = class {
2137
2148
  const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
2138
2149
  if (sections.length === 1 && cards.length === 0) {
2139
2150
  const singleSec = sections[0];
2140
- const pageH = 1056;
2151
+ const contentContainer = singleSec.querySelector("article") || singleSec;
2152
+ const children = Array.from(contentContainer.children);
2153
+ const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
2141
2154
  const secH = singleSec.offsetHeight || singleSec.scrollHeight;
2142
- if (secH > pageH * 1.25) {
2143
- const children = Array.from(singleSec.children);
2144
- if (children.length > 1) {
2145
- const parent = singleSec.parentElement || wrapper;
2146
- const newSections = [singleSec];
2147
- singleSec.innerHTML = "";
2148
- singleSec.style.minHeight = `${pageH}px`;
2149
- singleSec.style.maxHeight = `${pageH}px`;
2150
- singleSec.style.overflow = "hidden";
2151
- singleSec.style.boxSizing = "border-box";
2152
- let curSec = singleSec;
2153
- let curH = 0;
2154
- const maxH = pageH - 96;
2155
- for (let i = 0; i < children.length; i++) {
2156
- const child = children[i];
2157
- curSec.appendChild(child);
2158
- const chH = child.offsetHeight || 28;
2159
- curH += chH;
2160
- if (curH >= maxH && i < children.length - 1) {
2161
- const nextSec = document.createElement("section");
2162
- nextSec.className = singleSec.className;
2163
- nextSec.style.cssText = singleSec.style.cssText;
2164
- nextSec.style.width = singleSec.style.width || "816px";
2165
- nextSec.style.minHeight = `${pageH}px`;
2166
- nextSec.style.maxHeight = `${pageH}px`;
2167
- nextSec.style.overflow = "hidden";
2168
- nextSec.style.boxSizing = "border-box";
2169
- nextSec.style.backgroundColor = "#ffffff";
2170
- nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2171
- nextSec.style.borderRadius = "4px";
2172
- nextSec.style.marginBottom = "24px";
2173
- parent.appendChild(nextSec);
2174
- newSections.push(nextSec);
2175
- curSec = nextSec;
2176
- curH = 0;
2155
+ if (secH > pageH * 1.25 && children.length > 1) {
2156
+ const childHeights = children.map((c) => {
2157
+ const rectH = c.getBoundingClientRect().height;
2158
+ const offH = c.offsetHeight;
2159
+ const textLen = c.textContent?.trim().length || 0;
2160
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
2161
+ return Math.max(rectH, offH, estH);
2162
+ });
2163
+ const parent = singleSec.parentElement || wrapper;
2164
+ const newSections = [singleSec];
2165
+ const headerEl = singleSec.querySelector("header");
2166
+ const footerEl = singleSec.querySelector("footer");
2167
+ contentContainer.innerHTML = "";
2168
+ singleSec.style.minHeight = `${pageH}px`;
2169
+ singleSec.style.boxSizing = "border-box";
2170
+ let curContent = contentContainer;
2171
+ let curH = 0;
2172
+ const maxH = pageH - 140;
2173
+ for (let i = 0; i < children.length; i++) {
2174
+ const child = children[i];
2175
+ const chH = childHeights[i];
2176
+ curContent.appendChild(child);
2177
+ curH += chH;
2178
+ if (curH >= maxH && i < children.length - 1) {
2179
+ const nextSec = document.createElement("section");
2180
+ nextSec.className = singleSec.className;
2181
+ nextSec.style.cssText = singleSec.style.cssText;
2182
+ nextSec.style.minHeight = `${pageH}px`;
2183
+ nextSec.style.boxSizing = "border-box";
2184
+ nextSec.style.backgroundColor = "#ffffff";
2185
+ nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2186
+ nextSec.style.borderRadius = "4px";
2187
+ nextSec.style.marginBottom = "24px";
2188
+ if (headerEl) {
2189
+ nextSec.appendChild(headerEl.cloneNode(true));
2190
+ }
2191
+ const nextArticle = document.createElement("article");
2192
+ if (contentContainer.tagName.toLowerCase() === "article") {
2193
+ nextArticle.style.cssText = contentContainer.style.cssText;
2177
2194
  }
2195
+ nextSec.appendChild(nextArticle);
2196
+ if (footerEl) {
2197
+ nextSec.appendChild(footerEl.cloneNode(true));
2198
+ }
2199
+ parent.appendChild(nextSec);
2200
+ newSections.push(nextSec);
2201
+ curContent = nextArticle;
2202
+ curH = 0;
2178
2203
  }
2179
- sections = newSections;
2180
2204
  }
2205
+ sections = newSections;
2181
2206
  }
2182
2207
  }
2183
2208
  const pageElements = sections.length > 0 ? sections : cards;
@@ -2216,6 +2241,7 @@ var DocxPlugin = class {
2216
2241
  if (indicator) {
2217
2242
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
2218
2243
  }
2244
+ ctx.container.scrollTop = 0;
2219
2245
  ctx.emit("page-change", { page: currentPage, total: totalPages });
2220
2246
  };
2221
2247
  if (totalPages > 1) {
@@ -3148,17 +3174,39 @@ var CodePlugin = class {
3148
3174
  let rawPages = [];
3149
3175
  if (isTxt) {
3150
3176
  const explicitPages = fullText.split(/(?:\f|\x0C)/);
3177
+ const charsPerLine = 85;
3178
+ const maxVisualLines = 45;
3179
+ const charsPerPage = charsPerLine * maxVisualLines;
3151
3180
  for (const ep of explicitPages) {
3152
3181
  const lines = ep.split(/\r?\n/);
3153
3182
  let currentChunk = [];
3183
+ let currentLines = 0;
3154
3184
  for (let i = 0; i < lines.length; i++) {
3155
- currentChunk.push(lines[i]);
3156
- if (currentChunk.length >= 46) {
3185
+ const line = lines[i];
3186
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
3187
+ if (currentLines + vLines > maxVisualLines && currentChunk.length > 0) {
3157
3188
  rawPages.push(currentChunk.join("\n"));
3158
3189
  currentChunk = [];
3190
+ currentLines = 0;
3191
+ }
3192
+ if (vLines > maxVisualLines) {
3193
+ let remaining = line;
3194
+ while (remaining.length > charsPerPage) {
3195
+ let splitIdx = remaining.lastIndexOf(" ", charsPerPage);
3196
+ if (splitIdx < charsPerPage * 0.75) splitIdx = charsPerPage;
3197
+ rawPages.push(remaining.slice(0, splitIdx));
3198
+ remaining = remaining.slice(splitIdx).trimStart();
3199
+ }
3200
+ if (remaining.length > 0) {
3201
+ currentChunk.push(remaining);
3202
+ currentLines = Math.ceil(remaining.length / charsPerLine);
3203
+ }
3204
+ } else {
3205
+ currentChunk.push(line);
3206
+ currentLines += vLines;
3159
3207
  }
3160
3208
  }
3161
- if (currentChunk.length > 0 || lines.length === 0) {
3209
+ if (currentChunk.length > 0) {
3162
3210
  rawPages.push(currentChunk.join("\n"));
3163
3211
  }
3164
3212
  }
@@ -3268,6 +3316,7 @@ var CodePlugin = class {
3268
3316
  if (indicator) {
3269
3317
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
3270
3318
  }
3319
+ container.scrollTop = 0;
3271
3320
  ctx.emit("page-change", { page: currentPage, total: totalPages });
3272
3321
  };
3273
3322
  if (totalPages > 1) {
@@ -4332,11 +4381,60 @@ var RtfPlugin = class {
4332
4381
  }
4333
4382
  const doc = new RTFJS__namespace.Document(ctx.buffer, {});
4334
4383
  const htmlElements = await doc.render();
4335
- pageElements = htmlElements;
4336
- for (let i = 0; i < htmlElements.length; i++) {
4337
- const el = htmlElements[i];
4338
- el.style.display = i === 0 ? "block" : "none";
4339
- wrapper.appendChild(el);
4384
+ if (htmlElements.length === 1) {
4385
+ const singleEl = htmlElements[0];
4386
+ wrapper.appendChild(singleEl);
4387
+ const children = Array.from(singleEl.children);
4388
+ const secH = singleEl.offsetHeight || singleEl.scrollHeight;
4389
+ if (secH > 1300 && children.length > 1) {
4390
+ const childHeights = children.map((c) => {
4391
+ const rectH = c.getBoundingClientRect().height;
4392
+ const offH = c.offsetHeight;
4393
+ const textLen = c.textContent?.trim().length || 0;
4394
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
4395
+ return Math.max(rectH, offH, estH);
4396
+ });
4397
+ wrapper.innerHTML = "";
4398
+ const createRtfCard = () => {
4399
+ const card = document.createElement("div");
4400
+ card.className = "fp-rtf-page-card";
4401
+ card.style.backgroundColor = "#ffffff";
4402
+ card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
4403
+ card.style.borderRadius = "4px";
4404
+ card.style.padding = "72px 56px";
4405
+ card.style.width = "816px";
4406
+ card.style.minHeight = "1056px";
4407
+ card.style.boxSizing = "border-box";
4408
+ card.style.marginBottom = "24px";
4409
+ return card;
4410
+ };
4411
+ let curCard = createRtfCard();
4412
+ wrapper.appendChild(curCard);
4413
+ pageElements = [curCard];
4414
+ let curH = 0;
4415
+ const maxH = 920;
4416
+ for (let i = 0; i < children.length; i++) {
4417
+ const child = children[i];
4418
+ const chH = childHeights[i];
4419
+ curCard.appendChild(child);
4420
+ curH += chH;
4421
+ if (curH >= maxH && i < children.length - 1) {
4422
+ curCard = createRtfCard();
4423
+ wrapper.appendChild(curCard);
4424
+ pageElements.push(curCard);
4425
+ curH = 0;
4426
+ }
4427
+ }
4428
+ } else {
4429
+ pageElements = [singleEl];
4430
+ }
4431
+ } else {
4432
+ pageElements = htmlElements;
4433
+ for (let i = 0; i < htmlElements.length; i++) {
4434
+ const el = htmlElements[i];
4435
+ el.style.display = i === 0 ? "block" : "none";
4436
+ wrapper.appendChild(el);
4437
+ }
4340
4438
  }
4341
4439
  } catch (err) {
4342
4440
  console.warn("[RtfPlugin] RTF render error, fallback text:", err);
@@ -4402,6 +4500,7 @@ var RtfPlugin = class {
4402
4500
  if (indicator) {
4403
4501
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4404
4502
  }
4503
+ ctx.container.scrollTop = 0;
4405
4504
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4406
4505
  };
4407
4506
  if (totalPages > 1) {
@@ -4873,12 +4972,9 @@ var OpenDocumentPlugin = class {
4873
4972
  page.style.backgroundColor = "#ffffff";
4874
4973
  page.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
4875
4974
  page.style.borderRadius = "4px";
4876
- page.style.boxSizing = "border-box";
4877
4975
  page.style.display = idx === 0 ? "block" : "none";
4878
- page.style.position = "absolute";
4879
- page.style.top = "0";
4880
- page.style.left = "50%";
4881
- page.style.transform = "translateX(-50%)";
4976
+ page.style.margin = "0 auto 24px";
4977
+ page.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4882
4978
  elements.forEach((el) => page.appendChild(el));
4883
4979
  wrapper.appendChild(page);
4884
4980
  slides.push(page);
@@ -4916,6 +5012,7 @@ var OpenDocumentPlugin = class {
4916
5012
  if (indicator) {
4917
5013
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4918
5014
  }
5015
+ container.scrollTop = 0;
4919
5016
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4920
5017
  };
4921
5018
  return {
@@ -5408,6 +5505,7 @@ var DocPlugin = class {
5408
5505
  if (indicator) {
5409
5506
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
5410
5507
  }
5508
+ container.scrollTop = 0;
5411
5509
  ctx.emit("page-change", { page: currentPage, total: totalPages });
5412
5510
  };
5413
5511
  if (totalPages > 1) {
@@ -5585,45 +5683,50 @@ var DocPlugin = class {
5585
5683
  }
5586
5684
  splitIntoPages(text) {
5587
5685
  if (!text) return [""];
5588
- 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);
5589
- if (explicitParts.length === 0) explicitParts.push(text);
5590
- const maxLinesPerPage = 48;
5686
+ const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
5687
+ 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);
5688
+ if (explicitParts.length === 0) explicitParts.push(normalized);
5689
+ const maxLinesPerPage = 32;
5690
+ const charsPerLine = 80;
5591
5691
  const finalPages = [];
5592
5692
  for (const part of explicitParts) {
5593
- const lines = part.split(/\r?\n/);
5693
+ const lines = part.split("\n");
5594
5694
  let currentLines = [];
5595
5695
  let count = 0;
5596
5696
  for (const line of lines) {
5597
- currentLines.push(line);
5598
- count++;
5599
- if (count >= maxLinesPerPage) {
5697
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
5698
+ if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
5600
5699
  finalPages.push(currentLines.join("\n"));
5601
5700
  currentLines = [];
5602
5701
  count = 0;
5603
5702
  }
5703
+ currentLines.push(line);
5704
+ count += vLines;
5604
5705
  }
5605
5706
  if (currentLines.length > 0) {
5606
5707
  finalPages.push(currentLines.join("\n"));
5607
5708
  }
5608
5709
  }
5609
- return finalPages.length > 0 ? finalPages : [text];
5710
+ return finalPages.length > 0 ? finalPages : [normalized];
5610
5711
  }
5611
5712
  /**
5612
5713
  * Format cleaned extracted text into attractive HTML paragraphs, headings, and lists
5613
5714
  */
5614
5715
  formatDocToHtml(text, filename) {
5615
- const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").split("\n");
5716
+ 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");
5616
5717
  let html = "";
5617
5718
  let inList = false;
5618
5719
  let tableLines = [];
5619
5720
  const flushTable = () => {
5620
5721
  if (tableLines.length > 0) {
5621
- html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12px;">';
5622
- for (const tLine of tableLines) {
5623
- html += "<tr>";
5624
- const cols = tLine.split(" ");
5722
+ html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px; font-family: Calibri, sans-serif;">';
5723
+ for (let rIdx = 0; rIdx < tableLines.length; rIdx++) {
5724
+ const tLine = tableLines[rIdx];
5725
+ const isHeader = rIdx === 0;
5726
+ html += `<tr style="${isHeader ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
5727
+ const cols = tLine.split(" ").filter((c) => c.trim().length > 0);
5625
5728
  for (const col of cols) {
5626
- html += `<td style="border: 1px solid #cbd5e1; padding: 6px 8px;">${DOMPurify6__default.default.sanitize(col.trim())}</td>`;
5729
+ html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px;">${DOMPurify6__default.default.sanitize(col.trim())}</td>`;
5627
5730
  }
5628
5731
  html += "</tr>";
5629
5732
  }
@@ -5636,27 +5739,18 @@ var DocPlugin = class {
5636
5739
  let line = lines[i];
5637
5740
  let tabCount = (line.match(/\t/g) || []).length;
5638
5741
  if (tabCount > 0) {
5639
- let consecutiveTableLines = 1;
5640
- let j = i + 1;
5641
- while (j < lines.length) {
5642
- const nextTabCount = (lines[j].match(/\t/g) || []).length;
5643
- if (nextTabCount === tabCount) {
5644
- consecutiveTableLines++;
5645
- j++;
5646
- } else {
5647
- break;
5648
- }
5742
+ let j = i;
5743
+ while (j < lines.length && (lines[j].match(/\t/g) || []).length > 0) {
5744
+ j++;
5649
5745
  }
5650
- if (consecutiveTableLines >= 3) {
5651
- if (inList) {
5652
- html += "</ul>";
5653
- inList = false;
5654
- }
5655
- tableLines = lines.slice(i, j);
5656
- flushTable();
5657
- i = j;
5658
- continue;
5746
+ if (inList) {
5747
+ html += "</ul>";
5748
+ inList = false;
5659
5749
  }
5750
+ tableLines = lines.slice(i, j);
5751
+ flushTable();
5752
+ i = j;
5753
+ continue;
5660
5754
  }
5661
5755
  line = line.trim();
5662
5756
  if (!line) {