Reveals passwords on mouse hover or focus, with improved performance, features, and safety.
// ==UserScript== // @name Advanced Password Revealer // @namespace http://userscripts.org/users/23652 // @description Reveals passwords on mouse hover or focus, with improved performance, features, and safety. // @include http://* // @include https://* // @include file:///* // @exclude file:///*/perf.html* // @copyright JoeSimmons // @version 1.2.0 // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html // ==/UserScript== (function() { const showOnlyOnClick = false; // Change to true to show passwords only on click const handlers = new Set(); function togglePasswordVisibility(input, show) { const { selectionStart, selectionEnd, type } = input; input.type = show ? 'text' : 'password'; input.setSelectionRange(selectionStart, selectionEnd); } function handleFocus(event) { const input = event.target; if (input.tagName === 'INPUT' && input.type === 'password') { togglePasswordVisibility(input, true); } } function handleBlur(event) { const input = event.target; if (input.tagName === 'INPUT' && input.type === 'text') { togglePasswordVisibility(input, false); } } function addHandlers() { const passwordFields = document.querySelectorAll('input[type="password"]'); passwordFields.forEach(field => { if (!handlers.has(field)) { field.addEventListener('focus', handleFocus); field.addEventListener('blur', handleBlur); handlers.add(field); } }); } function setupGlobalListeners() { if (!showOnlyOnClick) { window.addEventListener('mouseover', handleFocus); window.addEventListener('mouseout', handleBlur); } } function observeMutations() { const observer = new MutationObserver(addHandlers); observer.observe(document.body, { childList: true, subtree: true }); } // Initialize the script function init() { addHandlers(); setupGlobalListeners(); observeMutations(); // Watch for changes in the DOM } // Start the script init(); })();