您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Adds an "Ignore Answer" button during reviews that makes WaniKani ignore the current answer (useful if, for example, you made a stupid typo)
当前为
// ==UserScript== // @name Wanikani Override // @namespace wkoverride // @description Adds an "Ignore Answer" button during reviews that makes WaniKani ignore the current answer (useful if, for example, you made a stupid typo) // @include http://www.wanikani.com/review/session* // @include https://www.wanikani.com/review/session* // @version 1.1.3 // @author Rui Pinheiro // @grant GM_addStyle // @grant unsafeWindow // @require http://code.jquery.com/jquery-1.11.2.min.js // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html // ==/UserScript== // ESC shortcut /* * Debug Settings */ var debugLogEnabled = true; var scriptShortName = 'WKO'; scriptLog = debugLogEnabled ? function (msg) { if (typeof msg === 'string') { console.log(scriptShortName + ': ' + msg); } else { console.log(msg); } } : function () { }; /* * Other settings */ var prefAllowUnignore = true; /* * "Ignore Answer" Button Click */ var ActionEnum = Object.freeze({ ignore: 0, unignore: 1 }); function WKO_ignoreAnswer() { try { /* Check if the current item was answered incorrectly */ var elmnts = document.getElementsByClassName('incorrect'); var elmnts2 = document.getElementsByClassName('WKO_ignored'); var curAction; if (!isEmpty(elmnts[0])) // Current answer is wrong curAction = ActionEnum.ignore; else if (prefAllowUnignore && !isEmpty(elmnts2[0])) // Current answer is ignored curAction = ActionEnum.unignore; else // Either there is no current answer, or it's correct { alert('WKO: Current item wasn\'t answered incorrectly, nor ignored previously!'); return false; } /* Grab information about current question */ var curItem = $.jStorage.get('currentItem'); var questionType = $.jStorage.get('questionType'); /* Build item name */ var itemName; if (curItem.rad) itemName = 'r'; else if (curItem.kan) itemName = 'k'; else itemName = 'v'; itemName += curItem.id; scriptLog(itemName); /* Grab item from jStorage. * * item.rc and item.mc => Reading/Meaning Completed (if answered the item correctly) * item.ri and item.mi => Reading/Meaning Invalid (number of mistakes before answering correctly) */ var item = $.jStorage.get(itemName) || { }; /* Update the item data */ if (questionType === 'meaning') { if (!('mi' in item) || isEmpty(item.mi)) { throw Error('item.mi undefined'); return false; } else if (item.mi < 0 || (item.mi == 0 && curAction == ActionEnum.ignore)) { throw Error('item.mi too small'); return false; } if (curAction == ActionEnum.ignore) item.mi -= 1; else item.mi += 1; delete item.mc; } else { if (!('ri' in item) || isEmpty(item.ri)) { throw Error('item.ri undefined'); return false; } else if (item.ri < 0 || (item.ri == 0 && curAction == ActionEnum.ignore)) { throw Error('i.ri too small'); return false; } if (curAction == ActionEnum.ignore) item.ri -= 1; else item.ri += 1; delete item.rc; } /* Save the new state back into jStorage */ $.jStorage.set(itemName, item); /* Modify the questions counter and wrong counter and change the style of the answer field */ var wrongCount = $.jStorage.get('wrongCount'); var questionCount = $.jStorage.get('questionCount'); if (curAction == ActionEnum.ignore) { $.jStorage.set('wrongCount', wrongCount - 1); $.jStorage.set('questionCount', questionCount - 1); $('#answer-form fieldset').removeClass('incorrect'); $('#answer-form fieldset').addClass('WKO_ignored'); } else { $.jStorage.set('wrongCount', wrongCount + 1); $.jStorage.set('questionCount', questionCount + 1); $('#answer-form fieldset').removeClass('WKO_ignored'); $('#answer-form fieldset').addClass('incorrect'); } return true; } catch (err) { logError(err); } } /* * Bind '~' as a hotkey */ function bindHotkey() { jQuery(document).on('keydown.reviewScreen', function (event) { if ($('#reviews').is(':visible') && !$('*:focus').is('textarea, input')) { //alert('keycode: ' + event.keyCode); switch (event.keyCode) { //case 176: //Firefox '~' //case 192: //Chrome '~' case 27: // ESC Button event.stopPropagation(); event.preventDefault(); if ($('#user-response').is(':disabled')) WKO_ignoreAnswer(); return false; break; } } }); } /* * Inject Ignore Button */ function addIgnoreAnswerBtn() { var footer = document.getElementsByTagName('footer'), $btn = jQuery('<div id="WKO_button" title="Ignore Answer">Ignore Answer</div>').on('click', WKO_ignoreAnswer); jQuery(footer[0]).prepend($btn); } /* * Prepares the script */ function scriptInit() { // Add global CSS styles GM_addStyle('#WKO_button {background-color: #CC0000; color: #FFFFFF; cursor: pointer; display: inline-block; font-size: 0.8125em; padding: 10px; vertical-align: bottom;}'); GM_addStyle('#answer-form fieldset.WKO_ignored input[type="text"]:-moz-placeholder, #answer-form fieldset.WKO_ignored input[type="text"]:-moz-placeholder {color: #FFFFFF; font-family: "Source Sans Pro",sans-serif; font-weight: 300; text-shadow: none; transition: color 0.15s linear 0s; } #answer-form fieldset.WKO_ignored button, #answer-form fieldset.WKO_ignored input[type="text"], #answer-form fieldset.WKO_ignored input[type="text"]:disabled { background-color: #FFCC00 !important; }'); scriptLog('loaded'); // Set up hooks try { addIgnoreAnswerBtn(); bindHotkey(); } catch (err) { logError(err); } } /* * Helper Functions/Variables */ //use 'jQuery' for greasemonkey's version, $ is WK's jQuery $ = unsafeWindow.$; function isEmpty(value) { return (typeof value === 'undefined' || value === null); } /* * Error handling * Can use 'error.stack', not cross-browser (though it should work on Firefox and Chrome) */ function logError(error) { var stackMessage = ''; if ('stack' in error) stackMessage = '\n\tStack: ' + error.stack; console.error(scriptShortName + ' Error: ' + error.name + '\n\tMessage: ' + error.message + stackMessage); } /* * Start the script */ scriptInit();