Fixed firefox compatibility and added missing icons to feature pages (#2863)

# Description of Changes

Fixed icon incompatibility with firefox
Added missing icons to feature pages

Closes #(2833)


![image](https://github.com/user-attachments/assets/51ba008a-f6ab-4e29-9a79-99d85d152689)


---

## Checklist

### General

- [ x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ x] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md)
(if applicable)
- [ x] I have performed a self-review of my own code
- [ x] My changes generate no new warnings

### Documentation

- [ x] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ x] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing)
for more details.

Co-authored-by: Reece Browne <reece@stirling.pdf>
This commit is contained in:
reecebrowne
2025-02-03 15:19:18 +00:00
committed by GitHub
parent 04696dc2aa
commit dc46172deb
11 changed files with 213 additions and 174 deletions

View File

@@ -17,7 +17,9 @@
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon advance">cut</span>
<svg class="material-symbols-rounded tool-header-icon advance">
<use xlink:href="/images/split-auto.svg#icon-split-auto"></use>
</svg>
<span class="tool-header-text" th:text="#{autoSplitPDF.header}"></span>
</div>

View File

@@ -1,13 +1,14 @@
<th:block th:fragment="navbarEntry(endpoint, toolIcon, titleKey, descKey, tagKey, toolGroup)"
th:if="${@endpointConfiguration.isEndpointEnabled(endpoint)}">
th:if="${@endpointConfiguration.isEndpointEnabled(endpoint)}">
<a th:id="@{${endpoint}}" class="dropdown-item" style="position:relative" th:href="@{${endpoint}}"
th:data-bs-link="@{${endpoint}}"
th:classappend="${endpoint.equals(currentPage)} ? ${toolGroup} + ' active' : '' + ${toolGroup}"
th:data-bs-tags="#{${tagKey}}" th:data-bs-title='#{${titleKey}}'>
<div style="height:2.5rem;align-items: center;display: flex" th:title="#{${descKey}}" class="icon" alt="icon"
th:class="@{${toolGroup}}">
<svg class="nav-icon" style="height: 2.7rem; width:2.7rem; align-items:center; display: flex; justify-content: center;">
<use th:href="@{${toolIcon}}"></use>
<svg class="nav-icon"
style="height: 2.7rem; width:2.7rem; align-items:center; display: flex; justify-content: center;">
<use th:xlink:href="@{${toolIcon}}"></use>
</svg>
<span class="icon-text" th:text="#{${titleKey}}"></span>
</div>

View File

