mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-06-10 12:11:12 +02:00
Merge pull request #20681 from calixteman/bug2016212
Correctly handle tab/page down when on a menu (bug 2016212)
This commit is contained in:
commit
6b1b94e7d4
@ -355,4 +355,73 @@ describe("PDF Thumbnail View", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Menu keyboard navigation with multi-character keys (bug 2016212)", () => {
|
||||
let pages;
|
||||
|
||||
beforeEach(async () => {
|
||||
pages = await loadAndWait(
|
||||
"page_with_number_and_link.pdf",
|
||||
"#viewsManagerSelectorButton",
|
||||
null,
|
||||
null,
|
||||
{ enableSplitMerge: true }
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await closePages(pages);
|
||||
});
|
||||
|
||||
it("must navigate menus with ArrowDown and Tab keys", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
await page.click("#viewsManagerToggleButton");
|
||||
await waitForThumbnailVisible(page, 1);
|
||||
|
||||
// Focus the views manager selector button
|
||||
await page.waitForSelector("#viewsManagerSelectorButton", {
|
||||
visible: true,
|
||||
});
|
||||
await page.focus("#viewsManagerSelectorButton");
|
||||
|
||||
// Open menu with Enter key
|
||||
await page.keyboard.press("Enter");
|
||||
|
||||
// Wait for menu to be expanded
|
||||
await waitForMenu(page, "#viewsManagerSelectorButton");
|
||||
|
||||
// Check that focus moved to the first menu button (pages)
|
||||
await page.waitForSelector("#thumbnailsViewMenu:focus", {
|
||||
visible: true,
|
||||
});
|
||||
|
||||
// Press ArrowDown to navigate to second item
|
||||
await page.keyboard.press("ArrowDown");
|
||||
|
||||
// Should now be on outlines button
|
||||
await page.waitForSelector("#outlinesViewMenu:focus", {
|
||||
visible: true,
|
||||
});
|
||||
|
||||
// Press Tab to move to the manage button (should close views menu)
|
||||
await page.keyboard.press("Tab");
|
||||
|
||||
// Wait for views manager menu to be collapsed
|
||||
await waitForMenu(page, "#viewsManagerSelectorButton", false);
|
||||
|
||||
// Focus should be on manage button
|
||||
await page.waitForSelector("#viewsManagerStatusActionButton:focus", {
|
||||
visible: true,
|
||||
});
|
||||
|
||||
// Open manage menu with Space key
|
||||
await page.keyboard.press(" ");
|
||||
|
||||
// Wait for manage menu to be expanded
|
||||
await waitForMenu(page, "#viewsManagerStatusActionButton");
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
23
web/menu.js
23
web/menu.js
@ -28,6 +28,8 @@ class Menu {
|
||||
|
||||
#lastIndex = -1;
|
||||
|
||||
#onFocusOutBound = this.#onFocusOut.bind(this);
|
||||
|
||||
/**
|
||||
* Create a menu for the given button.
|
||||
* @param {HTMLElement} menuContainer
|
||||
@ -97,7 +99,18 @@ class Menu {
|
||||
},
|
||||
{ signal }
|
||||
);
|
||||
window.addEventListener("blur", this.#closeMenu.bind(this), { signal });
|
||||
const closeMenu = this.#closeMenu.bind(this);
|
||||
window.addEventListener("blur", closeMenu, { signal });
|
||||
menu.addEventListener("focusout", this.#onFocusOutBound, { signal });
|
||||
}
|
||||
|
||||
#onFocusOut({ relatedTarget }) {
|
||||
if (
|
||||
!this.#triggeringButton.contains(relatedTarget) &&
|
||||
!this.#menu.contains(relatedTarget)
|
||||
) {
|
||||
this.#closeMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,6 +125,7 @@ class Menu {
|
||||
|
||||
this.#openMenu();
|
||||
});
|
||||
this.#triggeringButton.addEventListener("focusout", this.#onFocusOutBound);
|
||||
|
||||
const { signal } = this.#menuAC;
|
||||
|
||||
@ -148,7 +162,12 @@ class Menu {
|
||||
stopEvent(e);
|
||||
break;
|
||||
default:
|
||||
const char = e.key.toLocaleLowerCase();
|
||||
const { key } = e;
|
||||
if (!/^\p{L}$/u.test(key)) {
|
||||
// It isn't a single letter, so ignore it.
|
||||
break;
|
||||
}
|
||||
const char = key.toLocaleLowerCase();
|
||||
this.#goToNextItem(e.target, true, item =>
|
||||
item.textContent.trim().toLowerCase().startsWith(char)
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user