Metadata editting and local only JS and pdf to image change and format pages (#44)
* Formatting * changeMeta * pdf to img fix * foramtting * new image * lang changes
This commit is contained in:
@@ -6,49 +6,35 @@
|
||||
|
||||
|
||||
<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="#{addImage.header}"></h2>
|
||||
|
||||
|
||||
|
||||
<form method="post" th:action="@{add-image}"
|
||||
enctype="multipart/form-data">
|
||||
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" required> <label
|
||||
class="custom-file-label" for="fileInput" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput2"
|
||||
name="fileInput2" required> <label
|
||||
class="custom-file-label" for="fileInput2" th:text="#{imgPrompt}"></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="x">X</label> <input type="number" class="form-control"
|
||||
id="x" name="x" step="0.01" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="y">Y</label> <input type="number" class="form-control"
|
||||
id="y" name="y" step="0.01" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{addImage.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
<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="#{addImage.header}"></h2>
|
||||
<form method="post" th:action="@{add-image}" enctype="multipart/form-data">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput2" name="fileInput2" required>
|
||||
<label class="custom-file-label" for="fileInput2" th:text="#{imgPrompt}"></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="x">X</label> <input type="number" class="form-control" id="x" name="x" step="0.01" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="y">Y</label> <input type="number" class="form-control" id="y" name="y" step="0.01" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{addImage.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -5,40 +5,32 @@
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{compress.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="#{compress.header}"></h2>
|
||||
<form action="#" th:action="@{compress-pdf}"
|
||||
th:object="${rotateForm}" method="post"
|
||||
enctype="multipart/form-data">
|
||||
<p th:text="#{processTimeWarning}"></p>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" required> <label
|
||||
class="custom-file-label" for="fileInput" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="imageCompressionLevel" th:text="#{compress.compressLevel}"></label> <input type="number" class="form-control"
|
||||
id="imageCompressionLevel" name="imageCompressionLevel" step="1"
|
||||
value="1" min="1" max="100" required>
|
||||
</div>
|
||||
<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="#{compress.header}"></h2>
|
||||
<form action="#" th:action="@{compress-pdf}" th:object="${rotateForm}" method="post" enctype="multipart/form-data">
|
||||
<p th:text="#{processTimeWarning}"></p>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
<div class="form-group">
|
||||
<label for="imageCompressionLevel" th:text="#{compress.compressLevel}"></label>
|
||||
<input type="number" class="form-control" id="imageCompressionLevel" name="imageCompressionLevel" step="1" value="1" min="1" max="100" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{compress.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
|
||||
<button type="submit" class="btn btn-primary" th:text="#{compress.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -3,37 +3,33 @@
|
||||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{imageToPDF.title})}"></th:block>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<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="#{imageToPDF.header}"></h2>
|
||||
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
<form method="post" enctype="multipart/form-data" th:action="@{img-to-pdf}">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput" name="fileInput" required>
|
||||
<label class="custom-file-label" for="fileInput" th:text="#{imgPrompt}"></label>
|
||||
</div>
|
||||
<br> <br>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{imageToPDF.submit}"></button>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<h2 th:text="#{imageToPDF.header}"></h2>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" th:action="@{img-to-pdf}">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput" name="fileInput" required>
|
||||
<label class="custom-file-label" for="fileInput" th:text="#{imgPrompt}"></label>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{imageToPDF.submit}"></button>
|
||||
</form>
|
||||
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,45 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{pdfToImage})}"></th:block>
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{pdfToImage.title})}"></th:block>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
||||
<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="#{pdfToImage.header}"></h2>
|
||||
<p th:text="#{processTimeWarning}"></p>
|
||||
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-img}">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{pdfToImage.selectText}"></label>
|
||||
<select class="form-control" name="imageFormat">
|
||||
<option value="png">PNG</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{pdfToImage.singleOrMultiple}"></label>
|
||||
<select class="form-control" name="singleOrMultiple">
|
||||
<option value="single" th:text="#{pdfToImage.single}"></option>
|
||||
<option value="multiple" th:text="#{pdfToImage.multi}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{pdfToImage.colorType}"></label>
|
||||
<select class="form-control" name="colorType">
|
||||
<option value="color" th:text="#{pdfToImage.color}"></option>
|
||||
<option value="greyscale" th:text="#{pdfToImage.grey}"></option>
|
||||
<option value="blackwhite" th:text="#{pdfToImage.blackwhite}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="dpi">DPI:</label>
|
||||
<input type="number" name="dpi" class="form-control" id="dpi" min="1" max="100" step="1" value="30" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{pdfToImage.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<h2 th:text="#{pdfToImage.header}"></h2>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-img}">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput" name="fileInput" required>
|
||||
<label class="custom-file-label" for="fileInput" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{pdfToImage.selectText}"></label> <select class="form-control"
|
||||
name="imageFormat">
|
||||
<option value="jpg">JPEG</option>
|
||||
<option value="png">PNG</option>
|
||||
<option value="gif">GIF</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{pdfToImage.submit}"></button>
|
||||
</form>
|
||||
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,5 @@
|
||||
<div th:fragment="card" class="feature-card">
|
||||
<h5 class="card-title" th:text="${cardTitle}"></h5>
|
||||
<p class="card-text" th:text="${cardText}"></p>
|
||||
<a class="btn btn-primary" th:href="${cardLink}" th:text="#{goToPage}"></a>
|
||||
<div th:fragment="card" class="feature-card">
|
||||
<h5 class="card-title" th:text="${cardTitle}"></h5>
|
||||
<p class="card-text" th:text="${cardText}"></p>
|
||||
<a class="btn btn-primary" th:href="${cardLink}" th:text="#{goToPage}"></a>
|
||||
</div>
|
||||
@@ -1,31 +1,29 @@
|
||||
<head th:fragment="head">
|
||||
|
||||
<!-- Metadata -->
|
||||
<meta charset="UTF-8">
|
||||
<title th:text="'S-PDF ' + ${title}"></title>
|
||||
<link rel="shortcut icon" href="favicon.svg">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Metadata -->
|
||||
<meta charset="UTF-8">
|
||||
<title th:text="'S-PDF ' + ${title}"></title>
|
||||
<link rel="shortcut icon" href="favicon.svg">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
||||
<!-- jQuery -->
|
||||
<script src="js/jquery.min.js"></script>
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css">
|
||||
<!-- Bootstrap -->
|
||||
<script src="js/popper.min.js"></script>
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="css/bootstrap-icons.css">
|
||||
|
||||
<!-- FontAwesome -->
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
|
||||
<!-- PDF.js -->
|
||||
<script src="pdfjs/pdf.min.js"></script>
|
||||
<link href="pdfjs/pdf_viewer.min.css" rel="stylesheet">
|
||||
|
||||
<!-- PDF.js -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.3.122/build/pdf.min.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.3.122/web/pdf_viewer.min.css" rel="stylesheet">
|
||||
<!-- Custom -->
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" th:href="@{css/dark-mode.css}" id="dark-mode-styles">
|
||||
|
||||
<!-- Custom -->
|
||||
<link rel="stylesheet" href="general.css">
|
||||
<link rel="stylesheet" th:href="@{dark-mode.css}" id="dark-mode-styles">
|
||||
|
||||
<script>
|
||||
<script>
|
||||
function toggleDarkMode() {
|
||||
var checkbox = document.getElementById("toggle-dark-mode");
|
||||
var darkModeStyles = document.getElementById("dark-mode-styles");
|
||||
@@ -54,9 +52,9 @@
|
||||
</head>
|
||||
|
||||
<th:block th:fragment="filelist">
|
||||
<div id="fileList"></div>
|
||||
<div id="fileList2"></div>
|
||||
<script>
|
||||
<div id="fileList"></div>
|
||||
<div id="fileList2"></div>
|
||||
<script>
|
||||
var input = document.getElementById("fileInput");
|
||||
var output = document.getElementById("fileList");
|
||||
|
||||
@@ -71,7 +69,7 @@
|
||||
output.innerHTML = fileNames;
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
var input2 = document.getElementById("fileInput2");
|
||||
var output2 = document.getElementById("fileList2");
|
||||
if (input2 != null && !input2) {
|
||||
@@ -89,7 +87,7 @@
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
<script>
|
||||
if (dropContainer) {
|
||||
dropContainer.ondragover = dropContainer.ondragenter = function(evt) {
|
||||
evt.preventDefault();
|
||||
@@ -112,14 +110,14 @@
|
||||
</th:block>
|
||||
|
||||
<th:block th:fragment="fileSelector(name, multiple)">
|
||||
<div class="custom-file-chooser">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" th:name="${name}" th:id="${name}+'-input'" th:multiple="${multiple}">
|
||||
<label class="custom-file-label" th:for="${name}+'-input'" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="custom-file-chooser">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" th:name="${name}" th:id="${name}+'-input'" th:multiple="${multiple}">
|
||||
<label class="custom-file-label" th:for="${name}+'-input'" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script th:inline="javascript">
|
||||
<script th:inline="javascript">
|
||||
$([[${"#"+name+"-input"}]]).on("change", function() {
|
||||
const files = $(this).get(0).files;
|
||||
const fileNames = Array.from(files).map(f => f.name).join(", ");
|
||||
@@ -131,9 +129,9 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.custom-file-label {
|
||||
padding-right: 90px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.custom-file-label {
|
||||
padding-right: 90px;
|
||||
}
|
||||
</style>
|
||||
</th:block>
|
||||
@@ -1,6 +1,6 @@
|
||||
<div th:fragment="footer">
|
||||
<div th:fragment="footer">
|
||||
<footer id="footer" class="text-center py-3">
|
||||
<a href="https://github.com/Frooodle/Stirling-PDF" target="_blank" class="mx-1"> <i class="fab fa-github fa-2x"></i></a>
|
||||
<a href="https://hub.docker.com/r/frooodle/s-pdf" target="_blank" class="mx-1"> <i class="fab fa-docker fa-2x"></i></a>
|
||||
<a href="https://github.com/Frooodle/Stirling-PDF" target="_blank" class="mx-1"><img src="images/github.svg"></img></a>
|
||||
<a href="https://hub.docker.com/r/frooodle/s-pdf" target="_blank" class="mx-1"><img src="images/docker.svg"></img></a>
|
||||
</footer>
|
||||
</div>
|
||||
@@ -45,6 +45,7 @@
|
||||
<a class="dropdown-item" href="#" th:href="@{remove-password}" th:classappend="${currentPage}=='remove-password' ? 'active' : ''" th:text="#{home.removePassword.title}"></a>
|
||||
<a class="dropdown-item" href="#" th:href="@{change-permissions}" th:classappend="${currentPage}=='change-permissions' ? 'active' : ''" th:text="#{home.permissions.title}"></a>
|
||||
<a class="dropdown-item" href="#" th:href="@{add-watermark}" th:classappend="${currentPage}=='add-watermark' ? 'active' : ''" th:text="#{home.watermark.title}"></a>
|
||||
<a class="dropdown-item" href="#" th:href="@{change-metadata}" th:classappend="${currentPage}=='change-metadata' ? 'active' : ''" th:text="#{home.changeMetadata.title}"></a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -64,11 +65,11 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" th:href="@{compress-pdf}" th:classappend="${currentPage}=='compress-pdf' ? 'active' : ''"></a>
|
||||
</li>
|
||||
|
||||
|
||||
<input type="checkbox" id="toggle-dark-mode" checked="true" th:onclick="javascript:toggleDarkMode()">
|
||||
|
||||
<a class="nav-link" href="#" for="toggle-dark-mode" th:text="#{navbar.darkmode}"></a>
|
||||
|
||||
|
||||
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="languageDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="bi bi-globe2"></i>
|
||||
@@ -77,7 +78,7 @@
|
||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="en_US">English (US)</a>
|
||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="en_GB">English (UK)</a>
|
||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="ar_AR">العربية</a>
|
||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="de_DE">German</a>
|
||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="de_DE">Deutsch</a>
|
||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="fr_FR">Français</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -5,62 +5,63 @@
|
||||
<th:block th:insert="~{fragments/common :: head(title='')}"></th:block>
|
||||
|
||||
<style>
|
||||
.features-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
}
|
||||
.feature-card {
|
||||
border: 1px solid rgba(0,0,0,.125);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
.features-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.feature-card .card-text {
|
||||
flex: 1;
|
||||
}
|
||||
.feature-card {
|
||||
border: 1px solid rgba(0, 0, 0, .125);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.feature-card .card-text {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
<!-- Jumbotron -->
|
||||
<div class="jumbotron jumbotron-fluid" id="jumbotron">
|
||||
<div class="container">
|
||||
<h1 class="display-4">Stirling PDF</h1>
|
||||
<p class="lead" th:text="#{home.desc}"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
<!-- Jumbotron -->
|
||||
<div class="jumbotron jumbotron-fluid" id="jumbotron">
|
||||
<div class="container">
|
||||
<h1 class="display-4">Stirling PDF</h1>
|
||||
<p class="lead" th:text="#{home.desc}"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features -->
|
||||
<div class="features-container container">
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.merge.title}, cardText=#{home.merge.desc}, cardLink='merge-pdfs')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.split.title}, cardText=#{home.split.desc}, cardLink='split-pdfs')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.rotate.title}, cardText=#{home.rotate.desc}, cardLink='rotate-pdf')}"></div>
|
||||
<!-- Features -->
|
||||
<div class="features-container container">
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.merge.title}, cardText=#{home.merge.desc}, cardLink='merge-pdfs')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.split.title}, cardText=#{home.split.desc}, cardLink='split-pdfs')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.rotate.title}, cardText=#{home.rotate.desc}, cardLink='rotate-pdf')}"></div>
|
||||
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.imageToPdf.title}, cardText=#{home.imageToPdf.desc}, cardLink='img-to-pdf')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.pdfToImage.title}, cardText=#{home.pdfToImage.desc}, cardLink='pdf-to-img')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.pdfOrganiser.title}, cardText=#{home.pdfOrganiser.desc}, cardLink='pdf-organizer')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.imageToPdf.title}, cardText=#{home.imageToPdf.desc}, cardLink='img-to-pdf')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.pdfToImage.title}, cardText=#{home.pdfToImage.desc}, cardLink='pdf-to-img')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.pdfOrganiser.title}, cardText=#{home.pdfOrganiser.desc}, cardLink='pdf-organizer')}"></div>
|
||||
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.addImage.title}, cardText=#{home.addImage.desc}, cardLink='add-image')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.watermark.title}, cardText=#{home.watermark.desc}, cardLink='add-watermark')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.permissions.title}, cardText=#{home.permissions.desc}, cardLink='change-permissions')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.addImage.title}, cardText=#{home.addImage.desc}, cardLink='add-image')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.watermark.title}, cardText=#{home.watermark.desc}, cardLink='add-watermark')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.permissions.title}, cardText=#{home.permissions.desc}, cardLink='change-permissions')}"></div>
|
||||
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.removePages.title}, cardText=#{home.removePages.desc}, cardLink='remove-pages')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.addPassword.title}, cardText=#{home.addPassword.desc}, cardLink='add-password')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.removePassword.title}, cardText=#{home.removePassword.desc}, cardLink='remove-password')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.removePages.title}, cardText=#{home.removePages.desc}, cardLink='remove-pages')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.addPassword.title}, cardText=#{home.addPassword.desc}, cardLink='add-password')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.removePassword.title}, cardText=#{home.removePassword.desc}, cardLink='remove-password')}"></div>
|
||||
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.compressPdfs.title}, cardText=#{home.compressPdfs.desc}, cardLink='compress-pdf')}"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.compressPdfs.title}, cardText=#{home.compressPdfs.desc}, cardLink='compress-pdf')}"></div>
|
||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.changeMetadata.title}, cardText=#{home.changeMetadata.desc}, cardLink='change-metadata')}"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -4,130 +4,124 @@
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{merge.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" id="dropContainer">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<h2 th:text="#{merge.header}"></h2>
|
||||
<form action="merge-pdfs" method="post"
|
||||
enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label th:text="#{multiPdfDropPrompt}"></label>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" multiple required> <label
|
||||
class="custom-file-label" th:text="#{pdfPrompt}">s</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<ul id="selectedFiles" class="list-group"></ul>
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<button type="submit" class="btn btn-primary" th:text="#{merge.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
<body>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
<br> <br>
|
||||
<div class="container" id="dropContainer">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<h2 th:text="#{merge.header}"></h2>
|
||||
<form action="merge-pdfs" method="post" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label th:text="#{multiPdfDropPrompt}"></label>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput" name="fileInput" multiple required>
|
||||
<label class="custom-file-label" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<ul id="selectedFiles" class="list-group"></ul>
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<button type="submit" class="btn btn-primary" th:text="#{merge.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document
|
||||
.getElementById(
|
||||
"fileInput")
|
||||
.addEventListener(
|
||||
"change",
|
||||
function() {
|
||||
var files = this.files;
|
||||
var list = document
|
||||
.getElementById("selectedFiles");
|
||||
list.innerHTML = "";
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var item = document
|
||||
.createElement("li");
|
||||
item.className = "list-group-item d-flex justify-content-between align-items-center";
|
||||
item.textContent = files[i].name;
|
||||
item.innerHTML += '<div><button class="btn btn-secondary move-up"><i class="fas fa-arrow-up"></i></button> <button class="btn btn-secondary move-down"><i class="fas fa-arrow-down"></i></button></div>';
|
||||
list
|
||||
.appendChild(item);
|
||||
}
|
||||
var moveUpButtons = document
|
||||
.querySelectorAll(".move-up");
|
||||
for (var i = 0; i < moveUpButtons.length; i++) {
|
||||
moveUpButtons[i]
|
||||
.addEventListener(
|
||||
"click",
|
||||
function(
|
||||
event) {
|
||||
event
|
||||
.preventDefault();
|
||||
var parent = this.parentNode.parentNode;
|
||||
var grandParent = parent.parentNode;
|
||||
if (parent.previousElementSibling) {
|
||||
grandParent
|
||||
.insertBefore(
|
||||
parent,
|
||||
parent.previousElementSibling);
|
||||
updateFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
var moveDownButtons = document
|
||||
.querySelectorAll(".move-down");
|
||||
for (var i = 0; i < moveDownButtons.length; i++) {
|
||||
moveDownButtons[i]
|
||||
.addEventListener(
|
||||
"click",
|
||||
function(
|
||||
event) {
|
||||
event
|
||||
.preventDefault();
|
||||
var parent = this.parentNode.parentNode;
|
||||
var grandParent = parent.parentNode;
|
||||
if (parent.nextElementSibling) {
|
||||
grandParent
|
||||
.insertBefore(
|
||||
parent.nextElementSibling,
|
||||
parent);
|
||||
updateFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateFiles() {
|
||||
var dataTransfer = new DataTransfer();
|
||||
var liElements = document
|
||||
.querySelectorAll("#selectedFiles li");
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
document
|
||||
.getElementById("fileInput")
|
||||
.addEventListener(
|
||||
"change",
|
||||
function() {
|
||||
var files = this.files;
|
||||
var list = document
|
||||
.getElementById("selectedFiles");
|
||||
list.innerHTML = "";
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var item = document
|
||||
.createElement("li");
|
||||
item.className = "list-group-item d-flex justify-content-between align-items-center";
|
||||
item.textContent = files[i].name;
|
||||
item.innerHTML += '<div><button class="btn btn-secondary move-up">Move Up</button> <button class="btn btn-secondary move-down">Move Down</button></div>';
|
||||
list.appendChild(item);
|
||||
}
|
||||
var moveUpButtons = document
|
||||
.querySelectorAll(".move-up");
|
||||
for (var i = 0; i < moveUpButtons.length; i++) {
|
||||
moveUpButtons[i]
|
||||
.addEventListener(
|
||||
"click",
|
||||
function(event) {
|
||||
event
|
||||
.preventDefault();
|
||||
var parent = this.parentNode.parentNode;
|
||||
var grandParent = parent.parentNode;
|
||||
if (parent.previousElementSibling) {
|
||||
grandParent
|
||||
.insertBefore(
|
||||
parent,
|
||||
parent.previousElementSibling);
|
||||
updateFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
var moveDownButtons = document
|
||||
.querySelectorAll(".move-down");
|
||||
for (var i = 0; i < moveDownButtons.length; i++) {
|
||||
moveDownButtons[i]
|
||||
.addEventListener(
|
||||
"click",
|
||||
function(event) {
|
||||
event
|
||||
.preventDefault();
|
||||
var parent = this.parentNode.parentNode;
|
||||
var grandParent = parent.parentNode;
|
||||
if (parent.nextElementSibling) {
|
||||
grandParent
|
||||
.insertBefore(
|
||||
parent.nextElementSibling,
|
||||
parent);
|
||||
updateFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateFiles() {
|
||||
var dataTransfer = new DataTransfer();
|
||||
var liElements = document
|
||||
.querySelectorAll("#selectedFiles li");
|
||||
|
||||
for (var i = 0; i < liElements.length; i++) {
|
||||
var fileNameFromList = liElements[i].innerText
|
||||
.replace(
|
||||
"\nMove Up Move Down",
|
||||
"");
|
||||
var fileFromFiles
|
||||
for (var j = 0; j < files.length; j++) {
|
||||
var file = files[j];
|
||||
if (file.name === fileNameFromList) {
|
||||
dataTransfer.items
|
||||
.add(file);
|
||||
break;
|
||||
for (var i = 0; i < liElements.length; i++) {
|
||||
var fileNameFromList = liElements[i].innerText
|
||||
.replace(
|
||||
"\nMove Up Move Down",
|
||||
"");
|
||||
var fileFromFiles
|
||||
for (var j = 0; j < files.length; j++) {
|
||||
var file = files[j];
|
||||
if (file.name === fileNameFromList) {
|
||||
dataTransfer.items
|
||||
.add(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
document
|
||||
.getElementById("fileInput").files = dataTransfer.files;
|
||||
}
|
||||
document
|
||||
.getElementById("fileInput").files = dataTransfer.files;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,37 +4,31 @@
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{pdfOrganiser.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="#{pdfOrganiser.header}"></h2>
|
||||
|
||||
<form th:action="@{rearrange-pages}" method="post"
|
||||
enctype="multipart/form-data">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" required> <label
|
||||
class="custom-file-label" for="fileInput" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pageOrder" th:text="#{pageOrderPrompt}"></label> <input type="text" class="form-control"
|
||||
id="fileInput" name="pageOrder"
|
||||
placeholder="(e.g. 1,3,2 or 4-8,2,10-12)" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{pdfOrganiser.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></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="#{pdfOrganiser.header}"></h2>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
<form th:action="@{rearrange-pages}" method="post" enctype="multipart/form-data">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
<div class="form-group">
|
||||
<label for="pageOrder" th:text="#{pageOrderPrompt}"></label>
|
||||
<input type="text" class="form-control" id="fileInput" name="pageOrder" placeholder="(e.g. 1,3,2 or 4-8,2,10-12)" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{pdfOrganiser.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,37 +4,31 @@
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{pageRemover.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="#{pageRemover.header}"></h2>
|
||||
<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="#{pageRemover.header}"></h2>
|
||||
|
||||
<form th:action="@{remove-pages}" method="post"
|
||||
enctype="multipart/form-data">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" required> <label
|
||||
class="custom-file-label" for="fileInput" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pagesToDelete" th:text="#{pageRemover.pagesToDelete}"></label> <input type="text" class="form-control"
|
||||
id="fileInput" name="pagesToDelete"
|
||||
placeholder="(e.g. 1,2,6 or 1-10,15-30)" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{pageRemover.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
<form th:action="@{remove-pages}" method="post" enctype="multipart/form-data">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
<div class="form-group">
|
||||
<label for="pagesToDelete" th:text="#{pageRemover.pagesToDelete}"></label>
|
||||
<input type="text" class="form-control" id="fileInput" name="pagesToDelete" placeholder="(e.g. 1,2,6 or 1-10,15-30)" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{pageRemover.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,45 +5,51 @@
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{rotate.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="#{rotate.header}"></h2>
|
||||
<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="#{rotate.header}"></h2>
|
||||
|
||||
<form action="#" th:action="@{rotate-pdf}" th:object="${rotateForm}" method="post" enctype="multipart/form-data">
|
||||
<div th:replace="fragments/common :: fileSelector(name='fileInput', multiple=false)"></div>
|
||||
<input type="hidden" id="angleInput" name="angle" value="0">
|
||||
<form action="#" th:action="@{rotate-pdf}" th:object="${rotateForm}" method="post" enctype="multipart/form-data">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
<input type="hidden" id="angleInput" name="angle" value="0">
|
||||
|
||||
<div id="editSection" style="display: none">
|
||||
<div class="previewContainer">
|
||||
<img id="pdf-preview"/>
|
||||
</div>
|
||||
<div id="editSection" style="display: none">
|
||||
<div class="previewContainer">
|
||||
<img id="pdf-preview" />
|
||||
</div>
|
||||
|
||||
<div class="buttonContainer">
|
||||
<button type="button" class="btn btn-secondary" onclick="rotate(-90)">
|
||||
<i class="bi bi-arrow-counterclockwise"></i>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{rotate.submit}"></button>
|
||||
<button type="button" class="btn btn-secondary" onclick="rotate(90)">
|
||||
<i class="bi bi-arrow-clockwise"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="buttonContainer">
|
||||
<button type="button" class="btn btn-secondary" onclick="rotate(-90)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z" />
|
||||
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{rotate.submit}"></button>
|
||||
<button type="button" class="btn btn-secondary" onclick="rotate(90)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
||||
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<script>
|
||||
const angleInput = document.getElementById("angleInput");
|
||||
const fileInput = document.getElementById("fileInput-input");
|
||||
const preview = document.getElementById("pdf-preview");
|
||||
@@ -90,36 +96,37 @@
|
||||
angleInput.value = newAngle;
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#pdf-preview {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
max-width: calc(100% - 30px);
|
||||
max-height: calc(100% - 30px);
|
||||
box-shadow: 0 0 4px rgba(100,100,100,.25);
|
||||
transition: rotate .3s;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
translate: -50% -50%;
|
||||
}
|
||||
.previewContainer {
|
||||
aspect-ratio: 1;
|
||||
width: 100%;
|
||||
border: 1px solid rgba(0,0,0,.125);
|
||||
border-radius: 0.25rem;
|
||||
margin: 1rem 0;
|
||||
padding: 15px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
<style>
|
||||
#pdf-preview {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
max-width: calc(100% - 30px);
|
||||
max-height: calc(100% - 30px);
|
||||
box-shadow: 0 0 4px rgba(100, 100, 100, .25);
|
||||
transition: rotate .3s;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
translate: -50% -50%;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
</style>
|
||||
.previewContainer {
|
||||
aspect-ratio: 1;
|
||||
width: 100%;
|
||||
border: 1px solid rgba(0, 0, 0, .125);
|
||||
border-radius: 0.25rem;
|
||||
margin: 1rem 0;
|
||||
padding: 15px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -3,94 +3,78 @@
|
||||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{addPassword.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="#{addPassword.header}"></h2>
|
||||
<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="#{addPassword.header}"></h2>
|
||||
|
||||
<form action="add-password" method="post"
|
||||
enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label th:text="#{addPassword.selectText.1}"></label>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" required> <label
|
||||
class="custom-file-label" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{addPassword.selectText.2}"></label> <input type="password"
|
||||
class="form-control" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{addPassword.selectText.3}"></label> <select class="form-control"
|
||||
id="keyLength" name="keyLength">
|
||||
<option value="40">40</option>
|
||||
<option value="128">128</option>
|
||||
<option value="256">256</option>
|
||||
</select> <small class="form-text text-muted" th:text="#{addPassword.selectText.4}"></small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{addPassword.selectText.5}"></label>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canAssembleDocument" name="canAssembleDocument"> <label
|
||||
class="form-check-label" for="canAssembleDocument" th:text="#{addPassword.selectText.6}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canExtractContent" name="canExtractContent"> <label
|
||||
class="form-check-label" for="canExtractContent" th:text="#{addPassword.selectText.7}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canExtractForAccessibility"
|
||||
name="canExtractForAccessibility"> <label
|
||||
class="form-check-label" for="canExtractForAccessibility" th:text="#{addPassword.selectText.8}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canFillInForm" name="canFillInForm"> <label
|
||||
class="form-check-label" for="canFillInForm" th:text="#{addPassword.selectText.9}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canModify"
|
||||
name="canModify"> <label class="form-check-label"
|
||||
for="canModify" th:text="#{addPassword.selectText.10}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canModifyAnnotations" name="canModifyAnnotations"> <label
|
||||
class="form-check-label" for="canModifyAnnotations" th:text="#{addPassword.selectText.11}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canPrint"
|
||||
name="canPrint"> <label class="form-check-label"
|
||||
for="canPrint" th:text="#{addPassword.selectText.12}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canPrintFaithful" name="canPrintFaithful"> <label
|
||||
class="form-check-label" for="canPrintFaithful" th:text="#{addPassword.selectText.13}"></label>
|
||||
</div>
|
||||
<form action="add-password" method="post" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label th:text="#{addPassword.selectText.1}"></label>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{addPassword.selectText.2}"></label> <input type="password" class="form-control" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{addPassword.selectText.3}"></label> <select class="form-control" id="keyLength" name="keyLength">
|
||||
<option value="40">40</option>
|
||||
<option value="128">128</option>
|
||||
<option value="256">256</option>
|
||||
</select> <small class="form-text text-muted" th:text="#{addPassword.selectText.4}"></small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{addPassword.selectText.5}"></label>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canAssembleDocument" name="canAssembleDocument">
|
||||
<label class="form-check-label" for="canAssembleDocument" th:text="#{addPassword.selectText.6}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canExtractContent" name="canExtractContent">
|
||||
<label class="form-check-label" for="canExtractContent" th:text="#{addPassword.selectText.7}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canExtractForAccessibility" name="canExtractForAccessibility">
|
||||
<label class="form-check-label" for="canExtractForAccessibility" th:text="#{addPassword.selectText.8}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canFillInForm" name="canFillInForm">
|
||||
<label class="form-check-label" for="canFillInForm" th:text="#{addPassword.selectText.9}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canModify" name="canModify">
|
||||
<label class="form-check-label" for="canModify" th:text="#{addPassword.selectText.10}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canModifyAnnotations" name="canModifyAnnotations">
|
||||
<label class="form-check-label" for="canModifyAnnotations" th:text="#{addPassword.selectText.11}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canPrint" name="canPrint">
|
||||
<label class="form-check-label" for="canPrint" th:text="#{addPassword.selectText.12}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canPrintFaithful" name="canPrintFaithful">
|
||||
<label class="form-check-label" for="canPrintFaithful" th:text="#{addPassword.selectText.13}"></label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-group text-center">
|
||||
<button type="submit" class="btn btn-primary" th:text="#{addPassword.submit}"></button>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-group text-center">
|
||||
<button type="submit" class="btn btn-primary" th:text="#{addPassword.submit}"></button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,54 +3,50 @@
|
||||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{watermark.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="#{watermark.header}"></h2>
|
||||
<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="#{watermark.header}"></h2>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" action="add-watermark">
|
||||
<div class="form-group">
|
||||
<label th:text="#{watermark.selectText.1}"></label>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" required> <label
|
||||
class="custom-file-label" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="watermarkText" th:text="#{watermark.selectText.2}"></label>
|
||||
<input type="text" id="watermarkText" name="watermarkText" class="form-control" placeholder="Stirling-PDF" required/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="fontSize" th:text="#{watermark.selectText.3}"></label>
|
||||
<input type="text" id="fontSize" name="fontSize" class="form-control" value="30"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="rotation" th:text="#{watermark.selectText.4}"></label>
|
||||
<input type="text" id="rotation" name="rotation" class="form-control" value="45"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="widthSpacer" th:text="#{watermark.selectText.5}"></label>
|
||||
<input type="text" id="widthSpacer" name="widthSpacer" class="form-control" value="50"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="heightSpacer" th:text="#{watermark.selectText.6}"></label>
|
||||
<input type="text" id="heightSpacer" name="heightSpacer" class="form-control" value="50"/>
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<input type="submit" th:value="#{watermark.submit}" class="btn btn-primary"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
<form method="post" enctype="multipart/form-data" action="add-watermark">
|
||||
<div class="form-group">
|
||||
<label th:text="#{watermark.selectText.1}"></label>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="watermarkText" th:text="#{watermark.selectText.2}"></label>
|
||||
<input type="text" id="watermarkText" name="watermarkText" class="form-control" placeholder="Stirling-PDF" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="fontSize" th:text="#{watermark.selectText.3}"></label>
|
||||
<input type="text" id="fontSize" name="fontSize" class="form-control" value="30" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="rotation" th:text="#{watermark.selectText.4}"></label>
|
||||
<input type="text" id="rotation" name="rotation" class="form-control" value="45" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="widthSpacer" th:text="#{watermark.selectText.5}"></label>
|
||||
<input type="text" id="widthSpacer" name="widthSpacer" class="form-control" value="50" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="heightSpacer" th:text="#{watermark.selectText.6}"></label>
|
||||
<input type="text" id="heightSpacer" name="heightSpacer" class="form-control" value="50" />
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<input type="submit" th:value="#{watermark.submit}" class="btn btn-primary" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
254
src/main/resources/templates/security/change-metadata.html
Normal file
254
src/main/resources/templates/security/change-metadata.html
Normal file
@@ -0,0 +1,254 @@
|
||||
<!DOCTYPE html>
|
||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{changeMetadata.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="#{changeMetadata.header}"></h2>
|
||||
|
||||
<form method="post" id="form1" enctype="multipart/form-data" th:action="@{/update-metadata}">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
<p class="text-muted" th:text="#{changeMetadata.selectText.1}"></p>
|
||||
|
||||
<div class="form-group-inline form-check">
|
||||
<input type="checkbox" class="form-check-input" id="deleteAll" name="deleteAll">
|
||||
<label class="ml-3" for="deleteAll" th:text="#{changeMetadata.selectText.2}" ></label>
|
||||
</div>
|
||||
|
||||
<div class="form-group-inline form-check">
|
||||
<input type="checkbox" class="form-check-input" id="customModeCheckbox">
|
||||
<label class="ml-3" for="customModeCheckbox" th:text="#{changeMetadata.selectText.3}"></label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="author" th:text="#{changeMetadata.author}"></label>
|
||||
<input type="text" class="form-control" id="author" name="author">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="creationDate" th:text="#{changeMetadata.creationDate}"></label>
|
||||
<input type="text" class="form-control" id="creationDate" name="creationDate" placeholder="2020/12/25 18:30:59">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="creator" th:text="#{changeMetadata.creator}"></label>
|
||||
<input type="text" class="form-control" id="creator" name="creator">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="keywords" th:text="#{changeMetadata.keywords}"></label>
|
||||
<input type="text" class="form-control" id="keywords" name="keywords">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="modificationDate" th:text="#{changeMetadata.modDate}"></label>
|
||||
<input type="text" class="form-control" id="modificationDate" name="modificationDate" placeholder="2020/12/25 18:30:59">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="producer" th:text="#{changeMetadata.producer}"></label>
|
||||
<input type="text" class="form-control" id="producer" name="producer">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="subject" th:text="#{changeMetadata.subject}"></label>
|
||||
<input type="text" class="form-control" id="subject" name="subject">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="title" th:text="#{changeMetadata.title}"></label>
|
||||
<input type="text" class="form-control" id="title" name="title">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-check-label" for="trapped" th:text="#{changeMetadata.trapped}"></label>
|
||||
<select class="form-control" id="trapped" name="trapped">
|
||||
<option value="True" th:text="#{true}"></option>
|
||||
<option value="False" th:text="#{false}" selected></option>
|
||||
<option value="Unknown" th:text="#{unknown}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="customMetadata" style="display: none;">
|
||||
<h3 th:text="#{changeMetadata.selectText.4}"></h3>
|
||||
<div class="form-group" id="otherMetadataEntries"></div>
|
||||
</div>
|
||||
<div id="customMetadataEntries"></div>
|
||||
<button type="button" class="btn btn-secondary" id="addMetadataBtn" th:text="#{changeMetadata.selectText.5}"></button>
|
||||
<br>
|
||||
<br>
|
||||
<button class="btn btn-primary" type="submit" th:text="#{changeMetadata.submit}"></button>
|
||||
<script>
|
||||
|
||||
const deleteAllCheckbox = document.querySelector("#deleteAll");
|
||||
const inputs = document.querySelectorAll(".form-control");
|
||||
const customMetadataDiv = document.getElementById('customMetadata');
|
||||
const otherMetadataEntriesDiv = document.getElementById('otherMetadataEntries');
|
||||
|
||||
deleteAllCheckbox.addEventListener("change", function(event) {
|
||||
if (event.target !== deleteAllCheckbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
inputs.forEach(input => {
|
||||
if (input === deleteAllCheckbox) {
|
||||
return;
|
||||
}
|
||||
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)
|
||||
|
||||
const pdf = await pdfjsLib.getDocument(url).promise;
|
||||
const pdfMetadata = await pdf.getMetadata();
|
||||
lastPDFFile = pdfMetadata?.info
|
||||
console.log(pdfMetadata);
|
||||
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 = "customKey" + count;
|
||||
|
||||
const valueInput = document.createElement("input");
|
||||
valueInput.type = "text";
|
||||
valueInput.placeholder = "Value";
|
||||
valueInput.className = "form-control";
|
||||
valueInput.name = "customValue" + count;
|
||||
count = count + 1;
|
||||
|
||||
const formGroup = document.createElement("div");
|
||||
formGroup.className = "form-group";
|
||||
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) {
|
||||
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 = 'form-group';
|
||||
|
||||
|
||||
|
||||
entryDiv.innerHTML = `<div class="form-group"><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>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,81 +4,68 @@
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{permissions.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="#{permissions.header}"></h2>
|
||||
<p th:text="#{permissions.warning}"></p>
|
||||
<form action="add-password" method="post"
|
||||
enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label th:text="#{permissions.selectText.1}"></label>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput"> <label class="custom-file-label" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{permissions.selectText.2}"></label>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canAssembleDocument" name="canAssembleDocument"> <label
|
||||
class="form-check-label" for="canAssembleDocument" th:text="#{permissions.selectText.3}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canExtractContent" name="canExtractContent"> <label
|
||||
class="form-check-label" for="canExtractContent" th:text="#{permissions.selectText.4}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canExtractForAccessibility"
|
||||
name="canExtractForAccessibility"> <label
|
||||
class="form-check-label" for="canExtractForAccessibility" th:text="#{permissions.selectText.5}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canFillInForm" name="canFillInForm"> <label
|
||||
class="form-check-label" for="canFillInForm" th:text="#{permissions.selectText.6}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canModify"
|
||||
name="canModify"> <label class="form-check-label"
|
||||
for="canModify" th:text="#{permissions.selectText.7}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canModifyAnnotations" name="canModifyAnnotations"> <label
|
||||
class="form-check-label" for="canModifyAnnotations" th:text="#{permissions.selectText.8}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canPrint"
|
||||
name="canPrint"> <label class="form-check-label"
|
||||
for="canPrint" th:text="#{permissions.selectText.9}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="canPrintFaithful" name="canPrintFaithful"> <label
|
||||
class="form-check-label" for="canPrintFaithful" th:text="#{permissions.selectText.10}"></label>
|
||||
</div>
|
||||
<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="#{permissions.header}"></h2>
|
||||
<p th:text="#{permissions.warning}"></p>
|
||||
<form action="add-password" method="post" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label th:text="#{permissions.selectText.1}"></label>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{permissions.selectText.2}"></label>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canAssembleDocument" name="canAssembleDocument">
|
||||
<label class="form-check-label" for="canAssembleDocument" th:text="#{permissions.selectText.3}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canExtractContent" name="canExtractContent">
|
||||
<label class="form-check-label" for="canExtractContent" th:text="#{permissions.selectText.4}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canExtractForAccessibility" name="canExtractForAccessibility">
|
||||
<label class="form-check-label" for="canExtractForAccessibility" th:text="#{permissions.selectText.5}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canFillInForm" name="canFillInForm">
|
||||
<label class="form-check-label" for="canFillInForm" th:text="#{permissions.selectText.6}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canModify" name="canModify">
|
||||
<label class="form-check-label" for="canModify" th:text="#{permissions.selectText.7}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canModifyAnnotations" name="canModifyAnnotations">
|
||||
<label class="form-check-label" for="canModifyAnnotations" th:text="#{permissions.selectText.8}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canPrint" name="canPrint">
|
||||
<label class="form-check-label" for="canPrint" th:text="#{permissions.selectText.9}"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="canPrintFaithful" name="canPrintFaithful">
|
||||
<label class="form-check-label" for="canPrintFaithful" th:text="#{permissions.selectText.10}"></label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-group text-center">
|
||||
<button type="submit" class="btn btn-primary" th:text="#{permissions.submit}"></button>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-group text-center">
|
||||
<button type="submit" class="btn btn-primary" th:text="#{permissions.submit}"></button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,40 +3,35 @@
|
||||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{removePassword.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="#{removePassword.header}"></h2>
|
||||
<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="#{removePassword.header}"></h2>
|
||||
|
||||
<form action="add-password" method="post"
|
||||
enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label th:text="#{removePassword.selectText.1}"></label>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" required> <label
|
||||
class="custom-file-label" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{removePassword.selectText.2}"></label> <input type="password"
|
||||
class="form-control" id="password" name="password" required>
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-group text-center">
|
||||
<button type="submit" class="btn btn-primary" th:text="#{removePassword.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
<form action="add-password" method="post" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label th:text="#{removePassword.selectText.1}"></label>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label th:text="#{removePassword.selectText.2}"></label>
|
||||
<input type="password" class="form-control" id="password" name="password" required>
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-group text-center">
|
||||
<button type="submit" class="btn btn-primary" th:text="#{removePassword.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,49 +6,39 @@
|
||||
|
||||
<body>
|
||||
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<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">
|
||||
<h1 th:text="#{split.header}"></h1>
|
||||
<p th:text="#{split.desc.1}"></p>
|
||||
<p th:text="#{split.desc.2}"></p>
|
||||
<p th:text="#{split.desc.3}"></p>
|
||||
<p th:text="#{split.desc.4}"></p>
|
||||
<p th:text="#{split.desc.5}"></p>
|
||||
<p th:text="#{split.desc.6}"></p>
|
||||
<p th:text="#{split.desc.7}"></p>
|
||||
<p th:text="#{split.desc.8}"></p>
|
||||
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
<form th:action="@{split-pages}" method="post" enctype="multipart/form-data">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<h1 th:text="#{split.header}"></h1>
|
||||
|
||||
<p th:text="#{split.desc.1}"></p>
|
||||
<p th:text="#{split.desc.2}"></p>
|
||||
<p th:text="#{split.desc.3}"></p>
|
||||
<p th:text="#{split.desc.4}"></p>
|
||||
<p th:text="#{split.desc.5}"></p>
|
||||
<p th:text="#{split.desc.6}"></p>
|
||||
<p th:text="#{split.desc.7}"></p>
|
||||
<p th:text="#{split.desc.8}"></p>
|
||||
|
||||
<form th:action="@{split-pages}" method="post" enctype="multipart/form-data">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput" name="fileInput" required>
|
||||
<label class="custom-file-label" for="fileInput" th:text="#{pdfPrompt}"></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pages" th:text="#{split.splitPages}"></label>
|
||||
<input type="text" class="form-control" id="pages" name="pages" placeholder="1,3,5-10" required>
|
||||
</div>
|
||||
<br>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{split.submit}"></button>
|
||||
</form>
|
||||
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pages" th:text="#{split.splitPages}"></label>
|
||||
<input type="text" class="form-control" id="pages" name="pages" placeholder="1,3,5-10" required>
|
||||
</div>
|
||||
<br>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{split.submit}"></button>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user