2023-12-23 13:47:21 -05:00
|
|
|
<!DOCTYPE html>
|
2024-05-22 21:48:23 +01:00
|
|
|
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
|
2024-02-16 22:49:06 +01:00
|
|
|
<head>
|
|
|
|
<th:block th:insert="~{fragments/common :: head(title=#{removeAnnotations.title}, header=#{removeAnnotations.header})}"></th:block>
|
|
|
|
</head>
|
2023-12-23 13:47:21 -05:00
|
|
|
|
2024-02-16 22:49:06 +01:00
|
|
|
<body>
|
2023-12-23 13:47:21 -05:00
|
|
|
<div id="page-container">
|
2024-02-16 22:49:06 +01:00
|
|
|
<div id="content-wrap">
|
|
|
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
2024-03-21 21:58:01 +01:00
|
|
|
<br><br>
|
2024-02-16 22:49:06 +01:00
|
|
|
<div class="container">
|
|
|
|
<div class="row justify-content-center">
|
2024-05-19 12:44:54 +02:00
|
|
|
<div class="col-md-6 bg-card">
|
2024-05-05 15:19:53 +04:00
|
|
|
<div class="tool-header">
|
|
|
|
<span class="material-symbols-rounded tool-header-icon other">thread_unread</span>
|
|
|
|
<span class="tool-header-text" th:text="#{removeAnnotations.header}"></span>
|
|
|
|
</div>
|
2024-02-16 22:49:06 +01:00
|
|
|
<form id="pdfForm" class="mb-3">
|
|
|
|
<div class="custom-file">
|
|
|
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf', remoteCall='false')}"></div>
|
2023-12-23 13:47:21 -05:00
|
|
|
</div>
|
2024-02-16 22:49:06 +01:00
|
|
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removeAnnotations.submit}"></button>
|
|
|
|
</form>
|
2023-12-23 13:47:21 -05:00
|
|
|
</div>
|
2024-02-16 22:49:06 +01:00
|
|
|
</div>
|
2023-12-23 13:47:21 -05:00
|
|
|
</div>
|
2024-02-16 22:49:06 +01:00
|
|
|
</div>
|
|
|
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
2023-12-23 13:47:21 -05:00
|
|
|
</div>
|
|
|
|
<script src="js/local-pdf-input-download.js"></script>
|
|
|
|
<script>
|
2024-02-16 22:49:06 +01:00
|
|
|
document.getElementById('pdfForm').addEventListener('submit', async (e) => {
|
2023-12-23 13:47:21 -05:00
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
const { PDFDocument } = PDFLib;
|
|
|
|
|
|
|
|
const processFile = async (file) => {
|
2024-02-16 22:49:06 +01:00
|
|
|
const origFileUrl = URL.createObjectURL(file);
|
|
|
|
const formPdfBytes = await fetch(origFileUrl).then(res => res.arrayBuffer());
|
|
|
|
const pdfDoc = await PDFDocument.load(formPdfBytes, { ignoreEncryption: true });
|
2023-12-23 13:47:21 -05:00
|
|
|
|
2024-02-16 22:49:06 +01:00
|
|
|
const pages = pdfDoc.getPages();
|
2023-12-23 13:47:21 -05:00
|
|
|
|
2024-02-16 22:49:06 +01:00
|
|
|
for (let i = 0; i < pages.length; ++i) {
|
|
|
|
const page = pages[i];
|
|
|
|
const annotations = page.node.Annots();
|
|
|
|
if (!annotations) continue;
|
|
|
|
const ctx = annotations.context;
|
2023-12-23 13:47:21 -05:00
|
|
|
|
2024-02-16 22:49:06 +01:00
|
|
|
for (let j = 0; j < annotations.size(); ++j) {
|
|
|
|
const annotation = annotations.get(j);
|
|
|
|
ctx.delete(annotation);
|
2023-12-23 13:47:21 -05:00
|
|
|
}
|
2024-02-16 22:49:06 +01:00
|
|
|
}
|
2023-12-23 13:47:21 -05:00
|
|
|
|
2024-02-16 22:49:06 +01:00
|
|
|
const pdfBytes = await pdfDoc.save();
|
|
|
|
const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' });
|
|
|
|
const fileName = (file.name ? file.name.replace('.pdf', '') : 'pdf') + '_removed_annotations.pdf';
|
2023-12-23 13:47:21 -05:00
|
|
|
|
2024-02-16 22:49:06 +01:00
|
|
|
return { processedData: pdfBlob, fileName };
|
2023-12-23 13:47:21 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
await downloadFilesWithCallback(processFile);
|
2024-02-16 22:49:06 +01:00
|
|
|
});
|
2023-12-23 13:47:21 -05:00
|
|
|
</script>
|
2024-02-16 22:49:06 +01:00
|
|
|
</body>
|
|
|
|
</html>
|