@@ -1,86 +1,96 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
<head>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{autoRedact.title}, header=#{autoRedact.header})}"></th:block>
</head>
</head>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon security">playlist_remove</span>
<span class="tool-header-text" th:text="#{autoRedact.header}"></span>
</div>
<form th:action="@{'api/v1/security/auto-redact'}" method="post" enctype="multipart/form-data">
<div class="mb-3">
<input type="file" class="form-control" id="fileInput" name="fileInput" required accept="application/pdf">
</div>
<div class="mb-3">
<label for="listOfText" class="form-label" th:text="#{autoRedact.textsToRedactLabel}"></label>
<textarea class="form-control" id="listOfText" name="listOfText" rows="4" required th:placeholder="#{autoRedact.textsToRedactPlaceholder}"></textarea>
</div>
<div class="mb-3">
<label for="defaultColor" class="form-label" th:text="#{autoRedact.colorLabel}">Color</label>
<select class="form-control" id="defaultColor" name="defaultColor" onchange="handleColorChange(this.value)">
<option value="#000000" th:text="#{black}">Black</option>
<option value="#FFFFFF" th:text="#{white}">White</option>
<option value="#FF0000" th:text="#{red}">Red</option>
<option value="#00FF00" th:text="#{green}">Green</option>
<option value="#0000FF" th:text="#{blue}">Blue</option>
<option value="custom" th:text="#{custom}">Custom...</option>
</select>
</div>
<!-- Custom Color Input -->
<div class="mb-3" id="customColorContainer" style="display: none;">
<label for="customColor" class="form-label" th:text="#{autoRedact.colorLabel}">Custom Color</label>
<input type="text" class="form-control" id="customColor" name="redactColor" placeholder="#FF00FF">
</div>
<script>
function handleColorChange(selectedValue) {
if (selectedValue === "custom") {
document.getElementById('customColorContainer').style.display = 'block';
} else {
document.getElementById('customColorContainer').style.display = 'none';
document.getElementById('customColor').value = selectedValue;
}
}
</script>
<div class="mb-3 form-check">
<input type="checkbox" id="useRegex" name="useRegex">
<label for="useRegex" th:text="#{autoRedact.useRegexLabel}"></label>
</div>
<div class="mb-3 form-check">
<input type="checkbox" id="wholeWordSearch" name="wholeWordSearch">
<label for="wholeWordSearch" th:text="#{autoRedact.wholeWordSearchLabel}"></label>
</div>
<div class="mb-3">
<label for="customPadding" class="form-label" th:text="#{autoRedact.customPaddingLabel}"></label>
<input type="number" step="0.1" class="form-control" id="customPadding" name="customPadding" value="0.1">
</div>
<div class="mb-3 form-check">
<input type="checkbox" id="convertPDFToImage" name="convertPDFToImage" checked>
<label for="convertPDFToImage" th:text="#{autoRedact.convertPDFToImageLabel}"></label>
</div>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{autoRedact.submitButton}"></button>
</form>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<svg class="material-symbols-rounded tool-header-icon security">
<use xlink:href="/images/redact-auto.svg#icon-redact-auto"></use>
</svg>
<span class="tool-header-text" th:text="#{autoRedact.header}"></span>
</div>
<form th:action="@{'api/v1/security/auto-redact'}" method="post" enctype="multipart/form-data">
<div class="mb-3">
<input type="file" class="form-control" id="fileInput" name="fileInput" required
accept="application/pdf">
</div>
<div class="mb-3">
<label for="listOfText" class="form-label" th:text="#{autoRedact.textsToRedactLabel}"></label>
<textarea class="form-control" id="listOfText" name="listOfText" rows="4" required
th:placeholder="#{autoRedact.textsToRedactPlaceholder}"></textarea>
</div>
<div class="mb-3">
<label for="defaultColor" class="form-label" th:text="#{autoRedact.colorLabel}">Color</label>
<select class="form-control" id="defaultColor" name="defaultColor"
onchange="handleColorChange(this.value)">
<option value="#000000" th:text="#{black}">Black</option>
<option value="#FFFFFF" th:text="#{white}">White</option>
<option value="#FF0000" th:text="#{red}">Red</option>
<option value="#00FF00" th:text="#{green}">Green</option>
<option value="#0000FF" th:text="#{blue}">Blue</option>
<option value="custom" th:text="#{custom}">Custom...</option>
</select>
</div>
<!-- Custom Color Input -->
<div class="mb-3" id="customColorContainer" style="display: none;">
<label for="customColor" class="form-label" th:text="#{autoRedact.colorLabel}">Custom Color</label>
<input type="text" class="form-control" id="customColor" name="redactColor" placeholder="#FF00FF">
</div>
<script>
function handleColorChange(selectedValue) {
if (selectedValue === "custom") {
document.getElementById('customColorContainer').style.display = 'block';
} else {
document.getElementById('customColorContainer').style.display = 'none';
document.getElementById('customColor').value = selectedValue;
}
}
</script>
<div class="mb-3 form-check">
<input type="checkbox" id="useRegex" name="useRegex">
<label for="useRegex" th:text="#{autoRedact.useRegexLabel}"></label>
</div>
<div class="mb-3 form-check">
<input type="checkbox" id="wholeWordSearch" name="wholeWordSearch">
<label for="wholeWordSearch" th:text="#{autoRedact.wholeWordSearchLabel}"></label>
</div>
<div class="mb-3">
<label for="customPadding" class="form-label" th:text="#{autoRedact.customPaddingLabel}"></label>
<input type="number" step="0.1" class="form-control" id="customPadding" name="customPadding"
value="0.1">
</div>
<div class="mb-3 form-check">
<input type="checkbox" id="convertPDFToImage" name="convertPDFToImage" checked>
<label for="convertPDFToImage" th:text="#{autoRedact.convertPDFToImageLabel}"></label>
</div>
<button type="submit" id="submitBtn" class="btn btn-primary"
th:text="#{autoRedact.submitButton}"></button>
</form>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>

View File

@@ -31,7 +31,9 @@
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon security">playlist_remove</span>
<svg class="material-symbols-rounded tool-header-icon security">
<use xlink:href="/images/redact-manual.svg#icon-redact-manual"></use>
</svg>
<span class="tool-header-text" th:text="#{redact.header}"></span>
</div>
<form th:action="@{'api/v1/security/redact'}" method="post" enctype="multipart/form-data">

View File

