[Userscript] Skip to Quiz

What

Enables the quiz button without having to go through all the lessons.

chrome_2018-05-24_18-58-49

Why

Vocab lessons are by far the easiest for me, so I wanted a way to go skip the lessons and go right to the quiz.

Where

https://greasyfork.org/en/scripts/368413-wanikani-skip-to-quiz

6 Likes

I could see myself installing it for my hypothetical 3rd time through WK.

9 Likes

THANK YOU SO MUCH.

I am quite satisfied, for I am also of the vocabulary proficient. :rofl:

1 Like

Hypothetical

Edit: description of original behavior of skip to quiz script was wrong, now fixed

The Skip to Quiz script has saved me a bunch of time when testing other scripts that alter the lesson quiz. I noticed that during the studying part of the lesson, after you look at the last item to study, the script will take you back to the first item to continue studying without prompting whether you want to start the lesson quiz. In the same situation, WaniKani would normally ask what you whether you want to spend more time studying or start the quiz. In case anyone finds it useful, below is a version of the script which preserves WaniKani’s normal prompting behavior after studying all items in the lesson, while still allowing you to skip directly to the quiz without prompting if you click the quiz button. Also, the button starts out blue now, so you have an additional visual indication of whether you have looked at everything in the lesson or not (blue vs. green). Finally, it uses a MutationObserver instead of setInterval.

// ==UserScript==
// @name         Wanikani: Skip to Quiz
// @namespace    http://tampermonkey.net/
// @version      0.1.2
// @description  Enables the quiz button without having to go through any of the lessons.
// @author       Kumirei
// @match        https://www.wanikani.com/lesson/session
// @match        https://preview.wanikani.com/lesson/session
// @grant        none
// ==/UserScript==
/*global $, wkof */

(function() {
    // Make quiz button look clickable
    add_css('#lesson #batch-items ul li[data-index="quiz"] span {background-color: #004fdd; cursor: pointer !important;}','skip-to-quiz-css')

    // Enable clicking quiz button by adding class that the existing click handler
    // checks for before it fires
    onEachElementReady('li[data-index="quiz"]', null, function(e) {
        e = $(e);
        bindFirst(e,'click', function() {
            e.addClass('active-quiz');
        });
    });

    // Library Functions

    // Adds CSS to document
    // Does not escape its input
    function add_css(css, id="") {
        document.getElementsByTagName('head')[0].insertAdjacentHTML('beforeend', `<style id="${id}">${css}</style>`);
    }

    // Calls callback once on each element matching selector that is added
    // to the DOM, including existing elements at the time the function is first called.
    // options is options for the MutationObserver (optional, is merged with default options  {childList: true, subtree: true})
    function onEachElementReady(selector, options, callback) {
        if (!options)
            options = {};

        let els_found = new Set()
        function check_available() {
            for (const el of document.querySelectorAll(selector)) {
                if (!els_found.has(el)) {
                    els_found.add(el);
                    callback(el);
                }
            }
        }

        queueMicrotask(check_available);

        let mo = new MutationObserver(check_available);
        mo.observe(document.documentElement, {
            childList: true,
            subtree: true,
            ...options
        });
    }

    // Adds a jQuery event listener that runs before all ones added so far
    // Based on https://stackoverflow.com/questions/2360655/jquery-event-handlers-always-execute-in-order-they-were-bound-any-way-around-t
    // [name] is the name of the event "click", "mouseover", ..
    // same as you'd pass it to bind()
    // [fn] is the handler function
    let bindFirst = function(jqel, name, fn) {
        // bind as you normally would
        // don't want to miss out on any jQuery magic
        jqel.on(name, fn);

        // Thanks to a comment by @Martin, adding support for
        // namespaced events too.
        jqel.each(function() {
            var handlers = $._data(this, 'events')[name.split('.')[0]];
            // take out the handler we just inserted from the end
            var handler = handlers.pop();
            // move it at the beginning
            handlers.splice(0, 0, handler);
        });
    };
})();
2 Likes

I have merged your additions into the published script

2 Likes

It looks like the changes I made accidentally broke the “start quiz” keyboard shortcut which worked before. Sorry about that. Here is a fix:

@@ -1,7 +1,7 @@
 // ==UserScript==
 // @name         Wanikani: Skip to Quiz
 // @namespace    http://tampermonkey.net/
-// @version      1.1.0
+// @version      1.1.1
 // @description  Enables the quiz button without having to go through any of the lessons.
 // @author       Kumirei
 // @match        https://www.wanikani.com/lesson/session
@@ -15,13 +15,16 @@
     // Make quiz button look clickable
     add_css('#lesson #batch-items ul li[data-index="quiz"] span {background-color: #004fdd; cursor: pointer !important;}','skip-to-quiz-css');

-    // Enable clicking quiz button by adding class that the existing click handler
-    // checks for before it fires
+    // Enable clicking quiz button by adding class that the existing
+    // click handler / keyup handler checks for before it fires
     onEachElementReady('li[data-index="quiz"]', null, function(e) {
         e = $(e);
         bindFirst(e,'click', function() {
             e.addClass('active-quiz');
         });
+        bindFirst($('body'),'keyup', function(evt) {
+            if (evt.key == 'q') e.addClass('active-quiz');
+        });
     });

     // Library Functions
1 Like

Ah, thank you. I have updated the script

1 Like

@Kumirei Anyway you could take a look at this script again? I see you’ve been active recently (thank you for Omega), and I tried installing this recently only to find it’s not doing anything with compatibility mode off. I’m on Windows 10, Chrome, using Tampermonkey, and I’ve tested it with all the other scripts turned off. The keyboard shortcut works only once the button is pressable, which natively only happens when you click “i’m not ready yet” before the quiz, so the script doesn’t appear to be functioning.

Thanks in advance.

1 Like

Sure! I’ll have a look at it

Should be fixed in 1.2.0! Not sure if it works with compatibility mode on anymore, but I’m ok with that

Yup, works like a charm now. Thanks!

1 Like

Oh just kidding I’m still having an issue. It works fine when I load in for the first time, but after doing one quiz and choosing to learn more it reverts to being an unclickable grey button. I didn’t notice before because I have a low lesson tolerance and always do single batches xD

1 Like

Oh, oops! I’ll fix that tomorrow.

Does the button still work even though it doesn’t look like it?

Should be fixed in 1.2.1