Skip to content

Commit

Permalink
Fixed app menu tab navigation issue on Linux.
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyanziano committed Dec 10, 2019
1 parent 7e922ad commit d1806fa
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [2019](https://github.com/microsoft/BotFramework-Emulator/pull/2019)
- [2020](https://github.com/microsoft/BotFramework-Emulator/pull/2020)
- [2021](https://github.com/microsoft/BotFramework-Emulator/pull/2021)
- [2022](https://github.com/microsoft/BotFramework-Emulator/pull/2022)

- [main] Increased ngrok spawn timeout to 15 seconds to be more forgiving to slower networks in PR [1998](https://github.com/microsoft/BotFramework-Emulator/pull/1998)

Expand Down
19 changes: 18 additions & 1 deletion packages/app/client/src/utils/eventHandlers.spec.ts
Expand Up @@ -85,6 +85,10 @@ jest.mock('electron', () => ({
}));

const mockDOM = `
<ul class="app-menu">
<button id="file-btn">File</button>
<button id="edit-btn">Edit</button>
</ul>
<nav>
<button id="navBtn">NavBtn</button>
</nav>
Expand Down Expand Up @@ -267,7 +271,7 @@ describe('#globalHandlers', () => {
expect(mockRemoteCommandsCalled[0].commandName).toBe(ToggleDevTools);
});

it('should move focus to first element when Tab is pressed', async () => {
it('should move focus to first element when Tab is pressed on Mac', async () => {
const event = new KeyboardEvent('keydown', { key: 'Tab' });
Object.defineProperty(process, 'platform', { value: 'darwin' });

Expand All @@ -280,6 +284,19 @@ describe('#globalHandlers', () => {
expect(document.activeElement.id).toBe(mockFirstElement.id);
});

it('should move focus to first element when Tab is pressed on Linux', async () => {
const event = new KeyboardEvent('keydown', { key: 'Tab' });
Object.defineProperty(process, 'platform', { value: 'linux' });

document.body.innerHTML = mockDOM;
var mockFirstElement = document.getElementById('file-btn');
var mockLastElement = document.getElementById('btn3');
mockLastElement.focus();
await globalHandlers(event);

expect(document.activeElement.id).toBe(mockFirstElement.id);
});

it('should move focus to last element when Shift+Tab is pressed', async () => {
const event = new KeyboardEvent('keydown', { shiftKey: true, key: 'Tab' });
Object.defineProperty(process, 'platform', { value: 'darwin' });
Expand Down
17 changes: 12 additions & 5 deletions packages/app/client/src/utils/eventHandlers.ts
Expand Up @@ -137,13 +137,20 @@ class EventHandlers {

if (isMac() || isLinux()) {
const tabPressed: boolean = key === 'tab';
const lastDecendants = EventHandlers.getLastDecendants(document.querySelector('main'));
const firstElement = document.querySelector('nav').firstElementChild as HTMLElement;
const lastElement = lastDecendants[lastDecendants.length - 1] as HTMLElement;
const isFirstElement: boolean = document.activeElement === firstElement;
const isLastElement: boolean = document.activeElement === lastElement;

if (tabPressed) {
const lastDecendants = EventHandlers.getLastDecendants(document.querySelector('main'));
// TODO: More generalized approach to finding first and last focusable elements. This seems brittle.
let firstElement: HTMLElement;
if (isLinux()) {
firstElement = document.querySelector('[class*="app-menu"] button');
} else {
firstElement = document.querySelector('nav').firstElementChild as HTMLElement;
}
const lastElement = lastDecendants[lastDecendants.length - 1] as HTMLElement;
const isFirstElement: boolean = document.activeElement === firstElement;
const isLastElement: boolean = document.activeElement === lastElement;

if (shiftPressed && isFirstElement) {
lastElement.focus();
event.preventDefault();
Expand Down

0 comments on commit d1806fa

Please sign in to comment.