Input Text Logger

Track continuous text input on websites and save to Tampermonkey's local storage

当前为 2023-12-27 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Input Text Logger
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Track continuous text input on websites and save to Tampermonkey's local storage
  6. // @include *
  7. // @grant GM_setValue
  8. // @grant GM_getValue
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. "use strict";
  13.  
  14. let currentText = "";
  15. let lastDomain = "";
  16. let lastTimestamp = "";
  17. let inactivityTimer;
  18.  
  19. // STYLES
  20. const popupStyle = `
  21. position: fixed;
  22. bottom: 100px;
  23. right: 10px;
  24.  
  25. display: none;
  26. flex-direction: column;
  27. gap: 10px;
  28. width: 200px;
  29. padding: 10px;
  30.  
  31. background: white;
  32. border: 1px solid black;
  33. `;
  34.  
  35. // Функція для зберігання даних
  36. function saveData(newText, newDomain, newTimestamp) {
  37. // Отримання існуючих даних
  38. let existingData = GM_getValue("savedText", []);
  39. console.log(23, "до", GM_getValue("savedText"));
  40.  
  41. // Додавання нових даних
  42. existingData.unshift({
  43. text: newText,
  44. domain: newDomain,
  45. timestamp: newTimestamp,
  46. });
  47.  
  48. // Збереження оновлених даних
  49. GM_setValue("savedText", existingData);
  50. console.log(31, "після", GM_getValue("savedText"));
  51. }
  52.  
  53. function resetInactivityTimer() {
  54. clearTimeout(inactivityTimer);
  55. inactivityTimer = setTimeout(() => {
  56. if (currentText.length > 0) {
  57. saveData(currentText, lastDomain, lastTimestamp);
  58. currentText = "";
  59. }
  60. }, 10000); // 10 секунд неактивності
  61. }
  62.  
  63. document.addEventListener("input", function (event) {
  64. const target = event.target;
  65. if (
  66. (target.tagName === "INPUT" && target.type !== "password") ||
  67. target.tagName === "TEXTAREA"
  68. ) {
  69. const domain = window.location.hostname;
  70. const timestamp = new Date().toISOString();
  71.  
  72. if (domain !== lastDomain) {
  73. if (currentText.length > 0) {
  74. saveData(currentText, lastDomain, lastTimestamp);
  75. }
  76. currentText = target.value;
  77. lastDomain = domain;
  78. lastTimestamp = timestamp;
  79. } else {
  80. currentText = target.value;
  81. }
  82. resetInactivityTimer();
  83. }
  84. });
  85.  
  86. // Обробник події натискання клавіші
  87. document.addEventListener("keydown", function (event) {
  88. if (event.key === "Enter") {
  89. const domain = window.location.hostname;
  90. const timestamp = new Date().toISOString();
  91.  
  92. if (currentText.length > 0) {
  93. saveData(currentText, domain, timestamp);
  94. currentText = "";
  95. }
  96. }
  97. });
  98.  
  99. window.addEventListener("blur", function () {
  100. if (currentText.length > 0) {
  101. saveData(currentText, lastDomain, lastTimestamp);
  102. currentText = "";
  103. }
  104. });
  105.  
  106. window.addEventListener("beforeunload", function () {
  107. if (currentText.length > 0) {
  108. saveData(currentText, lastDomain, lastTimestamp);
  109. }
  110. });
  111.  
  112. // Функція для створення попапа
  113. function createPopup() {
  114. const popupHTML = `
  115. <div id="tmPopup" class="pure-u-1-3" style="${popupStyle}">
  116. <button id="viewTextBtn" class="pure-button pure-button-primary">Переглянути текст</button>
  117. <button id="deleteDataBtn" class="button-warning pure-button">Очистити дані</button>
  118. </div>
  119. `;
  120.  
  121. document.body.insertAdjacentHTML("beforeend", popupHTML);
  122.  
  123. // Обробник для кнопки перегляду тексту
  124. document
  125. .getElementById("viewTextBtn")
  126. .addEventListener("click", function () {
  127. const savedData = GM_getValue("savedText", {});
  128. const dataStr = `Дані: ${JSON.stringify(savedData, null, 2)}`;
  129. const newTab = window.open();
  130. newTab.document.body.innerText = dataStr;
  131. });
  132. document
  133. .getElementById("deleteDataBtn")
  134. .addEventListener("click", function () {
  135. GM_setValue("savedText", []);
  136. });
  137. }
  138.  
  139. // Виклик функції для створення попапа
  140. createPopup();
  141.  
  142. // Створення круглої кнопки
  143. const circleBtnHTML = `
  144. <div id="circleBtn" style="width: 50px; height: 50px; border-radius: 50%; background-color: green; position: fixed; bottom: 100px; right: 10px; z-index: 9999;"></div>
  145. `;
  146.  
  147. document.body.insertAdjacentHTML("beforeend", circleBtnHTML);
  148.  
  149. const circleBtn = document.getElementById("circleBtn");
  150. const tmPopup = document.getElementById("tmPopup");
  151.  
  152. // Функція для розкриття попапа
  153. function togglePopup() {
  154. if (tmPopup.style.display === "none") {
  155. tmPopup.style.display = "flex";
  156. circleBtn.style.display = "none";
  157. }
  158. }
  159.  
  160. // Функція для закриття попапа
  161. function closePopup() {
  162. tmPopup.style.display = "none";
  163. circleBtn.style.display = "block";
  164. }
  165.  
  166. // Додавання обробника подій
  167. circleBtn.addEventListener("click", togglePopup);
  168. window.addEventListener("click", function (event) {
  169. if (event.target !== circleBtn && event.target !== tmPopup) {
  170. closePopup();
  171. }
  172. });
  173. })();