2025-10-12 11:55:45 +05:30
|
|
|
import { showLoader, hideLoader, showAlert } from '../ui.js';
|
|
|
|
|
import { downloadFile } from '../utils/helpers.js';
|
|
|
|
|
import { state } from '../state.js';
|
|
|
|
|
|
|
|
|
|
const signState = {
|
2025-11-14 10:12:53 +05:30
|
|
|
viewerIframe: null,
|
|
|
|
|
viewerReady: false,
|
2025-10-12 11:55:45 +05:30
|
|
|
};
|
|
|
|
|
|
2025-10-17 11:37:32 +05:30
|
|
|
|
2025-11-14 10:12:53 +05:30
|
|
|
export async function setupSignTool() {
|
|
|
|
|
document.getElementById('signature-editor').classList.remove('hidden');
|
2025-10-12 11:55:45 +05:30
|
|
|
|
2025-11-14 10:12:53 +05:30
|
|
|
showLoader('Loading PDF viewer...');
|
|
|
|
|
|
2025-11-14 13:05:22 +05:30
|
|
|
const container = document.getElementById('canvas-container-sign');
|
|
|
|
|
if (container) {
|
|
|
|
|
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;
|
2025-11-14 10:12:53 +05:30
|
|
|
|
2025-11-14 13:05:22 +05:30
|
|
|
const pdfBytes = await state.pdfDoc.save();
|
|
|
|
|
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
|
|
|
|
|
const blobUrl = URL.createObjectURL(blob);
|
2025-11-14 10:12:53 +05:30
|
|
|
|
2025-11-14 13:05:22 +05:30
|
|
|
// PDF.js expects the file URL in the query string, while
|
|
|
|
|
// the annotation extension reads its options from the URL hash.
|
|
|
|
|
const viewerBase = '/pdfjs-annotation-viewer/web/viewer.html';
|
|
|
|
|
const query = new URLSearchParams({ file: blobUrl });
|
|
|
|
|
const hash = new URLSearchParams({
|
|
|
|
|
// Annotation extension params (must be in the hash, not the query)
|
|
|
|
|
ae_username: 'Bento User',
|
|
|
|
|
ae_default_editor_active: 'true',
|
|
|
|
|
ae_default_sidebar_open: 'true',
|
|
|
|
|
// We intentionally do NOT set ae_post_url because Bento uses
|
|
|
|
|
// client-side export only (no backend save endpoint).
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
iframe.src = `${viewerBase}?${query.toString()}#${hash.toString()}`;
|
2025-11-14 10:12:53 +05:30
|
|
|
|
|
|
|
|
iframe.onload = () => {
|
|
|
|
|
hideLoader();
|
|
|
|
|
signState.viewerReady = true;
|
|
|
|
|
|
|
|
|
|
try {
|
2025-11-14 13:05:22 +05:30
|
|
|
const viewerWindow: any = iframe.contentWindow;
|
2025-11-14 10:12:53 +05:30
|
|
|
if (viewerWindow) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
const sigButton = viewerWindow.document.getElementById('editorSignature');
|
|
|
|
|
if (sigButton) {
|
|
|
|
|
sigButton.removeAttribute('hidden');
|
|
|
|
|
const sigButtonElement = viewerWindow.document.getElementById('editorSignatureButton');
|
|
|
|
|
if (sigButtonElement) {
|
|
|
|
|
sigButtonElement.removeAttribute('disabled');
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-14 13:05:22 +05:30
|
|
|
|
|
|
|
|
// Make the annotation extension's "Save" button behave like
|
|
|
|
|
// "Export PDF" (purely client-side) instead of POSTing to
|
|
|
|
|
// ae_post_url, which we don't use in Bento.
|
|
|
|
|
const ext = viewerWindow.pdfjsAnnotationExtensionInstance;
|
|
|
|
|
if (ext && typeof ext.exportPdf === 'function') {
|
|
|
|
|
ext.saveData = async () => {
|
|
|
|
|
try {
|
|
|
|
|
await ext.exportPdf();
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error('Failed to export annotated PDF via Save button:', err);
|
|
|
|
|
viewerWindow.alert?.('Failed to export the signed PDF. Please try again.');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
2025-11-14 10:12:53 +05:30
|
|
|
}, 500);
|
2025-10-17 11:37:32 +05:30
|
|
|
}
|
2025-11-14 10:12:53 +05:30
|
|
|
} catch (e) {
|
|
|
|
|
console.error('Could not enable signature button:', e);
|
2025-10-17 11:37:32 +05:30
|
|
|
}
|
2025-10-12 11:55:45 +05:30
|
|
|
};
|
2025-11-14 10:12:53 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const saveBtn = document.getElementById('process-btn');
|
|
|
|
|
if (saveBtn) {
|
|
|
|
|
saveBtn.style.display = 'none';
|
|
|
|
|
}
|
2025-10-12 11:55:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function applyAndSaveSignatures() {
|
2025-11-14 10:12:53 +05:30
|
|
|
if (!signState.viewerReady || !signState.viewerIframe) {
|
|
|
|
|
showAlert('Viewer not ready', 'Please wait for the PDF viewer to load.');
|
2025-11-14 13:05:22 +05:30
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const viewerWindow: any = signState.viewerIframe.contentWindow;
|
|
|
|
|
if (!viewerWindow || !viewerWindow.pdfjsAnnotationExtensionInstance) {
|
|
|
|
|
showAlert('Annotations not ready', 'Please wait for the annotation tools to finish loading.');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Trigger the extension's Export PDF flow so annotations are baked into the downloaded file.
|
|
|
|
|
await viewerWindow.pdfjsAnnotationExtensionInstance.exportPdf();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to export annotated PDF:', error);
|
|
|
|
|
showAlert('Export failed', 'Could not export the PDF with annotations. Please try again.');
|
2025-10-17 11:37:32 +05:30
|
|
|
}
|
2025-10-12 11:55:45 +05:30
|
|
|
}
|