@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.js CHANGED
@@ -1564,6 +1564,7 @@ var PdfPlugin = class {
1564
1564
  getPageCount: () => totalPages,
1565
1565
  getCurrentPage: () => currentPage,
1566
1566
  goToPage: (page) => {
1567
+ container.scrollTop = 0;
1567
1568
  renderPage(page);
1568
1569
  },
1569
1570
  download: () => {
@@ -2068,7 +2069,14 @@ var DocxPlugin = class {
2068
2069
  ignoreFonts: true,
2069
2070
  // Avoid crashes on embedded obfuscated fonts
2070
2071
  breakPages: true,
2071
- experimental: true
2072
+ experimental: true,
2073
+ ignoreLastRenderedPageBreak: false,
2074
+ // Honor Word's exact page breaks!
2075
+ renderHeaders: true,
2076
+ renderFooters: true,
2077
+ renderFootnotes: true,
2078
+ renderEndnotes: true,
2079
+ useBase64URL: true
2072
2080
  });
2073
2081
  if (!ctx.container.contains(wrapper)) {
2074
2082
  ctx.container.appendChild(wrapper);
@@ -2089,11 +2097,14 @@ var DocxPlugin = class {
2089
2097
  renderedSuccessfully = true;
2090
2098
  } catch (fallbackErr) {
2091
2099
  console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
2100
+ const isCorrupt = fallbackErr?.message?.includes("invalid zip") || fallbackErr?.message?.includes("corrupted");
2092
2101
  wrapper.innerHTML = `
2093
- <div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
2094
- <div style="font-size:48px; margin-bottom: 16px;">\u{1F4C4}</div>
2095
- <h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
2096
- <p style="color: #64748b; margin: 0;">Could not parse document content</p>
2102
+ <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;">
2103
+ <div style="font-size:48px; margin-bottom: 16px;">${isCorrupt ? "\u26A0\uFE0F" : "\u{1F4C4}"}</div>
2104
+ <h3 style="margin: 0 0 8px; color: #1e293b; font-size: 18px;">${ctx.metadata.name || "Word Document"}</h3>
2105
+ <p style="color: #64748b; margin: 0 0 16px; font-size: 14px; line-height: 1.5;">
2106
+ ${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."}
2107
+ </p>
2097
2108
  </div>
2098
2109
  `;
2099
2110
  if (!ctx.container.contains(wrapper)) {
@@ -2105,47 +2116,61 @@ var DocxPlugin = class {
2105
2116
  const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
2106
2117
  if (sections.length === 1 && cards.length === 0) {
2107
2118
  const singleSec = sections[0];
2108
- const pageH = 1056;
2119
+ const contentContainer = singleSec.querySelector("article") || singleSec;
2120
+ const children = Array.from(contentContainer.children);
2121
+ const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
2109
2122
  const secH = singleSec.offsetHeight || singleSec.scrollHeight;
2110
- if (secH > pageH * 1.25) {
2111
- const children = Array.from(singleSec.children);
2112
- if (children.length > 1) {
2113
- const parent = singleSec.parentElement || wrapper;
2114
- const newSections = [singleSec];
2115
- singleSec.innerHTML = "";
2116
- singleSec.style.minHeight = `${pageH}px`;
2117
- singleSec.style.maxHeight = `${pageH}px`;
2118
- singleSec.style.overflow = "hidden";
2119
- singleSec.style.boxSizing = "border-box";
2120
- let curSec = singleSec;
2121
- let curH = 0;
2122
- const maxH = pageH - 96;
2123
- for (let i = 0; i < children.length; i++) {
2124
- const child = children[i];
2125
- curSec.appendChild(child);
2126
- const chH = child.offsetHeight || 28;
2127
- curH += chH;
2128
- if (curH >= maxH && i < children.length - 1) {
2129
- const nextSec = document.createElement("section");
2130
- nextSec.className = singleSec.className;
2131
- nextSec.style.cssText = singleSec.style.cssText;
2132
- nextSec.style.width = singleSec.style.width || "816px";
2133
- nextSec.style.minHeight = `${pageH}px`;
2134
- nextSec.style.maxHeight = `${pageH}px`;
2135
- nextSec.style.overflow = "hidden";
2136
- nextSec.style.boxSizing = "border-box";
2137
- nextSec.style.backgroundColor = "#ffffff";
2138
- nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2139
- nextSec.style.borderRadius = "4px";
2140
- nextSec.style.marginBottom = "24px";
2141
- parent.appendChild(nextSec);
2142
- newSections.push(nextSec);
2143
- curSec = nextSec;
2144
- curH = 0;
2123
+ if (secH > pageH * 1.25 && children.length > 1) {
2124
+ const childHeights = children.map((c) => {
2125
+ const rectH = c.getBoundingClientRect().height;
2126
+ const offH = c.offsetHeight;
2127
+ const textLen = c.textContent?.trim().length || 0;
2128
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
2129
+ return Math.max(rectH, offH, estH);
2130
+ });
2131
+ const parent = singleSec.parentElement || wrapper;
2132
+ const newSections = [singleSec];
2133
+ const headerEl = singleSec.querySelector("header");
2134
+ const footerEl = singleSec.querySelector("footer");
2135
+ contentContainer.innerHTML = "";
2136
+ singleSec.style.minHeight = `${pageH}px`;
2137
+ singleSec.style.boxSizing = "border-box";
2138
+ let curContent = contentContainer;
2139
+ let curH = 0;
2140
+ const maxH = pageH - 140;
2141
+ for (let i = 0; i < children.length; i++) {
2142
+ const child = children[i];
2143
+ const chH = childHeights[i];
2144
+ curContent.appendChild(child);
2145
+ curH += chH;
2146
+ if (curH >= maxH && i < children.length - 1) {
2147
+ const nextSec = document.createElement("section");
2148
+ nextSec.className = singleSec.className;
2149
+ nextSec.style.cssText = singleSec.style.cssText;
2150
+ nextSec.style.minHeight = `${pageH}px`;
2151
+ nextSec.style.boxSizing = "border-box";
2152
+ nextSec.style.backgroundColor = "#ffffff";
2153
+ nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2154
+ nextSec.style.borderRadius = "4px";
2155
+ nextSec.style.marginBottom = "24px";
2156
+ if (headerEl) {
2157
+ nextSec.appendChild(headerEl.cloneNode(true));
2158
+ }
2159
+ const nextArticle = document.createElement("article");
2160
+ if (contentContainer.tagName.toLowerCase() === "article") {
2161
+ nextArticle.style.cssText = contentContainer.style.cssText;
2145
2162
  }
2163
+ nextSec.appendChild(nextArticle);
2164
+ if (footerEl) {
2165
+ nextSec.appendChild(footerEl.cloneNode(true));
2166
+ }
2167
+ parent.appendChild(nextSec);
2168
+ newSections.push(nextSec);
2169
+ curContent = nextArticle;
2170
+ curH = 0;
2146
2171
  }
2147
- sections = newSections;
2148
2172
  }
2173
+ sections = newSections;
2149
2174
  }
2150
2175
  }
2151
2176
  const pageElements = sections.length > 0 ? sections : cards;
@@ -2184,6 +2209,7 @@ var DocxPlugin = class {
2184
2209
  if (indicator) {
2185
2210
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
2186
2211
  }
2212
+ ctx.container.scrollTop = 0;
2187
2213
  ctx.emit("page-change", { page: currentPage, total: totalPages });
2188
2214
  };
2189
2215
  if (totalPages > 1) {
@@ -3116,17 +3142,39 @@ var CodePlugin = class {
3116
3142
  let rawPages = [];
3117
3143
  if (isTxt) {
3118
3144
  const explicitPages = fullText.split(/(?:\f|\x0C)/);
3145
+ const charsPerLine = 85;
3146
+ const maxVisualLines = 45;
3147
+ const charsPerPage = charsPerLine * maxVisualLines;
3119
3148
  for (const ep of explicitPages) {
3120
3149
  const lines = ep.split(/\r?\n/);
3121
3150
  let currentChunk = [];
3151
+ let currentLines = 0;
3122
3152
  for (let i = 0; i < lines.length; i++) {
3123
- currentChunk.push(lines[i]);
3124
- if (currentChunk.length >= 46) {
3153
+ const line = lines[i];
3154
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
3155
+ if (currentLines + vLines > maxVisualLines && currentChunk.length > 0) {
3125
3156
  rawPages.push(currentChunk.join("\n"));
3126
3157
  currentChunk = [];
3158
+ currentLines = 0;
3159
+ }
3160
+ if (vLines > maxVisualLines) {
3161
+ let remaining = line;
3162
+ while (remaining.length > charsPerPage) {
3163
+ let splitIdx = remaining.lastIndexOf(" ", charsPerPage);
3164
+ if (splitIdx < charsPerPage * 0.75) splitIdx = charsPerPage;
3165
+ rawPages.push(remaining.slice(0, splitIdx));
3166
+ remaining = remaining.slice(splitIdx).trimStart();
3167
+ }
3168
+ if (remaining.length > 0) {
3169
+ currentChunk.push(remaining);
3170
+ currentLines = Math.ceil(remaining.length / charsPerLine);
3171
+ }
3172
+ } else {
3173
+ currentChunk.push(line);
3174
+ currentLines += vLines;
3127
3175
  }
3128
3176
  }
3129
- if (currentChunk.length > 0 || lines.length === 0) {
3177
+ if (currentChunk.length > 0) {
3130
3178
  rawPages.push(currentChunk.join("\n"));
3131
3179
  }
3132
3180
  }
@@ -3236,6 +3284,7 @@ var CodePlugin = class {
3236
3284
  if (indicator) {
3237
3285
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
3238
3286
  }
3287
+ container.scrollTop = 0;
3239
3288
  ctx.emit("page-change", { page: currentPage, total: totalPages });
3240
3289
  };
3241
3290
  if (totalPages > 1) {
@@ -4300,11 +4349,60 @@ var RtfPlugin = class {
4300
4349
  }
4301
4350
  const doc = new RTFJS.Document(ctx.buffer, {});
4302
4351
  const htmlElements = await doc.render();
4303
- pageElements = htmlElements;
4304
- for (let i = 0; i < htmlElements.length; i++) {
4305
- const el = htmlElements[i];
4306
- el.style.display = i === 0 ? "block" : "none";
4307
- wrapper.appendChild(el);
4352
+ if (htmlElements.length === 1) {
4353
+ const singleEl = htmlElements[0];
4354
+ wrapper.appendChild(singleEl);
4355
+ const children = Array.from(singleEl.children);
4356
+ const secH = singleEl.offsetHeight || singleEl.scrollHeight;
4357
+ if (secH > 1300 && children.length > 1) {
4358
+ const childHeights = children.map((c) => {
4359
+ const rectH = c.getBoundingClientRect().height;
4360
+ const offH = c.offsetHeight;
4361
+ const textLen = c.textContent?.trim().length || 0;
4362
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
4363
+ return Math.max(rectH, offH, estH);
4364
+ });
4365
+ wrapper.innerHTML = "";
4366
+ const createRtfCard = () => {
4367
+ const card = document.createElement("div");
4368
+ card.className = "fp-rtf-page-card";
4369
+ card.style.backgroundColor = "#ffffff";
4370
+ card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
4371
+ card.style.borderRadius = "4px";
4372
+ card.style.padding = "72px 56px";
4373
+ card.style.width = "816px";
4374
+ card.style.minHeight = "1056px";
4375
+ card.style.boxSizing = "border-box";
4376
+ card.style.marginBottom = "24px";
4377
+ return card;
4378
+ };
4379
+ let curCard = createRtfCard();
4380
+ wrapper.appendChild(curCard);
4381
+ pageElements = [curCard];
4382
+ let curH = 0;
4383
+ const maxH = 920;
4384
+ for (let i = 0; i < children.length; i++) {
4385
+ const child = children[i];
4386
+ const chH = childHeights[i];
4387
+ curCard.appendChild(child);
4388
+ curH += chH;
4389
+ if (curH >= maxH && i < children.length - 1) {
4390
+ curCard = createRtfCard();
4391
+ wrapper.appendChild(curCard);
4392
+ pageElements.push(curCard);
4393
+ curH = 0;
4394
+ }
4395
+ }
4396
+ } else {
4397
+ pageElements = [singleEl];
4398
+ }
4399
+ } else {
4400
+ pageElements = htmlElements;
4401
+ for (let i = 0; i < htmlElements.length; i++) {
4402
+ const el = htmlElements[i];
4403
+ el.style.display = i === 0 ? "block" : "none";
4404
+ wrapper.appendChild(el);
4405
+ }
4308
4406
  }
4309
4407
  } catch (err) {
4310
4408
  console.warn("[RtfPlugin] RTF render error, fallback text:", err);
@@ -4370,6 +4468,7 @@ var RtfPlugin = class {
4370
4468
  if (indicator) {
4371
4469
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4372
4470
  }
4471
+ ctx.container.scrollTop = 0;
4373
4472
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4374
4473
  };
4375
4474
  if (totalPages > 1) {
@@ -4841,12 +4940,9 @@ var OpenDocumentPlugin = class {
4841
4940
  page.style.backgroundColor = "#ffffff";
4842
4941
  page.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
4843
4942
  page.style.borderRadius = "4px";
4844
- page.style.boxSizing = "border-box";
4845
4943
  page.style.display = idx === 0 ? "block" : "none";
4846
- page.style.position = "absolute";
4847
- page.style.top = "0";
4848
- page.style.left = "50%";
4849
- page.style.transform = "translateX(-50%)";
4944
+ page.style.margin = "0 auto 24px";
4945
+ page.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4850
4946
  elements.forEach((el) => page.appendChild(el));
4851
4947
  wrapper.appendChild(page);
4852
4948
  slides.push(page);
@@ -4884,6 +4980,7 @@ var OpenDocumentPlugin = class {
4884
4980
  if (indicator) {
4885
4981
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4886
4982
  }
4983
+ container.scrollTop = 0;
4887
4984
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4888
4985
  };
4889
4986
  return {
@@ -5376,6 +5473,7 @@ var DocPlugin = class {
5376
5473
  if (indicator) {
5377
5474
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
5378
5475
  }
5476
+ container.scrollTop = 0;
5379
5477
  ctx.emit("page-change", { page: currentPage, total: totalPages });
5380
5478
  };
5381
5479
  if (totalPages > 1) {
@@ -5553,45 +5651,50 @@ var DocPlugin = class {
5553
5651
  }
5554
5652
  splitIntoPages(text) {
5555
5653
  if (!text) return [""];
5556
- 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);
5557
- if (explicitParts.length === 0) explicitParts.push(text);
5558
- const maxLinesPerPage = 48;
5654
+ const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
5655
+ 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);
5656
+ if (explicitParts.length === 0) explicitParts.push(normalized);
5657
+ const maxLinesPerPage = 32;
5658
+ const charsPerLine = 80;
5559
5659
  const finalPages = [];
5560
5660
  for (const part of explicitParts) {
5561
- const lines = part.split(/\r?\n/);
5661
+ const lines = part.split("\n");
5562
5662
  let currentLines = [];
5563
5663
  let count = 0;
5564
5664
  for (const line of lines) {
5565
- currentLines.push(line);
5566
- count++;
5567
- if (count >= maxLinesPerPage) {
5665
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
5666
+ if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
5568
5667
  finalPages.push(currentLines.join("\n"));
5569
5668
  currentLines = [];
5570
5669
  count = 0;
5571
5670
  }
5671
+ currentLines.push(line);
5672
+ count += vLines;
5572
5673
  }
5573
5674
  if (currentLines.length > 0) {
5574
5675
  finalPages.push(currentLines.join("\n"));
5575
5676
  }
5576
5677
  }
5577
- return finalPages.length > 0 ? finalPages : [text];
5678
+ return finalPages.length > 0 ? finalPages : [normalized];
5578
5679
  }
5579
5680
  /**
5580
5681
  * Format cleaned extracted text into attractive HTML paragraphs, headings, and lists
5581
5682
  */
5582
5683
  formatDocToHtml(text, filename) {
5583
- const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").split("\n");
5684
+ 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");
5584
5685
  let html = "";
5585
5686
  let inList = false;
5586
5687
  let tableLines = [];
5587
5688
  const flushTable = () => {
5588
5689
  if (tableLines.length > 0) {
5589
- html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12px;">';
5590
- for (const tLine of tableLines) {
5591
- html += "<tr>";
5592
- const cols = tLine.split(" ");
5690
+ html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px; font-family: Calibri, sans-serif;">';
5691
+ for (let rIdx = 0; rIdx < tableLines.length; rIdx++) {
5692
+ const tLine = tableLines[rIdx];
5693
+ const isHeader = rIdx === 0;
5694
+ html += `<tr style="${isHeader ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
5695
+ const cols = tLine.split(" ").filter((c) => c.trim().length > 0);
5593
5696
  for (const col of cols) {
5594
- html += `<td style="border: 1px solid #cbd5e1; padding: 6px 8px;">${DOMPurify6.sanitize(col.trim())}</td>`;
5697
+ html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px;">${DOMPurify6.sanitize(col.trim())}</td>`;
5595
5698
  }
5596
5699
  html += "</tr>";
5597
5700
  }
@@ -5604,27 +5707,18 @@ var DocPlugin = class {
5604
5707
  let line = lines[i];
5605
5708
  let tabCount = (line.match(/\t/g) || []).length;
5606
5709
  if (tabCount > 0) {
5607
- let consecutiveTableLines = 1;
5608
- let j = i + 1;
5609
- while (j < lines.length) {
5610
- const nextTabCount = (lines[j].match(/\t/g) || []).length;
5611
- if (nextTabCount === tabCount) {
5612
- consecutiveTableLines++;
5613
- j++;
5614
- } else {
5615
- break;
5616
- }
5710
+ let j = i;
5711
+ while (j < lines.length && (lines[j].match(/\t/g) || []).length > 0) {
5712
+ j++;
5617
5713
  }
5618
- if (consecutiveTableLines >= 3) {
5619
- if (inList) {
5620
- html += "</ul>";
5621
- inList = false;
5622
- }
5623
- tableLines = lines.slice(i, j);
5624
- flushTable();
5625
- i = j;
5626
- continue;
5714
+ if (inList) {
5715
+ html += "</ul>";
5716
+ inList = false;
5627
5717
  }
5718
+ tableLines = lines.slice(i, j);
5719
+ flushTable();
5720
+ i = j;
5721
+ continue;
5628
5722
  }
5629
5723
  line = line.trim();
5630
5724
  if (!line) {