mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-22 15:35:03 +00:00

* 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>
134 lines
3.3 KiB
JavaScript
134 lines
3.3 KiB
JavaScript
import { Command } from "./command.js";
|
|
|
|
export class AbstractMovePageCommand extends Command {
|
|
constructor(
|
|
startElement,
|
|
endElement,
|
|
pagesContainer,
|
|
pagesContainerWrapper,
|
|
scrollTo = false
|
|
) {
|
|
super();
|
|
|
|
this.pagesContainer = pagesContainer;
|
|
const childArray = Array.from(this.pagesContainer.childNodes);
|
|
|
|
this.startIndex = childArray.indexOf(startElement);
|
|
this.endIndex = childArray.indexOf(endElement);
|
|
|
|
this.startElement = startElement;
|
|
this.endElement = endElement;
|
|
|
|
this.scrollTo = scrollTo;
|
|
this.pagesContainerWrapper = pagesContainerWrapper;
|
|
}
|
|
|
|
execute() {
|
|
// Check & remove page number elements here too if they exist because Firefox doesn't fire the relevant event on page move.
|
|
const pageNumberElement = this.startElement.querySelector(".page-number");
|
|
if (pageNumberElement) {
|
|
this.startElement.removeChild(pageNumberElement);
|
|
}
|
|
|
|
this.pagesContainer.removeChild(this.startElement);
|
|
if (!this.endElement) {
|
|
this.pagesContainer.append(this.startElement);
|
|
} else {
|
|
this.pagesContainer.insertBefore(this.startElement, this.endElement);
|
|
}
|
|
|
|
if (this.scrollTo) {
|
|
const { width } = this.startElement.getBoundingClientRect();
|
|
const vector =
|
|
this.endIndex !== -1 && this.startIndex > this.endIndex
|
|
? 0 - width
|
|
: width;
|
|
|
|
this.pagesContainerWrapper.scroll({
|
|
left: this.pagesContainerWrapper.scrollLeft + vector,
|
|
});
|
|
}
|
|
}
|
|
|
|
undo() {
|
|
// Requires overriding in child classes
|
|
|
|
}
|
|
|
|
redo() {
|
|
this.execute();
|
|
}
|
|
}
|
|
|
|
export class MovePageUpCommand extends AbstractMovePageCommand {
|
|
constructor(
|
|
startElement,
|
|
endElement,
|
|
pagesContainer,
|
|
pagesContainerWrapper,
|
|
scrollTo = false
|
|
) {
|
|
super(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo);
|
|
}
|
|
|
|
undo() {
|
|
if (this.endElement) {
|
|
this.pagesContainer.removeChild(this.endElement);
|
|
this.startElement.insertAdjacentElement("beforebegin", this.endElement);
|
|
}
|
|
|
|
if (this.scrollTo) {
|
|
const { width } = this.startElement.getBoundingClientRect();
|
|
const vector =
|
|
this.endIndex === -1 || this.startIndex <= this.endIndex
|
|
? 0 - width
|
|
: width;
|
|
|
|
this.pagesContainerWrapper.scroll({
|
|
left: this.pagesContainerWrapper.scrollLeft - vector,
|
|
});
|
|
}
|
|
}
|
|
|
|
redo() {
|
|
this.execute();
|
|
}
|
|
}
|
|
|
|
export class MovePageDownCommand extends AbstractMovePageCommand {
|
|
constructor(
|
|
startElement,
|
|
endElement,
|
|
pagesContainer,
|
|
pagesContainerWrapper,
|
|
scrollTo = false
|
|
) {
|
|
super(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo);
|
|
}
|
|
|
|
undo() {
|
|
let previousElement = this.startElement.previousSibling;
|
|
|
|
if (this.startElement) {
|
|
this.pagesContainer.removeChild(this.startElement);
|
|
previousElement.insertAdjacentElement("beforebegin", this.startElement);
|
|
}
|
|
|
|
if (this.scrollTo) {
|
|
const { width } = this.startElement.getBoundingClientRect();
|
|
const vector =
|
|
this.endIndex === -1 || this.startIndex <= this.endIndex
|
|
? 0 - width
|
|
: width;
|
|
|
|
this.pagesContainerWrapper.scroll({
|
|
left: this.pagesContainerWrapper.scrollLeft - vector,
|
|
});
|
|
}
|
|
}
|
|
|
|
redo() {
|
|
this.execute();
|
|
}
|
|
}
|