diff --git a/src/main/resources/static/js/multitool/DragDropManager.js b/src/main/resources/static/js/multitool/DragDropManager.js index 11536e891..7cbe97ab0 100644 --- a/src/main/resources/static/js/multitool/DragDropManager.js +++ b/src/main/resources/static/js/multitool/DragDropManager.js @@ -39,7 +39,7 @@ class DragDropManager { // Multi-page drag logic this.selectedPageElements = window.selectedPages .map((index) => { - const pageEl = document.getElementById(`page-container-${index}`); + const pageEl = Array.from(this.wrapper.childNodes)[index]; if (pageEl) { pageEl.initialTransform = pageEl.style.transform || 'translate(0px, 0px)'; pageEl.classList.add('drag-manager_dragging'); @@ -114,13 +114,15 @@ class DragDropManager { } else { this.selectedPageElements.forEach((pageEl) => { pageEl.classList.remove('drag-manager_dragging'); + }); - if (this.hoveredEl === this.endInsertionElement) { - this.movePageTo(pageEl); - } else { - this.movePageTo(pageEl, this.hoveredEl); - } + this.movePageTo( + this.selectedPageElements, + this.hoveredEl === this.endInsertionElement + ? null + : this.hoveredEl); + this.selectedPageElements.forEach((pageEl) => { // Handle timeout for the current element this.handleTimeoutForElement(pageEl); }); diff --git a/src/main/resources/static/js/multitool/PdfActionsManager.js b/src/main/resources/static/js/multitool/PdfActionsManager.js index 834247940..80df8d310 100644 --- a/src/main/resources/static/js/multitool/PdfActionsManager.js +++ b/src/main/resources/static/js/multitool/PdfActionsManager.js @@ -35,8 +35,7 @@ class PdfActionsManager { const sibling = imgContainer.previousSibling; if (sibling) { - let movePageCommand = this.movePageTo(imgContainer, sibling, true, true); - this._pushUndoClearRedo(movePageCommand); + this.movePageTo(imgContainer, sibling, true); } } @@ -44,12 +43,11 @@ class PdfActionsManager { var imgContainer = this.getPageContainer(e.target); const sibling = imgContainer.nextSibling; if (sibling) { - let movePageCommand = this.movePageTo( + this.movePageTo( imgContainer, sibling.nextSibling, true ); - this._pushUndoClearRedo(movePageCommand); } } @@ -185,8 +183,6 @@ class PdfActionsManager { const pageNumber = Array.from(div.parentNode.children).indexOf(div) + 1; let selectPageCommand = new SelectPageCommand(pageNumber, selectCheckbox); selectPageCommand.execute(); - - this._pushUndoClearRedo(selectPageCommand); }; const insertFileButtonContainer = document.createElement("div"); diff --git a/src/main/resources/static/js/multitool/PdfContainer.js b/src/main/resources/static/js/multitool/PdfContainer.js index 86bdb55f4..f9955a71c 100644 --- a/src/main/resources/static/js/multitool/PdfContainer.js +++ b/src/main/resources/static/js/multitool/PdfContainer.js @@ -1,4 +1,4 @@ -import { MovePageUpCommand, MovePageDownCommand } from './commands/move-page.js'; +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'; @@ -6,6 +6,7 @@ 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'; class PdfContainer { fileName; @@ -109,27 +110,41 @@ class PdfContainer { downloadBtn.disabled = true; } - movePageTo(startElement, endElement, scrollTo = false, moveUp = false) { - let movePageCommand; - if (moveUp) { - movePageCommand = new MovePageUpCommand( - startElement, + movePagesTo(startElements, endElement, scrollTo = false) { + let commands = []; + startElements.forEach((page) => { + let command = new MovePageCommand( + page, endElement, this.pagesContainer, this.pagesContainerWrapper, scrollTo - ); - } else { - movePageCommand = new MovePageDownCommand( - startElement, - endElement, - this.pagesContainer, - this.pagesContainerWrapper, - scrollTo - ); + ) + command.execute(); + commands.push(command); + }) + + let commandSequence = new CommandSequence(commands); + this.undoManager.pushUndoClearRedo(commandSequence); + return commandSequence; + } + + movePageTo(startElements, endElement, scrollTo = false) { + + if (Array.isArray(startElements)){ + return this.movePagesTo(startElements, endElement, scrollTo = false); } + let movePageCommand = new MovePageCommand( + startElements, + endElement, + this.pagesContainer, + this.pagesContainerWrapper, + scrollTo + ); + movePageCommand.execute(); + this.undoManager.pushUndoClearRedo(movePageCommand); return movePageCommand; } diff --git a/src/main/resources/static/js/multitool/commands/add-page.js b/src/main/resources/static/js/multitool/commands/add-page.js index cd67eba3a..b910320c9 100644 --- a/src/main/resources/static/js/multitool/commands/add-page.js +++ b/src/main/resources/static/js/multitool/commands/add-page.js @@ -34,12 +34,10 @@ export class AddFilesCommand extends Command { if (this.pagesContainer.childElementCount === 0) { const filenameInput = document.getElementById('filename-input'); - const filenameParagraph = document.getElementById('filename'); const downloadBtn = document.getElementById('export-button'); filenameInput.disabled = true; filenameInput.value = ''; - filenameParagraph.innerText = ''; downloadBtn.disabled = true; } diff --git a/src/main/resources/static/js/multitool/commands/commands-sequence.js b/src/main/resources/static/js/multitool/commands/commands-sequence.js new file mode 100644 index 000000000..61d2ba469 --- /dev/null +++ b/src/main/resources/static/js/multitool/commands/commands-sequence.js @@ -0,0 +1,20 @@ +import {Command} from './command.js'; + +export class CommandSequence extends Command { + constructor(commands) { + super(); + this.commands = commands; + + } + execute() { + this.commands.forEach((command) => command.execute()) + } + + undo() { + this.commands.slice().reverse().forEach((command) => command.undo()) + } + + redo() { + this.execute(); + } +} diff --git a/src/main/resources/static/js/multitool/commands/move-page.js b/src/main/resources/static/js/multitool/commands/move-page.js index 738af9502..b209e6a7d 100644 --- a/src/main/resources/static/js/multitool/commands/move-page.js +++ b/src/main/resources/static/js/multitool/commands/move-page.js @@ -1,6 +1,6 @@ import {Command} from './command.js'; -export class AbstractMovePageCommand extends Command { +export class MovePageCommand extends Command { constructor(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo = false) { super(); @@ -16,7 +16,6 @@ export class AbstractMovePageCommand extends Command { 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'); @@ -42,51 +41,11 @@ export class AbstractMovePageCommand extends Command { } 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); + let previousNeighbour = Array.from(this.pagesContainer.childNodes)[this.startIndex]; + previousNeighbour?.insertAdjacentElement('beforebegin', this.startElement) + ?? this.pagesContainer.append(this.startElement); } if (this.scrollTo) {