Toggle Passwords

Places an eye-icon at the right side of every password field. Clicking this icon toggles the display of all passwords between •••• and text.(submitting a form will allways revert the fields to type=password, to make sure no auto-completion information is stored for these fields by your browser.)

当前为 2019-07-17 提交的版本,查看 最新版本

  1. //
  2. // ==UserScript==
  3. // @name Toggle Passwords
  4. // @namespace http://jaron.nl/
  5. // @description Places an eye-icon at the right side of every password field. Clicking this icon toggles the display of all passwords between •••• and text.(submitting a form will allways revert the fields to type=password, to make sure no auto-completion information is stored for these fields by your browser.)
  6. // @version 2.0.2
  7. // @include *
  8. // @exclude
  9. // ==/UserScript==
  10. (() => {
  11. const css = `
  12. .tggl-pw {
  13. --icon-width: 18px;
  14. --icon-height: calc(2 * var(--icon-width) / 3);
  15. --pd-v: 10px;
  16. --pd-h: 15px;
  17.  
  18. position: relative;
  19. display: inline-block;
  20. border-radius: 5px;
  21. background: white;
  22. vertical-align: middle;
  23. }
  24.  
  25. /*
  26. .tggl-pw::before {
  27. content: '';
  28. display: block;
  29. position: absolute;
  30. border: 8px solid transparent;
  31. border-right-color: white;
  32. top: 50%;
  33. transform: translateY(-50%);
  34. right: 100%;
  35. }
  36. */
  37.  
  38. .tggl-pw__btn {
  39. --hide-icon: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 60"><path d="M45 15c-2.8 0-5.3.8-7.6 2.1 1.3 1.1 2.1 2.7 2.1 4.5 0 3.2-2.6 5.8-5.8 5.8-1.2 0-2.4-.4-3.3-1-.2 1.1-.4 2.3-.4 3.6 0 8.3 6.7 15 15 15s15-6.7 15-15-6.7-15-15-15z"/><g stroke="black" stroke-width="7" stroke-miterlimit="10"><path fill="none" stroke-linecap="round" d="M5 55L85 5"/><path d="M85 30S67.1 55 45 55 5 30 5 30 22.9 5 45 5s40 25 40 25z" fill="none"/></g></svg>');
  40.  
  41. --show-icon: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 60"><style></style><g id="Layer_4"><path d="M85 30S67.1 55 45 55 5 30 5 30 22.9 5 45 5s40 25 40 25z" fill="none" stroke="black" stroke-width="7" stroke-miterlimit="10"/><path d="M45 15c-2.8 0-5.3.8-7.6 2.1 1.3 1.1 2.1 2.7 2.1 4.5 0 3.2-2.6 5.8-5.8 5.8-1.2 0-2.4-.4-3.3-1-.2 1.1-.4 2.3-.4 3.6 0 8.3 6.7 15 15 15s15-6.7 15-15-6.7-15-15-15z"/></g></svg>');
  42.  
  43. position: absolute;
  44. z-index: 1;
  45. top: 50%;
  46. left: 0;
  47. width: 100%;
  48. height: 100%;
  49. border: none;
  50. padding: var(--pd-v) var(--pd-h);
  51. width: 0;
  52. height: 0;
  53. transform: translate(-100%, -50%);
  54. cursor: pointer;
  55. background: var(--show-icon) center center no-repeat;
  56. background-size: var(--icon-width) var(--icon-height);
  57. background-color: white;
  58. opacity: 0.5;
  59. transition: opacity 0.3s ease-in-out;
  60. }
  61.  
  62. .tggl-pw__btn:hover,
  63. .tggl-pw__btn:focus {
  64. outline: none;
  65. opacity: 0.8;
  66. }
  67.  
  68. .tggl-pw__btn--hide {
  69. background-image: var(--hide-icon);
  70. }
  71. `;
  72.  
  73. let pwFields = [];
  74. let allToggleBtns = [];
  75.  
  76. /**
  77. * add a toggle to a password field
  78. * @returns {undefined}
  79. */
  80. const addToggle = function(pwField) {
  81. const span = document.createElement('span');
  82. const btn = document.createElement('button');
  83. span.classList.add('tggl-pw');
  84. btn.classList.add('tggl-pw__btn');
  85. btn.type = "button";
  86. btn.title = "toggle all password fields";
  87. span.appendChild(btn);
  88. btn.addEventListener('click', toggleAllFields);
  89. pwField.after(span);
  90. allToggleBtns.push(btn);
  91. };
  92.  
  93. /**
  94. * toggle all password fields
  95. * @returns {undefined}
  96. */
  97. const toggleAllFields = function(e) {
  98. let newType;
  99. pwFields.forEach((pwField) => {
  100. if (!newType) {
  101. newType = (pwField.type === 'password') ? 'text' : 'password';
  102. }
  103. pwField.type = newType;
  104.  
  105. allToggleBtns.forEach((btn) => {
  106. if (pwField.type === 'password') {
  107. btn.classList.remove('tggl-pw__btn--hide');
  108. } else {
  109. btn.classList.add('tggl-pw__btn--hide');
  110. }
  111. });
  112. });
  113. };
  114.  
  115. /**
  116. * reset all password fields to type password
  117. * @returns {undefined}
  118. */
  119. const resetAllPwFields = function(e) {
  120. pwFields.forEach(pwField => pwField.type = 'password')
  121. };
  122.  
  123. /**
  124. * initialize
  125. * @returns {undefined}
  126. */
  127. const init = function() {
  128. pwFields = document.querySelectorAll(`input[type="password"]`) ;
  129. pwFields.forEach((pwField) => {
  130. addToggle(pwField);
  131. const currForm = pwField.closest('form');
  132. if (currForm) {
  133. currForm.addEventListener('submit', resetAllPwFields);
  134. }
  135. });
  136. const styles = document.createElement('style');
  137. styles.innerHTML = css;
  138. document.querySelector('head').appendChild(styles);
  139. };
  140.  
  141. init();
  142. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址