mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-11 09:23:36 +01:00
refactor: update PDF comparison types and enhance UI for better usability
- Refactored CompareState to import from a centralized type definition. - Enhanced the compare-pdfs.html layout with improved styles for overlay and side-by-side modes. - Added new CSS styles for various UI components including panels, buttons, and highlights. - Implemented a new sidebar for displaying change summaries and filters. - Created unit tests for text comparison logic, including diffing text runs and page pairing. - Added tests for text normalization functions to ensure proper handling of punctuation and character normalization.
This commit is contained in:
1 parent
86cbaf6cd3
commit
1d68691331
20 files changed
+3447
-332
No files matched your search
@@ -0,0 +1,77 @@
|
||||
import type { ComparePagePair, ComparePageResult } from '../types.ts';
|
||||
|
||||
function escapeHtml(text: string) {
|
||||
return text
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
export function buildCompareReport(
|
||||
fileName1: string,
|
||||
fileName2: string,
|
||||
pairs: ComparePagePair[],
|
||||
results: ComparePageResult[]
|
||||
) {
|
||||
const totals = results.reduce(
|
||||
(summary, result) => {
|
||||
summary.added += result.summary.added;
|
||||
summary.removed += result.summary.removed;
|
||||
summary.modified += result.summary.modified;
|
||||
return summary;
|
||||
},
|
||||
{ added: 0, removed: 0, modified: 0 }
|
||||
);
|
||||
|
||||
const rows = results
|
||||
.map((result, index) => {
|
||||
const pair = pairs[index];
|
||||
const changes = result.changes
|
||||
.map(
|
||||
(change) =>
|
||||
`<li><strong>${escapeHtml(change.type)}</strong>: ${escapeHtml(change.description)}</li>`
|
||||
)
|
||||
.join('');
|
||||
|
||||
return `
|
||||
<section class="pair-card">
|
||||
<h2>Comparison ${pair?.pairIndex || index + 1}</h2>
|
||||
<p class="meta">PDF 1 page: ${pair?.leftPageNumber ?? 'none'} | PDF 2 page: ${pair?.rightPageNumber ?? 'none'} | Confidence: ${((pair?.confidence || 0) * 100).toFixed(0)}%</p>
|
||||
<p class="meta">Status: ${escapeHtml(result.status)}${result.usedOcr ? ' | OCR used' : ''}</p>
|
||||
<p class="meta">Added: ${result.summary.added} | Removed: ${result.summary.removed} | Modified: ${result.summary.modified}</p>
|
||||
<ul>${changes || '<li>No semantic changes detected.</li>'}</ul>
|
||||
</section>
|
||||
`;
|
||||
})
|
||||
.join('');
|
||||
|
||||
return `<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Compare report</title>
|
||||
<style>
|
||||
body { font-family: ui-sans-serif, system-ui, sans-serif; margin: 0; padding: 2rem; background: #111827; color: #e5e7eb; }
|
||||
.summary { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; margin: 1.5rem 0; }
|
||||
.card, .pair-card { background: #1f2937; border: 1px solid #374151; border-radius: 12px; padding: 1rem 1.25rem; }
|
||||
.pair-card { margin-bottom: 1rem; }
|
||||
.meta { color: #9ca3af; font-size: 0.95rem; }
|
||||
h1, h2 { margin: 0 0 0.75rem 0; }
|
||||
ul { margin: 0.75rem 0 0 1.25rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>PDF Compare Report</h1>
|
||||
<p class="meta">PDF 1: ${escapeHtml(fileName1)} | PDF 2: ${escapeHtml(fileName2)}</p>
|
||||
<div class="summary">
|
||||
<div class="card"><div class="meta">Added</div><div>${totals.added}</div></div>
|
||||
<div class="card"><div class="meta">Removed</div><div>${totals.removed}</div></div>
|
||||
<div class="card"><div class="meta">Modified</div><div>${totals.modified}</div></div>
|
||||
</div>
|
||||
${rows}
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { buildCompareReport } from './build-report.ts';
|
||||
import type { ComparePagePair, ComparePageResult } from '../types.ts';
|
||||
|
||||
export function exportCompareHtmlReport(
|
||||
fileName1: string,
|
||||
fileName2: string,
|
||||
pairs: ComparePagePair[],
|
||||
results: ComparePageResult[]
|
||||
) {
|
||||
const html = buildCompareReport(fileName1, fileName2, pairs, results);
|
||||
const blob = new Blob([html], { type: 'text/html;charset=utf-8' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchor = document.createElement('a');
|
||||
anchor.href = url;
|
||||
anchor.download = 'bentopdf-compare-report.html';
|
||||
anchor.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
Reference in new issue
Block a user