mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-08 08:52:28 +01:00
feat: enhance PDF comparison with new change types and zoom functionality
- Added support for 'moved' and 'style-changed' change types in PDF comparison. - Implemented category filters for changes, allowing users to filter by text, images, headers, annotations, formatting, and background. - Introduced zoom functionality with buttons for zooming in, out, and resetting to default. - Updated UI to reflect new change types and categories, including visual indicators for moved and style-changed items. - Enhanced summary display to include counts for moved and style-changed changes. - Refactored rendering logic to accommodate zoom levels and improve performance. - Added tests for new change detection features and category assignments.
This commit is contained in:
1 parent
89d7cd8e3d
commit
5232102ac0
31 files changed
+2503
-183
No files matched your search
@@ -0,0 +1,90 @@
|
||||
import type {
|
||||
CompareTextItem,
|
||||
ComparePageSignature,
|
||||
ComparePagePair,
|
||||
CompareChangeSummary,
|
||||
CompareTextChange,
|
||||
} from './types.ts';
|
||||
import { diffTextRuns } from './engine/diff-text-runs.ts';
|
||||
import { pairPages } from './engine/pair-pages.ts';
|
||||
|
||||
let worker: Worker | null = null;
|
||||
let messageId = 0;
|
||||
const pending = new Map<
|
||||
number,
|
||||
{ resolve: (value: unknown) => void; reject: (reason: unknown) => void }
|
||||
>();
|
||||
|
||||
function getWorker(): Worker | null {
|
||||
if (worker) return worker;
|
||||
try {
|
||||
worker = new Worker(
|
||||
new URL('./engine/compare.worker.ts', import.meta.url),
|
||||
{ type: 'module' }
|
||||
);
|
||||
worker.onmessage = function (e) {
|
||||
const { id, type, ...rest } = e.data;
|
||||
const p = pending.get(id);
|
||||
if (!p) return;
|
||||
pending.delete(id);
|
||||
if (type === 'error') {
|
||||
p.reject(new Error((rest as { message: string }).message));
|
||||
} else {
|
||||
p.resolve(rest);
|
||||
}
|
||||
};
|
||||
worker.onerror = function () {
|
||||
worker?.terminate();
|
||||
worker = null;
|
||||
for (const [, p] of pending) {
|
||||
p.reject(new Error('Worker crashed'));
|
||||
}
|
||||
pending.clear();
|
||||
};
|
||||
return worker;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function postToWorker(msg: Record<string, unknown>): Promise<unknown> {
|
||||
const w = getWorker();
|
||||
if (!w) return Promise.reject(new Error('No worker'));
|
||||
const id = ++messageId;
|
||||
return new Promise((resolve, reject) => {
|
||||
pending.set(id, { resolve, reject });
|
||||
w.postMessage({ ...msg, id });
|
||||
});
|
||||
}
|
||||
|
||||
export async function diffTextRunsAsync(
|
||||
beforeItems: CompareTextItem[],
|
||||
afterItems: CompareTextItem[]
|
||||
): Promise<{ changes: CompareTextChange[]; summary: CompareChangeSummary }> {
|
||||
try {
|
||||
const result = (await postToWorker({
|
||||
type: 'diff',
|
||||
beforeItems,
|
||||
afterItems,
|
||||
})) as { changes: CompareTextChange[]; summary: CompareChangeSummary };
|
||||
return result;
|
||||
} catch {
|
||||
return diffTextRuns(beforeItems, afterItems);
|
||||
}
|
||||
}
|
||||
|
||||
export async function pairPagesAsync(
|
||||
leftPages: ComparePageSignature[],
|
||||
rightPages: ComparePageSignature[]
|
||||
): Promise<ComparePagePair[]> {
|
||||
try {
|
||||
const result = (await postToWorker({
|
||||
type: 'pair',
|
||||
leftPages,
|
||||
rightPages,
|
||||
})) as { pairs: ComparePagePair[] };
|
||||
return result.pairs;
|
||||
} catch {
|
||||
return pairPages(leftPages, rightPages);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user