Files
bentopdf/src/js/logic/delete-pages.ts
abdullahalam123 09436a689d feat(rotate,delete-pages): Add custom rotation angles and enhance page management UI
- Add TypeScript type definitions for merge and alternate-merge Web Workers
- Implement custom rotation angle input with increment/decrement controls for rotate tool
- Extend delete-pages tool to render page thumbnails for better UX
- Hide number input spin buttons across all number inputs via CSS
- Refactor rotateAll function to accept angle parameter instead of direction multiplier
- Update fileHandler to support delete-pages tool thumbnail rendering
- Improve type safety in alternate-merge logic with proper interface definitions
- Enhance rotate tool UI with custom angle input field and adjustment buttons
2025-12-01 14:54:46 +05:30

112 lines
3.6 KiB
TypeScript

import { showLoader, hideLoader, showAlert } from '../ui.js';
import { downloadFile } from '../utils/helpers.js';
import { state } from '../state.js';
import { PDFDocument as PDFLibDocument } from 'pdf-lib';
export async function deletePages() {
// @ts-expect-error TS(2339) FIXME: Property 'value' does not exist on type 'HTMLEleme... Remove this comment to see the full error message
const pageInput = document.getElementById('pages-to-delete').value;
if (!pageInput) {
showAlert('Invalid Input', 'Please enter page numbers to delete.');
return;
}
showLoader('Deleting pages...');
try {
const totalPages = state.pdfDoc.getPageCount();
const indicesToDelete = new Set();
const ranges = pageInput.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++) indicesToDelete.add(i - 1);
} else {
const pageNum = Number(trimmedRange);
if (isNaN(pageNum) || pageNum < 1 || pageNum > totalPages) continue;
indicesToDelete.add(pageNum - 1);
}
}
if (indicesToDelete.size === 0) {
showAlert('Invalid Input', 'No valid pages selected for deletion.');
hideLoader();
return;
}
if (indicesToDelete.size >= totalPages) {
showAlert('Invalid Input', 'You cannot delete all pages.');
hideLoader();
return;
}
const indicesToKeep = Array.from(
{ length: totalPages },
(_, i) => i
).filter((index) => !indicesToDelete.has(index));
const newPdf = await PDFLibDocument.create();
const copiedPages = await newPdf.copyPages(state.pdfDoc, indicesToKeep);
copiedPages.forEach((page: any) => newPdf.addPage(page));
const newPdfBytes = await newPdf.save();
downloadFile(
new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }),
'deleted-pages.pdf'
);
} catch (e) {
console.error(e);
showAlert('Error', 'Could not delete pages.');
} finally {
hideLoader();
}
}
export function setupDeletePagesTool() {
const input = document.getElementById('pages-to-delete') as HTMLInputElement;
if (!input) return;
const updateHighlights = () => {
const val = input.value;
const pagesToDelete = new Set<number>();
const parts = val.split(',');
for (const part of parts) {
const trimmed = part.trim();
if (trimmed.includes('-')) {
const [start, end] = trimmed.split('-').map(Number);
if (!isNaN(start) && !isNaN(end) && start <= end) {
for (let i = start; i <= end; i++) pagesToDelete.add(i);
}
} else {
const num = Number(trimmed);
if (!isNaN(num)) pagesToDelete.add(num);
}
}
const thumbnails = document.querySelectorAll('#delete-pages-preview .page-thumbnail');
thumbnails.forEach((thumb) => {
const pageNum = parseInt((thumb as HTMLElement).dataset.pageNumber || '0');
const innerContainer = thumb.querySelector('div.relative');
if (pagesToDelete.has(pageNum)) {
innerContainer?.classList.add('border-red-500');
innerContainer?.classList.remove('border-gray-600');
} else {
innerContainer?.classList.remove('border-red-500');
innerContainer?.classList.add('border-gray-600');
}
});
};
input.addEventListener('input', updateHighlights);
updateHighlights();
}