mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-05 20:02:47 +01:00
- 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.
91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
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);
|
|
}
|
|
}
|