mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-04-19 19:21:18 +00:00
Tweak additional files to integrate decryption and clean up js
This commit is contained in:
parent
ef8231de3a
commit
64dfa4b841
@ -2,7 +2,6 @@ import FileIconFactory from './file-icon-factory.js';
|
||||
import FileUtils from './file-utils.js';
|
||||
import UUID from './uuid.js';
|
||||
import {DecryptFile} from './DecryptFiles.js';
|
||||
const decryptFile = new DecryptFile();
|
||||
let isScriptExecuted = false;
|
||||
if (!isScriptExecuted) {
|
||||
isScriptExecuted = true;
|
||||
@ -123,6 +122,7 @@ function setupFileInput(chooser) {
|
||||
return decryptedFile;
|
||||
} catch (error) {
|
||||
console.error(`Error decrypting file: ${file.name}`, error);
|
||||
if (!file.uniqueId) file.uniqueId = UUID.uuidv4();
|
||||
return file;
|
||||
}
|
||||
})
|
||||
|
47
src/main/resources/static/js/pages/add-image.js
Normal file
47
src/main/resources/static/js/pages/add-image.js
Normal file
@ -0,0 +1,47 @@
|
||||
document.getElementById('download-pdf').addEventListener('click', async () => {
|
||||
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();
|
||||
const modifiedPdfBytes = await modifiedPdf.save();
|
||||
const blob = new Blob([modifiedPdfBytes], {type: 'application/pdf'});
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = originalFileName + '_addedImage.pdf';
|
||||
link.click();
|
||||
});
|
||||
let originalFileName = '';
|
||||
document.querySelector('input[name=pdf-upload]').addEventListener('change', async (event) => {
|
||||
const fileInput = event.target;
|
||||
fileInput.addEventListener('file-input-change', async (e) => {
|
||||
const {allFiles} = e.detail;
|
||||
if (allFiles && allFiles.length > 0) {
|
||||
const file = allFiles[0];
|
||||
originalFileName = file.name.replace(/\.[^/.]+$/, '');
|
||||
const pdfData = await file.arrayBuffer();
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||
const pdfDoc = await pdfjsLib.getDocument({data: pdfData}).promise;
|
||||
await DraggableUtils.renderPage(pdfDoc, 0);
|
||||
|
||||
document.querySelectorAll('.show-on-file-selected').forEach((el) => {
|
||||
el.style.cssText = '';
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.querySelectorAll('.show-on-file-selected').forEach((el) => {
|
||||
el.style.cssText = 'display:none !important';
|
||||
});
|
||||
});
|
||||
|
||||
const imageUpload = document.querySelector('input[name=image-upload]');
|
||||
imageUpload.addEventListener('change', (e) => {
|
||||
if (!e.target.files) {
|
||||
return;
|
||||
}
|
||||
for (const imageFile of e.target.files) {
|
||||
var reader = new FileReader();
|
||||
reader.readAsDataURL(imageFile);
|
||||
reader.onloadend = function (e) {
|
||||
DraggableUtils.createDraggableCanvasFromUrl(e.target.result);
|
||||
};
|
||||
}
|
||||
});
|
150
src/main/resources/static/js/pages/change-metadata.js
Normal file
150
src/main/resources/static/js/pages/change-metadata.js
Normal file
@ -0,0 +1,150 @@
|
||||
const deleteAllCheckbox = document.querySelector('#deleteAll');
|
||||
let inputs = document.querySelectorAll('input');
|
||||
const customMetadataDiv = document.getElementById('customMetadata');
|
||||
const otherMetadataEntriesDiv = document.getElementById('otherMetadataEntries');
|
||||
|
||||
deleteAllCheckbox.addEventListener('change', function (event) {
|
||||
inputs.forEach((input) => {
|
||||
// If it's the deleteAllCheckbox or any file input, skip
|
||||
if (input === deleteAllCheckbox || input.type === 'file') {
|
||||
return;
|
||||
}
|
||||
// Disable or enable based on the checkbox state
|
||||
input.disabled = deleteAllCheckbox.checked;
|
||||
});
|
||||
});
|
||||
|
||||
const customModeCheckbox = document.getElementById('customModeCheckbox');
|
||||
const addMetadataBtn = document.getElementById('addMetadataBtn');
|
||||
const customMetadataFormContainer = document.getElementById('customMetadataEntries');
|
||||
var count = 1;
|
||||
const fileInput = document.querySelector('#fileInput-input');
|
||||
const authorInput = document.querySelector('#author');
|
||||
const creationDateInput = document.querySelector('#creationDate');
|
||||
const creatorInput = document.querySelector('#creator');
|
||||
const keywordsInput = document.querySelector('#keywords');
|
||||
const modificationDateInput = document.querySelector('#modificationDate');
|
||||
const producerInput = document.querySelector('#producer');
|
||||
const subjectInput = document.querySelector('#subject');
|
||||
const titleInput = document.querySelector('#title');
|
||||
const trappedInput = document.querySelector('#trapped');
|
||||
var lastPDFFileMeta = null;
|
||||
var lastPDFFile = null;
|
||||
|
||||
fileInput.addEventListener('change', async function () {
|
||||
fileInput.addEventListener('file-input-change', async (e) => {
|
||||
const {allFiles} = e.detail;
|
||||
if (allFiles && allFiles.length > 0) {
|
||||
const file = allFiles[0];
|
||||
while (otherMetadataEntriesDiv.firstChild) {
|
||||
otherMetadataEntriesDiv.removeChild(otherMetadataEntriesDiv.firstChild);
|
||||
}
|
||||
while (customMetadataFormContainer.firstChild) {
|
||||
customMetadataFormContainer.removeChild(customMetadataFormContainer.firstChild);
|
||||
}
|
||||
var url = URL.createObjectURL(file);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||
const pdf = await pdfjsLib.getDocument(url).promise;
|
||||
const pdfMetadata = await pdf.getMetadata();
|
||||
lastPDFFile = pdfMetadata?.info;
|
||||
console.log(pdfMetadata);
|
||||
if (!pdfMetadata?.info?.Custom || pdfMetadata?.info?.Custom.size == 0) {
|
||||
customModeCheckbox.disabled = true;
|
||||
customModeCheckbox.checked = false;
|
||||
} else {
|
||||
customModeCheckbox.disabled = false;
|
||||
}
|
||||
authorInput.value = pdfMetadata?.info?.Author;
|
||||
creationDateInput.value = convertDateFormat(pdfMetadata?.info?.CreationDate);
|
||||
creatorInput.value = pdfMetadata?.info?.Creator;
|
||||
keywordsInput.value = pdfMetadata?.info?.Keywords;
|
||||
modificationDateInput.value = convertDateFormat(pdfMetadata?.info?.ModDate);
|
||||
producerInput.value = pdfMetadata?.info?.Producer;
|
||||
subjectInput.value = pdfMetadata?.info?.Subject;
|
||||
titleInput.value = pdfMetadata?.info?.Title;
|
||||
console.log(pdfMetadata?.info);
|
||||
const trappedValue = pdfMetadata?.info?.Trapped;
|
||||
// Get all options in the select element
|
||||
const options = trappedInput.options;
|
||||
// Loop through all options to find the one with a matching value
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i].value === trappedValue) {
|
||||
options[i].selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
addExtra();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
addMetadataBtn.addEventListener('click', () => {
|
||||
const keyInput = document.createElement('input');
|
||||
keyInput.type = 'text';
|
||||
keyInput.placeholder = 'Key';
|
||||
keyInput.className = 'form-control';
|
||||
keyInput.name = `allRequestParams[customKey${count}]`;
|
||||
|
||||
const valueInput = document.createElement('input');
|
||||
valueInput.type = 'text';
|
||||
valueInput.placeholder = 'Value';
|
||||
valueInput.className = 'form-control';
|
||||
valueInput.name = `allRequestParams[customValue${count}]`;
|
||||
count = count + 1;
|
||||
|
||||
const formGroup = document.createElement('div');
|
||||
formGroup.className = 'mb-3';
|
||||
formGroup.appendChild(keyInput);
|
||||
formGroup.appendChild(valueInput);
|
||||
|
||||
customMetadataFormContainer.appendChild(formGroup);
|
||||
});
|
||||
function convertDateFormat(dateTimeString) {
|
||||
if (!dateTimeString || dateTimeString.length < 17) {
|
||||
return dateTimeString;
|
||||
}
|
||||
|
||||
const year = dateTimeString.substring(2, 6);
|
||||
const month = dateTimeString.substring(6, 8);
|
||||
const day = dateTimeString.substring(8, 10);
|
||||
const hour = dateTimeString.substring(10, 12);
|
||||
const minute = dateTimeString.substring(12, 14);
|
||||
const second = dateTimeString.substring(14, 16);
|
||||
|
||||
return year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second;
|
||||
}
|
||||
|
||||
function addExtra() {
|
||||
const event = document.getElementById('customModeCheckbox');
|
||||
if (event.checked && lastPDFFile.Custom != null) {
|
||||
customMetadataDiv.style.display = 'block';
|
||||
for (const [key, value] of Object.entries(lastPDFFile.Custom)) {
|
||||
if (
|
||||
key === 'Author' ||
|
||||
key === 'CreationDate' ||
|
||||
key === 'Creator' ||
|
||||
key === 'Keywords' ||
|
||||
key === 'ModDate' ||
|
||||
key === 'Producer' ||
|
||||
key === 'Subject' ||
|
||||
key === 'Title' ||
|
||||
key === 'Trapped'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const entryDiv = document.createElement('div');
|
||||
entryDiv.className = 'mb-3';
|
||||
entryDiv.innerHTML = `<div class="mb-3"><label class="form-check-label" for="${key}">${key}:</label><input name="${key}" value="${value}" type="text" class="form-control" id="${key}"></div>`;
|
||||
otherMetadataEntriesDiv.appendChild(entryDiv);
|
||||
}
|
||||
} else {
|
||||
customMetadataDiv.style.display = 'none';
|
||||
while (otherMetadataEntriesDiv.firstChild) {
|
||||
otherMetadataEntriesDiv.removeChild(otherMetadataEntriesDiv.firstChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customModeCheckbox.addEventListener('change', (event) => {
|
||||
addExtra();
|
||||
});
|
159
src/main/resources/static/js/pages/crop.js
Normal file
159
src/main/resources/static/js/pages/crop.js
Normal file
@ -0,0 +1,159 @@
|
||||
let pdfCanvas = document.getElementById('cropPdfCanvas');
|
||||
let overlayCanvas = document.getElementById('overlayCanvas');
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
canvasesContainer.style.display = 'none';
|
||||
let containerRect = canvasesContainer.getBoundingClientRect();
|
||||
|
||||
let context = pdfCanvas.getContext('2d');
|
||||
let overlayContext = overlayCanvas.getContext('2d');
|
||||
|
||||
overlayCanvas.width = pdfCanvas.width;
|
||||
overlayCanvas.height = pdfCanvas.height;
|
||||
|
||||
let isDrawing = false; // New flag to check if drawing is ongoing
|
||||
|
||||
let cropForm = document.getElementById('cropForm');
|
||||
let fileInput = document.getElementById('fileInput-input');
|
||||
let xInput = document.getElementById('x');
|
||||
let yInput = document.getElementById('y');
|
||||
let widthInput = document.getElementById('width');
|
||||
let heightInput = document.getElementById('height');
|
||||
|
||||
let pdfDoc = null;
|
||||
let currentPage = 1;
|
||||
let totalPages = 0;
|
||||
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let rectWidth = 0;
|
||||
let rectHeight = 0;
|
||||
|
||||
let pageScale = 1; // The scale which the pdf page renders
|
||||
let timeId = null; // timeout id for resizing canvases event
|
||||
|
||||
function renderPageFromFile(file) {
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
let typedArray = new Uint8Array(reader.result);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||
pdfjsLib.getDocument(typedArray).promise.then(function (pdf) {
|
||||
pdfDoc = pdf;
|
||||
totalPages = pdf.numPages;
|
||||
renderPage(currentPage);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('resize', function () {
|
||||
clearTimeout(timeId);
|
||||
|
||||
timeId = setTimeout(function () {
|
||||
if (fileInput.files.length == 0) return;
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
let containerRect = canvasesContainer.getBoundingClientRect();
|
||||
|
||||
context.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
|
||||
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
|
||||
|
||||
pdfCanvas.width = containerRect.width;
|
||||
pdfCanvas.height = containerRect.height;
|
||||
|
||||
overlayCanvas.width = containerRect.width;
|
||||
overlayCanvas.height = containerRect.height;
|
||||
|
||||
let file = fileInput.files[0];
|
||||
renderPageFromFile(file);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
fileInput.addEventListener('change', function (e) {
|
||||
fileInput.addEventListener('file-input-change', async (e) => {
|
||||
const {allFiles} = e.detail;
|
||||
if (allFiles && allFiles.length > 0) {
|
||||
canvasesContainer.style.display = 'block'; // set for visual purposes
|
||||
let file = allFiles[0];
|
||||
renderPageFromFile(file);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
cropForm.addEventListener('submit', function (e) {
|
||||
if (xInput.value == '' && yInput.value == '' && widthInput.value == '' && heightInput.value == '') {
|
||||
// Ορίστε συντεταγμένες για ολόκληρη την επιφάνεια του PDF
|
||||
xInput.value = 0;
|
||||
yInput.value = 0;
|
||||
widthInput.value = containerRect.width;
|
||||
heightInput.value = containerRect.height;
|
||||
}
|
||||
});
|
||||
|
||||
overlayCanvas.addEventListener('mousedown', function (e) {
|
||||
// Clear previously drawn rectangle on the main canvas
|
||||
context.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
|
||||
renderPage(currentPage); // Re-render the PDF
|
||||
|
||||
// Clear the overlay canvas to ensure old drawings are removed
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
|
||||
|
||||
startX = e.offsetX;
|
||||
startY = e.offsetY;
|
||||
isDrawing = true;
|
||||
});
|
||||
|
||||
overlayCanvas.addEventListener('mousemove', function (e) {
|
||||
if (!isDrawing) return;
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); // Clear previous rectangle
|
||||
|
||||
rectWidth = e.offsetX - startX;
|
||||
rectHeight = e.offsetY - startY;
|
||||
overlayContext.strokeStyle = 'red';
|
||||
overlayContext.strokeRect(startX, startY, rectWidth, rectHeight);
|
||||
});
|
||||
|
||||
overlayCanvas.addEventListener('mouseup', function (e) {
|
||||
isDrawing = false;
|
||||
|
||||
rectWidth = e.offsetX - startX;
|
||||
rectHeight = e.offsetY - startY;
|
||||
|
||||
let flippedY = pdfCanvas.height - e.offsetY;
|
||||
|
||||
xInput.value = startX / pageScale;
|
||||
yInput.value = flippedY / pageScale;
|
||||
widthInput.value = rectWidth / pageScale;
|
||||
heightInput.value = rectHeight / pageScale;
|
||||
|
||||
// Draw the final rectangle on the main canvas
|
||||
context.strokeStyle = 'red';
|
||||
context.strokeRect(startX, startY, rectWidth, rectHeight);
|
||||
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); // Clear the overlay
|
||||
});
|
||||
|
||||
function renderPage(pageNumber) {
|
||||
pdfDoc.getPage(pageNumber).then(function (page) {
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
let containerRect = canvasesContainer.getBoundingClientRect();
|
||||
|
||||
pageScale = containerRect.width / page.getViewport({scale: 1}).width; // The new scale
|
||||
|
||||
let viewport = page.getViewport({scale: containerRect.width / page.getViewport({scale: 1}).width});
|
||||
|
||||
canvasesContainer.width = viewport.width;
|
||||
canvasesContainer.height = viewport.height;
|
||||
|
||||
pdfCanvas.width = viewport.width;
|
||||
pdfCanvas.height = viewport.height;
|
||||
|
||||
overlayCanvas.width = viewport.width; // Match overlay canvas size with PDF canvas
|
||||
overlayCanvas.height = viewport.height;
|
||||
|
||||
let renderContext = {canvasContext: context, viewport: viewport};
|
||||
page.render(renderContext);
|
||||
pdfCanvas.classList.add('shadow-canvas');
|
||||
});
|
||||
}
|
138
src/main/resources/static/js/pages/pdf-to-csv.js
Normal file
138
src/main/resources/static/js/pages/pdf-to-csv.js
Normal file
@ -0,0 +1,138 @@
|
||||
let pdfCanvas = document.getElementById('cropPdfCanvas');
|
||||
let overlayCanvas = document.getElementById('overlayCanvas');
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
canvasesContainer.style.display = 'none';
|
||||
// let paginationBtnContainer = ;
|
||||
|
||||
let context = pdfCanvas.getContext('2d');
|
||||
let overlayContext = overlayCanvas.getContext('2d');
|
||||
|
||||
let btn1Object = document.getElementById('previous-page-btn');
|
||||
let btn2Object = document.getElementById('next-page-btn');
|
||||
overlayCanvas.width = pdfCanvas.width;
|
||||
overlayCanvas.height = pdfCanvas.height;
|
||||
|
||||
let fileInput = document.getElementById('fileInput-input');
|
||||
|
||||
let file;
|
||||
|
||||
let pdfDoc = null;
|
||||
let pageId = document.getElementById('pageId');
|
||||
let currentPage = 1;
|
||||
let totalPages = 0;
|
||||
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let rectWidth = 0;
|
||||
let rectHeight = 0;
|
||||
|
||||
let timeId = null; // timeout id for resizing canvases event
|
||||
|
||||
btn1Object.addEventListener('click', function (e) {
|
||||
if (currentPage !== 1) {
|
||||
currentPage = currentPage - 1;
|
||||
pageId.value = currentPage;
|
||||
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
let typedArray = new Uint8Array(reader.result);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||
pdfjsLib.getDocument(typedArray).promise.then(function (pdf) {
|
||||
pdfDoc = pdf;
|
||||
totalPages = pdf.numPages;
|
||||
renderPage(currentPage);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
btn2Object.addEventListener('click', function (e) {
|
||||
if (currentPage !== totalPages) {
|
||||
currentPage = currentPage + 1;
|
||||
pageId.value = currentPage;
|
||||
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
let typedArray = new Uint8Array(reader.result);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||
pdfjsLib.getDocument(typedArray).promise.then(function (pdf) {
|
||||
pdfDoc = pdf;
|
||||
totalPages = pdf.numPages;
|
||||
renderPage(currentPage);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function renderPageFromFile(file) {
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
let typedArray = new Uint8Array(reader.result);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||
pdfjsLib.getDocument(typedArray).promise.then(function (pdf) {
|
||||
pdfDoc = pdf;
|
||||
totalPages = pdf.numPages;
|
||||
renderPage(currentPage);
|
||||
});
|
||||
pageId.value = currentPage;
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
document.getElementById('pagination-button-container').style.display = 'flex';
|
||||
document.getElementById('instruction-text').style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('resize', function () {
|
||||
clearTimeout(timeId);
|
||||
timeId = setTimeout(function () {
|
||||
if (fileInput.files.length == 0) return;
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
let containerRect = canvasesContainer.getBoundingClientRect();
|
||||
|
||||
context.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
|
||||
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
|
||||
|
||||
pdfCanvas.width = containerRect.width;
|
||||
pdfCanvas.height = containerRect.height;
|
||||
|
||||
overlayCanvas.width = containerRect.width;
|
||||
overlayCanvas.height = containerRect.height;
|
||||
|
||||
let file = fileInput.files[0];
|
||||
renderPageFromFile(file);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
fileInput.addEventListener('change', function (e) {
|
||||
fileInput.addEventListener('file-input-change', async (e) => {
|
||||
const {allFiles} = e.detail;
|
||||
if (allFiles && allFiles.length > 0) {
|
||||
canvasesContainer.style.display = 'block'; // set for visual purposes
|
||||
file = e.target.files[0];
|
||||
renderPageFromFile(file);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function renderPage(pageNumber) {
|
||||
pdfDoc.getPage(pageNumber).then(function (page) {
|
||||
let viewport = page.getViewport({scale: 1.0});
|
||||
pdfCanvas.width = viewport.width;
|
||||
pdfCanvas.height = viewport.height;
|
||||
|
||||
overlayCanvas.width = viewport.width; // Match overlay canvas size with PDF canvas
|
||||
overlayCanvas.height = viewport.height;
|
||||
|
||||
let renderContext = {canvasContext: context, viewport: viewport};
|
||||
page.render(renderContext);
|
||||
pdfCanvas.classList.add('shadow-canvas');
|
||||
});
|
||||
}
|
@ -52,8 +52,6 @@ function addSignatureFromPreview() {
|
||||
let originalFileName = '';
|
||||
document.querySelector('input[name=pdf-upload]').addEventListener('change', async (event) => {
|
||||
const fileInput = event.target;
|
||||
|
||||
// Wait for the second function to complete
|
||||
fileInput.addEventListener('file-input-change', async (e) => {
|
||||
const {allFiles} = e.detail;
|
||||
if (allFiles && allFiles.length > 0) {
|
||||
|
@ -34,140 +34,8 @@
|
||||
<canvas id="overlayCanvas" style="position: absolute; top: 0; left: 0; z-index: 2; width: 100%"></canvas>
|
||||
</div>
|
||||
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
||||
<script>
|
||||
let pdfCanvas = document.getElementById('cropPdfCanvas');
|
||||
let overlayCanvas = document.getElementById('overlayCanvas');
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
canvasesContainer.style.display = "none";
|
||||
// let paginationBtnContainer = ;
|
||||
|
||||
let context = pdfCanvas.getContext('2d');
|
||||
let overlayContext = overlayCanvas.getContext('2d');
|
||||
|
||||
let btn1Object = document.getElementById('previous-page-btn');
|
||||
let btn2Object = document.getElementById('next-page-btn');
|
||||
overlayCanvas.width = pdfCanvas.width;
|
||||
overlayCanvas.height = pdfCanvas.height;
|
||||
|
||||
let fileInput = document.getElementById('fileInput-input');
|
||||
|
||||
let file;
|
||||
|
||||
let pdfDoc = null;
|
||||
let pageId = document.getElementById('pageId');
|
||||
let currentPage = 1;
|
||||
let totalPages = 0;
|
||||
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let rectWidth = 0;
|
||||
let rectHeight = 0;
|
||||
|
||||
let timeId = null; // timeout id for resizing canvases event
|
||||
|
||||
btn1Object.addEventListener('click',function (e){
|
||||
if (currentPage !== 1) {
|
||||
currentPage = currentPage - 1;
|
||||
pageId.value = currentPage;
|
||||
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
let typedArray = new Uint8Array(reader.result);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs'
|
||||
pdfjsLib.getDocument(typedArray).promise.then(function (pdf) {
|
||||
pdfDoc = pdf;
|
||||
totalPages = pdf.numPages;
|
||||
renderPage(currentPage);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
btn2Object.addEventListener('click',function (e){
|
||||
if (currentPage !== totalPages){
|
||||
currentPage=currentPage+1;
|
||||
pageId.value = currentPage;
|
||||
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function(ev) {
|
||||
let typedArray = new Uint8Array(reader.result);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs'
|
||||
pdfjsLib.getDocument(typedArray).promise.then(function(pdf) {
|
||||
pdfDoc = pdf;
|
||||
totalPages = pdf.numPages;
|
||||
renderPage(currentPage);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function renderPageFromFile(file) {
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
let typedArray = new Uint8Array(reader.result);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||
pdfjsLib.getDocument(typedArray).promise.then(function (pdf) {
|
||||
pdfDoc = pdf;
|
||||
totalPages = pdf.numPages;
|
||||
renderPage(currentPage);
|
||||
});
|
||||
pageId.value = currentPage;
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
document.getElementById("pagination-button-container").style.display = "flex";
|
||||
document.getElementById("instruction-text").style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", function() {
|
||||
clearTimeout(timeId);
|
||||
timeId = setTimeout(function () {
|
||||
if (fileInput.files.length == 0) return;
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
let containerRect = canvasesContainer.getBoundingClientRect();
|
||||
|
||||
context.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
|
||||
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
|
||||
|
||||
pdfCanvas.width = containerRect.width;
|
||||
pdfCanvas.height = containerRect.height;
|
||||
|
||||
overlayCanvas.width = containerRect.width;
|
||||
overlayCanvas.height = containerRect.height;
|
||||
|
||||
let file = fileInput.files[0];
|
||||
renderPageFromFile(file);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
fileInput.addEventListener('change', function(e) {
|
||||
canvasesContainer.style.display = "block"; // set for visual purposes
|
||||
file = e.target.files[0];
|
||||
renderPageFromFile(file);
|
||||
});
|
||||
|
||||
function renderPage(pageNumber) {
|
||||
pdfDoc.getPage(pageNumber).then(function(page) {
|
||||
let viewport = page.getViewport({ scale: 1.0 });
|
||||
pdfCanvas.width = viewport.width;
|
||||
pdfCanvas.height = viewport.height;
|
||||
|
||||
overlayCanvas.width = viewport.width; // Match overlay canvas size with PDF canvas
|
||||
overlayCanvas.height = viewport.height;
|
||||
|
||||
let renderContext = { canvasContext: context, viewport: viewport };
|
||||
page.render(renderContext);
|
||||
pdfCanvas.classList.add("shadow-canvas");
|
||||
});
|
||||
}
|
||||
<script th:src="@{'/js/thirdParty/pdf-lib.min.js'}"></script>
|
||||
<script type="module" th:src="@{'/js/pages/pdf-to-csv.js'}">
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,163 +32,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
||||
<script>
|
||||
let pdfCanvas = document.getElementById('cropPdfCanvas');
|
||||
let overlayCanvas = document.getElementById('overlayCanvas');
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
canvasesContainer.style.display = "none";
|
||||
let containerRect = canvasesContainer.getBoundingClientRect();
|
||||
|
||||
let context = pdfCanvas.getContext('2d');
|
||||
let overlayContext = overlayCanvas.getContext('2d');
|
||||
|
||||
overlayCanvas.width = pdfCanvas.width;
|
||||
overlayCanvas.height = pdfCanvas.height;
|
||||
|
||||
let isDrawing = false; // New flag to check if drawing is ongoing
|
||||
|
||||
let cropForm = document.getElementById('cropForm');
|
||||
let fileInput = document.getElementById('fileInput-input');
|
||||
let xInput = document.getElementById('x');
|
||||
let yInput = document.getElementById('y');
|
||||
let widthInput = document.getElementById('width');
|
||||
let heightInput = document.getElementById('height');
|
||||
|
||||
let pdfDoc = null;
|
||||
let currentPage = 1;
|
||||
let totalPages = 0;
|
||||
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let rectWidth = 0;
|
||||
let rectHeight = 0;
|
||||
|
||||
|
||||
let pageScale = 1; // The scale which the pdf page renders
|
||||
let timeId = null; // timeout id for resizing canvases event
|
||||
|
||||
function renderPageFromFile(file) {
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function(ev) {
|
||||
let typedArray = new Uint8Array(reader.result);
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs'
|
||||
pdfjsLib.getDocument(typedArray).promise.then(function(pdf) {
|
||||
pdfDoc = pdf;
|
||||
totalPages = pdf.numPages;
|
||||
renderPage(currentPage);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", function() {
|
||||
clearTimeout(timeId);
|
||||
|
||||
timeId = setTimeout(function () {
|
||||
if (fileInput.files.length == 0) return;
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
let containerRect = canvasesContainer.getBoundingClientRect();
|
||||
|
||||
context.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
|
||||
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
|
||||
|
||||
pdfCanvas.width = containerRect.width;
|
||||
pdfCanvas.height = containerRect.height;
|
||||
|
||||
overlayCanvas.width = containerRect.width;
|
||||
overlayCanvas.height = containerRect.height;
|
||||
|
||||
let file = fileInput.files[0];
|
||||
renderPageFromFile(file);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
fileInput.addEventListener('change', function(e) {
|
||||
canvasesContainer.style.display = "block"; // set for visual purposes
|
||||
let file = e.target.files[0];
|
||||
renderPageFromFile(file);
|
||||
});
|
||||
|
||||
cropForm.addEventListener('submit', function(e) {
|
||||
if (xInput.value == "" && yInput.value == "" && widthInput.value == "" && heightInput.value == "") {
|
||||
// Ορίστε συντεταγμένες για ολόκληρη την επιφάνεια του PDF
|
||||
xInput.value = 0;
|
||||
yInput.value = 0;
|
||||
widthInput.value = containerRect.width;
|
||||
heightInput.value = containerRect.height;
|
||||
}
|
||||
});
|
||||
|
||||
overlayCanvas.addEventListener('mousedown', function(e) {
|
||||
// Clear previously drawn rectangle on the main canvas
|
||||
context.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
|
||||
renderPage(currentPage); // Re-render the PDF
|
||||
|
||||
// Clear the overlay canvas to ensure old drawings are removed
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
|
||||
|
||||
startX = e.offsetX;
|
||||
startY = e.offsetY;
|
||||
isDrawing = true;
|
||||
});
|
||||
|
||||
overlayCanvas.addEventListener('mousemove', function(e) {
|
||||
if (!isDrawing) return;
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); // Clear previous rectangle
|
||||
|
||||
rectWidth = e.offsetX - startX;
|
||||
rectHeight = e.offsetY - startY;
|
||||
overlayContext.strokeStyle = 'red';
|
||||
overlayContext.strokeRect(startX, startY, rectWidth, rectHeight);
|
||||
});
|
||||
|
||||
overlayCanvas.addEventListener('mouseup', function(e) {
|
||||
isDrawing = false;
|
||||
|
||||
rectWidth = e.offsetX - startX;
|
||||
rectHeight = e.offsetY - startY;
|
||||
|
||||
let flippedY = pdfCanvas.height - e.offsetY;
|
||||
|
||||
xInput.value = startX / pageScale;
|
||||
yInput.value = flippedY / pageScale;
|
||||
widthInput.value = rectWidth / pageScale;
|
||||
heightInput.value = rectHeight /pageScale;
|
||||
|
||||
// Draw the final rectangle on the main canvas
|
||||
context.strokeStyle = 'red';
|
||||
context.strokeRect(startX, startY, rectWidth, rectHeight);
|
||||
|
||||
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); // Clear the overlay
|
||||
});
|
||||
|
||||
function renderPage(pageNumber) {
|
||||
pdfDoc.getPage(pageNumber).then(function(page) {
|
||||
let canvasesContainer = document.getElementById('canvasesContainer');
|
||||
let containerRect = canvasesContainer.getBoundingClientRect();
|
||||
|
||||
pageScale = containerRect.width / page.getViewport({ scale: 1 }).width; // The new scale
|
||||
|
||||
let viewport = page.getViewport({ scale: containerRect.width / page.getViewport({ scale: 1 }).width });
|
||||
|
||||
canvasesContainer.width =viewport.width;
|
||||
canvasesContainer.height = viewport.height;
|
||||
|
||||
pdfCanvas.width = viewport.width;
|
||||
pdfCanvas.height = viewport.height;
|
||||
|
||||
overlayCanvas.width = viewport.width; // Match overlay canvas size with PDF canvas
|
||||
overlayCanvas.height = viewport.height;
|
||||
|
||||
let renderContext = { canvasContext: context, viewport: viewport };
|
||||
page.render(renderContext);
|
||||
pdfCanvas.classList.add("shadow-canvas");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<script type="module" th:src="@{'/js/pages/crop.js'}"></script>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
|
@ -22,46 +22,9 @@
|
||||
<!-- pdf selector -->
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='pdf-upload', disableMultipleFiles=true, multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
||||
<script>
|
||||
let originalFileName = '';
|
||||
document.querySelector('input[name=pdf-upload]').addEventListener('change', async (event) => {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
originalFileName = file.name.replace(/\.[^/.]+$/, "");
|
||||
const pdfData = await file.arrayBuffer();
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs'
|
||||
const pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
|
||||
await DraggableUtils.renderPage(pdfDoc, 0);
|
||||
|
||||
document.querySelectorAll(".show-on-file-selected").forEach(el => {
|
||||
el.style.cssText = '';
|
||||
});
|
||||
}
|
||||
});
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.querySelectorAll(".show-on-file-selected").forEach(el => {
|
||||
el.style.cssText = "display:none !important";
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="module" th:src="@{'/js/pages/add-image.js'}"></script>
|
||||
<div class="tab-group show-on-file-selected">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=true, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}"></div>
|
||||
<script>
|
||||
const imageUpload = document.querySelector('input[name=image-upload]');
|
||||
imageUpload.addEventListener('change', e => {
|
||||
if(!e.target.files) {
|
||||
return;
|
||||
}
|
||||
for (const imageFile of e.target.files) {
|
||||
var reader = new FileReader();
|
||||
reader.readAsDataURL(imageFile);
|
||||
reader.onloadend = function (e) {
|
||||
DraggableUtils.createDraggableCanvasFromUrl(e.target.result);
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<!-- draggables box -->
|
||||
@ -93,17 +56,6 @@
|
||||
<div class="margin-auto-parent">
|
||||
<button id="download-pdf" class="btn btn-primary mb-2 show-on-file-selected margin-center" th:text="#{downloadPdf}"></button>
|
||||
</div>
|
||||
<script>
|
||||
document.getElementById("download-pdf").addEventListener('click', async() => {
|
||||
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();
|
||||
const modifiedPdfBytes = await modifiedPdf.save();
|
||||
const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = originalFileName + '_addedImage.pdf';
|
||||
link.click();
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -85,140 +85,7 @@
|
||||
<br>
|
||||
<button class="btn btn-primary" type="submit" id="submitBtn" th:text="#{changeMetadata.submit}"></button>
|
||||
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
||||
<script>
|
||||
const deleteAllCheckbox = document.querySelector("#deleteAll");
|
||||
let inputs = document.querySelectorAll("input");
|
||||
const customMetadataDiv = document.getElementById('customMetadata');
|
||||
const otherMetadataEntriesDiv = document.getElementById('otherMetadataEntries');
|
||||
|
||||
deleteAllCheckbox.addEventListener("change", function(event) {
|
||||
inputs.forEach(input => {
|
||||
// If it's the deleteAllCheckbox or any file input, skip
|
||||
if (input === deleteAllCheckbox || input.type === "file") {
|
||||
return;
|
||||
}
|
||||
// Disable or enable based on the checkbox state
|
||||
input.disabled = deleteAllCheckbox.checked;
|
||||
});
|
||||
});
|
||||
|
||||
const customModeCheckbox = document.getElementById('customModeCheckbox');
|
||||
const addMetadataBtn = document.getElementById("addMetadataBtn");
|
||||
const customMetadataFormContainer = document.getElementById("customMetadataEntries");
|
||||
var count = 1;
|
||||
const fileInput = document.querySelector("#fileInput-input");
|
||||
const authorInput = document.querySelector("#author");
|
||||
const creationDateInput = document.querySelector("#creationDate");
|
||||
const creatorInput = document.querySelector("#creator");
|
||||
const keywordsInput = document.querySelector("#keywords");
|
||||
const modificationDateInput = document.querySelector("#modificationDate");
|
||||
const producerInput = document.querySelector("#producer");
|
||||
const subjectInput = document.querySelector("#subject");
|
||||
const titleInput = document.querySelector("#title");
|
||||
const trappedInput = document.querySelector("#trapped");
|
||||
var lastPDFFileMeta = null;
|
||||
fileInput.addEventListener("change", async function() {
|
||||
while (otherMetadataEntriesDiv.firstChild) {
|
||||
otherMetadataEntriesDiv.removeChild(otherMetadataEntriesDiv.firstChild);
|
||||
}
|
||||
while (customMetadataFormContainer.firstChild) {
|
||||
customMetadataFormContainer.removeChild(customMetadataFormContainer.firstChild);
|
||||
}
|
||||
const file = this.files[0];
|
||||
var url = URL.createObjectURL(file)
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs'
|
||||
const pdf = await pdfjsLib.getDocument(url).promise;
|
||||
const pdfMetadata = await pdf.getMetadata();
|
||||
lastPDFFile = pdfMetadata?.info
|
||||
console.log(pdfMetadata);
|
||||
if(!pdfMetadata?.info?.Custom || pdfMetadata?.info?.Custom.size == 0) {
|
||||
customModeCheckbox.disabled = true;
|
||||
customModeCheckbox.checked = false;
|
||||
} else {
|
||||
customModeCheckbox.disabled = false;
|
||||
}
|
||||
authorInput.value = pdfMetadata?.info?.Author;
|
||||
creationDateInput.value = convertDateFormat(pdfMetadata?.info?.CreationDate);
|
||||
creatorInput.value = pdfMetadata?.info?.Creator;
|
||||
keywordsInput.value = pdfMetadata?.info?.Keywords;
|
||||
modificationDateInput.value = convertDateFormat(pdfMetadata?.info?.ModDate);
|
||||
producerInput.value = pdfMetadata?.info?.Producer;
|
||||
subjectInput.value = pdfMetadata?.info?.Subject;
|
||||
titleInput.value = pdfMetadata?.info?.Title;
|
||||
console.log(pdfMetadata?.info);
|
||||
const trappedValue = pdfMetadata?.info?.Trapped;
|
||||
// Get all options in the select element
|
||||
const options = trappedInput.options;
|
||||
// Loop through all options to find the one with a matching value
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i].value === trappedValue) {
|
||||
options[i].selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
addExtra();
|
||||
});
|
||||
|
||||
addMetadataBtn.addEventListener("click", () => {
|
||||
const keyInput = document.createElement("input");
|
||||
keyInput.type = "text";
|
||||
keyInput.placeholder = 'Key';
|
||||
keyInput.className = "form-control";
|
||||
keyInput.name = `allRequestParams[customKey${count}]`;
|
||||
|
||||
const valueInput = document.createElement("input");
|
||||
valueInput.type = "text";
|
||||
valueInput.placeholder = 'Value';
|
||||
valueInput.className = "form-control";
|
||||
valueInput.name = `allRequestParams[customValue${count}]`;
|
||||
count = count + 1;
|
||||
|
||||
const formGroup = document.createElement("div");
|
||||
formGroup.className = "mb-3";
|
||||
formGroup.appendChild(keyInput);
|
||||
formGroup.appendChild(valueInput);
|
||||
|
||||
customMetadataFormContainer.appendChild(formGroup);
|
||||
});
|
||||
function convertDateFormat(dateTimeString) {
|
||||
if (!dateTimeString || dateTimeString.length < 17) {
|
||||
return dateTimeString;
|
||||
}
|
||||
|
||||
const year = dateTimeString.substring(2, 6);
|
||||
const month = dateTimeString.substring(6, 8);
|
||||
const day = dateTimeString.substring(8, 10);
|
||||
const hour = dateTimeString.substring(10, 12);
|
||||
const minute = dateTimeString.substring(12, 14);
|
||||
const second = dateTimeString.substring(14, 16);
|
||||
|
||||
return year + "/" + month + "/" + day + " " + hour + ":" + minute + ":" + second;
|
||||
}
|
||||
|
||||
function addExtra() {
|
||||
const event = document.getElementById("customModeCheckbox");
|
||||
if (event.checked && lastPDFFile.Custom != null) {
|
||||
customMetadataDiv.style.display = 'block';
|
||||
for (const [key, value] of Object.entries(lastPDFFile.Custom)) {
|
||||
if (key === 'Author' || key === 'CreationDate' || key === 'Creator' || key === 'Keywords' || key === 'ModDate' || key === 'Producer' || key === 'Subject' || key === 'Title' || key === 'Trapped') {
|
||||
continue;
|
||||
}
|
||||
const entryDiv = document.createElement('div');
|
||||
entryDiv.className = 'mb-3';
|
||||
entryDiv.innerHTML = `<div class="mb-3"><label class="form-check-label" for="${key}">${key}:</label><input name="${key}" value="${value}" type="text" class="form-control" id="${key}"></div>`;
|
||||
otherMetadataEntriesDiv.appendChild(entryDiv);
|
||||
}
|
||||
} else {
|
||||
customMetadataDiv.style.display = 'none';
|
||||
while (otherMetadataEntriesDiv.firstChild) {
|
||||
otherMetadataEntriesDiv.removeChild(otherMetadataEntriesDiv.firstChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customModeCheckbox.addEventListener('change', (event) => {
|
||||
addExtra();
|
||||
});
|
||||
<script type="module" th:src="@{'/js/pages/change-metadata.js'}">
|
||||
</script>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@
|
||||
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{split-by-size-or-count.title}, header=#{split-by-size-or-count.header})}"></th:block>
|
||||
<script th:src="@{'/js/thirdParty/pdf-lib.min.js'}"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user