@@ -1,41 +1,52 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{split-by-size-or-count.title}, header=#{split-by-size-or-count.header})}"></th:block>
</head>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
xmlns:th="https://www.thymeleaf.org">
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon advance">vertical_split</span>
<span class="tool-header-text" th:text="#{split-by-size-or-count.header}"></span>
</div>
<form method="post" enctype="multipart/form-data" th:action="@{'/api/v1/general/split-by-size-or-count'}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
<label for="splitType" th:text="#{split-by-size-or-count.type.label}">Split Type</label>
<select id="splitType" name="splitType" class="form-control">
<option value="0" th:text="#{split-by-size-or-count.type.size}">Size</option>
<option value="1" th:text="#{split-by-size-or-count.type.pageCount}">Page Count</option>
<option value="2" th:text="#{split-by-size-or-count.type.docCount}">Document Count</option>
</select>
<br>
<label for="splitValue" th:text="#{split-by-size-or-count.value.label}">Split Value</label>
<input type="text" id="splitValue" name="splitValue" class="form-control" required th:placeholder="#{split-by-size-or-count.value.placeholder}">
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{split-by-size-or-count.submit}">Submit</button>
</form>
<head>
<th:block
th:insert="~{fragments/common :: head(title=#{split-by-size-or-count.title}, header=#{split-by-size-or-count.header})}">
</th:block>
</head>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<svg class="material-symbols-rounded tool-header-icon advance">
<use xlink:href="/images/split-size.svg#icon-split-size"></use>
</svg>
<span class="tool-header-text" th:text="#{split-by-size-or-count.header}"></span>
</div>
<form method="post" enctype="multipart/form-data" th:action="@{'/api/v1/general/split-by-size-or-count'}">
<div
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}">
</div>
<label for="splitType" th:text="#{split-by-size-or-count.type.label}">Split Type</label>
<select id="splitType" name="splitType" class="form-control">
<option value="0" th:text="#{split-by-size-or-count.type.size}">Size</option>
<option value="1" th:text="#{split-by-size-or-count.type.pageCount}">Page Count</option>
<option value="2" th:text="#{split-by-size-or-count.type.docCount}">Document Count</option>
</select>
<br>
<label for="splitValue" th:text="#{split-by-size-or-count.value.label}">Split Value</label>
<input type="text" id="splitValue" name="splitValue" class="form-control" required
th:placeholder="#{split-by-size-or-count.value.placeholder}">
<br>
<button type="submit" id="submitBtn" class="btn btn-primary"
th:text="#{split-by-size-or-count.submit}">Submit</button>
</form>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>

View File

@@ -1,66 +1,72 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
xmlns:th="https://www.thymeleaf.org">
xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{splitByChapters.title}, header=#{splitByChapters.header})}"></th:block>
<th:block th:insert="~{fragments/common :: head(title=#{splitByChapters.title}, header=#{splitByChapters.header})}">
</th:block>
</head>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon organize">book</span>
<span class="tool-header-text" th:text="#{splitByChapters.header}"></span>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<svg class="material-symbols-rounded tool-header-icon advance">
<use xlink:href="/images/split-chapters.svg#icon-split-chapters"></use>
</svg>
<span class="tool-header-text" th:text="#{splitByChapters.header}"></span>
</div>
<form th:action="@{'/api/v1/general/split-pdf-by-chapters'}" method="post" enctype="multipart/form-data">
<div
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}">
</div>
<div class="mb-3">
<label for="bookmarkLevel" th:text="#{splitByChapters.bookmarkLevel}"></label>
<input type="number" class="form-control" id="bookmarkLevel" name="bookmarkLevel" min="0" value="0"
required>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="includeMetadata" name="includeMetadata">
<label class="form-check-label" for="includeMetadata"
th:text="#{splitByChapters.includeMetadata}"></label>
<input type="hidden" name="includeMetadata" value="false" />
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="allowDuplicates" name="allowDuplicates">
<label class="form-check-label" for="allowDuplicates"
th:text="#{splitByChapters.allowDuplicates}"></label>
<input type="hidden" name="allowDuplicates" value="false" />
</div>
<p>
<a class="btn btn-outline-primary" data-bs-toggle="collapse" href="#info" role="button"
aria-expanded="false" aria-controls="info" th:text="#{info}"></a>
</p>
<div class="collapse" id="info">
<p th:text="#{splitByChapters.desc.1}"></p>
<p th:text="#{splitByChapters.desc.2}"></p>
<p th:text="#{splitByChapters.desc.3}"></p>
<p th:text="#{splitByChapters.desc.4}"></p>
</div>
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{splitByChapters.submit}"></button>
</form>
</div>
<form th:action="@{'/api/v1/general/split-pdf-by-chapters'}" method="post" enctype="multipart/form-data">
<div
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}">
</div>
<div class="mb-3">
<label for="bookmarkLevel" th:text="#{splitByChapters.bookmarkLevel}"></label>
<input type="number" class="form-control" id="bookmarkLevel" name="bookmarkLevel" min="0" value="0" required>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="includeMetadata" name="includeMetadata">
<label class="form-check-label" for="includeMetadata" th:text="#{splitByChapters.includeMetadata}"></label>
<input type="hidden" name="includeMetadata" value="false" />
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="allowDuplicates" name="allowDuplicates">
<label class="form-check-label" for="allowDuplicates" th:text="#{splitByChapters.allowDuplicates}"></label>
<input type="hidden" name="allowDuplicates" value="false" />
</div>
<p>
<a class="btn btn-outline-primary" data-bs-toggle="collapse" href="#info" role="button"
aria-expanded="false" aria-controls="info" th:text="#{info}"></a>
</p>
<div class="collapse" id="info">
<p th:text="#{splitByChapters.desc.1}"></p>
<p th:text="#{splitByChapters.desc.2}"></p>
<p th:text="#{splitByChapters.desc.3}"></p>
<p th:text="#{splitByChapters.desc.4}"></p>
</div>
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{splitByChapters.submit}"></button>
</form>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>