Skip to content

Commit 3a80ae4

Browse files
authored
Merge pull request #20800 from calixteman/bug2020731
Once a page has been deleted or pasted, make sure the focus stays in the sidebar (bug 2020731)
2 parents 688ae9b + d489ad0 commit 3a80ae4

2 files changed

Lines changed: 97 additions & 16 deletions

File tree

test/integration/reorganize_pages_spec.mjs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,76 @@ describe("Reorganize Pages View", () => {
11121112
});
11131113
});
11141114

1115+
describe("Focus stays in sidebar after page operations (bug 2020731)", () => {
1116+
let pages;
1117+
1118+
beforeEach(async () => {
1119+
pages = await loadAndWait(
1120+
"page_with_number.pdf",
1121+
"#viewsManagerToggleButton",
1122+
"1",
1123+
null,
1124+
{ enableSplitMerge: true }
1125+
);
1126+
});
1127+
1128+
afterEach(async () => {
1129+
await closePages(pages);
1130+
});
1131+
1132+
it("should keep focus on a thumbnail after deleting pages", async () => {
1133+
await Promise.all(
1134+
pages.map(async ([browserName, page]) => {
1135+
await waitForThumbnailVisible(page, 1);
1136+
await waitAndClick(
1137+
page,
1138+
`.thumbnail:has(${getThumbnailSelector(1)}) input`
1139+
);
1140+
1141+
const handlePagesEdited = await waitForPagesEdited(page);
1142+
await waitAndClick(page, "#viewsManagerStatusActionButton");
1143+
await waitAndClick(page, "#viewsManagerStatusActionDelete");
1144+
await awaitPromise(handlePagesEdited);
1145+
1146+
await page.waitForSelector(
1147+
"#thumbnailsView .thumbnailImageContainer:focus",
1148+
{
1149+
visible: true,
1150+
}
1151+
);
1152+
})
1153+
);
1154+
});
1155+
1156+
it("should keep focus on a thumbnail after pasting pages", async () => {
1157+
await Promise.all(
1158+
pages.map(async ([browserName, page]) => {
1159+
await waitForThumbnailVisible(page, 1);
1160+
await waitAndClick(
1161+
page,
1162+
`.thumbnail:has(${getThumbnailSelector(1)}) input`
1163+
);
1164+
1165+
let handlePagesEdited = await waitForPagesEdited(page, "cut");
1166+
await waitAndClick(page, "#viewsManagerStatusActionButton");
1167+
await waitAndClick(page, "#viewsManagerStatusActionCut");
1168+
await awaitPromise(handlePagesEdited);
1169+
1170+
handlePagesEdited = await waitForPagesEdited(page);
1171+
await waitAndClick(page, `${getThumbnailSelector(1)}+button`);
1172+
await awaitPromise(handlePagesEdited);
1173+
1174+
await page.waitForSelector(
1175+
"#thumbnailsView .thumbnailImageContainer:focus",
1176+
{
1177+
visible: true,
1178+
}
1179+
);
1180+
})
1181+
);
1182+
});
1183+
});
1184+
11151185
describe("Extract some pages from a pdf", () => {
11161186
let pages;
11171187

web/pdf_thumbnail_viewer.js

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ class PDFThumbnailViewer {
125125

126126
#copiedPageNumbers = null;
127127

128+
#boundPastePages = this.#pastePages.bind(this);
129+
128130
#isCut = false;
129131

130132
#isOneColumnView = false;
@@ -252,6 +254,15 @@ class PDFThumbnailViewer {
252254
});
253255
}
254256

257+
#resetCurrentThumbnail(newPageNumber) {
258+
if (!this.pdfDocument) {
259+
return;
260+
}
261+
const thumbnailView = this._thumbnails[this._currentPageNumber - 1];
262+
thumbnailView?.toggleCurrent(/* isCurrent = */ false);
263+
this._currentPageNumber = newPageNumber;
264+
}
265+
255266
scrollThumbnailIntoView(pageNumber) {
256267
if (!this.pdfDocument) {
257268
return;
@@ -263,10 +274,8 @@ class PDFThumbnailViewer {
263274
return;
264275
}
265276
if (pageNumber !== this._currentPageNumber) {
266-
const prevThumbnailView = this._thumbnails[this._currentPageNumber - 1];
267-
prevThumbnailView?.toggleCurrent(/* isCurrent = */ false);
277+
this.#resetCurrentThumbnail(pageNumber);
268278
thumbnailView.toggleCurrent(/* isCurrent = */ true);
269-
this._currentPageNumber = pageNumber;
270279
}
271280
const { first, last, views } = this.#getVisibleThumbs();
272281

@@ -640,10 +649,7 @@ class PDFThumbnailViewer {
640649
type: "move",
641650
});
642651

643-
setTimeout(() => {
644-
this.forceRendering();
645-
this.linkService.goToPage(currentPageNumber);
646-
}, 0);
652+
this.#updateCurrentPage(currentPageNumber);
647653
}
648654

649655
if (!isNaN(this.#pageNumberToRemove)) {
@@ -659,6 +665,17 @@ class PDFThumbnailViewer {
659665
this.#selectedPages.clear();
660666
}
661667

668+
#updateCurrentPage(currentPageNumber) {
669+
setTimeout(() => {
670+
this.#resetCurrentThumbnail(0);
671+
this.forceRendering();
672+
const newPageNumber = currentPageNumber || 1;
673+
this.linkService.goToPage(newPageNumber);
674+
const thumbnailView = this._thumbnails[newPageNumber - 1];
675+
thumbnailView.imageContainer.focus();
676+
}, 0);
677+
}
678+
662679
#saveExtractedPages() {
663680
this.eventBus.dispatch("saveextractedpages", {
664681
source: this,
@@ -688,7 +705,7 @@ class PDFThumbnailViewer {
688705
this.#clearSelection();
689706
}
690707
for (const thumbnail of this._thumbnails) {
691-
thumbnail.addPasteButton(this.#pastePages.bind(this));
708+
thumbnail.addPasteButton(this.#boundPastePages);
692709
}
693710
this.container.classList.add("pasteMode");
694711
this.#toggleMenuEntries(false);
@@ -728,10 +745,7 @@ class PDFThumbnailViewer {
728745
this.#isCut = false;
729746
this.#updateMenuEntries();
730747

731-
setTimeout(() => {
732-
this.forceRendering();
733-
this.linkService.goToPage(currentPageNumber || 1);
734-
}, 0);
748+
this.#updateCurrentPage(currentPageNumber);
735749
}
736750

737751
#deletePages(type = "delete") {
@@ -757,10 +771,7 @@ class PDFThumbnailViewer {
757771
type,
758772
});
759773

760-
setTimeout(() => {
761-
this.forceRendering();
762-
this.linkService.goToPage(currentPageNumber || 1);
763-
}, 0);
774+
this.#updateCurrentPage(currentPageNumber);
764775
}
765776

766777
#updateMenuEntries() {

0 commit comments

Comments
 (0)