Focus input text field on Esc

Focus the first visible input text field when you press Esc key, or restore the previously focused element on second press

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name          Focus input text field on Esc
// @description   Focus the first visible input text field when you press Esc key, or restore the previously focused element on second press
// @version       1.0.11
// @include       *
// @author        wOxxOm
// @namespace     wOxxOm.scripts
// @license       MIT License
// @run-at        document-start
// @grant         none
// ==/UserScript==

var TEXT_FIELD = ' search text number url textarea ';
var previousElement;
var scrollPos;
var first;

window.addEventListener('keydown', function (e) {
  if (e.defaultPrevented || e.which !== 27 || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
    return;
  }
  if (window !== top) {
    rememberFocus();
    window.addEventListener('message', maybeRestoreFocus);
    top.postMessage(GM_info.script.name, '*');
    e.preventDefault();
    e.stopPropagation();
    return;
  }
  run();
}, true);

if (window === top) {
  window.addEventListener('message', function (e) {
    if (e.data === GM_info.script.name) {
      run({relayedFromFrame: true});
    }
  });
}

function run(params) {
  // find text inputs inside visible DOM containers
  var inputs = [];
  populateInputs(inputs);
  for (var i = 0, input, il = inputs.length; i < il && (input = inputs[i]); i++) {
    var priority = TEXT_FIELD.indexOf(' ' + input.type + ' ');
    if (priority < 0) continue;
    var n = input, style;
    while (n && n.style && (style = getComputedStyle(n)) && style.display !== 'none' && style.visibility !== 'hidden') {
      n = n.parentNode;
    }
    // visible if reached DOM root
    if (n && n.style) continue;
    // set the first OR if it's empty, try to select an identically named input field with some text (happens on some sites)
    if (!first || (
      input.value &&
      input.name === first.name && (
        !input.form && !first.form ||
        input.form && first.form && input.form.action === first.form.action
      )
    )) {
      first = input;
      if (first.value) break;
    }
  }

  if (!first) return;

  var invoke = params && params.relayedFromFrame ? passthru : onkeyup;

  if (first !== getActiveElement()) {
    rememberFocus();
    invoke(setFocus);
  } else if (previousElement) {
    invoke(restoreFocus);
    if (previousElement && previousElement.localName === 'iframe') {
      previousElement.contentWindow.postMessage(GM_info.script.name, '*');
    }
  }
}

function populateInputs(inputs, root) {
  var walker = document.createTreeWalker(root || document, NodeFilter.SHOW_ELEMENT);
  var el;
  while ((el = walker.nextNode())) {
    if (el.shadowRoot)
      populateInputs(inputs, el.shadowRoot);
    if (/^(input|textarea)$/.test(el.localName))
      inputs.push(el);
  }
}

function getActiveElement() {
  var el = document.activeElement;
  while (el) {
    if (!el.shadowRoot)
      return el;
    el = el.shadowRoot.activeElement;
  }
}

function rememberFocus() {
  previousElement = document.activeElement;
  scrollPos = [scrollX, scrollY];
}

function setFocus() {
  first.focus();
}

function restoreFocus() {
  // in case document.body (page "background") was previously selected
  document.activeElement.blur();
  previousElement.focus();
  scrollTo(scrollPos[0], scrollPos[1]);
}

function maybeRestoreFocus(e) {
  if (e.data === GM_info.script.name) {
    restoreFocus();
  }
}

// focusing should be done at key-up to prevent the Esc-keydown being also chain-handled by the just focused element
function onkeyup(cb) {
  window.addEventListener('keyup', function keyup(e) {
    if (e.which !== 27) return;
    window.removeEventListener('keyup', keyup);
    if (e.defaultPrevented) return;
    cb(e);
  });
}

function passthru(fn) {
  return fn.apply(this, arguments);
}