WK Auto Commit

Auto commit for Wanikani

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

  1. // ==UserScript==
  2. // @name WK Auto Commit
  3. // @namespace WKAUTOCOMMIT
  4. // @version 0.4.5
  5. // @description Auto commit for Wanikani
  6. // @author Johannes Mikulasch
  7. // @match http://www.wanikani.com/subjects/*
  8. // @match https://www.wanikani.com/subjects/*
  9. // @grant none
  10. // @run-at document-end
  11. // @license
  12. // ==/UserScript==
  13.  
  14. /*
  15. * WK Auto Commit
  16. * If you typed in the correct answer then it is automatically commited.
  17. * Therefore, you have to use the 'enter' key way less than before.
  18. *
  19. * Version 0.4.5
  20. * Consider user-defined synonyms for the meaning of a vocab/kanji/radical as well
  21. * Further prevent double commits by using the "input" element's "input" event instead of the "onkeyup" function
  22. * Version 0.4.4
  23. * Bugfix: correctly detect double-check from lightning mode
  24. * Version 0.4.3
  25. * Bugfix: prevent a double commit when typing fast, which led to a shaking input window or in the worst case to
  26. * wrong input.
  27. * Version 0.4.2
  28. * Quickfix: adapt to Wanikani update, which was deployed on March 27th, 2023
  29. * (see https://community.wanikani.com/t/updates-to-lessons-reviews-and-extra-study/60912)
  30. * - removed jStorage and jQuery references
  31. * - changed the @match for the new lesson and review urls
  32. * - Note: did not check with compatibilites of other user scripts (like Lightning mode or Katakana for On'yomi) yet.
  33. * Version 0.4.1
  34. * Bugfix: call commit() at most one time for each item
  35. * (see https://community.wanikani.com/t/userscript-auto-commit-the-end-of-the-enter-key/11825/64)
  36. * Version 0.4
  37. * Compatibility with Lightning mode from the Double-Check userscript
  38. * Compatibility with Katakana For On'yomi userscript
  39. * Version 0.3
  40. * Script works now on the Lessons page too
  41. * Version 0.2
  42. * Makes script work with Greasemonkey and Firefox
  43. * Version 0.1
  44. * Initial version
  45. *
  46. */
  47.  
  48. /* jshint -W097 */
  49. 'use strict';
  50.  
  51. var activated = true;
  52. var click_threshold = 600;
  53.  
  54. let expected_answers = [];
  55. let synonyms = {};
  56.  
  57. var is_userscript_lightningmode_active = function () {
  58. /* Returns true if "Lightning Mode" from Userscript Double-Check is active */
  59. return Boolean(document.querySelector('.doublecheck-active'));
  60. };
  61.  
  62. var toggle = function () {
  63. var button = document.querySelector("#WKAUTOCOMMIT_button");
  64. if (activated) {
  65. // Deactivates WK Auto Commit mode
  66. button.title = "Switch auto commit on";
  67. button.style.opacity = 0.5;
  68. button.textContent = "Auto Commit is off";
  69. activated = false;
  70. } else {
  71. // Activates WK Auto Commit mode
  72. button.title = "Switch auto commit off";
  73. button.style.opacity = 1.0;
  74. button.textContent = "Auto Commit is on";
  75. activated = true;
  76. }
  77. };
  78.  
  79. var sanitize = function (str1) {
  80. var str2 = str1.replace(/\s/g, ''); // Removes Whitespaces
  81. str2 = str2.toLowerCase();
  82. return str2;
  83. };
  84.  
  85. var commit = function () {
  86. if(!commit.usable) return;
  87. // Temporarily deactivate the commit function to prevent double commits
  88. commit.usable = false;
  89. const inputbutton = document.querySelector(".quiz-input__submit-button");
  90. inputbutton.click();
  91. if (!is_userscript_lightningmode_active()) {
  92. setTimeout(function(){ inputbutton.click();}, click_threshold);
  93. }
  94.  
  95. };
  96.  
  97. var check_input = function () {
  98. const currentresponse = document.querySelector("#user-response").value;
  99. //console.log("Checking Input", currentresponse, expected_answers);
  100. for (var i in expected_answers) {
  101. if (sanitize(currentresponse) === sanitize(expected_answers[i])) {
  102. commit();
  103. break;
  104. }
  105. }
  106. };
  107.  
  108. var register_check_input = function () {
  109. var userinput = document.querySelector("#user-response");
  110. userinput.addEventListener("input", function (event) {
  111. if (activated) {
  112. check_input();
  113. }
  114. });
  115. };
  116.  
  117. var addButton = function () {
  118. /* Define button */
  119. var button = document.querySelector("#WKAUTOCOMMIT_button");
  120. if (!button) {
  121. button = document.createElement("div");
  122. button.id = "WKAUTOCOMMIT_button";
  123. button.title = "Toggle Auto Commit Mode";
  124. button.textContent = "Auto Commit is on";
  125. button.style.backgroundColor = "#C55";
  126. button.style.opacity = 1;
  127. button.style.display = "inline-block";
  128. button.style.fontSize = "0.8125em";
  129. button.style.color = "#FFF";
  130. button.style.cursor = "pointer"
  131. button.style.padding = "10px";
  132. button.style.verticalAlign = "bottom";
  133. button.onclick = toggle;
  134.  
  135. /* Prepend button to footer */
  136. var body = document.querySelector("#turbo-body");
  137. body.appendChild(button);
  138. }
  139. };
  140.  
  141. /* Load user synonyms. Load them only once. */
  142. var loadSynonyms = function () {
  143. if (loadSynonyms.loaded) return;
  144. const dataUserSynonyms = document.querySelector('script[data-quiz-user-synonyms-target]');
  145. if (!dataUserSynonyms) return;
  146. synonyms = JSON.parse(dataUserSynonyms.innerHTML);
  147. loadSynonyms.loaded = true;
  148. };
  149.  
  150. /* Save synonyms added by the user during the quiz session */
  151. window.addEventListener("didUpdateUserSynonyms", function(event) {
  152. //console.log("Received didUpdateUserSynonyms event from WaniKani", event);
  153. synonyms[event.detail.subjectId] = event.detail.synonyms;
  154. });
  155.  
  156. /* React on a willShowNextQuestion event, which is triggered by WaniKani when a new question is shown */
  157. window.addEventListener("willShowNextQuestion", function(event) {
  158. //console.log("Received willShowNextQuestion event from WaniKani", event);
  159. register_check_input();
  160. addButton();
  161. loadSynonyms();
  162.  
  163. /* Get expected answers from current item depending on the task (reading or meaning) */
  164. expected_answers = []
  165. const item = event.detail;
  166. const subject = item.subject;
  167. if (item.questionType === "meaning") {
  168. expected_answers = expected_answers.concat(subject.meanings);
  169. const subjectSynonyms = (subject.id in synonyms) ? synonyms[subject.id] : [];
  170. expected_answers = expected_answers.concat(subjectSynonyms);
  171. } else if (item.questionType === "reading") {
  172. if (subject.type === 'Vocabulary') {
  173. expected_answers = expected_answers.concat(subject.readings.map((e) => e.reading));
  174. } else if (subject.type === 'Kanji') {
  175. if (subject.primary_reading_type === 'kunyomi') {
  176. expected_answers = expected_answers.concat(subject.kunyomi);
  177. } else if (subject.primary_reading_type === 'onyomi') {
  178. expected_answers = expected_answers.concat(subject.onyomi);
  179. }
  180. }
  181. }
  182.  
  183. // Make the commit function usable again
  184. commit.usable = true;
  185. });
  186.  
  187. (function () {
  188. console.log('WK Auto Commit (a plugin for Wanikani): Initialized');
  189. })();
  190.