161 lines
No EOL
6.2 KiB
HTML
161 lines
No EOL
6.2 KiB
HTML
<!DOCTYPE html>
|
|
<html th:lang="${#locale.toString()}"
|
|
th:lang-direction="#{language.direction}"
|
|
xmlns:th="http://www.thymeleaf.org">
|
|
<th:block
|
|
th:insert="~{fragments/common :: head(title=#{getPdfInfo.title})}"></th:block>
|
|
<body>
|
|
<div id="page-container">
|
|
<div id="content-wrap">
|
|
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
|
<br> <br>
|
|
<div class="container">
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-6">
|
|
<h2 th:text="#{getPdfInfo.header}"></h2>
|
|
<form id="pdfInfoForm" method="post" enctype="multipart/form-data"
|
|
th:action="@{get-info-on-pdf}">
|
|
<div
|
|
th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, remoteCall='false')}"></div>
|
|
<br>
|
|
<button type="submit" id="submitBtn" class="btn btn-primary"
|
|
th:text="#{getPdfInfo.submit}"></button>
|
|
|
|
</form>
|
|
<div class="container mt-5">
|
|
<!-- Iterate over each main section in the JSON -->
|
|
<div id="json-content">
|
|
<!-- JavaScript will populate this section -->
|
|
</div>
|
|
|
|
<!-- Button to download the JSON -->
|
|
<a href="#" id="downloadJson" class="btn btn-primary mt-3"
|
|
style="display: none;" th:text="#{getPdfInfo.downloadJson}">Download
|
|
JSON</a>
|
|
</div>
|
|
<script>
|
|
|
|
document.getElementById("pdfInfoForm").addEventListener("submit", function(event) {
|
|
event.preventDefault();
|
|
|
|
const formData = new FormData(event.target);
|
|
|
|
fetch('get-info-on-pdf', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
displayJsonData(data);
|
|
setDownloadLink(data);
|
|
document.getElementById("downloadJson").style.display = "block";
|
|
})
|
|
.catch(error => console.error('Error:', error));
|
|
});
|
|
|
|
function displayJsonData(jsonData) {
|
|
const jsonContent = document.getElementById('json-content');
|
|
|
|
while (jsonContent.firstChild) {
|
|
jsonContent.removeChild(jsonContent.firstChild);
|
|
}
|
|
|
|
for (const key in jsonData) {
|
|
const sectionElem = createJsonSection(key, jsonData[key]);
|
|
jsonContent.appendChild(sectionElem);
|
|
}
|
|
}
|
|
|
|
function setDownloadLink(jsonData) {
|
|
const downloadLink = document.getElementById('downloadJson');
|
|
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(jsonData, null, 4));
|
|
downloadLink.setAttribute("href", dataStr);
|
|
downloadLink.setAttribute("download", "data.json");
|
|
}
|
|
|
|
function createJsonSection(key, value, depth = 0) {
|
|
let safeKey = (typeof key === "string") ? key.replace(/[^a-zA-Z0-9]/g, '_') : key;
|
|
const card = document.createElement('div');
|
|
card.className = 'card mb-3';
|
|
|
|
const header = document.createElement('div');
|
|
header.className = 'card-header';
|
|
header.id = `${safeKey}-heading-${depth}`;
|
|
const h5Elem = document.createElement('h5');
|
|
h5Elem.className = 'mb-0';
|
|
|
|
if (key === 'XMPMetadata' && typeof value === "string") {
|
|
const buttonElem = createButtonElement(key, safeKey, depth);
|
|
h5Elem.appendChild(buttonElem);
|
|
} else if (value && typeof value === 'object') {
|
|
if (Array.isArray(value) && value.length === 0) {
|
|
h5Elem.textContent = `${key}: Empty array`;
|
|
} else if (!Array.isArray(value) && Object.keys(value).length === 0) {
|
|
h5Elem.textContent = `${key}: Empty object`;
|
|
} else {
|
|
const buttonElem = createButtonElement(key, safeKey, depth);
|
|
h5Elem.appendChild(buttonElem);
|
|
}
|
|
} else {
|
|
h5Elem.textContent = `${key}: ${String(value)}`;
|
|
}
|
|
|
|
header.appendChild(h5Elem);
|
|
card.appendChild(header);
|
|
|
|
const content = document.createElement('div');
|
|
content.id = `${safeKey}-content-${depth}`;
|
|
content.className = 'collapse';
|
|
content.setAttribute('aria-labelledby', `${safeKey}-heading-${depth}`);
|
|
|
|
if (key === 'XMPMetadata' && typeof value === "string") {
|
|
const body = document.createElement('div');
|
|
body.className = 'card-body';
|
|
const preElem = document.createElement('pre');
|
|
preElem.textContent = value; // Not escaping since we're using textContent
|
|
body.appendChild(preElem);
|
|
content.appendChild(body);
|
|
} else if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
const body = document.createElement('div');
|
|
body.className = 'card-body';
|
|
for (const subKey in value) {
|
|
const subElem = createJsonSection(subKey, value[subKey], depth + 1);
|
|
body.appendChild(subElem);
|
|
}
|
|
content.appendChild(body);
|
|
} else if (value && typeof value === 'object' && Array.isArray(value)) {
|
|
const body = document.createElement('div');
|
|
body.className = 'card-body';
|
|
value.forEach((val, index) => {
|
|
const subElem = createJsonSection(`${key}[${index}]`, val, depth + 1);
|
|
body.appendChild(subElem);
|
|
});
|
|
content.appendChild(body);
|
|
}
|
|
|
|
card.appendChild(content);
|
|
return card;
|
|
}
|
|
|
|
|
|
function createButtonElement(key, safeKey, depth) {
|
|
const buttonElem = document.createElement('button');
|
|
buttonElem.className = 'btn btn-link';
|
|
buttonElem.type = 'button';
|
|
buttonElem.dataset.toggle = "collapse";
|
|
buttonElem.dataset.target = `#${safeKey}-content-${depth}`;
|
|
buttonElem.setAttribute('aria-expanded', 'true');
|
|
buttonElem.setAttribute('aria-controls', `${safeKey}-content-${depth}`);
|
|
buttonElem.textContent = key;
|
|
return buttonElem;
|
|
}
|
|
</script>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
|
</div>
|
|
</body>
|
|
</html> |