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

2015-04-28 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==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.2
// @author        wOxxOm
// @namespace     wOxxOm.scripts
// @license       MIT License
// @run-at        document-start
// ==/UserScript==

var TEXT_FIELD = ' text number search url ';
var previousElement;
var toFocus;

document.addEventListener('keydown', function(e) {
  if (e.keyCode != 27 || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey)
    return;
  // find text inputs inside visible DOM containers
  var inputs = document.getElementsByTagName('input');
  var visible = [];
  for (var i=0, input, il=inputs.length; i<il && (input=inputs[i]); i++)
    if (TEXT_FIELD.indexOf(' '+input.type+' ') >= 0) {
      var n=input, style;
      while (n && n.style && (style=getComputedStyle(n)) && style.display!='none' && style.visibility!='hidden')
        n = n.parentNode;
      if (!n || !n.style) {
        visible.push(input);
        if (input.value)
          break;
      }
    }

  if (visible.length) {
    var toFocus = visible[0];
    // if empty, try to select an identically named input field with some text (happens on some sites)
    if (!toFocus.value)
      for (var i in visible)
        if (visible[i].value && visible[i].name == toFocus.name
            && (!visible[i].form && !toFocus.form || visible[i].form.action == toFocus.form.action)) {
          toFocus = visible[i];
          break;
        }
    if (toFocus != document.activeElement) {
      // switch to the found input field
      previousElement = document.activeElement;
      onkeyup(function(){
        toFocus.focus();
        toFocus.select();
      });
    } else if (previousElement) {
      // restore focus to the element from which we jumped to an input field previously
      onkeyup(function(){
        document.activeElement.blur(); // in case document.body (page "background") was previously selected
        previousElement.focus();
      });
    }
  }

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