Wanikani Lightning Mode

Eliminates second Enter or Click for correct review answers.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        Wanikani Lightning Mode
// @namespace   wklightning
// @description Eliminates second Enter or Click for correct review answers.
// @include     https://www.wanikani.com/review/session*
// @include     https://www.wanikani.com/lesson/session*
// @version     1.0.9
// @author      Robin Findley
// @copyright   2018+, Robin Findley
// @license     MIT; http://opensource.org/licenses/MIT
// @run-at      document-end
// @grant       none
// ==/UserScript==

//==[ History ]======================================================
// 1.0.8 - Fixed issue with proceeding at end of lesson group.
// 1.0.5 - Added support for lessons.
// 1.0.4 - Added option to show item info when slightly off or multi-answer.
// 1.0.3 - Fix to restore SRS status popup.  Thanks to @ccookf contributions!
// 1.0.2 - Enable lightning mode by default for new installs.
// 1.0.1 - Added option to not auto-advance if answer is slightly off.
//         Added option to not auto-advance if item has multiple answers.
// 1.0.0 - Initial release.
//===================================================================

//==[ Settings ]=====================================================
// The following script configuration variables are available.  You
// can enable them by pasting the corresponding line in the javascript
// console (press F12 in most browsers to open the console), or by
// removing the "//" before the corresponding "localStorage" line
// below.  The setting will be saved in storage.
// To remove a setting from storage, enter the following line in the
// javascript console, with corresponding setting name replaced:
//   delete localStorage.wkdpp_setting_name;
//-------------------------------------------------------------------
//
// Halt if answer is slightly off.
//   localStorage.wklightning_halt_slightly_off = 1;
//
// Halt if answer has multiple meanings.
//   localStorage.wklightning_halt_multiple = 1;
//
// Open item info when halting for "slightly off" or "multiple meanings".
//   localStorage.wklightning_info_on_halt = 1;
//===================================================================

wklightning = {};

(function(gobj){

    var lightning = false;
    var observer;
    var ignore;

    function addStyle(css) {
        var head, style;
        head = document.getElementsByTagName('head')[0];
        if (head) {
            style = document.createElement('style');
            style.setAttribute('type', 'text/css');
            style.textContent = css;
            head.appendChild(style);
            return style;
        }
        return null;
    }

    //-------------------------------------------------------------------
    // Process stored configuration settings.
    //-------------------------------------------------------------------
    function process_settings() {
        function value_or_default(value, dflt) {return (value===undefined ? dflt : value);}

        // Halt if answer is slightly off.
        gobj.halt_slightly_off = value_or_default(localStorage.wklightning_halt_slightly_off, 0);

        // Halt if answer has multiple meanings.
        gobj.halt_multiple = value_or_default(localStorage.wklightning_halt_multiple, 0);

        // Halt if answer has multiple meanings.
        gobj.info_on_halt = value_or_default(localStorage.wklightning_info_on_halt, 0);
    }

    //-------------------------------------------------------------------
    // main() - Runs after page is done loading.
    //-------------------------------------------------------------------
    function main() {
        process_settings();
        addStyle(
            '#lightning-mode.active {color:#ff0; opacity:1.0;}'+
            '#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;}'
        );

        lightning = localStorage.getItem('lightning');
        lightning = (lightning !== 'false');
        $('#summary-button').append('<a id="lightning-mode" href="#"'+(lightning?' class="active"':'')+'><i class="icon-bolt"></i></a>');
        $('#lightning-mode').on('click', function() {
            lightning = !lightning;
            console.log('Lightning mode '+(lightning?'en':'dis')+'abled!');
            localStorage.setItem('lightning', lightning);
            $(this).toggleClass('active', lightning);
            return false;
        });
        ignore = false;
        observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                if (!lightning || ignore) return;
                switch (mutation.target.className) {
                    case 'correct':
                        var exception = $('#answer-exception');
                        var advance = true;
                        if (exception.length > 0) {
                            var msg = exception.text();
                            // Show the item info.
                            if (msg.match('multiple') !== null && gobj.halt_multiple) {
                                advance = false;
                            } else if (msg.match('answer was a bit off') !== null && gobj.halt_slightly_off) {
                                advance = false;
                            }
                        }
                        // Auto-advance.
                        if (advance) {
                            var srs_notice = $('#question-type .srs').detach();
                            // Simulate an <enter> on the submit button.
                            var event = $.Event('keydown');
                            event.keyCode = 13; event.which = 13; event.key = 'Enter';
                            $('#answer-form button').trigger(event);
                            setTimeout(function(){
                                $('#question-type').append(srs_notice);
                                setTimeout(function(){
                                    $('#question-type .srs').fadeOut(function(){this.remove();});
                                },1500);
                            },100);
                        } else {
                            $("#answer-form fieldset").addClass("WKLM_warn");
                            if (gobj.info_on_halt) {
                                var ae = $('#answer-exception').remove();
                                var ac = $('#additional-content');
                                $('#additional-content #option-item-info').click();
                                ac.append(ae);
                                ac.attr('style','z-index:1000');
                            }
                        }
                        break;
                    case 'warning':
                    case '':
                        break;
                    default:
                        $('#additional-content #option-item-info').click();
                        break;
                }

                // Ignore additional changes for 100ms
                ignore = true;
                setTimeout(function(){ignore = false;}, 100);
            });
        });
        observer.observe(document.querySelector('#answer-form fieldset'), {attributes: true, subtree: true, attributeFilter: ['class']});
    }

    //-------------------------------------------------------------------
    // Run main() upon load.
    //-------------------------------------------------------------------
    if (document.readyState === 'complete')
        main();
    else
        window.addEventListener("load", main, false);

}(wklightning));