Merge branch 'main' into feature/#3403/analytics-accepts-cookies

This commit is contained in:
Reece Browne 2025-05-10 12:44:30 +01:00 committed by GitHub
commit d93f8b7a0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 246 additions and 148 deletions

View File

@ -127,7 +127,7 @@ Stirling-PDF currently supports 39 languages!
| Dutch (Nederlands) (nl_NL) | ![79%](https://geps.dev/progress/79) | | Dutch (Nederlands) (nl_NL) | ![79%](https://geps.dev/progress/79) |
| English (English) (en_GB) | ![100%](https://geps.dev/progress/100) | | English (English) (en_GB) | ![100%](https://geps.dev/progress/100) |
| English (US) (en_US) | ![100%](https://geps.dev/progress/100) | | English (US) (en_US) | ![100%](https://geps.dev/progress/100) |
| French (Français) (fr_FR) | ![91%](https://geps.dev/progress/91) | | French (Français) (fr_FR) | ![92%](https://geps.dev/progress/92) |
| German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) | | German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) |
| Greek (Ελληνικά) (el_GR) | ![91%](https://geps.dev/progress/91) | | Greek (Ελληνικά) (el_GR) | ![91%](https://geps.dev/progress/91) |
| Hindi (हिंदी) (hi_IN) | ![91%](https://geps.dev/progress/91) | | Hindi (हिंदी) (hi_IN) | ![91%](https://geps.dev/progress/91) |

View File

@ -29,7 +29,7 @@ ext {
} }
group = "stirling.software" group = "stirling.software"
version = "0.46.0" version = "0.46.1"
java { java {
// 17 is lowest but we support and recommend 21 // 17 is lowest but we support and recommend 21

View File

@ -34,6 +34,11 @@ public class EEAppConfig {
return licenseKeyChecker.getPremiumLicenseEnabledResult() != License.NORMAL; return licenseKeyChecker.getPremiumLicenseEnabledResult() != License.NORMAL;
} }
@Bean(name = "license")
public String licenseType() {
return licenseKeyChecker.getPremiumLicenseEnabledResult().name();
}
@Bean(name = "runningEE") @Bean(name = "runningEE")
public boolean runningEnterprise() { public boolean runningEnterprise() {
return licenseKeyChecker.getPremiumLicenseEnabledResult() == License.ENTERPRISE; return licenseKeyChecker.getPremiumLicenseEnabledResult() == License.ENTERPRISE;

View File

@ -5,6 +5,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Properties; import java.util.Properties;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -15,6 +16,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
@ -33,6 +35,8 @@ public class AppConfig {
private final ApplicationProperties applicationProperties; private final ApplicationProperties applicationProperties;
private final Environment env;
@Bean @Bean
@ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true") @ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true")
public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) { public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) {
@ -193,4 +197,37 @@ public class AppConfig {
public String uuid() { public String uuid() {
return applicationProperties.getAutomaticallyGenerated().getUUID(); return applicationProperties.getAutomaticallyGenerated().getUUID();
} }
@Bean(name = "disablePixel")
public boolean disablePixel() {
return Boolean.getBoolean(env.getProperty("DISABLE_PIXEL"));
}
@Bean(name = "machineType")
public String determineMachineType() {
try {
boolean isDocker = runningInDocker();
boolean isKubernetes = System.getenv("KUBERNETES_SERVICE_HOST") != null;
boolean isBrowserOpen = "true".equalsIgnoreCase(env.getProperty("BROWSER_OPEN"));
if (isKubernetes) {
return "Kubernetes";
} else if (isDocker) {
return "Docker";
} else if (isBrowserOpen) {
String os = System.getProperty("os.name").toLowerCase(Locale.ROOT);
if (os.contains("win")) {
return "Client-windows";
} else if (os.contains("mac")) {
return "Client-mac";
} else {
return "Client-unix";
}
} else {
return "Server-jar";
}
} catch (Exception e) {
return "Unknown";
}
}
} }

View File

@ -180,14 +180,15 @@ public class AnalysisController {
// Get permissions // Get permissions
Map<String, Boolean> permissions = new HashMap<>(); Map<String, Boolean> permissions = new HashMap<>();
permissions.put("canPrint", document.getCurrentAccessPermission().canPrint()); permissions.put("preventPrinting", !document.getCurrentAccessPermission().canPrint());
permissions.put("canModify", document.getCurrentAccessPermission().canModify());
permissions.put( permissions.put(
"canExtractContent", "preventModify", !document.getCurrentAccessPermission().canModify());
document.getCurrentAccessPermission().canExtractContent());
permissions.put( permissions.put(
"canModifyAnnotations", "preventExtractContent",
document.getCurrentAccessPermission().canModifyAnnotations()); !document.getCurrentAccessPermission().canExtractContent());
permissions.put(
"preventModifyAnnotations",
!document.getCurrentAccessPermission().canModifyAnnotations());
securityInfo.put("permissions", permissions); securityInfo.put("permissions", permissions);
} else { } else {

View File

@ -627,23 +627,30 @@ public class CompressController {
// Scale factors for different optimization levels // Scale factors for different optimization levels
private double getScaleFactorForLevel(int optimizeLevel) { private double getScaleFactorForLevel(int optimizeLevel) {
return switch (optimizeLevel) { return switch (optimizeLevel) {
case 4 -> 0.9; // 90% - lite compression case 3 -> 0.85;
case 5 -> 0.8; // 80% - lite compression case 4 -> 0.75;
case 6 -> 0.7; // 70% - lite compression case 5 -> 0.65;
case 7 -> 0.6; // 60% - intense compression case 6 -> 0.55;
case 8 -> 0.5; // 50% - intense compression case 7 -> 0.45;
case 9, 10 -> 0.4; // 40% - intense compression case 8 -> 0.35;
default -> 1.0; // No scaling for levels 1-3 case 9 -> 0.25;
case 10 -> 0.15;
default -> 1.0;
}; };
} }
// JPEG quality for different optimization levels // JPEG quality for different optimization levels
private float getJpegQualityForLevel(int optimizeLevel) { private float getJpegQualityForLevel(int optimizeLevel) {
return switch (optimizeLevel) { return switch (optimizeLevel) {
case 7 -> 0.8f; // 80% quality case 3 -> 0.85f;
case 8 -> 0.6f; // 60% quality case 4 -> 0.80f;
case 9, 10 -> 0.4f; // 40% quality case 5 -> 0.75f;
default -> 0.7f; // 70% quality for levels 1-6 case 6 -> 0.70f;
case 7 -> 0.60f;
case 8 -> 0.50f;
case 9 -> 0.35f;
case 10 -> 0.2f;
default -> 0.7f;
}; };
} }
@ -698,7 +705,7 @@ public class CompressController {
while (!sizeMet && optimizeLevel <= 9) { while (!sizeMet && optimizeLevel <= 9) {
// Apply image compression for levels 4-9 // Apply image compression for levels 4-9
if ((optimizeLevel >= 4 || Boolean.TRUE.equals(convertToGrayscale)) if ((optimizeLevel >= 3 || Boolean.TRUE.equals(convertToGrayscale))
&& !imageCompressionApplied) { && !imageCompressionApplied) {
double scaleFactor = getScaleFactorForLevel(optimizeLevel); double scaleFactor = getScaleFactorForLevel(optimizeLevel);
float jpegQuality = getJpegQualityForLevel(optimizeLevel); float jpegQuality = getJpegQualityForLevel(optimizeLevel);
@ -790,10 +797,14 @@ public class CompressController {
log.info("Pre-QPDF file size: {}", GeneralUtils.formatBytes(preQpdfSize)); log.info("Pre-QPDF file size: {}", GeneralUtils.formatBytes(preQpdfSize));
// Map optimization levels to QPDF compression levels // Map optimization levels to QPDF compression levels
int qpdfCompressionLevel = int qpdfCompressionLevel;
optimizeLevel <= 3 if (optimizeLevel == 1) {
? optimizeLevel * 3 // Level 1->3, 2->6, 3->9 qpdfCompressionLevel = 5;
: 9; // Max compression for levels 4-9 } else if (optimizeLevel == 2) {
qpdfCompressionLevel = 9;
} else {
qpdfCompressionLevel = 9;
}
// Create output file for QPDF // Create output file for QPDF
Path qpdfOutputFile = Files.createTempFile("qpdf_output_", ".pdf"); Path qpdfOutputFile = Files.createTempFile("qpdf_output_", ".pdf");

View File

@ -63,25 +63,25 @@ public class PasswordController {
String ownerPassword = request.getOwnerPassword(); String ownerPassword = request.getOwnerPassword();
String password = request.getPassword(); String password = request.getPassword();
int keyLength = request.getKeyLength(); int keyLength = request.getKeyLength();
boolean canAssembleDocument = request.isCanAssembleDocument(); boolean preventAssembly = request.isPreventAssembly();
boolean canExtractContent = request.isCanExtractContent(); boolean preventExtractContent = request.isPreventExtractContent();
boolean canExtractForAccessibility = request.isCanExtractForAccessibility(); boolean preventExtractForAccessibility = request.isPreventExtractForAccessibility();
boolean canFillInForm = request.isCanFillInForm(); boolean preventFillInForm = request.isPreventFillInForm();
boolean canModify = request.isCanModify(); boolean preventModify = request.isPreventModify();
boolean canModifyAnnotations = request.isCanModifyAnnotations(); boolean preventModifyAnnotations = request.isPreventModifyAnnotations();
boolean canPrint = request.isCanPrint(); boolean preventPrinting = request.isPreventPrinting();
boolean canPrintFaithful = request.isCanPrintFaithful(); boolean preventPrintingFaithful = request.isPreventPrintingFaithful();
PDDocument document = pdfDocumentFactory.load(fileInput); PDDocument document = pdfDocumentFactory.load(fileInput);
AccessPermission ap = new AccessPermission(); AccessPermission ap = new AccessPermission();
ap.setCanAssembleDocument(!canAssembleDocument); ap.setCanAssembleDocument(!preventAssembly);
ap.setCanExtractContent(!canExtractContent); ap.setCanExtractContent(!preventExtractContent);
ap.setCanExtractForAccessibility(!canExtractForAccessibility); ap.setCanExtractForAccessibility(!preventExtractForAccessibility);
ap.setCanFillInForm(!canFillInForm); ap.setCanFillInForm(!preventFillInForm);
ap.setCanModify(!canModify); ap.setCanModify(!preventModify);
ap.setCanModifyAnnotations(!canModifyAnnotations); ap.setCanModifyAnnotations(!preventModifyAnnotations);
ap.setCanPrint(!canPrint); ap.setCanPrint(!preventPrinting);
ap.setCanPrintFaithful(!canPrintFaithful); ap.setCanPrintFaithful(!preventPrintingFaithful);
StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, password, ap); StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, password, ap);
if (!"".equals(ownerPassword) || !"".equals(password)) { if (!"".equals(ownerPassword) || !"".equals(password)) {

View File

@ -170,15 +170,16 @@ public class RedactController {
} }
private Color decodeOrDefault(String hex, Color defaultColor) { private Color decodeOrDefault(String hex, Color defaultColor) {
Color color = null;
try { try {
color = Color.decode(hex); if (hex != null && !hex.startsWith("#")) {
hex = "#" + hex;
}
return Color.decode(hex);
} catch (Exception e) { } catch (Exception e) {
color = defaultColor; return defaultColor;
}
} }
return color;
}
private List<Integer> getPageNumbers(ManualRedactPdfRequest request, int pagesCount) { private List<Integer> getPageNumbers(ManualRedactPdfRequest request, int pagesCount) {
String pageNumbersInput = request.getPageNumbers(); String pageNumbersInput = request.getPageNumbers();

View File

@ -29,31 +29,29 @@ public class AddPasswordRequest extends PDFFile {
defaultValue = "256") defaultValue = "256")
private int keyLength = 256; private int keyLength = 256;
@Schema(description = "Whether the document assembly is allowed", example = "false") @Schema(description = "Whether document assembly is prevented", example = "false")
private boolean canAssembleDocument; private boolean preventAssembly;
@Schema(description = "Whether content extraction is prevented", example = "false")
private boolean preventExtractContent;
@Schema( @Schema(
description = "Whether content extraction for accessibility is allowed", description = "Whether content extraction for accessibility is prevented",
example = "false") example = "false")
private boolean canExtractContent; private boolean preventExtractForAccessibility;
@Schema( @Schema(description = "Whether form filling is prevented", example = "false")
description = "Whether content extraction for accessibility is allowed", private boolean preventFillInForm;
example = "false")
private boolean canExtractForAccessibility;
@Schema(description = "Whether form filling is allowed", example = "false") @Schema(description = "Whether document modification is prevented", example = "false")
private boolean canFillInForm; private boolean preventModify;
@Schema(description = "Whether the document modification is allowed", example = "false") @Schema(description = "Whether modification of annotations is prevented", example = "false")
private boolean canModify; private boolean preventModifyAnnotations;
@Schema(description = "Whether modification of annotations is allowed", example = "false") @Schema(description = "Whether printing of the document is prevented", example = "false")
private boolean canModifyAnnotations; private boolean preventPrinting;
@Schema(description = "Whether printing of the document is allowed", example = "false") @Schema(description = "Whether faithful printing is prevented", example = "false")
private boolean canPrint; private boolean preventPrintingFaithful;
@Schema(description = "Whether faithful printing is allowed", example = "false")
private boolean canPrintFaithful;
} }

View File

@ -23,7 +23,7 @@ public class RedactPdfRequest extends PDFFile {
@Schema(description = "Whether to use whole word search", defaultValue = "false") @Schema(description = "Whether to use whole word search", defaultValue = "false")
private boolean wholeWordSearch; private boolean wholeWordSearch;
@Schema(description = "The color for redaction", defaultValue = "#000000") @Schema(description = "Hexadecimal color code for redaction, e.g. #FF0000 or 000000", defaultValue = "#000000")
private String redactColor = "#000000"; private String redactColor = "#000000";
@Schema(description = "Custom padding for redaction", type = "number") @Schema(description = "Custom padding for redaction", type = "number")

View File

@ -517,13 +517,13 @@ home.showJS.title=Afficher le JavaScript
home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF. home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF.
showJS.tags=JS showJS.tags=JS
home.autoRedact.title=Censure automatique home.autoRedact.title=Caviardage automatique
home.autoRedact.desc=Censurer automatiquement les informations sensibles d'un PDF. home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF.
autoRedact.tags=caviarder,rédiger,censurer,redact,auto autoRedact.tags=caviarder,redact,auto,Masquer,noircir,noir,marqueur,caché,rédiger,censurer
home.redact.title=Censure manuelle home.redact.title=Caviardage manuel
home.redact.desc=Censurer un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées. home.redact.desc=Caviarder un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées.
redact.tags=Redact,Hide,black out,black,marker,hidden,manual,caviarder,rédiger,censurer redact.tags=Caviarder,Redact,Masquer,noircir,noir,marqueur,caché,rédiger,censurer
home.tableExtraxt.title=PDF en CSV home.tableExtraxt.title=PDF en CSV
home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV. home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV.
@ -624,31 +624,31 @@ autoRedact.convertPDFToImageLabel=Convertir un PDF en PDF-Image (utilisé pour s
autoRedact.submitButton=Caviarder autoRedact.submitButton=Caviarder
#redact #redact
redact.title=Rédaction manuelle redact.title=Caviardage manuel
redact.header=Rédaction manuelle redact.header=Caviardage manuel
redact.submit=Rédiger redact.submit=Caviarder
redact.textBasedRedaction=Rédaction en fonction de texte redact.textBasedRedaction=Caviarder du texte
redact.pageBasedRedaction=Rédaction en fonction de pages redact.pageBasedRedaction=Caviarder des pages
redact.convertPDFToImageLabel=Convertir en PDF-Image (pour supprimer le texte derrière le rectangle) redact.convertPDFToImageLabel=Convertir en PDF-Image (pour supprimer le texte derrière le rectangle)
redact.pageRedactionNumbers.title=Pages redact.pageRedactionNumbers.title=Pages
redact.pageRedactionNumbers.placeholder=(ex: 1,2,8 ou 4,7,12-16 ou 2n-1) redact.pageRedactionNumbers.placeholder=(ex: 1,2,8 ou 4,7,12-16 ou 2n-1)
redact.redactionColor.title=Couleur redact.redactionColor.title=Couleur
redact.export=Exporter redact.export=Exporter
redact.upload=Téléverser redact.upload=Téléverser
redact.boxRedaction=Dessiner le rectangle à rédiger redact.boxRedaction=Tracer le rectangle à caviarder
redact.zoom=Zoom redact.zoom=Zoom
redact.zoomIn=Zoom avant redact.zoomIn=Zoom avant
redact.zoomOut=Zoom arrière redact.zoomOut=Zoom arrière
redact.nextPage=Page suivante redact.nextPage=Page suivante
redact.previousPage=Page précédente redact.previousPage=Page précédente
redact.toggleSidebar=Toggle Sidebar redact.toggleSidebar=Montrer la barre latérale
redact.showThumbnails=Afficher les miniatures redact.showThumbnails=Afficher les miniatures
redact.showDocumentOutline=Montrer les contours du document (double-click pour agrandir/réduire tous les éléments) redact.showDocumentOutline=Montrer les contours du document (double-click pour agrandir/réduire tous les éléments)
redact.showAttatchments=Montrer les éléments attachés redact.showAttatchments=Montrer les éléments attachés
redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut) redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut)
redact.colourPicker=Sélection de couleur redact.colourPicker=Sélection de couleur
redact.findCurrentOutlineItem=Trouver l'élément de contour courrant redact.findCurrentOutlineItem=Trouver l'élément de contour courrant
redact.applyChanges=Apply Changes redact.applyChanges=Appliquer les changements
#showJS #showJS
showJS.title=Afficher le JavaScript showJS.title=Afficher le JavaScript

View File

@ -1,7 +1,8 @@
#page-container { #page-container {
min-height: 100vh; height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow-x: clip;
} }
#content-wrap { #content-wrap {

View File

@ -162,6 +162,7 @@ html[dir="rtl"] .lang-dropdown-item-wrapper {
text-wrap: wrap; text-wrap: wrap;
word-break: break-word; word-break: break-word;
width: 80%; width: 80%;
font-size: large;
} }
.close-icon { .close-icon {
@ -476,6 +477,9 @@ html[dir="rtl"] .dropdown-menu[data-bs-popper] {
display: flex; display: flex;
gap: 30px; gap: 30px;
justify-content: center; justify-content: center;
width: 140%;
position: relative;
left: -20%;
} }
.feature-group { .feature-group {

View File

@ -299,21 +299,42 @@ document.getElementById("addOperationBtn").addEventListener("click", function ()
} }
} }
listItem.innerHTML = ` let containerDiv = document.createElement("div");
<div class="d-flex justify-content-between align-items-center w-100"> containerDiv.className = "d-flex justify-content-between align-items-center w-100";
<div class="operationName">${selectedOperation}</div>
<div class="arrows d-flex"> let operationNameDiv = document.createElement("div");
<button class="btn btn-secondary move-up ms-1"><span class="material-symbols-rounded">arrow_upward</span></button> operationNameDiv.className = "operationName";
<button class="btn btn-secondary move-down ms-1"><span class="material-symbols-rounded">arrow_downward</span></button> operationNameDiv.textContent = selectedOperation;
<button class="btn ${hasSettings ? "btn-warning" : "btn-secondary"} pipelineSettings ms-1" ${ containerDiv.appendChild(operationNameDiv);
hasSettings ? "" : "disabled"
}> let arrowsDiv = document.createElement("div");
<span class="material-symbols-rounded">settings</span> arrowsDiv.className = "arrows d-flex";
</button>
<button class="btn btn-danger remove ms-1"><span class="material-symbols-rounded">close</span></button> let moveUpButton = document.createElement("button");
</div> moveUpButton.className = "btn btn-secondary move-up ms-1";
</div> moveUpButton.innerHTML = '<span class="material-symbols-rounded">arrow_upward</span>';
`; arrowsDiv.appendChild(moveUpButton);
let moveDownButton = document.createElement("button");
moveDownButton.className = "btn btn-secondary move-down ms-1";
moveDownButton.innerHTML = '<span class="material-symbols-rounded">arrow_downward</span>';
arrowsDiv.appendChild(moveDownButton);
let settingsButton = document.createElement("button");
settingsButton.className = `btn ${hasSettings ? "btn-warning" : "btn-secondary"} pipelineSettings ms-1`;
if (!hasSettings) {
settingsButton.disabled = true;
}
settingsButton.innerHTML = '<span class="material-symbols-rounded">settings</span>';
arrowsDiv.appendChild(settingsButton);
let removeButton = document.createElement("button");
removeButton.className = "btn btn-danger remove ms-1";
removeButton.innerHTML = '<span class="material-symbols-rounded">close</span>';
arrowsDiv.appendChild(removeButton);
containerDiv.appendChild(arrowsDiv);
listItem.appendChild(containerDiv);
pipelineList.appendChild(listItem); pipelineList.appendChild(listItem);

View File

@ -9,7 +9,7 @@ TabContainer = {
tabList.classList.add('tab-buttons'); tabList.classList.add('tab-buttons');
tabTitles.forEach((title) => { tabTitles.forEach((title) => {
const tabButton = document.createElement('button'); const tabButton = document.createElement('button');
tabButton.innerHTML = title; tabButton.textContent = title;
tabButton.onclick = (e) => { tabButton.onclick = (e) => {
this.setActiveTab(e.target); this.setActiveTab(e.target);
}; };

View File

@ -41,7 +41,13 @@
<link rel="stylesheet" th:href="@{'/css/bootstrap-icons.min.css'}"> <link rel="stylesheet" th:href="@{'/css/bootstrap-icons.min.css'}">
<!-- Pixel, doesn't collect any PII--> <!-- Pixel, doesn't collect any PII-->
<img referrerpolicy="no-referrer-when-downgrade" src="https://pixel.stirlingpdf.com/a.png?x-pxid=4f5fa02f-a065-4efb-bb2c-24509a4b6b92" style="position: absolute; visibility: hidden;"/> <img th:if="${!@disablePixel}" referrerpolicy="no-referrer-when-downgrade"
th:src="'https://pixel.stirlingpdf.com/a.png?x-pxid=4f5fa02f-a065-4efb-bb2c-24509a4b6b92'
+ '&machineType=' + ${@machineType}
+ '&appVersion=' + ${@appVersion}
+ '&licenseType=' + ${@license}
+ '&loginEnabled=' + ${@loginEnabled}"
style="position: absolute; visibility: hidden;" />
<!-- Custom --> <!-- Custom -->
<link rel="stylesheet" th:href="@{'/css/general.css'}"> <link rel="stylesheet" th:href="@{'/css/general.css'}">

View File

@ -1,4 +1,4 @@
<div th:fragment="navbar" class="mx-auto" style="position: sticky; top:0; z-index:10000"> <div th:fragment="navbar" class="mx-auto" style="position: sticky; top:0; z-index:10000; width:100%">
<script th:src="@{'/js/languageSelection.js'}"></script> <script th:src="@{'/js/languageSelection.js'}"></script>
<script th:src="@{'/js/navbar.js'}"></script> <script th:src="@{'/js/navbar.js'}"></script>
<script th:src="@{'/js/additionalLanguageCode.js'}"></script> <script th:src="@{'/js/additionalLanguageCode.js'}"></script>

View File

@ -8,19 +8,17 @@
<body> <body>
<div id="page-container"> <div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block> <th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<div style="transform-origin: top;"
id="scale-wrap">
<br class="d-md-none"> <br class="d-md-none">
<!-- Features --> <!-- Features -->
<script th:src="@{'/js/homecard.js'}"></script> <script th:src="@{'/js/homecard.js'}"></script>
<div style=" <div style="
width: 100%; width: 100%;
display: flex; display: flex;
flex-direction: column;"> flex-direction: column;"
>
<div> <div>
<br> <br>
<div style="justify-content: center; display: flex;"> <div style="justify-content: center; display: flex;">
@ -45,7 +43,7 @@
th:insert="~{fragments/navbarEntry :: navbarEntry ('multi-tool', 'construction', 'home.multiTool.title', 'home.multiTool.desc', 'multiTool.tags', 'organize')}"> th:insert="~{fragments/navbarEntry :: navbarEntry ('multi-tool', 'construction', 'home.multiTool.title', 'home.multiTool.desc', 'multiTool.tags', 'organize')}">
</div> </div>
<div class="newfeature" <div class="newfeature"
th:insert="~{fragments/navbarEntry :: navbarEntry('validate-signature', 'verified', 'home.validateSignature.title', 'home.validateSignature.desc', 'validateSignature.tags', 'security')}"> th:insert="~{fragments/navbarEntry :: navbarEntry('compress-pdf', 'zoom_in_map', 'home.compressPdfs.title', 'home.compressPdfs.desc', 'compressPDFs.tags', 'advance')}">
</div> </div>
</div> </div>
</div> </div>
@ -123,9 +121,10 @@
</div> </div>
</div> </div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block> <th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</div>
</div> </div>
@ -222,6 +221,20 @@
window.showSurvey = /*[[${showSurveyFromDocker}]]*/ true window.showSurvey = /*[[${showSurveyFromDocker}]]*/ true
</script> </script>
<script th:src="@{'/js/pages/home.js'}" th:inline="javascript"></script> <script th:src="@{'/js/pages/home.js'}" th:inline="javascript"></script>
<script>
function applyScale() {
const baseWidth = 1440;
const baseHeight = 1000;
const scaleX = window.innerWidth / baseWidth;
const scaleY = window.innerHeight / baseHeight;
const scale = Math.max(0.9, Math.min(scaleX, scaleY)); // keep aspect ratio, honor minScale
const ui = document.getElementById('scale-wrap');
ui.style.transform = `scale(${scale*0.75})`;
}
window.addEventListener('resize', applyScale);
window.addEventListener('load', applyScale);
</script>
</body> </body>

View File

@ -41,36 +41,36 @@
<div class="mb-3"> <div class="mb-3">
<label class="mb-2" th:text="#{addPassword.selectText.5}"></label> <label class="mb-2" th:text="#{addPassword.selectText.5}"></label>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canAssembleDocument" name="canAssembleDocument"> <input type="checkbox" id="preventAssembly" name="preventAssembly">
<label for="canAssembleDocument" th:text="#{addPassword.selectText.6}"></label> <label for="preventAssembly" th:text="#{addPassword.selectText.6}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canExtractContent" name="canExtractContent"> <input type="checkbox" id="preventExtractContent" name="preventExtractContent">
<label for="canExtractContent" th:text="#{addPassword.selectText.7}"></label> <label for="preventExtractContent" th:text="#{addPassword.selectText.7}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canExtractForAccessibility" name="canExtractForAccessibility"> <input type="checkbox" id="preventExtractForAccessibility" name="preventExtractForAccessibility">
<label for="canExtractForAccessibility" th:text="#{addPassword.selectText.8}"></label> <label for="preventExtractForAccessibility" th:text="#{addPassword.selectText.8}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canFillInForm" name="canFillInForm"> <input type="checkbox" id="preventFillInForm" name="preventFillInForm">
<label for="canFillInForm" th:text="#{addPassword.selectText.9}"></label> <label for="preventFillInForm" th:text="#{addPassword.selectText.9}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canModify" name="canModify"> <input type="checkbox" id="preventModify" name="preventModify">
<label for="canModify" th:text="#{addPassword.selectText.10}"></label> <label for="preventModify" th:text="#{addPassword.selectText.10}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canModifyAnnotations" name="canModifyAnnotations"> <input type="checkbox" id="preventModifyAnnotations" name="preventModifyAnnotations">
<label for="canModifyAnnotations" th:text="#{addPassword.selectText.11}"></label> <label for="preventModifyAnnotations" th:text="#{addPassword.selectText.11}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canPrint" name="canPrint"> <input type="checkbox" id="preventPrinting" name="preventPrinting">
<label for="canPrint" th:text="#{addPassword.selectText.12}"></label> <label for="preventPrinting" th:text="#{addPassword.selectText.12}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canPrintFaithful" name="canPrintFaithful"> <input type="checkbox" id="preventPrintingFaithful" name="preventPrintingFaithful">
<label for="canPrintFaithful" th:text="#{addPassword.selectText.13}"></label> <label for="preventPrintingFaithful" th:text="#{addPassword.selectText.13}"></label>
</div> </div>
</div> </div>
<br> <br>

View File

@ -25,36 +25,36 @@
<div class="mb-3"> <div class="mb-3">
<label class="mb-2" th:text="#{permissions.selectText.2}"></label> <label class="mb-2" th:text="#{permissions.selectText.2}"></label>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canAssembleDocument" name="canAssembleDocument"> <input type="checkbox" id="preventAssembly" name="preventAssembly">
<label for="canAssembleDocument" th:text="#{permissions.selectText.3}"></label> <label for="preventAssembly" th:text="#{permissions.selectText.3}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canExtractContent" name="canExtractContent"> <input type="checkbox" id="preventExtractContent" name="preventExtractContent">
<label for="canExtractContent" th:text="#{permissions.selectText.4}"></label> <label for="preventExtractContent" th:text="#{permissions.selectText.4}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canExtractForAccessibility" name="canExtractForAccessibility"> <input type="checkbox" id="preventExtractForAccessibility" name="preventExtractForAccessibility">
<label for="canExtractForAccessibility" th:text="#{permissions.selectText.5}"></label> <label for="preventExtractForAccessibility" th:text="#{permissions.selectText.5}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canFillInForm" name="canFillInForm"> <input type="checkbox" id="preventFillInForm" name="preventFillInForm">
<label for="canFillInForm" th:text="#{permissions.selectText.6}"></label> <label for="preventFillInForm" th:text="#{permissions.selectText.6}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canModify" name="canModify"> <input type="checkbox" id="preventModify" name="preventModify">
<label for="canModify" th:text="#{permissions.selectText.7}"></label> <label for="preventModify" th:text="#{permissions.selectText.7}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canModifyAnnotations" name="canModifyAnnotations"> <input type="checkbox" id="preventModifyAnnotations" name="preventModifyAnnotations">
<label for="canModifyAnnotations" th:text="#{permissions.selectText.8}"></label> <label for="preventModifyAnnotations" th:text="#{permissions.selectText.8}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canPrint" name="canPrint"> <input type="checkbox" id="preventPrinting" name="preventPrinting">
<label for="canPrint" th:text="#{permissions.selectText.9}"></label> <label for="preventPrinting" th:text="#{permissions.selectText.9}"></label>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input type="checkbox" id="canPrintFaithful" name="canPrintFaithful"> <input type="checkbox" id="preventPrintingFaithful" name="preventPrintingFaithful">
<label for="canPrintFaithful" th:text="#{permissions.selectText.10}"></label> <label for="preventPrintingFaithful" th:text="#{permissions.selectText.10}"></label>
</div> </div>
</div> </div>
<br> <br>