0
votes

Is there any way to programmatically trigger keyboard shortcuts from Javascript? For example, take gmail.com, where pressing 'e' will archive the selected email.

Could I write any type of code (say in a Chrome Extension) that can simulate the user pressing 'e' on the keyboard?

E.g. I tried copy-pasting something like this in the Chrome console:

document.body.addEventListener('keydown', function(event) {
  console.log('key detected: ', event);
});

document.body.addEventListener('click', () => {
  console.log('click...');
    document.body.dispatchEvent(new KeyboardEvent('keydown', {
    'key': 'e',
    'keyCode': 69,
    'which': 69,
    'code': 'KeyE',
    'isTrusted': true,  // this has no effect
    'bubbles': true,
    'cancelable': true,
    'view': window,
    'charCode': 0,
  }));
});

So any click on the page will print the key, which looks the same as pressing 'e' on the keyboard. But the click event keypress does not trigger the 'archive' feature in Gmail.

Is it that the event is not trusted, and it's not possible to do what I had intended?

1
Yes, I'm aware, so is that the reason why this doesn't work?kufudo
Tried all that, none of that works.kufudo

1 Answers

1
votes

I found a working solution that does what I need. It works only in a Chrome Extension (there could be similar methods for Firefox Extensions and other browsers). I could not find any native JavaScript only solution (I believe it's not possible by design due to untrusted events).

In any case, the Chrome Extension solution works as follows:

// Attach debugger to the active tab (it's the only way to send
// trusted events.
chrome.debugger.attach({tabId: tab.id}, '1.2', () => {
  // Create shortcut args and send to the tab.
  const eventArgs = {
    'modifiers': 0,
    'text': 'e',
    'unmodifiedText': 'e',
    'key': 'e',
    'code': 'KeyE',
    'windowsVirtualKeyCode': 69,
    'type': 'keyDown'
  };
  chrome.debugger.sendCommand(
    {tabId: tab.id}, 'Input.dispatchKeyEvent', eventArgs,
      (result) => {
        if (chrome.runtime.lastError) {
          console.warn('Error sending the shortcut to active tab:',
              chrome.runtime.lastError);
        }
        chrome.debugger.detach({tabId: tab.id});
      });
    });
  });

Note that the debugger can't attach on some very specific websites like gmail.com or drive.google.com when users have a Chrome App installed for these sites. You may see an error like:

Cannot attach to this target.

See https://bugs.chromium.org/p/chromium/issues/detail?id=885025 for details. The only workaround is to uninstall the Chrome Apps for the target sites.