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

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==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);
}