Skip to content

Commit

Permalink
Merge 50b4d5c into cb08d7d
Browse files Browse the repository at this point in the history
  • Loading branch information
denscollo committed Nov 26, 2019
2 parents cb08d7d + 50b4d5c commit 1b414d8
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [1997](https://github.com/microsoft/BotFramework-Emulator/pull/1997)
- [1999](https://github.com/microsoft/BotFramework-Emulator/pull/1999)
- [2000](https://github.com/microsoft/BotFramework-Emulator/pull/2000)
- [2001](https://github.com/microsoft/BotFramework-Emulator/pull/2001)
- [2009](https://github.com/microsoft/BotFramework-Emulator/pull/2009)
- [2010](https://github.com/microsoft/BotFramework-Emulator/pull/2010)

Expand Down
39 changes: 39 additions & 0 deletions packages/app/client/src/utils/eventHandlers.spec.ts
Expand Up @@ -84,6 +84,19 @@ jest.mock('electron', () => ({
},
}));

const mockDOM = `
<nav>
<button id="navBtn">NavBtn</button>
</nav>
<main>
<button id="btn1">btn 1</button>
<button id="btn2">btn 2</button>
<div>
<button id="btn3">btn 3</button>
</div>
</main>
`;

describe('#globalHandlers', () => {
let commandService: CommandServiceImpl;

Expand Down Expand Up @@ -253,4 +266,30 @@ describe('#globalHandlers', () => {
expect(mockRemoteCommandsCalled).toHaveLength(1);
expect(mockRemoteCommandsCalled[0].commandName).toBe(ToggleDevTools);
});

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

document.body.innerHTML = mockDOM;
var mockFirstElement = document.getElementById('navBtn');
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' });

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

expect(document.activeElement.id).toBe(mockLastElement.id);
});
});
54 changes: 43 additions & 11 deletions packages/app/client/src/utils/eventHandlers.ts
Expand Up @@ -30,47 +30,65 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

import { Notification, NotificationType, SharedConstants } from '@bfemulator/app-shared';
import { CommandServiceImpl, CommandServiceInstance } from '@bfemulator/sdk-shared';
import { remote } from 'electron';

import { isMac } from '../../../../app/main/src/utils/platform';
const maxZoomFactor = 3; // 300%
const minZoomFactor = 0.25; // 25%;

class EventHandlers {
@CommandServiceInstance()
public static commandService: CommandServiceImpl;

private static getLastChildWithChildren(node) {
for (let index = node.children.length; index > 0; index--) {
if (node.children[index - 1].children.length > 0 && !node.children[index - 1].hidden) {
return node.children[index - 1];
}
}
}

private static getLastDecendants(node, list = []) {
if (node.children.length > 0) {
const child = this.getLastChildWithChildren(node);
if (child) {
list.push(child);
this.getLastDecendants(child, list);
}
}

const result = [].filter.call(list[list.length - 1].children, element => !element.hasAttribute('disabled'));

return result;
}

public static async globalHandles(event: KeyboardEvent): Promise<any> {
// Meta corresponds to 'Command' on Mac
const ctrlOrCmdPressed = event.ctrlKey || event.metaKey;
const shiftPressed = event.shiftKey;
const key = event.key.toLowerCase();
const keyCode = event.keyCode;
const {
Commands: {
Electron: { ToggleDevTools },
UI: { ShowBotCreationDialog, ShowOpenBotDialog },
Notifications: { Add },
},
} = SharedConstants;

let awaitable: Promise<any>;
// Ctrl+O
if (ctrlOrCmdPressed && key === 'o') {
awaitable = EventHandlers.commandService.call(ShowOpenBotDialog);
}

// Ctrl+N
if (ctrlOrCmdPressed && key === 'n') {
awaitable = EventHandlers.commandService.call(ShowBotCreationDialog);
}

// Ctrl+0
if (ctrlOrCmdPressed && key === '0') {
remote.getCurrentWebContents().setZoomLevel(0);
}

// Ctrl+= or Ctrl+Shift+=
if (ctrlOrCmdPressed && (key === '=' || key === '+')) {
const webContents = remote.getCurrentWebContents();
Expand All @@ -83,7 +101,6 @@ class EventHandlers {
}
});
}

// Ctrl+- or Ctrl+Shift+-
if (ctrlOrCmdPressed && (key === '-' || key === '_')) {
const webContents = remote.getCurrentWebContents();
Expand All @@ -96,18 +113,15 @@ class EventHandlers {
}
});
}

// F11
if (key === 'f11') {
const currentWindow = remote.getCurrentWindow();
currentWindow.setFullScreen(!currentWindow.isFullScreen());
}

// Ctrl+Shift+I
if (ctrlOrCmdPressed && shiftPressed && key === 'i') {
awaitable = EventHandlers.commandService.remoteCall(ToggleDevTools);
}

if (awaitable) {
// Prevents the char from showing up if an input is focused
event.preventDefault();
Expand All @@ -121,7 +135,25 @@ class EventHandlers {
} as Notification);
}
}

if (isMac()) {
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) {
if (shiftPressed && isFirstElement) {
lastElement.focus();
event.preventDefault();
} else if (!shiftPressed && isLastElement) {
firstElement.focus();
event.preventDefault();
}
}
}
}
}

export const globalHandlers = EventHandlers.globalHandles;

0 comments on commit 1b414d8

Please sign in to comment.