mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-07-31 19:37:21 +02:00
Correctly handle tab/page down when on a menu (bug 2016212)
This commit is contained in:
parent
61de56440a
commit
5290534c53
@ -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;
|
#lastIndex = -1;
|
||||||
|
|
||||||
|
#onFocusOutBound = this.#onFocusOut.bind(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a menu for the given button.
|
* Create a menu for the given button.
|
||||||
* @param {HTMLElement} menuContainer
|
* @param {HTMLElement} menuContainer
|
||||||
@ -97,7 +99,18 @@ class Menu {
|
|||||||
},
|
},
|
||||||
{ signal }
|
{ 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.#openMenu();
|
||||||
});
|
});
|
||||||
|
this.#triggeringButton.addEventListener("focusout", this.#onFocusOutBound);
|
||||||
|
|
||||||
const { signal } = this.#menuAC;
|
const { signal } = this.#menuAC;
|
||||||
|
|
||||||
@ -148,7 +162,12 @@ class Menu {
|
|||||||
stopEvent(e);
|
stopEvent(e);
|
||||||
break;
|
break;
|
||||||
default:
|
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 =>
|
this.#goToNextItem(e.target, true, item =>
|
||||||
item.textContent.trim().toLowerCase().startsWith(char)
|
item.textContent.trim().toLowerCase().startsWith(char)
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user