Skip to content

Commit c91de76

Browse files
authored
Merge pull request #20697 from calixteman/bug2018139
Add keyboard shortcuts for copying/cutting/deleting the pages (bug 2018139, bug 2010831)
2 parents 176e085 + 63c340f commit c91de76

3 files changed

Lines changed: 181 additions & 0 deletions

File tree

test/integration/reorganize_pages_spec.mjs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ import {
2323
getAnnotationSelector,
2424
getRect,
2525
getThumbnailSelector,
26+
kbCopy,
27+
kbCut,
28+
kbDelete,
2629
loadAndWait,
2730
scrollIntoView,
2831
waitAndClick,
@@ -841,4 +844,144 @@ describe("Reorganize Pages View", () => {
841844
);
842845
});
843846
});
847+
848+
describe("Keyboard shortcuts for cut and copy (bug 2018139)", () => {
849+
let pages;
850+
851+
beforeEach(async () => {
852+
pages = await loadAndWait(
853+
"page_with_number.pdf",
854+
"#viewsManagerToggleButton",
855+
"1",
856+
null,
857+
{ enableSplitMerge: true }
858+
);
859+
});
860+
861+
afterEach(async () => {
862+
await closePages(pages);
863+
});
864+
865+
it("should cut pages with Ctrl+X and paste them", async () => {
866+
await Promise.all(
867+
pages.map(async ([browserName, page]) => {
868+
await waitForThumbnailVisible(page, 1);
869+
await waitAndClick(
870+
page,
871+
`.thumbnail:has(${getThumbnailSelector(1)}) input`
872+
);
873+
await waitAndClick(
874+
page,
875+
`.thumbnail:has(${getThumbnailSelector(3)}) input`
876+
);
877+
878+
let handlePagesEdited = await waitForPagesEdited(page, "cut");
879+
await kbCut(page);
880+
881+
let pageIndices = await awaitPromise(handlePagesEdited);
882+
let expected = [2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];
883+
expect(pageIndices)
884+
.withContext(`In ${browserName}`)
885+
.toEqual(expected);
886+
await waitForHavingContents(page, expected);
887+
888+
handlePagesEdited = await waitForPagesEdited(page);
889+
await waitAndClick(page, `${getThumbnailSelector(1)}+button`);
890+
pageIndices = await awaitPromise(handlePagesEdited);
891+
expected = [
892+
2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
893+
];
894+
expect(pageIndices)
895+
.withContext(`In ${browserName}`)
896+
.toEqual(expected);
897+
await waitForHavingContents(page, expected);
898+
})
899+
);
900+
});
901+
902+
it("should copy pages with Ctrl+C and paste them", async () => {
903+
await Promise.all(
904+
pages.map(async ([browserName, page]) => {
905+
await waitForThumbnailVisible(page, 1);
906+
await waitAndClick(
907+
page,
908+
`.thumbnail:has(${getThumbnailSelector(1)}) input`
909+
);
910+
await waitAndClick(
911+
page,
912+
`.thumbnail:has(${getThumbnailSelector(3)}) input`
913+
);
914+
915+
let handlePagesEdited = await waitForPagesEdited(page, "copy");
916+
await kbCopy(page);
917+
918+
let pageIndices = await awaitPromise(handlePagesEdited);
919+
let expected = [
920+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
921+
];
922+
expect(pageIndices)
923+
.withContext(`In ${browserName}`)
924+
.toEqual(expected);
925+
await waitForHavingContents(page, expected);
926+
927+
handlePagesEdited = await waitForPagesEdited(page);
928+
await waitAndClick(page, `${getThumbnailSelector(2)}+button`);
929+
pageIndices = await awaitPromise(handlePagesEdited);
930+
expected = [
931+
1, 2, 1, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
932+
];
933+
expect(pageIndices)
934+
.withContext(`In ${browserName}`)
935+
.toEqual(expected);
936+
await waitForHavingContents(page, expected);
937+
})
938+
);
939+
});
940+
});
941+
942+
describe("Keyboard shortcuts for delete (bug 2010831)", () => {
943+
let pages;
944+
945+
beforeEach(async () => {
946+
pages = await loadAndWait(
947+
"page_with_number.pdf",
948+
"#viewsManagerToggleButton",
949+
"1",
950+
null,
951+
{ enableSplitMerge: true }
952+
);
953+
});
954+
955+
afterEach(async () => {
956+
await closePages(pages);
957+
});
958+
959+
it("should delete pages with the Delete key", async () => {
960+
await Promise.all(
961+
pages.map(async ([browserName, page]) => {
962+
await waitForThumbnailVisible(page, 1);
963+
await waitAndClick(
964+
page,
965+
`.thumbnail:has(${getThumbnailSelector(1)}) input`
966+
);
967+
await waitAndClick(
968+
page,
969+
`.thumbnail:has(${getThumbnailSelector(3)}) input`
970+
);
971+
972+
const handlePagesEdited = await waitForPagesEdited(page);
973+
await kbDelete(page);
974+
975+
const pageIndices = await awaitPromise(handlePagesEdited);
976+
const expected = [
977+
2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
978+
];
979+
expect(pageIndices)
980+
.withContext(`In ${browserName}`)
981+
.toEqual(expected);
982+
await waitForHavingContents(page, expected);
983+
})
984+
);
985+
});
986+
});
844987
});

test/integration/test_utils.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,14 @@ async function kbCopy(page) {
702702
await page.keyboard.press("c", { commands: ["Copy"] });
703703
await page.keyboard.up(modifier);
704704
}
705+
async function kbCut(page) {
706+
await page.keyboard.down(modifier);
707+
await page.keyboard.press("x", { commands: ["Cut"] });
708+
await page.keyboard.up(modifier);
709+
}
710+
async function kbDelete(page) {
711+
await page.keyboard.press("Delete");
712+
}
705713
async function kbPaste(page) {
706714
await page.keyboard.down(modifier);
707715
await page.keyboard.press("v", { commands: ["Paste"] });
@@ -997,6 +1005,9 @@ export {
9971005
kbBigMoveLeft,
9981006
kbBigMoveRight,
9991007
kbBigMoveUp,
1008+
kbCopy,
1009+
kbCut,
1010+
kbDelete,
10001011
kbDeleteLastWord,
10011012
kbFocusNext,
10021013
kbFocusPrevious,

web/pdf_thumbnail_viewer.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,33 @@ class PDFThumbnailViewer {
884884
}
885885
// For checkboxes, let the default behavior handle toggling
886886
break;
887+
case "c":
888+
if (
889+
this.#enableSplitMerge &&
890+
(e.ctrlKey || e.metaKey) &&
891+
this.#selectedPages?.size
892+
) {
893+
this.#copyPages();
894+
stopEvent(e);
895+
}
896+
break;
897+
case "x":
898+
if (
899+
this.#enableSplitMerge &&
900+
(e.ctrlKey || e.metaKey) &&
901+
this.#selectedPages?.size
902+
) {
903+
this.#cutPages();
904+
stopEvent(e);
905+
}
906+
break;
907+
case "Delete":
908+
case "Backspace":
909+
if (this.#enableSplitMerge && this.#selectedPages?.size) {
910+
this.#deletePages();
911+
stopEvent(e);
912+
}
913+
break;
887914
}
888915
});
889916
this.container.addEventListener("click", e => {

0 commit comments

Comments
 (0)