Disable dragging a thumbnail when the user has to paste what they copied (bug 2021934)

This commit is contained in:
Calixte Denizet 2026-03-09 18:10:33 +01:00
parent cc680f68c3
commit 7010086cd5
No known key found for this signature in database
GPG Key ID: 0C5442631EE0691F
2 changed files with 74 additions and 16 deletions

View File

@ -190,13 +190,12 @@ describe("Reorganize Pages View", () => {
return false;
}
);
const dndPromise = dragAndDrop(
await dragAndDrop(
page,
getThumbnailSelector(1),
[[0, rect2.y - rect1.y + rect2.height / 2]],
10
);
await dndPromise;
await awaitPromise(handleAddedMarker);
await awaitPromise(handleRemovedMarker);
})
@ -1639,4 +1638,66 @@ describe("Reorganize Pages View", () => {
);
});
});
describe("Dragging mustn't be possible when pasting (bug 2021934)", () => {
let pages;
beforeEach(async () => {
pages = await loadAndWait(
"page_with_number.pdf",
"#viewsManagerToggleButton",
"page-fit",
null,
{ enableSplitMerge: true }
);
});
afterEach(async () => {
await closePages(pages);
});
it("should check that dragging is disabled when pasting", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await waitForThumbnailVisible(page, 1);
await Promise.all([
page.waitForSelector(`#thumbnailsView.isDragging`, {
visible: true,
}),
dragAndDrop(page, getThumbnailSelector(1), [[0, 10]], 10),
]);
await page.waitForSelector(`#thumbnailsView.isDragging`, {
hidden: true,
});
await waitAndClick(
page,
`.thumbnail:has(${getThumbnailSelector(1)}) input`
);
await waitAndClick(page, "#viewsManagerStatusActionButton");
await waitAndClick(page, "#viewsManagerStatusActionCopy");
// If dragging isn't disabled, the promise will resolve with the
// selector. Otherwise, it will resolve with undefined (dragAndDrop
// has no return), which is the expected behavior.
const abortController = new AbortController();
const first = await Promise.race([
page.waitForSelector(`#thumbnailsView.isDragging`, {
visible: true,
signal: abortController.signal,
}),
dragAndDrop(page, getThumbnailSelector(1), [[0, 10]], 10),
]);
abortController.abort();
expect(first)
.withContext(
`In ${browserName}, dragging should be disabled when pasting`
)
.toBeUndefined();
})
);
});
});
});

View File

@ -159,6 +159,8 @@ class PDFThumbnailViewer {
#undoCloseButton = null;
#isInPasteMode = false;
/**
* @param {PDFThumbnailViewerOptions} options
*/
@ -525,6 +527,7 @@ class PDFThumbnailViewer {
}
#updateThumbnails(currentPageNumber) {
this.#resetCurrentThumbnail(0);
let newCurrentPageNumber = 0;
const pagesMapper = this.#pagesMapper;
const prevThumbnails = (this.#savedThumbnails = this._thumbnails);
@ -658,13 +661,13 @@ class PDFThumbnailViewer {
const newIndex = lastDraggedOverIndex + 1;
const pagesToMove = Array.from(selectedPages).sort((a, b) => a - b);
const pagesMapper = this.#pagesMapper;
let currentPageNumber = isNaN(this.#pageNumberToRemove)
const currentPageNumber = isNaN(this.#pageNumberToRemove)
? pagesToMove[0]
: this.#pageNumberToRemove;
pagesMapper.movePages(selectedPages, pagesToMove, newIndex);
currentPageNumber = this.#updateThumbnails(currentPageNumber);
this.#updateCurrentPage(this.#updateThumbnails(currentPageNumber));
this.#computeThumbnailsPosition();
selectedPages.clear();
@ -676,8 +679,6 @@ class PDFThumbnailViewer {
pagesMapper,
type: "move",
});
this.#updateCurrentPage(currentPageNumber);
}
if (!isNaN(this.#pageNumberToRemove)) {
@ -695,7 +696,6 @@ class PDFThumbnailViewer {
#updateCurrentPage(currentPageNumber) {
setTimeout(() => {
this.#resetCurrentThumbnail(0);
this.forceRendering();
const newPageNumber = currentPageNumber || 1;
this.linkService.goToPage(newPageNumber);
@ -765,6 +765,7 @@ class PDFThumbnailViewer {
}
#togglePasteMode(enable) {
this.#isInPasteMode = enable;
if (enable) {
this.container.classList.add("pasteMode");
for (const thumbnail of this._thumbnails) {
@ -822,14 +823,14 @@ class PDFThumbnailViewer {
this.#toggleMenuEntries(true);
const pagesMapper = this.#pagesMapper;
let currentPageNumber = this.#copiedPageNumbers.includes(
const currentPageNumber = this.#copiedPageNumbers.includes(
this._currentPageNumber
)
? 0
: this._currentPageNumber;
pagesMapper.pastePages(index);
currentPageNumber = this.#updateThumbnails(currentPageNumber);
this.#updateCurrentPage(this.#updateThumbnails(currentPageNumber));
this.eventBus.dispatch("pagesedited", {
source: this,
@ -842,8 +843,6 @@ class PDFThumbnailViewer {
this.#isCut = false;
this.#updateMenuEntries();
this.#updateStatus("select");
this.#updateCurrentPage(currentPageNumber);
}
#deletePages(type = "delete") {
@ -855,7 +854,7 @@ class PDFThumbnailViewer {
this.#updateStatus("delete");
}
const pagesMapper = this.#pagesMapper;
let currentPageNumber = selectedPages.has(this._currentPageNumber)
const currentPageNumber = selectedPages.has(this._currentPageNumber)
? 0
: this._currentPageNumber;
const pagesToDelete = (this.#deletedPageNumbers = Uint32Array.from(
@ -863,7 +862,7 @@ class PDFThumbnailViewer {
).sort((a, b) => a - b));
pagesMapper.deletePages(pagesToDelete);
currentPageNumber = this.#updateThumbnails(currentPageNumber);
this.#updateCurrentPage(this.#updateThumbnails(currentPageNumber));
selectedPages.clear();
this.#updateMenuEntries();
@ -873,8 +872,6 @@ class PDFThumbnailViewer {
pageNumbers: pagesToDelete,
type,
});
this.#updateCurrentPage(currentPageNumber);
}
#updateMenuEntries() {
@ -1224,7 +1221,7 @@ class PDFThumbnailViewer {
} = e;
if (
e.button !== 0 || // Skip right click.
this.#pagesMapper.copiedPageNumbers?.length > 0 ||
this.#isInPasteMode ||
!isNaN(this.#lastDraggedOverIndex) ||
!draggedImage.classList.contains("thumbnailImageContainer")
) {