MENDO.MK Enhancement

Adds dark mode, search in tasks and other to MENDO.MK

目前为 2022-09-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name MENDO.MK Enhancement
  3. // @version 14
  4. // @namespace mendo-mk-enhancement
  5. // @description Adds dark mode, search in tasks and other to MENDO.MK
  6. // @author EntityPlantt
  7. // @match *://mendo.mk/*
  8. // @noframes
  9. // @icon https://mendo.mk/img/favicon.ico
  10. // @grant none
  11. // @license CC-BY-ND
  12. // ==/UserScript==
  13.  
  14. console.log("%cMENDO.MK Enhancement%c loaded", "color:magenta;text-decoration:underline", "");
  15. var loadingSuccess = 0;
  16. setTimeout(() => {
  17. if (loadingSuccess == 1) {
  18. console.log("Loading %csuccessful", "color:#0f0");
  19. }
  20. else if (loadingSuccess == 2) {
  21. console.log("Loading %cwith errors", "color:#ff0");
  22. }
  23. else {
  24. console.log("Loading %cunsuccessful", "color:red");
  25. }
  26. }, 1000);
  27. async function MendoMkEnhancement() {
  28. try {
  29. function logFinish(taskName) {
  30. console.log("%cFinished task:%c " + taskName, "color:#0f0", "");
  31. }
  32. console.groupCollapsed("Start log");
  33. var style = document.createElement("style");
  34. style.innerHTML = `
  35. ${ // Dark mode
  36. localStorage.getItem("mendo-mk-enhancement-theme") == "dark" ? `
  37. html, img, svg, #cboxOverlay, .copy-io-btn span {
  38. filter: invert(1) hue-rotate(180deg);
  39. }
  40. body, img, svg {
  41. background: white;
  42. }
  43. ::-webkit-scrollbar {
  44. width: initial;
  45. }
  46. ::-webkit-scrollbar-track {
  47. background: #eee;
  48. }
  49. body::-webkit-scrollbar-track {
  50. background: #111;
  51. }
  52. ::-webkit-scrollbar-thumb {
  53. background: #ddd;
  54. }
  55. body::-webkit-scrollbar-thumb {
  56. background: #222;
  57. }
  58. td.solved, td.correct {
  59. background: #bfb !important;
  60. }
  61. td.wrong {
  62. background: #fbb !important;
  63. }
  64. ` : ""}
  65. #search {
  66. font-family: consolas;
  67. }
  68. #search, #search-submit {
  69. border: solid 2px black;
  70. transition: box-shadow .5s;
  71. }
  72. #search-submit:hover {
  73. cursor: pointer;
  74. }
  75. #search:focus {
  76. background: #eee;
  77. }
  78. #search-submit:hover, #search:hover {
  79. background: #ddd;
  80. }
  81. .copy-io-btn {
  82. float: right;
  83. background: #ddd;
  84. padding: 5px;
  85. cursor: pointer;
  86. border-radius: 5px;
  87. user-select: none;
  88. }
  89. .copy-io-btn:hover {
  90. background: #e8e8e8;
  91. }
  92. #search:active, #search:focus, #search-submit:active, #search-submit:focus {
  93. box-shadow: 0 0 2.5px 2.5px black;
  94. }
  95. `;
  96. document.head.appendChild(style);
  97. logFinish("inject style sheet");
  98. if (/^http(s)?:\/\/(www\.)?mendo\.mk\/Training\.do/.test(document.URL)) {
  99. document.querySelectorAll("div.main-content > div:nth-child(3) > div > table > tbody > tr > td:nth-child(2) > a").forEach(e => {
  100. e.target = "_blank";
  101. });
  102. logFinish("make task links open in another window");
  103. var search = document.createElement("form");
  104. search.className = "content-search";
  105. search.action = "#";
  106. search.innerHTML = `
  107. <input type=text id=search autocomplete=off>
  108. <input type=submit id=search-submit value=Search>
  109. `;
  110. search.onsubmit = e => {
  111. e.preventDefault();
  112. location.hash = "#" + escape(search.querySelector("#search").value);
  113. hashChange();
  114. }
  115. function hashChange() {
  116. var kw = unescape(location.hash.substr(1));
  117. search.querySelector("#search").value = kw;
  118. kw = kw.toLowerCase();
  119. console.log("Searching keyword:", kw);
  120. document.querySelectorAll("body > div.page-container > div.main > div.main-content > div:nth-child(4) > div > table > tbody > tr").forEach(elm => {
  121. if (!elm.querySelector("td:nth-child(2) > a")) {
  122. return;
  123. }
  124. if (elm.innerText.toLowerCase().includes(kw) || elm.querySelector("td:nth-child(2) > a").href.toLowerCase().includes(kw)) {
  125. elm.style.display = "";
  126. }
  127. else {
  128. elm.style.display = "none";
  129. }
  130. });
  131. }
  132. window.onhashcange = hashChange;
  133. setTimeout(hashChange, 500);
  134. document.querySelector(".main-content").prepend(search);
  135. logFinish("add task search bar");
  136. document.querySelector("body > div.page-container > div.main > div.main-content > div:nth-child(3)").innerHTML += `<a href="./Training.do?cid=5">[ ${document.cookie.includes("mkjudge_language=en") ? "Other tasks" : "Други задачи"} ]</a>&nbsp;&nbsp;`;
  137. document.querySelector("body > div.page-container > div.main > div.main-content > div:last-child").innerHTML =
  138. document.querySelector("body > div.page-container > div.main > div.main-content > div:nth-child(3)").innerHTML;
  139. logFinish("add secret tasks");
  140. }
  141. if (document.querySelector("body > div.page-container > div.header > div.header-breadcrumbs > ul > li:last-child > a")) {
  142. window.name = document.querySelector("body > div.page-container > div.header > div.header-breadcrumbs > ul > li:last-child > a").innerText;
  143. }
  144. else if (document.querySelector(".pagetitle")) {
  145. window.name = document.querySelector(".pagetitle").innerText;
  146. }
  147. document.title = (document.querySelector("body > div.page-container > div.header > div.header-breadcrumbs > ul > li:last-child > a")
  148. ?? document.querySelector(".pagetitle")
  149. ?? document.querySelector(".pagename")
  150. ?? {innerText: document.URL.substr(document.URL.indexOf("/", 8))}
  151. ).innerText + " – МЕНДО";
  152. logFinish("document title set");
  153. if (document.URL.includes("Task.do?id=")) {
  154. document.querySelectorAll("body > div.page-container > div.main > div.main-content > div.column1-unit.taskContentView > table pre").forEach(pre => {
  155. var text = pre.innerText.substr(pre.innerText.indexOf("\n") + 1);
  156. var copyIoBtn = document.createElement("span");
  157. copyIoBtn.innerHTML = "<span>📃</span>";
  158. copyIoBtn.setAttribute("onclick", `navigator.clipboard.writeText(${JSON.stringify(text)})`);
  159. copyIoBtn.className = "copy-io-btn";
  160. pre.parentElement.appendChild(copyIoBtn);
  161. });
  162. logFinish("copy io buttons");
  163. }
  164. (document.querySelector(".footer") ?? {}).innerHTML += `<p class="credits">MENDO.MK Enhancement <a href="javascript:toggleTheme()">🎨</a></p>`;
  165. window.toggleTheme = () => {
  166. localStorage.setItem("mendo-mk-enhancement-theme", localStorage.getItem("mendo-mk-enhancement-theme") == "dark" ? "light" : "dark");
  167. location.reload();
  168. };
  169. logFinish("dark mode button");
  170. loadingSuccess = 1;
  171. if (/^https?:\/\/mendo\.mk\/.+\.do/.test(document.URL) && Math.random() < .01) {
  172. document.querySelector(".sitelogo").style.backgroundImage = "url(https://i1.sndcdn.com/artworks-TWCDacMc5lCrZIPb-2W7mgg-t500x500.jpg)";
  173. document.querySelector(".sitelogo").style.backgroundSize = "contain";
  174. document.querySelector(".sitename h1").innerText = "O B A M I U M";
  175. document.querySelector(".sitename h2").innerText = "Let Obamium bless you";
  176. (document.querySelector(".footer") || {}).innerHTML = "<p>Let Obamium bless you</p>";
  177. document.querySelectorAll("img").forEach(elm => {
  178. elm.src = "https://i1.sndcdn.com/artworks-TWCDacMc5lCrZIPb-2W7mgg-t500x500.jpg";
  179. elm.width = elm.height ||= 50;
  180. });
  181. logFinish("obamium");
  182. }
  183. }
  184. catch (_) {
  185. console.error(_);
  186. loadingSuccess = 2;
  187. }
  188. console.groupEnd();
  189. }
  190. window.MendoMkEnhancement = MendoMkEnhancement;
  191. MendoMkEnhancement();