Naurok Auto Copy & Notify (Enhanced Version)

Оптимизированное автокопирование вопросов и ответов с изображениями

安装此脚本?
作者推荐脚本

您可能也喜欢Naurok Bypass v2

安装此脚本
  1. // ==UserScript==
  2. // @name Naurok Auto Copy & Notify (Enhanced Version)
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.4
  5. // @description Оптимизированное автокопирование вопросов и ответов с изображениями
  6. // @author ENDERVANO
  7. // @license MIT
  8. // @match *://naurok.com.ua/test/testing/*
  9. // @grant GM_setClipboard
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. let currentQuestionId = null;
  16. let darkMode = false;
  17.  
  18. function getCurrentQuestionId() {
  19. const questionElem = document.querySelector('.test-content-text-inner');
  20. if (!questionElem) return null;
  21. const imageUrl = document.querySelector('.test-content-image img')?.src || '';
  22. return questionElem.innerText.trim() + imageUrl;
  23. }
  24.  
  25. function formatQuestion() {
  26. let questionElem = document.querySelector('.test-content-text-inner');
  27. let question = questionElem ? questionElem.innerText.trim() : "Вопрос не найден";
  28.  
  29. // Улучшенная проверка наличия изображения
  30. let imageElem = document.querySelector('.test-content-image img');
  31. let imageText = "";
  32. if (imageElem && imageElem.src && !imageElem.src.endsWith('/')) {
  33. imageText = `\n[Изображение вопроса: ${imageElem.src}]`;
  34. }
  35.  
  36. let answerElems = document.querySelectorAll('.question-option-inner');
  37. let answers = [];
  38. let correctAnswers = [];
  39.  
  40. answerElems.forEach((el, index) => {
  41. let textElem = el.querySelector('.question-option-inner-content');
  42. let imageElem = el.querySelector('.question-option-image');
  43.  
  44. let text = textElem ? textElem.innerText.trim() : "";
  45.  
  46. // Улучшенная проверка наличия изображения в ответе
  47. let answerImage = "";
  48. if (imageElem && imageElem.style.backgroundImage &&
  49. imageElem.style.backgroundImage !== 'none' &&
  50. !imageElem.style.backgroundImage.includes('url("")')) {
  51. answerImage = ` [Изображение ответа: ${imageElem.style.backgroundImage.replace(/url\(["']?(.*?)["']?\)/, '$1')}]`;
  52. }
  53.  
  54. let answerText = `${index + 1}) ${text}${answerImage}`;
  55. if (text.trim()) {
  56. answers.push(answerText);
  57. if (el.classList.contains('correct')) {
  58. correctAnswers.push(answerText);
  59. }
  60. }
  61. });
  62.  
  63. return {
  64. question: question,
  65. imageText: imageText,
  66. answers: answers,
  67. correctAnswers: correctAnswers
  68. };
  69. }
  70.  
  71. function addCopyButton() {
  72. const newQuestionId = getCurrentQuestionId();
  73. if (!newQuestionId) return;
  74.  
  75. if (newQuestionId === currentQuestionId && document.querySelector("#copyQuestionButton")) return;
  76.  
  77. currentQuestionId = newQuestionId;
  78.  
  79. let questionContainer = document.querySelector('.test-content-text') ||
  80. document.querySelector('.test-content') ||
  81. document.querySelector('.question-container');
  82.  
  83. if (!questionContainer) return;
  84.  
  85. let oldButton = document.querySelector("#copyQuestionButton");
  86. if (oldButton) oldButton.remove();
  87.  
  88. let oldControls = document.querySelector("#questionControls");
  89. if (oldControls) oldControls.remove();
  90.  
  91. const formattedContent = formatQuestion();
  92. if (!formattedContent.question || formattedContent.answers.length === 0) return;
  93.  
  94. let copyText = `❓ Вопрос: ${formattedContent.question}${formattedContent.imageText}\n\n` +
  95. `🔹 Варианты ответов:\n${formattedContent.answers.join("\n")}`;
  96.  
  97. if (formattedContent.correctAnswers.length > 0) {
  98. copyText += `\n\n Правильные ответы:\n${formattedContent.correctAnswers.join("\n")}`;
  99. }
  100.  
  101. // Create controls container
  102. let controls = document.createElement("div");
  103. controls.id = "questionControls";
  104. controls.style.cssText = `
  105. display: flex;
  106. gap: 10px;
  107. margin-top: 15px;
  108. width: 100%;
  109. `;
  110.  
  111. // Create copy button
  112. let copyButton = document.createElement("button");
  113. copyButton.id = "copyQuestionButton";
  114. copyButton.innerHTML = "📋 Скопировать вопрос";
  115. copyButton.style.cssText = `
  116. flex: 1;
  117. padding: 12px 20px;
  118. background: ${darkMode ? '#2c3e50' : '#007BFF'};
  119. color: white;
  120. border: none;
  121. border-radius: 8px;
  122. cursor: pointer;
  123. font-size: 16px;
  124. font-weight: bold;
  125. text-align: center;
  126. transition: all 0.3s ease-in-out;
  127. box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
  128. `;
  129.  
  130. // Create theme toggle button
  131. let themeButton = document.createElement("button");
  132. themeButton.innerHTML = darkMode ? "☀️" : "🌙";
  133. themeButton.style.cssText = `
  134. padding: 12px 20px;
  135. background: ${darkMode ? '#2c3e50' : '#007BFF'};
  136. color: white;
  137. border: none;
  138. border-radius: 8px;
  139. cursor: pointer;
  140. font-size: 16px;
  141. font-weight: bold;
  142. transition: all 0.3s ease-in-out;
  143. box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
  144. `;
  145.  
  146. copyButton.onmouseover = () => copyButton.style.background = darkMode ? '#34495e' : '#0056b3';
  147. copyButton.onmouseout = () => copyButton.style.background = darkMode ? '#2c3e50' : '#007BFF';
  148.  
  149. copyButton.onclick = function () {
  150. GM_setClipboard(copyText, "text");
  151. showNotification("Скопировано!", formattedContent.imageText ? document.querySelector('.test-content-image img')?.src : null);
  152. };
  153.  
  154. themeButton.onclick = function () {
  155. darkMode = !darkMode;
  156. themeButton.innerHTML = darkMode ? "☀️" : "🌙";
  157. copyButton.style.background = darkMode ? '#2c3e50' : '#007BFF';
  158. themeButton.style.background = darkMode ? '#2c3e50' : '#007BFF';
  159. };
  160.  
  161. controls.appendChild(copyButton);
  162. controls.appendChild(themeButton);
  163. questionContainer.appendChild(controls);
  164. }
  165.  
  166. function showNotification(message, imageUrl) {
  167. let existingNotification = document.querySelector("#copyNotification");
  168. if (existingNotification) existingNotification.remove();
  169.  
  170. let notification = document.createElement("div");
  171. notification.id = "copyNotification";
  172. notification.style.cssText = `
  173. position: fixed;
  174. top: 20px;
  175. right: 20px;
  176. background: ${darkMode ? '#2c3e50' : 'white'};
  177. color: ${darkMode ? 'white' : 'black'};
  178. padding: 15px 20px;
  179. border-radius: 10px;
  180. box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2);
  181. display: flex;
  182. align-items: center;
  183. font-size: 16px;
  184. font-weight: bold;
  185. z-index: 9999;
  186. opacity: 0;
  187. transform: translateX(50px);
  188. transition: opacity 0.3s ease, transform 0.3s ease;
  189. `;
  190.  
  191. let icon = document.createElement("img");
  192. icon.src = "https://cdn-icons-png.flaticon.com/512/190/190411.png";
  193. icon.style.cssText = "width: 30px; height: 30px; margin-right: 10px;";
  194.  
  195. let text = document.createElement("span");
  196. text.innerText = message;
  197.  
  198. notification.appendChild(icon);
  199. notification.appendChild(text);
  200.  
  201. if (imageUrl && !imageUrl.endsWith('/')) {
  202. let image = document.createElement("img");
  203. image.src = imageUrl;
  204. image.style.cssText = "width: 40px; height: 40px; margin-left: 10px; border-radius: 5px;";
  205. notification.appendChild(image);
  206. }
  207.  
  208. document.body.appendChild(notification);
  209.  
  210. setTimeout(() => {
  211. notification.style.opacity = "1";
  212. notification.style.transform = "translateX(0)";
  213. }, 50);
  214.  
  215. setTimeout(() => {
  216. notification.style.opacity = "0";
  217. notification.style.transform = "translateX(50px)";
  218. setTimeout(() => notification.remove(), 300);
  219. }, 2000);
  220. }
  221.  
  222. function observeChanges() {
  223. const observer = new MutationObserver((mutations) => {
  224. for (let mutation of mutations) {
  225. if (mutation.type === 'childList' ||
  226. (mutation.type === 'attributes' && mutation.attributeName === 'class')) {
  227. addCopyButton();
  228. break;
  229. }
  230. }
  231. });
  232.  
  233. const container = document.querySelector('.question-container') || document.body;
  234. observer.observe(container, {
  235. childList: true,
  236. subtree: true,
  237. attributes: true,
  238. attributeFilter: ['class']
  239. });
  240. }
  241.  
  242. function init() {
  243. addCopyButton();
  244. observeChanges();
  245. setTimeout(addCopyButton, 1000);
  246. setTimeout(addCopyButton, 2000);
  247. setTimeout(addCopyButton, 3000);
  248. }
  249.  
  250. if (document.readyState === 'loading') {
  251. document.addEventListener('DOMContentLoaded', init);
  252. } else {
  253. init();
  254. }
  255. })();