Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

967 lines
32 KiB
JavaScript
Raw Normal View History

import { MovePageCommand } from './commands/move-page.js';
import { RemoveSelectedCommand } from './commands/remove.js';
import { RotateAllCommand, RotateElementCommand } from './commands/rotate.js';
import { SplitAllCommand } from './commands/split.js';
import { UndoManager } from './UndoManager.js';
import { PageBreakCommand } from './commands/page-break.js';
import { AddFilesCommand } from './commands/add-page.js';
import { DecryptFile } from '../DecryptFiles.js';
import { CommandSequence } from './commands/commands-sequence.js';
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
2023-07-22 13:17:24 +01:00
class PdfContainer {
fileName;
pagesContainer;
pagesContainerWrapper;
pdfAdapters;
downloadLink;
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
undoManager;
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
constructor(id, wrapperId, pdfAdapters, undoManager) {
this.pagesContainer = document.getElementById(id);
this.pagesContainerWrapper = document.getElementById(wrapperId);
this.downloadLink = null;
this.movePageTo = this.movePageTo.bind(this);
this.addFiles = this.addFiles.bind(this);
this.addFilesFromFiles = this.addFilesFromFiles.bind(this);
this.rotateElement = this.rotateElement.bind(this);
this.rotateAll = this.rotateAll.bind(this);
this.exportPdf = this.exportPdf.bind(this);
this.updateFilename = this.updateFilename.bind(this);
this.setDownloadAttribute = this.setDownloadAttribute.bind(this);
this.preventIllegalChars = this.preventIllegalChars.bind(this);
this.addImageFile = this.addImageFile.bind(this);
this.nameAndArchiveFiles = this.nameAndArchiveFiles.bind(this);
this.splitPDF = this.splitPDF.bind(this);
this.splitAll = this.splitAll.bind(this);
this.deleteSelected = this.deleteSelected.bind(this);
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
this.selectAll = this.selectAll.bind(this);
this.deselectAll = this.deselectAll.bind(this);
this.updateSelectedPagesDisplay = this.updateSelectedPagesDisplay.bind(this);
this.toggleSelectPageVisibility = this.toggleSelectPageVisibility.bind(this);
this.updatePagesFromCSV = this.updatePagesFromCSV.bind(this);
this.addFilesBlankAll = this.addFilesBlankAll.bind(this);
2024-11-15 13:21:23 -07:00
this.removeAllElements = this.removeAllElements.bind(this);
this.resetPages = this.resetPages.bind(this);
2024-12-06 19:08:18 +00:00
this.decryptFile = new DecryptFile();
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
this.undoManager = undoManager || new UndoManager();
this.pdfAdapters = pdfAdapters;
this.pdfAdapters.forEach((adapter) => {
adapter.setActions({
movePageTo: this.movePageTo,
addFiles: this.addFiles,
rotateElement: this.rotateElement,
updateFilename: this.updateFilename,
deleteSelected: this.deleteSelected,
});
});
window.addFiles = this.addFiles;
window.exportPdf = this.exportPdf;
window.rotateAll = this.rotateAll;
window.splitAll = this.splitAll;
window.deleteSelected = this.deleteSelected;
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
window.selectAll = this.selectAll;
window.deselectAll = this.deselectAll;
window.updateSelectedPagesDisplay = this.updateSelectedPagesDisplay;
window.toggleSelectPageVisibility = this.toggleSelectPageVisibility;
window.updatePagesFromCSV = this.updatePagesFromCSV;
window.updateSelectedPagesDisplay = this.updateSelectedPagesDisplay;
window.updatePageNumbersAndCheckboxes = this.updatePageNumbersAndCheckboxes;
window.addFilesBlankAll = this.addFilesBlankAll;
2024-11-15 13:21:23 -07:00
window.removeAllElements = this.removeAllElements;
window.resetPages = this.resetPages;
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
let undoBtn = document.getElementById('undo-btn');
let redoBtn = document.getElementById('redo-btn');
document.addEventListener('undo-manager-update', (e) => {
let canUndo = e.detail.canUndo;
let canRedo = e.detail.canRedo;
undoBtn.disabled = !canUndo;
redoBtn.disabled = !canRedo;
});
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
window.undo = () => {
if (undoManager.canUndo()) undoManager.undo();
else {
undoBtn.disabled = !undoManager.canUndo();
redoBtn.disabled = !undoManager.canRedo();
}
};
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
window.redo = () => {
if (undoManager.canRedo()) undoManager.redo();
else {
undoBtn.disabled = !undoManager.canUndo();
redoBtn.disabled = !undoManager.canRedo();
}
};
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
const filenameInput = document.getElementById('filename-input');
const downloadBtn = document.getElementById('export-button');
filenameInput.onkeyup = this.updateFilename;
filenameInput.onkeydown = this.preventIllegalChars;
filenameInput.disabled = false;
filenameInput.innerText = '';
downloadBtn.disabled = true;
}
movePagesTo(startElements, endElement, scrollTo = false) {
let commands = [];
startElements.forEach((page) => {
let command = new MovePageCommand(
page,
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
endElement,
this.pagesContainer,
this.pagesContainerWrapper,
scrollTo
)
command.execute();
commands.push(command);
})
let commandSequence = new CommandSequence(commands);
this.undoManager.pushUndoClearRedo(commandSequence);
return commandSequence;
}
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.
2025-03-20 00:06:47 +00:00
showButton(button, show) {
button.classList.toggle('hidden', !show);
}
movePageTo(startElements, endElement, scrollTo = false) {
if (Array.isArray(startElements)){
return this.movePagesTo(startElements, endElement, scrollTo = false);
2023-07-22 13:17:24 +01:00
}
2024-02-11 11:47:00 -05:00
let movePageCommand = new MovePageCommand(
startElements,
endElement,
this.pagesContainer,
this.pagesContainerWrapper,
scrollTo
);
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
movePageCommand.execute();
this.undoManager.pushUndoClearRedo(movePageCommand);
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
return movePageCommand;
}
async addFiles(element) {
let addFilesCommand = new AddFilesCommand(
element,
window.selectedPages,
this.addFilesAction.bind(this),
this.pagesContainer
);
await addFilesCommand.execute();
this.undoManager.pushUndoClearRedo(addFilesCommand);
window.tooltipSetup();
}
async addFilesAction(nextSiblingElement) {
let pages = [];
return new Promise((resolve) => {
var input = document.createElement('input');
input.type = 'file';
input.multiple = true;
input.setAttribute('accept', 'application/pdf,image/*');
input.onchange = async (e) => {
const files = e.target.files;
if (files.length > 0) {
pages = await this.addFilesFromFiles(files, nextSiblingElement, pages);
this.updateFilename(files[0].name);
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.
2025-03-20 00:06:47 +00:00
if(window.selectPage){
this.showButton(document.getElementById('select-pages-container'), true);
}
}
resolve(pages);
};
input.click();
});
}
async handleDroppedFiles(files, nextSiblingElement = null) {
if (files.length > 0) {
const pages = await this.addFilesFromFiles(files, nextSiblingElement, []);
this.updateFilename(files[0]?.name || 'untitled');
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.
2025-03-20 00:06:47 +00:00
if(window.selectPage) {
this.showButton(document.getElementById('select-pages-container'), true);
}
return pages;
}
}
async addFilesFromFiles(files, nextSiblingElement, pages) {
this.fileName = files[0].name;
for (var i = 0; i < files.length; i++) {
const startTime = Date.now();
let processingTime,
errorMessage = null,
pageCount = 0;
2024-12-06 19:08:18 +00:00
try {
2024-12-06 19:08:18 +00:00
let decryptedFile = files[i];
let isEncrypted = false;
let requiresPassword = false;
await this.decryptFile
.checkFileEncrypted(decryptedFile)
.then((result) => {
isEncrypted = result.isEncrypted;
requiresPassword = result.requiresPassword;
})
.catch((error) => {
console.error(error);
});
if (decryptedFile.type === 'application/pdf' && isEncrypted) {
decryptedFile = await this.decryptFile.decryptFile(decryptedFile, requiresPassword);
2024-12-06 19:08:18 +00:00
if (!decryptedFile) {
throw new Error('File decryption failed.');
}
}
if (decryptedFile.type === 'application/pdf') {
const { renderer, pdfDocument } = await this.loadFile(decryptedFile);
pageCount = renderer.pageCount || 0;
pages = await this.addPdfFile(renderer, pdfDocument, nextSiblingElement, pages);
2024-12-06 19:08:18 +00:00
} else if (decryptedFile.type.startsWith('image/')) {
pages = await this.addImageFile(decryptedFile, nextSiblingElement, pages);
}
2024-12-06 19:08:18 +00:00
processingTime = Date.now() - startTime;
2024-12-06 19:08:18 +00:00
this.captureFileProcessingEvent(true, decryptedFile, processingTime, null, pageCount);
} catch (error) {
processingTime = Date.now() - startTime;
errorMessage = error.message || 'Unknown error';
this.captureFileProcessingEvent(false, files[i], processingTime, errorMessage, pageCount);
}
}
2024-02-11 11:47:00 -05:00
document.querySelectorAll('.enable-on-file').forEach((element) => {
element.disabled = false;
});
2024-12-06 19:08:18 +00:00
return pages;
}
captureFileProcessingEvent(success, file, processingTime, errorMessage, pageCount) {
try {
if (analyticsEnabled) {
posthog.capture('file_processing', {
success,
file_type: file?.type || 'unknown',
file_size: file?.size || 0,
processing_time: processingTime,
error_message: errorMessage,
pdf_pages: pageCount,
});
}
} catch { }
}
2024-02-11 11:47:00 -05:00
async addFilesBlank(nextSiblingElement, pages) {
let doc = await PDFLib.PDFDocument.create();
let docBytes = await doc.save();
const url = URL.createObjectURL(new Blob([docBytes], { type: 'application/pdf' }));
const renderer = await this.toRenderer(url);
pages = await this.addPdfFile(renderer, doc, nextSiblingElement, pages);
return pages;
}
rotateElement(element, deg) {
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
let rotateCommand = new RotateElementCommand(element, deg);
rotateCommand.execute();
2024-10-14 22:34:41 +01:00
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
return rotateCommand;
}
async addPdfFile(renderer, pdfDocument, nextSiblingElement, pages) {
for (var i = 0; i < renderer.pageCount; i++) {
const div = document.createElement('div');
div.classList.add('page-container');
div.id = 'page-container-' + (i + 1);
var img = document.createElement('img');
img.classList.add('page-image');
const imageSrc = await renderer.renderPage(i);
img.src = imageSrc;
img.pageIdx = i;
img.rend = renderer;
img.doc = pdfDocument;
div.appendChild(img);
this.pdfAdapters.forEach((adapter) => {
adapter.adapt?.(div);
});
if (nextSiblingElement) {
this.pagesContainer.insertBefore(div, nextSiblingElement);
} else {
this.pagesContainer.appendChild(div);
}
pages.push(div);
2023-07-22 13:17:24 +01:00
}
return pages;
}
async addImageFile(file, nextSiblingElement, pages) {
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);
}
pages.push(div);
return pages;
}
async loadFile(file) {
var objectUrl = URL.createObjectURL(file);
var pdfDocument = await this.toPdfLib(objectUrl);
var renderer = await this.toRenderer(objectUrl);
return { renderer, pdfDocument };
}
async toRenderer(objectUrl) {
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
const pdf = await pdfjsLib.getDocument(objectUrl).promise;
return {
document: pdf,
pageCount: pdf.numPages,
renderPage: async function (pageIdx) {
const page = await this.document.getPage(pageIdx + 1);
const canvas = document.createElement('canvas');
// set the canvas size to the size of the page
if (page.rotate == 90 || page.rotate == 270) {
canvas.width = page.view[3];
canvas.height = page.view[2];
} else {
canvas.width = page.view[2];
canvas.height = page.view[3];
2023-07-22 13:17:24 +01:00
}
2024-02-11 11:47:00 -05:00
// render the page onto the canvas
var renderContext = {
canvasContext: canvas.getContext('2d'),
viewport: page.getViewport({ scale: 1 }),
2023-07-22 13:17:24 +01:00
};
2024-02-11 11:47:00 -05:00
await page.render(renderContext).promise;
return canvas.toDataURL();
},
};
}
async toPdfLib(objectUrl) {
const existingPdfBytes = await fetch(objectUrl).then((res) => res.arrayBuffer());
const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes, {
ignoreEncryption: true,
});
return pdfDoc;
}
rotateAll(deg) {
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
let elementsToRotate = [];
for (let i = 0; i < this.pagesContainer.childNodes.length; i++) {
const child = this.pagesContainer.children[i];
if (!child) continue;
const pageIndex = i + 1;
//if in page select mode is active rotate only selected pages
if (window.selectPage && !window.selectedPages.includes(pageIndex)) continue;
const img = child.querySelector('img');
if (!img) continue;
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
elementsToRotate.push(img);
2023-07-22 13:17:24 +01:00
}
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
let rotateAllCommand = new RotateAllCommand(elementsToRotate, deg);
rotateAllCommand.execute();
this.undoManager.pushUndoClearRedo(rotateAllCommand);
}
removeAllElements() {
let pageContainerNodeList = document.querySelectorAll('.page-container');
2024-11-15 13:21:23 -07:00
for (var i = 0; i < pageContainerNodeList.length; i++) {
pageContainerNodeList[i].remove();
}
document.querySelectorAll('.enable-on-file').forEach((element) => {
2024-11-15 13:21:23 -07:00
element.disabled = true;
});
}
deleteSelected() {
window.selectedPages.sort((a, b) => a - b);
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
let removeSelectedCommand = new RemoveSelectedCommand(
this.pagesContainer,
window.selectedPages,
this.updatePageNumbersAndCheckboxes
);
removeSelectedCommand.execute();
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
this.undoManager.pushUndoClearRedo(removeSelectedCommand);
}
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
selectAll() {
const checkboxes = document.querySelectorAll('.pdf-actions_checkbox');
const selectIcon = document.getElementById('select-All-Container');
const deselectIcon = document.getElementById('deselect-All-Container');
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
this.showButton(selectIcon, false);
this.showButton(deselectIcon, true);
checkboxes.forEach((checkbox) => {
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
checkbox.checked = true;
const pageNumber = Array.from(checkbox.parentNode.parentNode.children).indexOf(checkbox.parentNode) + 1;
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
if (!window.selectedPages.includes(pageNumber)) {
window.selectedPages.push(pageNumber);
}
});
this.updateSelectedPagesDisplay();
}
deselectAll() {
const checkboxes = document.querySelectorAll('.pdf-actions_checkbox');
const selectIcon = document.getElementById('select-All-Container');
const deselectIcon = document.getElementById('deselect-All-Container');
this.showButton(selectIcon, true);
this.showButton(deselectIcon, false);
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
checkboxes.forEach((checkbox) => {
checkbox.checked = false;
const pageNumber = Array.from(checkbox.parentNode.parentNode.children).indexOf(checkbox.parentNode) + 1;
const index = window.selectedPages.indexOf(pageNumber);
if (index !== -1) {
window.selectedPages.splice(index, 1);
}
});
this.updateSelectedPagesDisplay();
}
parseCSVInput(csvInput, maxPageIndex) {
const pages = new Set();
csvInput.split(',').forEach((item) => {
const range = item.split('-').map((p) => parseInt(p.trim()));
if (range.length === 2) {
const [start, end] = range;
for (let i = start; i <= end && i <= maxPageIndex; i++) {
if (i > 0) {
// Ensure the page number is greater than 0
pages.add(i);
}
}
} else if (range.length === 1 && Number.isInteger(range[0])) {
const page = range[0];
if (page > 0 && page <= maxPageIndex) {
// Ensure page is within valid range
pages.add(page);
}
}
});
return Array.from(pages).sort((a, b) => a - b);
}
updatePagesFromCSV() {
const csvInput = document.getElementById('csv-input').value;
const allPages = this.pagesContainer.querySelectorAll('.page-container');
const maxPageIndex = allPages.length;
window.selectedPages = this.parseCSVInput(csvInput, maxPageIndex);
this.updateSelectedPagesDisplay();
const allCheckboxes = document.querySelectorAll('.pdf-actions_checkbox');
allCheckboxes.forEach((checkbox) => {
const page = parseInt(checkbox.getAttribute('data-page-number'));
checkbox.checked = window.selectedPages.includes(page);
});
}
formatSelectedPages(pages) {
if (pages.length === 0) return '';
pages.sort((a, b) => a - b); // Sort the page numbers in ascending order
const ranges = [];
let start = pages[0];
let end = start;
for (let i = 1; i < pages.length; i++) {
if (pages[i] === end + 1) {
// Consecutive page, update end
end = pages[i];
} else {
// Non-consecutive page, finalize current range
ranges.push(start === end ? `${start}` : `${start}-${end}`);
start = pages[i];
end = start;
}
}
// Add the last range
ranges.push(start === end ? `${start}` : `${start}-${end}`);
return ranges.join(', ');
}
updateSelectedPagesDisplay() {
const selectedPagesList = document.getElementById('selected-pages-list');
const selectedPagesInput = document.getElementById('csv-input');
selectedPagesList.innerHTML = ''; // Clear the list
window.selectedPages.sort((a, b) => a - b);
window.selectedPages.forEach((page) => {
const pageItem = document.createElement('div');
pageItem.className = 'page-item';
const pageNumber = document.createElement('span');
const pagelabel = /*[[#{multiTool.page}]]*/ 'Page';
pageNumber.className = 'selected-page-number';
pageNumber.innerText = `${pagelabel} ${page}`;
pageItem.appendChild(pageNumber);
const removeBtn = document.createElement('span');
removeBtn.className = 'remove-btn';
removeBtn.innerHTML = '✕';
// Remove page from selected pages list and update display and checkbox
removeBtn.onclick = () => {
window.selectedPages = window.selectedPages.filter((p) => p !== page);
this.updateSelectedPagesDisplay();
const checkbox = document.getElementById(`selectPageCheckbox-${page}`);
if (checkbox) {
checkbox.checked = false;
}
};
pageItem.appendChild(removeBtn);
selectedPagesList.appendChild(pageItem);
});
// Update the input field with the formatted page list
selectedPagesInput.value = this.formatSelectedPages(window.selectedPages);
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
const selectIcon = document.getElementById('select-All-Container');
const deselectIcon = document.getElementById('deselect-All-Container');
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
if (window.selectPage) { // Check if selectPage mode is active
console.log("Page Select on. Showing buttons");
//Check if no pages are selected
if (window.selectedPages.length === 0) {
this.showButton(selectIcon, true);
this.showButton(deselectIcon, false);
} else {
this.showButton(deselectIcon, true);
}
//Check if all pages are selected
const allCheckboxes = document.querySelectorAll('.pdf-actions_checkbox');
const allSelected = Array.from(allCheckboxes).every((checkbox) => checkbox.checked);
if (allSelected) {
this.showButton(selectIcon, false);
this.showButton(deselectIcon, true);
} else {
this.showButton(selectIcon, true);
}
} else {
console.log("Page Select off. Hidding buttons");
this.showButton(selectIcon, false);
this.showButton(deselectIcon, false);
}
}
parsePageRanges(ranges) {
const pages = new Set();
ranges.split(',').forEach((range) => {
const [start, end] = range.split('-').map(Number);
if (end) {
for (let i = start; i <= end; i++) {
pages.add(i);
}
} else {
pages.add(start);
}
});
return Array.from(pages).sort((a, b) => a - b);
}
async addFilesBlankAll() {
const allPages = this.pagesContainer.querySelectorAll('.page-container');
let pageBreakCommand = new PageBreakCommand(
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
allPages,
window.selectPage,
window.selectedPages,
this.addFilesBlank.bind(this),
this.pagesContainer
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
);
await pageBreakCommand.execute();
this.undoManager.pushUndoClearRedo(pageBreakCommand);
}
splitAll() {
const allPages = this.pagesContainer.querySelectorAll('.page-container');
let splitAllCommand = new SplitAllCommand(allPages, window.selectPage, window.selectedPages, 'split-before');
Feature: Undo Redo options multi tool #2297 (#2348) * Implement Command class for Command Pattern Created a base `Command` class to implement the **Command Pattern**. This class provides a skeletal implementation for `execute`, `undo`, and `redo` methods. **Note:** This class is intended to be subclassed and not instantiated directly. * Add undo/redo stacks and operations * Use rotate element command to perform execute/undo/redo operations * Handle commands executed through events - Add "command-execution" event listener to execute commands that are not invoked from the same class while adding the command to the undo stack and clearing the redo stack. * Add and use rotate all command to rotate/redo/undo all elements * Use command pattern to delete pages * Use command pattern for page selection * Use command pattern to move pages up and down * Use command pattern to remove selected pages * Use command pattern to perform the splitting operation * Add undo/redo functionality with filename input exclusion - Implement undo (Ctrl+Z) and redo (Ctrl+Y) functionality. - Prevent undo/redo actions when the filename input field is focused. - Ensures proper handling of undo/redo actions without interfering with text editing. * Introduce UndoManager for managing undo/redo operations - Encapsulate undo/redo stacks and operations within UndoManager. - Simplify handling of undo/redo functionality through a dedicated manager. * Call execute on splitAllCommand - Fix a bug that caused split all functionality to not work as execute() wasn't called on splitAllCommand * Add undo/redo buttons to multi tool - Add undo/redo buttons to multi tool - Dispatch an event upon state change (such as changes in the undo/redo stacks) to update the UI accordingly. * Add undo/redo to translations * Replace hard-coded "Undo"/"Redo" with translation keys in multi tool --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-28 16:25:13 +02:00
splitAllCommand.execute();
this.undoManager.pushUndoClearRedo(splitAllCommand);
}
async splitPDF(baseDocBytes, splitters) {
const baseDocument = await PDFLib.PDFDocument.load(baseDocBytes);
const pageNum = baseDocument.getPages().length;
splitters.sort((a, b) => a - b); // We'll sort the separator indexes just in case querySelectorAll does something funny.
splitters.push(pageNum); // We'll also add a faux separator at the end in order to get the pages after the last separator.
const splitDocuments = [];
for (const splitterPosition of splitters) {
const subDocument = await PDFLib.PDFDocument.create();
const splitterIndex = splitters.indexOf(splitterPosition);
let firstPage = splitterIndex === 0 ? 0 : splitters[splitterIndex - 1];
const pageIndices = Array.from({ length: splitterPosition - firstPage }, (value, key) => firstPage + key);
const copiedPages = await subDocument.copyPages(baseDocument, pageIndices);
copiedPages.forEach((copiedPage) => {
subDocument.addPage(copiedPage);
});
const subDocumentBytes = await subDocument.save();
splitDocuments.push(subDocumentBytes);
}
return splitDocuments;
}
async nameAndArchiveFiles(pdfBytesArray, baseNameString) {
const zip = new JSZip();
for (let i = 0; i < pdfBytesArray.length; i++) {
const documentBlob = new Blob([pdfBytesArray[i]], {
type: 'application/pdf',
});
zip.file(baseNameString + '-' + (i + 1) + '.pdf', documentBlob);
}
return zip;
}
async exportPdf(selected) {
const pdfDoc = await PDFLib.PDFDocument.create();
const pageContainers = this.pagesContainer.querySelectorAll('.page-container'); // Select all .page-container elements
for (var i = 0; i < pageContainers.length; i++) {
if (!selected || window.selectedPages.includes(i + 1)) {
const img = pageContainers[i].querySelector('img'); // Find the img element within each .page-container
if (!img) continue;
let page;
if (img.doc) {
const pages = await pdfDoc.copyPages(img.doc, [img.pageIdx]);
page = pages[0];
pdfDoc.addPage(page);
} else {
page = pdfDoc.addPage([img.naturalWidth, img.naturalHeight]);
const imageBytes = await fetch(img.src).then((res) => res.arrayBuffer());
const uint8Array = new Uint8Array(imageBytes);
const imageType = detectImageType(uint8Array);
let image;
switch (imageType) {
case 'PNG':
image = await pdfDoc.embedPng(imageBytes);
break;
case 'JPEG':
image = await pdfDoc.embedJpg(imageBytes);
break;
case 'TIFF':
image = await pdfDoc.embedTiff(imageBytes);
break;
case 'GIF':
console.warn(`Unsupported image type: ${imageType}`);
continue; // Skip this image
default:
console.warn(`Unsupported image type: ${imageType}`);
continue; // Skip this image
}
page.drawImage(image, {
x: 0,
y: 0,
width: img.naturalWidth,
height: img.naturalHeight,
});
}
const rotation = img.style.rotate;
if (rotation) {
const rotationAngle = parseInt(rotation.replace(/[^\d-]/g, ''));
page.setRotation(PDFLib.degrees(page.getRotation().angle + rotationAngle));
}
}
2023-07-22 13:17:24 +01:00
}
2024-10-14 22:34:41 +01:00
pdfDoc.setCreator(stirlingPDFLabel);
pdfDoc.setProducer(stirlingPDFLabel);
const pdfBytes = await pdfDoc.save();
const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' });
2024-02-11 11:47:00 -05:00
const filenameInput = document.getElementById('filename-input');
2024-02-11 11:47:00 -05:00
let inputArr = filenameInput.value.split('.');
2024-02-11 11:47:00 -05:00
if (inputArr !== null && inputArr !== undefined && inputArr.length > 0) {
inputArr = inputArr.filter((n) => n); // remove all empty strings, nulls or undefined
2024-02-11 11:47:00 -05:00
if (inputArr.length > 1) {
inputArr.pop(); // remove right part after last dot
}
2024-02-11 11:47:00 -05:00
filenameInput.value = inputArr.join('');
this.fileName = filenameInput.value;
}
2024-02-11 11:47:00 -05:00
const separators = this.pagesContainer.querySelectorAll('.split-before');
if (separators.length !== 0) {
// Split the pdf if there are separators.
const baseName = this.fileName ? this.fileName : 'managed';
2024-02-11 11:47:00 -05:00
const pagesArray = Array.from(this.pagesContainer.children);
const splitters = [];
separators.forEach((page) => {
const pageIndex = pagesArray.indexOf(page);
if (pageIndex !== 0) {
splitters.push(pageIndex);
}
});
const splitDocuments = await this.splitPDF(pdfBytes, splitters);
const archivedDocuments = await this.nameAndArchiveFiles(splitDocuments, baseName);
const self = this;
archivedDocuments.generateAsync({ type: 'base64' }).then(function (base64) {
const url = 'data:application/zip;base64,' + base64;
self.downloadLink = document.createElement('a');
self.downloadLink.href = url;
self.downloadLink.setAttribute('download', baseName + '.zip');
self.downloadLink.setAttribute('target', '_blank');
self.downloadLink.click();
});
} else {
// Continue normally if there are no separators
const url = URL.createObjectURL(pdfBlob);
const downloadOption = localStorage.getItem('downloadOption');
if (!filenameInput.value.includes('.pdf')) {
filenameInput.value = filenameInput.value + '.pdf';
this.fileName = filenameInput.value;
}
if (downloadOption === 'sameWindow') {
// Open the file in the same window
window.location.href = url;
} else if (downloadOption === 'newWindow') {
// Open the file in a new window
window.open(url, '_blank');
} else {
// Download the file
this.downloadLink = document.createElement('a');
this.downloadLink.id = 'download-link';
this.downloadLink.href = url;
// downloadLink.download = this.fileName ? this.fileName : 'managed.pdf';
// downloadLink.download = this.fileName;
this.downloadLink.setAttribute('download', this.fileName ? this.fileName : 'managed.pdf');
this.downloadLink.setAttribute('target', '_blank');
this.downloadLink.onclick = this.setDownloadAttribute;
this.downloadLink.click();
}
2023-10-08 19:57:19 +03:00
}
}
2024-02-11 11:47:00 -05:00
resetPages() {
const pageContainers = this.pagesContainer.querySelectorAll('.page-container');
pageContainers.forEach((container, index) => {
container.id = 'page-container-' + (index + 1);
});
const checkboxes = document.querySelectorAll('.pdf-actions_checkbox');
const selectIcon = document.getElementById('select-All-Container');
const deselectIcon = document.getElementById('deselect-All-Container');
checkboxes.forEach((checkbox) => {
const pageNumber = Array.from(checkbox.parentNode.parentNode.children).indexOf(checkbox.parentNode) + 1;
const index = window.selectedPages.indexOf(pageNumber);
if (index !== -1) {
window.selectedPages.splice(index, 1);
}
});
window.toggleSelectPageVisibility();
}
setDownloadAttribute() {
this.downloadLink.setAttribute('download', this.fileName ? this.fileName : 'managed.pdf');
}
2024-02-11 11:47:00 -05:00
updateFilename(fileName = '') {
const filenameInput = document.getElementById('filename-input');
const pagesContainer = document.getElementById('pages-container');
const downloadBtn = document.getElementById('export-button');
2024-02-11 11:47:00 -05:00
downloadBtn.disabled = pagesContainer.childElementCount === 0;
2024-02-11 11:47:00 -05:00
if (!this.fileName) {
this.fileName = fileName;
}
2024-02-11 11:47:00 -05:00
if (!filenameInput.value) {
filenameInput.value = this.fileName;
}
}
preventIllegalChars(e) {
// const filenameInput = document.getElementById('filename-input');
//
// filenameInput.value = filenameInput.value.replace('.pdf', '');
//
// // prevent .
// if (filenameInput.value.includes('.')) {
// filenameInput.value.replace('.','');
// }
}
toggleSelectPageVisibility() {
window.selectPage = !window.selectPage;
const checkboxes = document.querySelectorAll('.pdf-actions_checkbox');
checkboxes.forEach((checkbox) => {
checkbox.classList.toggle('hidden', !window.selectPage);
});
const deleteButton = document.getElementById('delete-button');
deleteButton.classList.toggle('hidden', !window.selectPage);
const selectedPages = document.getElementById('selected-pages-display');
selectedPages.classList.toggle('hidden', !window.selectPage);
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01: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.
2025-03-20 00:06:47 +00:00
if(!window.selectPage)
{
this.showButton(document.getElementById('deselect-All-Container'), false);
this.showButton(document.getElementById('select-All-Container'), false);
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
// Uncheck all checkboxes and clear selected pages
const allCheckboxes = document.querySelectorAll('.pdf-actions_checkbox');
allCheckboxes.forEach((checkbox) => {
checkbox.checked = false;
});
window.selectedPages = [];
this.updateSelectedPagesDisplay();
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.
2025-03-20 00:06:47 +00:00
}
else{
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
const allCheckboxes = document.querySelectorAll('.pdf-actions_checkbox');
const allSelected = Array.from(allCheckboxes).every((checkbox) => checkbox.checked);
if (!allSelected) {
this.showButton(document.getElementById('select-All-Container'), true);
}
Multi tool select buttons bug (#3404) # Description of Changes Changes: - In the multitool page, the behavior of the "Select/Deselect All" buttons was changed so that if no pages are selected, then the "Deselect All" button is disabled, and if all pages are selected, then the "Select All" button is disabled. - These buttons will also appear if the "Page Select" is turned on, either by pressing the "Page Select" button or manually selecting one page. - Furthermore, a bug that caused the pages to remain selected when "Page Select" is off was also fixed Why the changes were made: - The multitool did not allow the "Select All" or "Deselect All" button to appear simultaneously. The multitool was relying on a toggle mechanic for the Page Selection and this could prevent the user from selecting or deselecting all pages as intended, if they manually select/deselect one or more pages. Other challenges: - No particular challenges encountered Relevant Screenshots: ![Screenshot_1](https://github.com/user-attachments/assets/47e1a4ad-fdfb-460a-9302-80a99f732874) *Fig. 1 - Only "Select All" button appears when Page Select is turned on, since no pages are selected* ![Screenshot_2](https://github.com/user-attachments/assets/7174b492-f503-4a19-9bc8-56e18fba64e9) *Fig. 2 - Both "Select All" and "Deselect All" buttons appear when one or more, but not all pages are selected* ![Screenshot_3](https://github.com/user-attachments/assets/8157ef49-3268-4fa1-b8df-c7f078237141) *Fig. 3 - Only "Deselect All" button appears when all pages are selected* ![Screenshot_4](https://github.com/user-attachments/assets/61b69e6a-1536-47b0-bf11-3dd56df8e365) *Fig. 4 - When Page Select is turned off, both "Select All" and "Deselect All" buttons disappear and all pages are deselected* Closes #3206 --- ## 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) - [ ] 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 - [ ] 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) - [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.
2025-04-28 22:44:51 +01:00
if (window.selectedPages.length > 0) {
this.showButton(document.getElementById('deselect-All-Container'), true);
}
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.
2025-03-20 00:06:47 +00:00
}
const exportSelected = document.getElementById('export-selected-button');
exportSelected.classList.toggle('hidden', !window.selectPage);
const selectPagesButton = document.getElementById('select-pages-button');
selectPagesButton.style.opacity = window.selectPage ? '1' : '0.5';
if (window.selectPage) {
this.updatePageNumbersAndCheckboxes();
}
}
updatePageNumbersAndCheckboxes() {
const pageDivs = document.querySelectorAll('.pdf-actions_container');
pageDivs.forEach((div, index) => {
const pageNumber = index + 1;
const checkbox = div.querySelector('.pdf-actions_checkbox');
checkbox.id = `selectPageCheckbox-${pageNumber}`;
checkbox.setAttribute('data-page-number', pageNumber);
checkbox.checked = window.selectedPages.includes(pageNumber);
});
}
2023-07-22 13:17:24 +01:00
}
function detectImageType(uint8Array) {
// Check for PNG signature
if (uint8Array[0] === 137 && uint8Array[1] === 80 && uint8Array[2] === 78 && uint8Array[3] === 71) {
return 'PNG';
}
// Check for JPEG signature
if (uint8Array[0] === 255 && uint8Array[1] === 216 && uint8Array[2] === 255) {
return 'JPEG';
}
2024-02-11 11:47:00 -05:00
// Check for TIFF signature (little-endian and big-endian)
if (
(uint8Array[0] === 73 && uint8Array[1] === 73 && uint8Array[2] === 42 && uint8Array[3] === 0) ||
(uint8Array[0] === 77 && uint8Array[1] === 77 && uint8Array[2] === 0 && uint8Array[3] === 42)
) {
return 'TIFF';
}
// Check for GIF signature
if (uint8Array[0] === 71 && uint8Array[1] === 73 && uint8Array[2] === 70) {
return 'GIF';
}
return 'UNKNOWN';
}
2023-07-22 13:17:24 +01:00
export default PdfContainer;