mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-05 08:42:00 +00:00
2385 feature request pdf multi tool to use new file input box (#3201)
# Description of Changes Please provide a summary of the changes, including: - Multitool now makes use of the common file input. - deleted multitool file input - moved tool bar to floating at the bottom of the view window Closes #(2385) --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] 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) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] 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) - [ ] 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) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] 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.
This commit is contained in:
parent
a93e3698f9
commit
75db6c80aa
@ -14,26 +14,30 @@ label {
|
||||
border-radius: 16px !important;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid var(--theme-color-outline-variant);
|
||||
flex-grow: 5;
|
||||
}
|
||||
|
||||
.mt-action-bar {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: start;
|
||||
background-color: var(--md-sys-color-surface-5);
|
||||
border: none;
|
||||
backdrop-filter: blur(2px);
|
||||
top: 10px;
|
||||
z-index: 10;
|
||||
z-index: 11;
|
||||
padding: 1.25rem;
|
||||
border-radius: 2rem;
|
||||
margin: 0px 25px;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
|
||||
.mt-action-bar>* {
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.mt-file-uploader {
|
||||
width:100%
|
||||
}
|
||||
.mt-action-bar svg,
|
||||
.mt-action-btn svg {
|
||||
width: 20px;
|
||||
@ -42,21 +46,29 @@ label {
|
||||
|
||||
.mt-action-bar .mt-filename {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.mt-action-btn {
|
||||
position: sticky;
|
||||
bottom: 10%;
|
||||
margin: auto;
|
||||
margin-bottom: 25px;
|
||||
border-radius: 2rem;
|
||||
z-index: 12;
|
||||
background-color: var(--md-sys-color-surface-container-low) ;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: start;
|
||||
top: 10px;
|
||||
z-index: 10;
|
||||
padding: 12px 0px 0px;
|
||||
width: 100%;
|
||||
width: fit-content;
|
||||
justify-content: center;
|
||||
padding: 10px 20px
|
||||
}
|
||||
|
||||
.mt-action-btn .btn {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
width: 3.5rem;
|
||||
height: 3.5rem;
|
||||
border-radius: 20px;
|
||||
padding: 0;
|
||||
}
|
||||
@ -64,7 +76,7 @@ label {
|
||||
.bg-card {
|
||||
background-color: var(--md-sys-color-surface-5);
|
||||
border-radius: 3rem;
|
||||
padding: 25px 0 0;
|
||||
padding: 25px 0;
|
||||
}
|
||||
|
||||
#pages-container-wrapper {
|
||||
@ -73,7 +85,7 @@ label {
|
||||
flex-direction: column;
|
||||
padding: 1rem;
|
||||
border-radius: 25px;
|
||||
overflow-y: auto;
|
||||
overflow-y: clip;
|
||||
overflow-x: auto;
|
||||
min-height: 275px;
|
||||
margin: 0 0 30px 0;
|
||||
@ -136,10 +148,6 @@ label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Pushes the last item to the left */
|
||||
.page-container:last-child {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.page-container:last-child:lang(ar),
|
||||
/* Arabic */
|
||||
|
@ -34,8 +34,10 @@ function setupFileInput(chooser) {
|
||||
const filesSelected = chooser.getAttribute('data-bs-files-selected');
|
||||
const pdfPrompt = chooser.getAttribute('data-bs-pdf-prompt');
|
||||
const inputContainerId = chooser.getAttribute('data-bs-element-container-id');
|
||||
const showUploads = chooser.getAttribute('data-bs-show-uploads') === "true";
|
||||
|
||||
let inputContainer = document.getElementById(inputContainerId);
|
||||
const input = document.getElementById(elementId);
|
||||
|
||||
if (inputContainer.id === 'pdf-upload-input-container') {
|
||||
inputContainer.querySelector('#dragAndDrop').innerHTML = window.fileInput.dragAndDropPDF;
|
||||
@ -46,6 +48,11 @@ function setupFileInput(chooser) {
|
||||
let overlay;
|
||||
let dragCounter = 0;
|
||||
|
||||
input.addEventListener('reset', (e) => {
|
||||
allFiles = [];
|
||||
input.value = null;
|
||||
});
|
||||
|
||||
inputContainer.addEventListener('click', (e) => {
|
||||
let inputBtn = document.getElementById(elementId);
|
||||
inputBtn.click();
|
||||
@ -353,7 +360,7 @@ function setupFileInput(chooser) {
|
||||
}
|
||||
|
||||
function showOrHideSelectedFilesContainer(files) {
|
||||
if (files && files.length > 0) {
|
||||
if (showUploads && files && files.length > 0) {
|
||||
chooser.style.setProperty('--selected-files-display', 'flex');
|
||||
} else {
|
||||
chooser.style.setProperty('--selected-files-display', 'none');
|
||||
|
@ -72,6 +72,7 @@ class PdfContainer {
|
||||
window.addFilesBlankAll = this.addFilesBlankAll;
|
||||
window.removeAllElements = this.removeAllElements;
|
||||
window.resetPages = this.resetPages;
|
||||
window.selectAll = false;
|
||||
|
||||
let undoBtn = document.getElementById('undo-btn');
|
||||
let redoBtn = document.getElementById('redo-btn');
|
||||
@ -129,6 +130,10 @@ class PdfContainer {
|
||||
return commandSequence;
|
||||
}
|
||||
|
||||
showButton(button, show) {
|
||||
button.classList.toggle('hidden', !show);
|
||||
}
|
||||
|
||||
movePageTo(startElements, endElement, scrollTo = false) {
|
||||
|
||||
if (Array.isArray(startElements)){
|
||||
@ -176,8 +181,10 @@ class PdfContainer {
|
||||
if (files.length > 0) {
|
||||
pages = await this.addFilesFromFiles(files, nextSiblingElement, pages);
|
||||
this.updateFilename(files[0].name);
|
||||
const selectAll = document.getElementById('select-pages-container');
|
||||
selectAll.classList.toggle('hidden', false);
|
||||
|
||||
if(window.selectPage){
|
||||
this.showButton(document.getElementById('select-pages-container'), true);
|
||||
}
|
||||
}
|
||||
resolve(pages);
|
||||
};
|
||||
@ -191,9 +198,8 @@ class PdfContainer {
|
||||
const pages = await this.addFilesFromFiles(files, nextSiblingElement, []);
|
||||
this.updateFilename(files[0]?.name || 'untitled');
|
||||
|
||||
const selectAll = document.getElementById('select-pages-container');
|
||||
if (selectAll) {
|
||||
selectAll.classList.remove('hidden');
|
||||
if(window.selectPage) {
|
||||
this.showButton(document.getElementById('select-pages-container'), true);
|
||||
}
|
||||
|
||||
return pages;
|
||||
@ -433,12 +439,12 @@ class PdfContainer {
|
||||
const selectIcon = document.getElementById('select-All-Container');
|
||||
const deselectIcon = document.getElementById('deselect-All-Container');
|
||||
|
||||
if (selectIcon.style.display === 'none') {
|
||||
selectIcon.style.display = 'inline';
|
||||
deselectIcon.style.display = 'none';
|
||||
if (!window.selectAll) {
|
||||
this.showButton(selectIcon, true);
|
||||
this.showButton(deselectIcon, false);
|
||||
} else {
|
||||
selectIcon.style.display = 'none';
|
||||
deselectIcon.style.display = 'inline';
|
||||
this.showButton(selectIcon, false);
|
||||
this.showButton(deselectIcon, true);
|
||||
}
|
||||
checkboxes.forEach((checkbox) => {
|
||||
checkbox.checked = window.selectAll;
|
||||
@ -846,8 +852,20 @@ class PdfContainer {
|
||||
deleteButton.classList.toggle('hidden', !window.selectPage);
|
||||
const selectedPages = document.getElementById('selected-pages-display');
|
||||
selectedPages.classList.toggle('hidden', !window.selectPage);
|
||||
const selectAll = document.getElementById('select-All-Container');
|
||||
selectAll.classList.toggle('hidden', !window.selectPage);
|
||||
if(!window.selectPage)
|
||||
{
|
||||
this.showButton(document.getElementById('deselect-All-Container'), false);
|
||||
this.showButton(document.getElementById('select-All-Container'), false);
|
||||
}
|
||||
else if(window.selectAll){
|
||||
this.showButton(document.getElementById('deselect-All-Container'), true);
|
||||
this.showButton(document.getElementById('select-All-Container'), false);
|
||||
}
|
||||
else{
|
||||
this.showButton(document.getElementById('deselect-All-Container'), false);
|
||||
this.showButton(document.getElementById('select-All-Container'), true);
|
||||
}
|
||||
|
||||
const exportSelected = document.getElementById('export-selected-button');
|
||||
exportSelected.classList.toggle('hidden', !window.selectPage);
|
||||
const selectPagesButton = document.getElementById('select-pages-button');
|
||||
|
@ -1,114 +0,0 @@
|
||||
class FileDragManager {
|
||||
overlay;
|
||||
dragCounter;
|
||||
updateFilename;
|
||||
|
||||
constructor(cb = null) {
|
||||
this.dragCounter = 0;
|
||||
this.setCallback(cb);
|
||||
|
||||
// Prevent default behavior for drag events
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
|
||||
document.body.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
this.dragenterListener = this.dragenterListener.bind(this);
|
||||
this.dragleaveListener = this.dragleaveListener.bind(this);
|
||||
this.dropListener = this.dropListener.bind(this);
|
||||
|
||||
document.body.addEventListener('dragenter', this.dragenterListener);
|
||||
document.body.addEventListener('dragleave', this.dragleaveListener);
|
||||
// Add drop event listener
|
||||
document.body.addEventListener('drop', this.dropListener);
|
||||
}
|
||||
|
||||
setActions({updateFilename}) {
|
||||
this.updateFilename = updateFilename;
|
||||
}
|
||||
|
||||
setCallback(cb) {
|
||||
if (cb) {
|
||||
this.callback = cb;
|
||||
} else {
|
||||
this.callback = (files) => console.warn('FileDragManager not set');
|
||||
}
|
||||
}
|
||||
|
||||
dragenterListener() {
|
||||
this.dragCounter++;
|
||||
if (!this.overlay) {
|
||||
// Create and show the overlay
|
||||
this.overlay = document.createElement('div');
|
||||
this.overlay.style.position = 'fixed';
|
||||
this.overlay.style.top = 0;
|
||||
this.overlay.style.left = 0;
|
||||
this.overlay.style.width = '100%';
|
||||
this.overlay.style.height = '100%';
|
||||
this.overlay.style.background = 'rgba(0, 0, 0, 0.5)';
|
||||
this.overlay.style.color = '#fff';
|
||||
this.overlay.style.zIndex = '1000';
|
||||
this.overlay.style.display = 'flex';
|
||||
this.overlay.style.alignItems = 'center';
|
||||
this.overlay.style.justifyContent = 'center';
|
||||
this.overlay.style.pointerEvents = 'none';
|
||||
this.overlay.innerHTML = '<p>Drop files anywhere to upload</p>';
|
||||
document.getElementById('content-wrap').appendChild(this.overlay);
|
||||
}
|
||||
}
|
||||
|
||||
dragleaveListener() {
|
||||
this.dragCounter--;
|
||||
if (this.dragCounter === 0) {
|
||||
// Hide and remove the overlay
|
||||
if (this.overlay) {
|
||||
this.overlay.remove();
|
||||
this.overlay = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dropListener(e) {
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
this.callback(files)
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
//maybe
|
||||
})
|
||||
.finally(() => {
|
||||
// Hide and remove the overlay
|
||||
if (this.overlay) {
|
||||
this.overlay.remove();
|
||||
this.overlay = null;
|
||||
}
|
||||
|
||||
this.updateFilename(files ? files[0].name : '');
|
||||
});
|
||||
}
|
||||
|
||||
async addImageFile(file, nextSiblingElement) {
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('page-container');
|
||||
|
||||
var img = document.createElement('img');
|
||||
img.classList.add('page-image');
|
||||
img.src = URL.createObjectURL(file);
|
||||
div.appendChild(img);
|
||||
|
||||
this.pdfAdapters.forEach((adapter) => {
|
||||
adapter.adapt?.(div);
|
||||
});
|
||||
if (nextSiblingElement) {
|
||||
this.pagesContainer.insertBefore(div, nextSiblingElement);
|
||||
} else {
|
||||
this.pagesContainer.appendChild(div);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default FileDragManager;
|
@ -196,7 +196,7 @@
|
||||
</th:block>
|
||||
|
||||
<th:block th:fragment="fileSelector(name, multipleInputsForSingleRequest)"
|
||||
th:with="accept=${accept} ?: '*/*', inputText=${inputText} ?: #{pdfPrompt}, remoteCall=${remoteCall} ?: true, disableMultipleFiles=${disableMultipleFiles} ?: false, notRequired=${notRequired} ?: false">
|
||||
th:with="accept=${accept} ?: '*/*', inputText=${inputText} ?: #{pdfPrompt}, remoteCall=${remoteCall} ?: true, disableMultipleFiles=${disableMultipleFiles} ?: false, showUploads=${showUploads} ?: true, notRequired=${notRequired} ?: false">
|
||||
<script th:inline="javascript">
|
||||
(function () {
|
||||
window.stirlingPDF.pdfPasswordPrompt = /*[[#{error.pdfPassword}]]*/ '';
|
||||
@ -227,7 +227,7 @@
|
||||
extractPDF: '[[#{fileChooser.extractPDF}]]'
|
||||
};</script>
|
||||
<div class="custom-file-chooser mb-3"
|
||||
th:attr="data-bs-unique-id=${name}, data-bs-element-id=${name+'-input'}, data-bs-element-container-id=${name+'-input-container'}, data-bs-files-selected=#{filesSelected}, data-bs-pdf-prompt=#{pdfPrompt}">
|
||||
th:attr="data-bs-unique-id=${name}, data-bs-element-id=${name+'-input'}, data-bs-element-container-id=${name+'-input-container'}, data-bs-show-uploads=${showUploads}, data-bs-files-selected=#{filesSelected}, data-bs-pdf-prompt=#{pdfPrompt}">
|
||||
<div class="mb-3 d-flex flex-row justify-content-center align-items-center flex-wrap input-container"
|
||||
th:name="${name}+'-input'" th:id="${name}+'-input-container'" th:data-text="#{fileChooser.hoveredDragAndDrop}">
|
||||
<label class="file-input-btn d-none">
|
||||
|
@ -14,117 +14,113 @@
|
||||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">construction</span>
|
||||
<span class="tool-header-text" th:text="#{multiTool.header}"></span>
|
||||
</div>
|
||||
<div class="mt-action-bar d-flex flex-wrap">
|
||||
<div class="mt-filename">
|
||||
<label for="filename-input" th:text="#{multiTool.uploadPrompts}">Filename</label>
|
||||
<input type="text" class="form-control" id="filename-input"
|
||||
th:placeholder="#{multiTool.uploadPrompts}">
|
||||
</div>
|
||||
<div class="mt-action-btn">
|
||||
<button class="btn btn-primary" th:title="#{multiTool.addFile}" onclick="addFiles()">
|
||||
<span class="material-symbols-rounded">
|
||||
add
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.rotateLeft}"
|
||||
onclick="rotateAll(-90)" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
rotate_left
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.rotateRight}"
|
||||
onclick="rotateAll(90)" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
rotate_right
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.split}" onclick="splitAll()"
|
||||
disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
cut
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.insertPageBreak}"
|
||||
onclick="addFilesBlankAll()" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
insert_page_break
|
||||
</span>
|
||||
</button>
|
||||
<button id="undo-btn" th:title="#{multiTool.undo}" class="btn btn-secondary" onclick="undo()"
|
||||
disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
undo
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button id="redo-btn" class="btn btn-secondary" th:title="#{multiTool.redo}" onclick="redo()"
|
||||
disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
redo
|
||||
</span>
|
||||
</button>
|
||||
</button>
|
||||
|
||||
<button id="select-pages-container" th:title="#{multiTool.selectPages}"
|
||||
class="btn btn-secondary enable-on-file" onclick="toggleSelectPageVisibility()" disabled>
|
||||
<span id="select-pages-button" class="material-symbols-rounded">
|
||||
event_list
|
||||
</span>
|
||||
</button>
|
||||
<button id="deselect-All-Container" th:title="#{multiTool.deselectAll}"
|
||||
class="btn btn-secondary enable-on-file hidden" onclick="toggleSelectAll()" disabled>
|
||||
<span class="material-symbols-rounded" id="deselect-icon">deselect</span>
|
||||
</button>
|
||||
<button id="select-All-Container" th:title="#{multiTool.selectAll}"
|
||||
class="btn btn-secondary enable-on-file hidden" onclick="toggleSelectAll()" disabled>
|
||||
<span class="material-symbols-rounded" id="select-icon">select_all</span>
|
||||
</button>
|
||||
<div class="button-container">
|
||||
<button id="delete-button" th:title="#{multiTool.deleteSelected}"
|
||||
class="btn btn-danger delete hidden" onclick="deleteSelected()">
|
||||
<span class="material-symbols-rounded">delete</span>
|
||||
</button>
|
||||
</div>
|
||||
<div style="margin-left:auto">
|
||||
<button id="export-selected-button" th:title="#{multiTool.downloadSelected}"
|
||||
style="border-color: green; color:#b2e3a8; background: rgba(24, 122, 5, 1)"
|
||||
class="btn btn-primary enable-on-file hidden" onclick="exportPdf(true)" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
file_save
|
||||
</span>
|
||||
</button>
|
||||
<button style="border-color: green; color:#b2e3a8; background: rgba(24, 122, 5, 1)"
|
||||
th:title="#{multiTool.downloadAll}" id="export-button" class="btn btn-primary enable-on-file"
|
||||
onclick="exportPdf(false)" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
download
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="selected-pages-display" class="selected-pages-container hidden">
|
||||
<div style="display:flex; height:3rem; margin-right:1rem">
|
||||
<h5 th:text="#{multiTool.selectedPages}" style="white-space: nowrap; margin-right: 1rem;">Selected
|
||||
Pages</h5>
|
||||
<input type="text" id="csv-input" class="form-control" style="height:2.5rem" placeholder="1,3,5-10"
|
||||
value="">
|
||||
</div>
|
||||
<ul id="selected-pages-list" class="pages-list"></ul>
|
||||
<div class="mt-action-bar d-flex flex-wrap">
|
||||
<div class="mt-filename">
|
||||
<input type="text" class="form-control" id="filename-input"
|
||||
th:placeholder="#{multiTool.uploadPrompts}">
|
||||
</div>
|
||||
<div class="mt-file-uploader">
|
||||
<div
|
||||
th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multipleInputsForSingleRequest=false, accept='image/*, application/pdf', showUploads=false)}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="selected-pages-display" class="selected-pages-container hidden">
|
||||
<div style="display:flex; height:3rem; margin-right:1rem">
|
||||
<h5 th:text="#{multiTool.selectedPages}" style="white-space: nowrap; margin-right: 1rem;">Selected
|
||||
Pages</h5>
|
||||
<input type="text" id="csv-input" class="form-control" style="height:2.5rem" placeholder="1,3,5-10"
|
||||
value="">
|
||||
</div>
|
||||
<ul id="selected-pages-list" class="pages-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="multi-tool-container">
|
||||
<div class="d-flex flex-wrap" id="pages-container-wrapper">
|
||||
<div id="pages-container">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-action-btn">
|
||||
<button id="undo-btn" th:title="#{multiTool.undo}" class="btn btn-secondary" onclick="undo()"
|
||||
disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
undo
|
||||
</span>
|
||||
</button>
|
||||
<button id="redo-btn" class="btn btn-secondary" th:title="#{multiTool.redo}" onclick="redo()"
|
||||
disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
redo
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.rotateLeft}"
|
||||
onclick="rotateAll(-90)" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
rotate_left
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.rotateRight}"
|
||||
onclick="rotateAll(90)" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
rotate_right
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.split}" onclick="splitAll()"
|
||||
disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
cut
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.insertPageBreak}"
|
||||
onclick="addFilesBlankAll()" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
insert_page_break
|
||||
</span>
|
||||
</button>
|
||||
<button id="select-pages-container" th:title="#{multiTool.selectPages}"
|
||||
class="btn btn-secondary enable-on-file" onclick="toggleSelectPageVisibility()" disabled>
|
||||
<span id="select-pages-button" class="material-symbols-rounded">
|
||||
event_list
|
||||
</span>
|
||||
</button>
|
||||
<button id="deselect-All-Container" th:title="#{multiTool.deselectAll}"
|
||||
class="btn btn-secondary enable-on-file hidden" onclick="toggleSelectAll()" disabled>
|
||||
<span class="material-symbols-rounded" id="deselect-icon">deselect</span>
|
||||
</button>
|
||||
<button id="select-All-Container" th:title="#{multiTool.selectAll}"
|
||||
class="btn btn-secondary enable-on-file hidden" onclick="toggleSelectAll()" disabled>
|
||||
<span class="material-symbols-rounded" id="select-icon">select_all</span>
|
||||
</button>
|
||||
<button id="delete-button" th:title="#{multiTool.deleteSelected}"
|
||||
class="btn btn-danger delete hidden" onclick="deleteSelected()">
|
||||
<span class="material-symbols-rounded">delete</span>
|
||||
</button>
|
||||
<button id="export-selected-button" th:title="#{multiTool.downloadSelected}"
|
||||
style="border-color: green; color:#b2e3a8; background: rgba(24, 122, 5, 1)"
|
||||
class="btn btn-primary enable-on-file hidden" onclick="exportPdf(true)" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
file_save
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button style="border-color: green; color:#b2e3a8; background: rgba(24, 122, 5, 1)"
|
||||
th:title="#{multiTool.downloadAll}" id="export-button" class="btn btn-primary enable-on-file"
|
||||
onclick="exportPdf(false)" disabled>
|
||||
<span class="material-symbols-rounded">
|
||||
download
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -180,8 +176,14 @@
|
||||
import DragDropManager from "./js/multitool/DragDropManager.js";
|
||||
import ImageHighlighter from "./js/multitool/ImageHighlighter.js";
|
||||
import PdfActionsManager from './js/multitool/PdfActionsManager.js';
|
||||
import FileDragManager from './js/multitool/fileInput.js';
|
||||
// enables drag and drop
|
||||
|
||||
const pdfUpload = document.querySelector("input[name=pdf-upload]");
|
||||
pdfUpload.addEventListener("change", async (e) => {
|
||||
if (!e.target.files) return;
|
||||
await pdfContainer.handleDroppedFiles( e.target.files);
|
||||
e.target.dispatchEvent(new CustomEvent('reset', {}));
|
||||
});
|
||||
|
||||
var undoManager = new UndoManager();
|
||||
const dragDropManager = new DragDropManager('drag-container', 'pages-container');
|
||||
@ -189,7 +191,6 @@
|
||||
const imageHighlighter = new ImageHighlighter('image-highlighter');
|
||||
// enables the default action buttons on each file
|
||||
const pdfActionsManager = new PdfActionsManager('pages-container', undoManager);
|
||||
const fileDragManager = new FileDragManager();
|
||||
// Scroll the wrapper horizontally
|
||||
|
||||
// Automatically exposes rotateAll, addFiles and exportPdf to the window for the global buttons.
|
||||
@ -199,13 +200,11 @@
|
||||
[
|
||||
dragDropManager,
|
||||
imageHighlighter,
|
||||
pdfActionsManager,
|
||||
fileDragManager
|
||||
pdfActionsManager
|
||||
],
|
||||
undoManager
|
||||
)
|
||||
|
||||
fileDragManager.setCallback(async (files) => pdfContainer.handleDroppedFiles(files));
|
||||
document.addEventListener('keydown', function (event) {
|
||||
let targetElementId = event.target.id;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user