Files
Stirling-PDF/src/main/resources/static/js/multitool/commands/split.js
Omar Ahmed Hassan 61e750646c 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 14:25:13 +00:00

102 lines
2.4 KiB
JavaScript

import { Command } from "./command.js";
export class SplitFileCommand extends Command {
constructor(element, splitClass) {
super();
this.element = element;
this.splitClass = splitClass;
}
execute() {
this.element.classList.toggle(this.splitClass);
}
undo() {
this.element.classList.toggle(this.splitClass);
}
redo() {
this.execute();
}
}
export class SplitAllCommand extends Command {
constructor(elements, isSelectedInWindow, selectedPages, splitClass) {
super();
this.elements = elements;
this.isSelectedInWindow = isSelectedInWindow;
this.selectedPages = selectedPages;
this.splitClass = splitClass;
}
execute() {
if (!this.isSelectedInWindow) {
const hasSplit = this._hasSplit(this.elements, this.splitClass);
if (hasSplit) {
this.elements.forEach((page) => {
page.classList.remove(this.splitClass);
});
} else {
this.elements.forEach((page) => {
page.classList.add(this.splitClass);
});
}
return;
}
this.elements.forEach((page, index) => {
const pageIndex = index;
if (this.isSelectedInWindow && !this.selectedPages.includes(pageIndex))
return;
if (page.classList.contains(this.splitClass)) {
page.classList.remove(this.splitClass);
} else {
page.classList.add(this.splitClass);
}
});
}
_hasSplit() {
if (!this.elements || this.elements.length == 0) return false;
for (const node of this.elements) {
if (node.classList.contains(this.splitClass)) return true;
}
return false;
}
undo() {
if (!this.isSelectedInWindow) {
const hasSplit = this._hasSplit(this.elements, this.splitClass);
if (hasSplit) {
this.elements.forEach((page) => {
page.classList.remove(this.splitClass);
});
} else {
this.elements.forEach((page) => {
page.classList.add(this.splitClass);
});
}
return;
}
this.elements.forEach((page, index) => {
const pageIndex = index;
if (this.isSelectedInWindow && !this.selectedPages.includes(pageIndex))
return;
if (page.classList.contains(this.splitClass)) {
page.classList.remove(this.splitClass);
} else {
page.classList.add(this.splitClass);
}
});
}
redo() {
this.execute();
}
}