127 lines
4.4 KiB
TypeScript
127 lines
4.4 KiB
TypeScript
import { showLoader, hideLoader, showAlert } from '../ui.js';
|
|
import { downloadFile } from '../utils/helpers.js';
|
|
import { state } from '../state.js';
|
|
import { PDFName } from 'pdf-lib';
|
|
|
|
export function setupRemoveAnnotationsTool() {
|
|
if (state.pdfDoc) {
|
|
document.getElementById('total-pages').textContent =
|
|
state.pdfDoc.getPageCount();
|
|
}
|
|
|
|
const pageScopeRadios = document.querySelectorAll('input[name="page-scope"]');
|
|
const pageRangeWrapper = document.getElementById('page-range-wrapper');
|
|
pageScopeRadios.forEach((radio) => {
|
|
radio.addEventListener('change', () => {
|
|
// @ts-expect-error TS(2339) FIXME: Property 'value' does not exist on type 'Element'.
|
|
pageRangeWrapper.classList.toggle('hidden', radio.value !== 'specific');
|
|
});
|
|
});
|
|
|
|
const selectAllCheckbox = document.getElementById('select-all-annotations');
|
|
const allAnnotCheckboxes = document.querySelectorAll('.annot-checkbox');
|
|
selectAllCheckbox.addEventListener('change', () => {
|
|
allAnnotCheckboxes.forEach((checkbox) => {
|
|
// @ts-expect-error TS(2339) FIXME: Property 'checked' does not exist on type 'Element... Remove this comment to see the full error message
|
|
checkbox.checked = selectAllCheckbox.checked;
|
|
});
|
|
});
|
|
}
|
|
|
|
export async function removeAnnotations() {
|
|
showLoader('Removing annotations...');
|
|
try {
|
|
const totalPages = state.pdfDoc.getPageCount();
|
|
let targetPageIndices = [];
|
|
|
|
// @ts-expect-error TS(2339) FIXME: Property 'value' does not exist on type 'Element'.
|
|
const pageScope = document.querySelector(
|
|
'input[name="page-scope"]:checked'
|
|
).value;
|
|
if (pageScope === 'all') {
|
|
targetPageIndices = Array.from({ length: totalPages }, (_, i) => i);
|
|
} else {
|
|
// @ts-expect-error TS(2339) FIXME: Property 'value' does not exist on type 'HTMLEleme... Remove this comment to see the full error message
|
|
const rangeInput = document.getElementById('page-range-input').value;
|
|
if (!rangeInput.trim()) throw new Error('Please enter a page range.');
|
|
const ranges = rangeInput.split(',');
|
|
for (const range of ranges) {
|
|
const trimmedRange = range.trim();
|
|
if (trimmedRange.includes('-')) {
|
|
const [start, end] = trimmedRange.split('-').map(Number);
|
|
if (
|
|
isNaN(start) ||
|
|
isNaN(end) ||
|
|
start < 1 ||
|
|
end > totalPages ||
|
|
start > end
|
|
)
|
|
continue;
|
|
for (let i = start; i <= end; i++) targetPageIndices.push(i - 1);
|
|
} else {
|
|
const pageNum = Number(trimmedRange);
|
|
if (isNaN(pageNum) || pageNum < 1 || pageNum > totalPages) continue;
|
|
targetPageIndices.push(pageNum - 1);
|
|
}
|
|
}
|
|
targetPageIndices = [...new Set(targetPageIndices)];
|
|
}
|
|
|
|
if (targetPageIndices.length === 0)
|
|
throw new Error('No valid pages were selected.');
|
|
|
|
const typesToRemove = new Set(
|
|
// @ts-expect-error TS(2339) FIXME: Property 'value' does not exist on type 'Element'.
|
|
Array.from(document.querySelectorAll('.annot-checkbox:checked')).map(
|
|
(cb) => cb.value
|
|
)
|
|
);
|
|
|
|
if (typesToRemove.size === 0)
|
|
throw new Error('Please select at least one annotation type to remove.');
|
|
|
|
const pages = state.pdfDoc.getPages();
|
|
|
|
for (const pageIndex of targetPageIndices) {
|
|
const page = pages[pageIndex];
|
|
const annotRefs = page.node.Annots()?.asArray() || [];
|
|
|
|
const annotsToKeep = [];
|
|
|
|
for (const ref of annotRefs) {
|
|
const annot = state.pdfDoc.context.lookup(ref);
|
|
const subtype = annot
|
|
.get(PDFName.of('Subtype'))
|
|
?.toString()
|
|
.substring(1);
|
|
|
|
// If the subtype is NOT in the list to remove, add it to our new array
|
|
if (!subtype || !typesToRemove.has(subtype)) {
|
|
annotsToKeep.push(ref);
|
|
}
|
|
}
|
|
|
|
if (annotsToKeep.length > 0) {
|
|
const newAnnotsArray = state.pdfDoc.context.obj(annotsToKeep);
|
|
page.node.set(PDFName.of('Annots'), newAnnotsArray);
|
|
} else {
|
|
page.node.delete(PDFName.of('Annots'));
|
|
}
|
|
}
|
|
|
|
const newPdfBytes = await state.pdfDoc.save();
|
|
downloadFile(
|
|
new Blob([newPdfBytes], { type: 'application/pdf' }),
|
|
'annotations-removed.pdf'
|
|
);
|
|
} catch (e) {
|
|
console.error(e);
|
|
showAlert(
|
|
'Error',
|
|
e.message || 'Could not remove annotations. Please check your page range.'
|
|
);
|
|
} finally {
|
|
hideLoader();
|
|
}
|
|
}
|