Files
bentopdf/src/js/logic/sign-pdf.ts
abdullahalam123 ae8bd3a004 feat(signature): add font and color customization for typed signatures
feat(stamps): implement new add stamps tool with image stamp support

fix(form-filler): improve form filler UI and XFA form support

refactor(sign-pdf): improve signature tool initialization and error handling

style(ui): update text color for better visibility in dark mode

chore: update navigation links to use root-relative paths
2025-11-14 20:35:43 +05:30

119 lines
4.0 KiB
TypeScript

import { showLoader, hideLoader, showAlert } from '../ui.js';
import { readFileAsArrayBuffer } from '../utils/helpers.js';
import { state } from '../state.js';
const signState = {
viewerIframe: null,
viewerReady: false,
};
export async function setupSignTool() {
document.getElementById('signature-editor').classList.remove('hidden');
showLoader('Loading PDF viewer...');
const container = document.getElementById('canvas-container-sign');
if (!container) {
console.error('Sign tool canvas container not found');
hideLoader();
return;
}
if (!state.files || !state.files[0]) {
console.error('No file loaded into state for signing');
hideLoader();
return;
}
container.textContent = '';
const iframe = document.createElement('iframe');
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.style.border = 'none';
container.appendChild(iframe);
signState.viewerIframe = iframe;
// Use original uploaded bytes to avoid re-writing the PDF structure
const file = state.files[0];
const pdfBytes = await readFileAsArrayBuffer(file);
const blob = new Blob([pdfBytes as BlobPart], { type: 'application/pdf' });
const blobUrl = URL.createObjectURL(blob);
const viewerBase = '/pdfjs-viewer/viewer.html';
const query = new URLSearchParams({ file: blobUrl });
iframe.src = `${viewerBase}?${query.toString()}`;
iframe.onload = () => {
hideLoader();
signState.viewerReady = true;
try {
const viewerWindow: any = iframe.contentWindow;
if (viewerWindow && viewerWindow.PDFViewerApplication) {
const app = viewerWindow.PDFViewerApplication;
const doc = viewerWindow.document;
const editorModeButtons = doc.getElementById('editorModeButtons');
editorModeButtons?.classList.remove('hidden');
const editorSignature = doc.getElementById('editorSignature');
editorSignature?.removeAttribute('hidden');
const editorSignatureButton = doc.getElementById('editorSignatureButton') as HTMLButtonElement | null;
if (editorSignatureButton) {
editorSignatureButton.disabled = false;
}
const editorStamp = doc.getElementById('editorStamp');
editorStamp?.removeAttribute('hidden');
const editorStampButton = doc.getElementById('editorStampButton') as HTMLButtonElement | null;
if (editorStampButton) {
editorStampButton.disabled = false;
}
// Ensure annotation editor is fully enabled; start in Signature mode
const pdfViewer = app.pdfViewer;
const AnnotationEditorType = viewerWindow.pdfjsLib?.AnnotationEditorType;
if (pdfViewer && AnnotationEditorType) {
pdfViewer.annotationEditorMode = {
mode: AnnotationEditorType.SIGNATURE,
};
}
}
} catch (e) {
console.error('Could not initialize base PDF.js viewer for signing:', e);
}
// Now that the viewer is ready, expose the Save Signed PDF button in the Bento UI
const saveBtn = document.getElementById('process-btn') as HTMLButtonElement | null;
if (saveBtn) {
saveBtn.style.display = '';
saveBtn.disabled = false;
saveBtn.onclick = () => {
void applyAndSaveSignatures();
};
}
};
}
export async function applyAndSaveSignatures() {
if (!signState.viewerReady || !signState.viewerIframe) {
showAlert('Viewer not ready', 'Please wait for the PDF viewer to load.');
return;
}
try {
const viewerWindow: any = signState.viewerIframe.contentWindow;
if (!viewerWindow || !viewerWindow.PDFViewerApplication) {
showAlert('Viewer not ready', 'The PDF viewer is still initializing.');
return;
}
// Delegate to the built-in download behavior of the base viewer.
const app = viewerWindow.PDFViewerApplication;
app.eventBus?.dispatch('download', { source: app });
} catch (error) {
console.error('Failed to trigger download in base PDF.js viewer:', error);
showAlert('Export failed', 'Could not export the signed PDF. Please try again.');
}
}