AnkiWeb Quiz

Shows quiz on ankiweb.

当前为 2023-07-03 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name AnkiWeb Quiz
  3. // @namespace https://greasyfork.org/users/102866
  4. // @description Shows quiz on ankiweb.
  5. // @match https://ankiuser.net/*
  6. // @match https://ankiweb.net/*
  7. // @author TiLied
  8. // @version 2.0.00
  9. // @grant GM_openInTab
  10. // @grant GM_listValues
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @grant GM_deleteValue
  14. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  15. // @grant GM.openInTab
  16. // @grant GM.listValues
  17. // @grant GM.getValue
  18. // @grant GM.setValue
  19. // @grant GM.deleteValue
  20. // ==/UserScript==
  21.  
  22. class AnkiWebQuiz {
  23. _Options = new Object();
  24. _Decks = new Object();
  25.  
  26. _DeckId;
  27.  
  28. constructor() {
  29. console.log("AnkiWeb Quiz v" + GM.info.script.version + " initialization");
  30.  
  31. this._LoadOptionsAndDecks();
  32. this._SetCSS();
  33. //_FirstTime();
  34. }
  35.  
  36. _SetCSS() {
  37. globalThis.window.document.head.append("<!--Start of AnkiWeb Quiz v" + GM.info.script.version + " CSS-->");
  38.  
  39.  
  40. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>div.awq_quizGrid" +
  41. "{" +
  42. "display: grid;" +
  43. "grid-template-columns: repeat(4,auto);" +
  44. "grid-template-rows: auto;" +
  45. "}</style>");
  46.  
  47. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>div.awq_quizButton" +
  48. "{" +
  49. "color: #fff;" +
  50. "background-color: #0275d8;" +
  51. "border-color: #0275d8;" +
  52. "padding: .75rem 1.5rem;" +
  53. "font-size: 1rem;" +
  54. "border-radius: .3rem;" +
  55. "border: 1px solid transparent;" +
  56. "max-width:250px;" +
  57. "margin:5px;" +
  58. "cursor: pointer;" +
  59. "max-height: 300px;" +
  60. "overflow: auto;" +
  61. "}</ style >");
  62. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>div.awq_quizButton:hover" +
  63. "{" +
  64. "background-color: #025aa5;" +
  65. "}</ style >");
  66.  
  67. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>div.awq_true" +
  68. "{" +
  69. "background-color: #75d802;" +
  70. "}</style>");
  71. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>div.awq_true:hover" +
  72. "{" +
  73. "background-color: #5aa502;" +
  74. "}</style>");
  75. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>.awq_trueBorder" +
  76. "{" +
  77. "border-color: #75d802;" +
  78. "}</style>");
  79. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>div.awq_false" +
  80. "{" +
  81. "background-color: #d80275;" +
  82. "}</style>");
  83. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>div.awq_false:hover" +
  84. "{" +
  85. "background-color: #a5025a;" +
  86. "}</style>");
  87. globalThis.window.document.head.insertAdjacentHTML("beforeend", "<style type='text/css'>.awq_falseBorder" +
  88. "{" +
  89. "border-color: #d80275;" +
  90. "}</style>");
  91.  
  92. globalThis.window.document.head.append("<!--End of AnkiWeb Quiz v" + GM.info.script.version + " CSS-->");
  93.  
  94. }
  95.  
  96. async _LoadOptionsAndDecks() {
  97. this._Options = await GM.getValue("awqOptions");
  98. this._Decks = await GM.getValue("awqDecks");
  99.  
  100. if (this._Options == null)
  101. this._Options = new Object();
  102. if (this._Decks == null)
  103. this._Decks = new Object();
  104.  
  105. //Console log prefs with value
  106. console.log("*prefs:");
  107. console.log("*-----*");
  108.  
  109. let vals = await GM.listValues();
  110.  
  111. for (let i = 0; i < vals.length; i++) {
  112. console.log("*" + vals[i] + ":" + await GM.getValue(vals[i]));
  113. }
  114. console.log("*-----*");
  115. }
  116.  
  117. async Main() {
  118. if (globalThis.window.document.location.pathname.startsWith("/decks")) {
  119. let strs = globalThis.window.document.querySelectorAll("button.btn-link");
  120. for (let i = 0; i < strs.length; i++) {
  121. let _id = strs[i].id;
  122.  
  123. //Console.WriteLine(_id);
  124.  
  125. if (_id.startsWith("did")) {
  126. if (this._Decks[_id.substring(3)] == null)
  127. this._Decks[_id.substring(3)] = new Object();
  128.  
  129. strs[i].addEventListener("click", () => {
  130. GM.setValue("awqDeckId", _id.substring(3));
  131. }, true);
  132. }
  133. }
  134. GM.setValue("awqDecks", this._Decks);
  135. }
  136. if (globalThis.window.document.location.pathname.startsWith("/study")) {
  137. this._DeckId = await GM.getValue("awqDeckId");
  138. if (this._DeckId == null) {
  139. console.log("Deck id is null");
  140. return;
  141. }
  142.  
  143. let _study = globalThis.window.eval("study");
  144. console.log(_study);
  145.  
  146. if (_study["currentCard"] == null) {
  147. globalThis.window.setTimeout(() => {
  148. this.Main();
  149. }, 1000);
  150. return;
  151. }
  152.  
  153. let _id = _study["currentCard"]["cardId"];
  154.  
  155. this._Decks[this._DeckId][_id] = _study["currentCard"];
  156.  
  157. for (let i = 0; i < _study["cards"].length; i++) {
  158. _id = _study["cards"][i]["cardId"];
  159. this._Decks[this._DeckId][_id] = _study["cards"][i];
  160. }
  161.  
  162. this.Qiuz(_study);
  163.  
  164. GM.setValue("awqDecks", this._Decks);
  165. }
  166. }
  167.  
  168. Qiuz(study) {
  169. let cardsId = new Array();
  170.  
  171. cardsId.push(study["currentCard"]["cardId"]);
  172.  
  173. let keys = Object.keys(this._Decks[this._DeckId]);
  174.  
  175. let len = 11;
  176. if (len >= keys.length) {
  177. len = keys.length - 1;
  178. }
  179.  
  180. for (let i = 0; i < len; i++) {
  181. let _randomInt = this.GetRandomInt(keys.length);
  182. let _id = keys[_randomInt];
  183. let _continue = false;
  184.  
  185. for (let j = 0; j < cardsId.length; j++) {
  186. if (_id == cardsId[j]) {
  187. i--;
  188. _continue = true;
  189. break;
  190. }
  191. }
  192. if (_continue)
  193. continue;
  194. else
  195. cardsId.push(_id);
  196. }
  197. //Console.WriteLine(cardsId);
  198.  
  199. cardsId = this.Shuffle(cardsId);
  200.  
  201. let before = globalThis.window.document.querySelector("#qa_box");
  202. let divGrid = globalThis.window.document.createElement("div");
  203. divGrid.classList.add("awq_quizGrid");
  204.  
  205. before.parentNode.insertBefore(divGrid, before);
  206.  
  207. let answer = globalThis.window.document.querySelector("#ansbuta");
  208. if (!answer.classList.contains("awqEvent")) {
  209. answer.classList.add("awqEvent");
  210. answer.addEventListener("click", () => {
  211. let eases = globalThis.window.document.querySelectorAll("#easebuts button");
  212.  
  213. //Console.WriteLine(eases);
  214. for (let i = 0; i < eases.length; i++) {
  215. if (eases[i].classList.contains("awqEvent"))
  216. continue;
  217.  
  218. eases[i].classList.add("awqEvent");
  219. eases[i].addEventListener("click", () => {
  220. this.AddEventsForEases();
  221. }, false);
  222. }
  223. }, false);
  224. }
  225.  
  226. for (let i = 0; i < cardsId.length; i++) {
  227. let div = globalThis.window.document.createElement("div");
  228. div.classList.add("awq_quizButton");
  229. div.id = cardsId[i];
  230.  
  231. div.addEventListener("click", (e) => {
  232. let _id = e.currentTarget.id;
  233. console.log(_id);
  234.  
  235. let _button = globalThis.window.document.querySelector("#ansbuta");
  236. _button.click();
  237.  
  238. let _eases = globalThis.window.document.querySelectorAll("#easebuts button");
  239.  
  240. //Console.WriteLine(_eases);
  241. for (let i = 0; i < _eases.length; i++) {
  242. if (_eases[i].classList.contains("awqEvent"))
  243. continue;
  244.  
  245. _eases[i].classList.add("awqEvent");
  246. _eases[i].addEventListener("click", () => {
  247. this.AddEventsForEases();
  248. }, false);
  249. }
  250.  
  251. if (_id == study["currentCard"]["cardId"]) {
  252. div.classList.add("awq_true");
  253. div.classList.add("awq_trueBorder");
  254.  
  255. _eases[1].classList.add("awq_trueBorder");
  256. }
  257. else {
  258. div.classList.add("awq_false");
  259. div.classList.add("awq_falseBorder");
  260.  
  261. _eases[0].classList.add("awq_falseBorder");
  262. }
  263. }, false);
  264.  
  265. let html = this._Decks[this._DeckId][cardsId[i]]["answer"].replace(this._Decks[this._DeckId][cardsId[i]]["question"], "").replace("\n\n<hr id=answer>\n\n", "").replace("<img", "<img width=\"100%\"");
  266.  
  267. div.insertAdjacentHTML("beforeend", html);
  268.  
  269. divGrid.append(div);
  270. }
  271. }
  272.  
  273. AddEventsForEases() {
  274. let _grid = globalThis.window.document.querySelector(".awq_quizGrid");
  275. _grid.remove();
  276. this.Main();
  277. }
  278.  
  279. GetRandomInt(max) {
  280. return Math.floor(Math.random() * max);
  281. }
  282.  
  283. Shuffle(array) {
  284. for (let i = array.length - 1; i > 0; i--) {
  285. let _i = i + 1;
  286. let j = Math.floor(Math.random() * _i);
  287. let temp = array[i];
  288. array[i] = array[j];
  289. array[j] = temp;
  290. }
  291.  
  292. return array;
  293. }
  294. }
  295.  
  296. let awq;
  297.  
  298. window.onload = function () {
  299. awq = new AnkiWebQuiz();
  300.  
  301. setTimeout(() => {
  302. awq.Main();
  303. console.log(awq);
  304. }, 1000);
  305. };