AnkiWeb Quiz

Shows quiz on ankiweb.

当前为 2023-08-11 提交的版本,查看 最新版本

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