Wanikani Lightning Mode

Eliminates second Enter or Click for correct review answers.

当前为 2017-10-16 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Wanikani Lightning Mode
  3. // @namespace wklightning
  4. // @description Eliminates second Enter or Click for correct review answers.
  5. // @include https://www.wanikani.com/review/session*
  6. // @version 1.0.4
  7. // @author Robin Findley
  8. // @copyright 2015+, Robin Findley
  9. // @license MIT; http://opensource.org/licenses/MIT
  10. // @run-at document-end
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. //==[ History ]======================================================
  15. // 1.0.4 - Added option to show item info when slightly off or multi-answer.
  16. // 1.0.3 - Fix to restore SRS status popup. Thanks to @ccookf contributions!
  17. // 1.0.2 - Enable lightning mode by default for new installs.
  18. // 1.0.1 - Added option to not auto-advance if answer is slightly off.
  19. // Added option to not auto-advance if item has multiple answers.
  20. // 1.0.0 - Initial release.
  21. //===================================================================
  22.  
  23. //==[ Settings ]=====================================================
  24. // The following script configuration variables are available. You
  25. // can enable them by pasting the corresponding line in the javascript
  26. // console (press F12 in most browsers to open the console), or by
  27. // removing the "//" before the corresponding "localStorage" line
  28. // below. The setting will be saved in storage.
  29. // To remove a setting from storage, enter the following line in the
  30. // javascript console, with corresponding setting name replaced:
  31. // delete localStorage.wkdpp_setting_name;
  32. //-------------------------------------------------------------------
  33. //
  34. // Halt if answer is slightly off.
  35. // localStorage.wklightning_halt_slightly_off = 1;
  36. //
  37. // Halt if answer has multiple meanings.
  38. // localStorage.wklightning_halt_multiple = 1;
  39. //
  40. // Open item info when halting for "slightly off" or "multiple meanings".
  41. // localStorage.wklightning_info_on_halt = 1;
  42. //===================================================================
  43.  
  44. wklightning = {};
  45.  
  46. (function(gobj){
  47.  
  48. var lightning = false;
  49. var observer;
  50. var ignore;
  51.  
  52. function addStyle(css) {
  53. var head, style;
  54. head = document.getElementsByTagName('head')[0];
  55. if (head) {
  56. style = document.createElement('style');
  57. style.setAttribute('type', 'text/css');
  58. style.textContent = css;
  59. head.appendChild(style);
  60. return style;
  61. }
  62. return null;
  63. }
  64.  
  65. //-------------------------------------------------------------------
  66. // Process stored configuration settings.
  67. //-------------------------------------------------------------------
  68. function process_settings() {
  69. function value_or_default(value, dflt) {return (value===undefined ? dflt : value);}
  70.  
  71. // Halt if answer is slightly off.
  72. gobj.halt_slightly_off = value_or_default(localStorage.wklightning_halt_slightly_off, 0);
  73.  
  74. // Halt if answer has multiple meanings.
  75. gobj.halt_multiple = value_or_default(localStorage.wklightning_halt_multiple, 0);
  76.  
  77. // Halt if answer has multiple meanings.
  78. gobj.info_on_halt = value_or_default(localStorage.wklightning_info_on_halt, 0);
  79. }
  80.  
  81. //-------------------------------------------------------------------
  82. // main() - Runs after page is done loading.
  83. //-------------------------------------------------------------------
  84. function main() {
  85. process_settings();
  86. addStyle(
  87. '#lightning-mode.active {color:#ff0; opacity:1.0;}'+
  88. '#answer-form fieldset.WKLM_warn button, #answer-form fieldset.WKLM_warn input[type=text], #answer-form fieldset.WKLM_warn input[type=text]:disabled {background-color:#fa2 !important;}'
  89. );
  90.  
  91. lightning = localStorage.getItem('lightning');
  92. lightning = (lightning !== 'false');
  93. $('#summary-button').append('<a id="lightning-mode" href="#"'+(lightning?' class="active"':'')+'><i class="icon-bolt"></i></a>');
  94. $('#lightning-mode').click(function() {
  95. lightning = !lightning;
  96. console.log('Lightning mode '+(lightning?'en':'dis')+'abled!');
  97. localStorage.setItem('lightning', lightning);
  98. $(this).toggleClass('active', lightning);
  99. return false;
  100. });
  101. ignore = false;
  102. observer = new MutationObserver(function(mutations) {
  103. mutations.forEach(function(mutation) {
  104. if (!lightning || ignore) return;
  105. switch (mutation.target.className) {
  106. case 'correct':
  107. var exception = $('#answer-exception');
  108. var advance = true;
  109. if (exception.length > 0) {
  110. var msg = exception.text();
  111. // Show the item info.
  112. if (msg.match('multiple') !== null && gobj.halt_multiple) {
  113. advance = false;
  114. } else if (msg.match('answer was a bit off') !== null && gobj.halt_slightly_off) {
  115. advance = false;
  116. }
  117. }
  118. // Auto-advance.
  119. if (advance) {
  120. var srs_notice = $('#question-type .srs').detach();
  121. $('#answer-form button').click();
  122. setTimeout(function(){
  123. $('#question-type').append(srs_notice);
  124. setTimeout(function(){
  125. $('#question-type .srs').fadeOut(function(){this.remove();});
  126. },1500);
  127. },100);
  128. } else {
  129. $("#answer-form fieldset").addClass("WKLM_warn");
  130. if (gobj.info_on_halt) {
  131. var ae = $('#answer-exception').remove();
  132. var ac = $('#additional-content');
  133. $('#additional-content #option-item-info').click();
  134. ac.append(ae);
  135. ac.attr('style','z-index:1000');
  136. }
  137. }
  138. break;
  139. case 'warning':
  140. case '':
  141. break;
  142. default:
  143. $('#additional-content #option-item-info').click();
  144. break;
  145. }
  146.  
  147. // Ignore additional changes for 100ms
  148. ignore = true;
  149. setTimeout(function(){ignore = false;}, 100);
  150. });
  151. });
  152. observer.observe(document.querySelector('#answer-form fieldset'), {attributes: true, subtree: true, attributeFilter: ['class']});
  153. }
  154.  
  155. //-------------------------------------------------------------------
  156. // Run main() upon load.
  157. //-------------------------------------------------------------------
  158. if (document.readyState === 'complete')
  159. main();
  160. else
  161. window.addEventListener("load", main, false);
  162.  
  163. }(wklightning));