vimium icon indicating copy to clipboard operation
vimium copied to clipboard

Bug: ESC should always go to normal mode, even when websites try to prevent it (e.g. WhatsApp Web)

Open dotmike opened this issue 2 years ago • 6 comments

Describe the bug If you are focused in a text field in WhatsApp Web, it prevents you from leaving using ESC. For a non vim based UI this might make sense, but I would love an option to go back into normal mode.

So if a website prevents you from leaving a text field, vimium should be able to overwrite this and go into normal mode. There could also be added an option to disable this behavior, but in most cases I think this is an improvement.

To Reproduce Steps to reproduce the behavior:

  1. Open https://web.whatsapp.com/ and connect it with your phone
  2. Open a Chat
  3. Select the text field
  4. Press ESC, it doesn't work

Browser and Vimium version Firefox 90.0.2

dotmike avatar Aug 06 '21 16:08 dotmike

This issue is still present in the current version of Whatsapp Web and Vimium

snprajwal avatar Jun 28 '22 17:06 snprajwal

I actually wrote some JS to disable WhatsApp Web's ESC overwrite as a workaround. If you have a Browser extension like "User JavaScript and CSS" installed, you can use this code. I inserted this JS only for WhatsApp Web.

https://chrome.google.com/webstore/detail/user-javascript-and-css/nbhcbdghjpllgmfilhnhkllmkecfmpld

// On ESC, stop focusing the message textfield, there is a reason that key is on my keyboard...

window.onkeyup = (e) => {
    // Setup and debugging helper
	
    const key = e.keyCode
    var isCtrlPressed, isShiftPressed, isAltPressed = false;

    if (e.shiftKey) { isShiftPressed = true }
    if (e.ctrlKey) { isCtrlPressed = true }
    if (e.altKey) { isAltPressed = true }
    
    const shiftStr = isShiftPressed ? '+shift' : ''
    const ctrlStr = isCtrlPressed ? '+ctrl' : ''
    const altStr = isAltPressed ? '+alt' : ''

    // uncomment this and open console, to customize the keycodes.
    // console.log(`KeyCode: ${key} ${shiftStr} ${ctrlStr} ${altStr}`)
    
    // esc key pressed

    if (key === 17) {
	var messageField = document.activeElement

	// only run once (on every chat) to prevent event listener stacking
	if (messageField.dataset.isEscListenerSet !== true) {
	    messageField.dataset.isEscListenerSet = true;

	    messageField.addEventListener('focusout', event => {
    	        event.stopImmediatePropagation();
	    });
	}
    }
}

dotmike avatar Jun 29 '22 10:06 dotmike

My customized version of Vimium, named Vimium C (https://github.com/gdh1995/vimium-c), supports an option of Compatibility of Escape. The option is a list of CSS selectors, and when a user presses <esc> and a currently active element matches the selector, Vimium C won't block the Escape's keydown and keyup events.

I think this feature may help on WhatsApp. Could you help me do some tests? I'm sorry but I don't have any account of WhatsApp so I can not test it by myself.

gdh1995 avatar Jun 29 '22 15:06 gdh1995

Interesting Fork, I'm going to try it out. But the Compatibility of Escape option does not help on WhatsApp Web (or maybe I couldn't figure out what selector is needed). WhatsApp is using some customized solution, there is not even an <input> element there (HTML in my screenshot). But Thanks for trying :-)

whatsapp web

dotmike avatar Jun 29 '22 16:06 dotmike

It seems WhatsApp hides its input box on page blurring. Please try this:

  1. make the DevTools window seperate (into a standalone window) and keep it running
  2. click the input box so that you may type letters on it
  3. press Ctrl+Shift+C to enter the mode of Select an element
  4. move mouse over the input box, but not click it, so that the DevTools window won't grab back focus

gdh1995 avatar Jun 29 '22 17:06 gdh1995

It's seriously not there, I was wondering this while writing my JS above.

While writing my own script, I used a delay with setTimeout() and quickly focused the text field to check the DOM of WhatsApp Web. I can't get an input field using the separate dev tools window too like you suggested.

While the input is focused:

  • document.querySelectorAll('input') returns an empty NodeList.
  • document.activeElement returns a div somehow.

I don't have a lot of experience with (React is used I think), maybe there is some other way to create an input field that is used by WhatsApp.

Well anyway, my solution above might not be the most elegant way, but it works perfectly fine for me.

dotmike avatar Jun 29 '22 20:06 dotmike