[Userscript] auto-commit; the end of the enter key

I got tired of refreshing the page every time I wanted to do reviews to get this script working, so I made a version that works without refreshing. I will leave it here in case anyone else also wants to use it.
I could not post the whole thing, because the @ symbols in the header were registering as mentions, and you can apparently only mention up to 10 people in a post. I don’t think the missing part of the header is important, but otherwise you can take that from the old verion.

Updated script

`// ==UserScript==
// @name WK Auto Commit
// @namespace WKAUTOCOMMIT
// @version 0.4.9
// @description Auto commit for Wanikani
// @author Johannes Mikulasch
// @match https://www.wanikani.com/*
// @match http://www.wanikani.com/subject-lessons/*
// @match https://www.wanikani.com/subject-lessons/*
// REST OF OLD HEADER HERE
// ==/UserScript==

/*

  • WK Auto Commit
  • If you typed in the correct answer then it is automatically commited.
  • Therefore, you have to use the ‘enter’ key way less than before.
  • Version 0.4.9
  • Fix: Support for turbo pages.
  • Version 0.4.8
  • Fix: Run this script on “wanikani.com/subject-lessons”, as Wanikani have just renamed their lessons URL
  • Version 0.4.7
  • Fix: show button to activate/deactivate in footer again.
  • Version 0.4.6
  • Revert input detection to onkeyup, as “input” event missed kana input
  • Version 0.4.5
  • Consider user-defined synonyms for the meaning of a vocab/kanji/radical as well
  • Further prevent double commits by using the “input” element’s “input” event instead of the “onkeyup” function
  • Version 0.4.4
  • Bugfix: correctly detect double-check from lightning mode
  • Version 0.4.3
  • Bugfix: prevent a double commit when typing fast, which led to a shaking input window or in the worst case to
  • wrong input.
  • Version 0.4.2
  • Quickfix: adapt to Wanikani update, which was deployed on March 27th, 2023
  • (see Updates to Lessons, Reviews, and Extra Study)
    • removed jStorage and jQuery references
    • changed the @match for the new lesson and review urls
    • Note: did not check with compatibilites of other user scripts (like Lightning mode or Katakana for On’yomi) yet.
  • Version 0.4.1
  • Bugfix: call commit() at most one time for each item
  • (see [Userscript] auto-commit; the end of the enter key - #64 by wanikanier)
  • Version 0.4
  • Compatibility with Lightning mode from the Double-Check userscript
  • Compatibility with Katakana For On’yomi userscript
  • Version 0.3
  • Script works now on the Lessons page too
  • Version 0.2
  • Makes script work with Greasemonkey and Firefox
  • Version 0.1
  • Initial version

*/

/* jshint -W097 */
‘use strict’;

let script_name = ‘WK Auto Commit’;
let wkof_version_needed = ‘1.2.3’;

if (!window.wkof) {
if (confirm(script_name+’ requires Wanikani Open Framework.\nDo you want to be forwarded to the installation instructions?‘)) {
window.location.href = ‘Installing Wanikani Open Framework’;
}
return;
}
if (wkof.version.compare_to(wkof_version_needed) === ‘older’) {
if (confirm(script_name+’ requires Wanikani Open Framework version ‘+wkof_version_needed+’.\nDo you want to be forwarded to the update page?')) {
window.location.href = ‘Wanikani Open Framework’;
}
return;
}

wkof.on_pageload([
‘/subjects/extra_study’,
‘/subjects/review’,
‘/subject-lessons/*’
], () => setTimeout(load_script, 0));

var activated = true;
var click_threshold = 600;

let expected_answers = ;
let synonyms = {};

var is_userscript_lightningmode_active = function () {
/* Returns true if “Lightning Mode” from Userscript Double-Check is active */
return Boolean(document.querySelector(‘.doublecheck-active’));
};

var toggle = function () {
var button = document.querySelector(“#WKAUTOCOMMIT_button”);
if (activated) {
// Deactivates WK Auto Commit mode
button.title = “Switch auto commit on”;
button.style.opacity = 0.5;
button.textContent = “Auto Commit is off”;
activated = false;
} else {
// Activates WK Auto Commit mode
button.title = “Switch auto commit off”;
button.style.opacity = 1.0;
button.textContent = “Auto Commit is on”;
activated = true;
}
};

var sanitize = function (str1) {
var str2 = str1.replace(/\s/g, ‘’); // Removes Whitespaces
str2 = str2.toLowerCase();
return str2;
};

var commit = function () {
if(!commit.usable) return;
// Temporarily deactivate the commit function to prevent double commits
commit.usable = false;
const inputbutton = document.querySelector(“.quiz-input__submit-button”);
inputbutton.click();
if (!is_userscript_lightningmode_active()) {
setTimeout(function(){ inputbutton.click();}, click_threshold);
}

};

var check_input = function () {
const currentresponse = document.querySelector(“#user-response”).value;
//console.log(“Checking Input”, currentresponse, expected_answers);
for (var i in expected_answers) {
if (sanitize(currentresponse) === sanitize(expected_answers[i])) {
commit();
break;
}
}
};

var register_check_input = function () {
var userinput = document.querySelector(“#user-response”);
//userinput.addEventListener(“input”, function (event) {
userinput.onkeyup = function (event) {
if (activated) {
check_input();
}
};
};

var addButton = function () {
/* Define button */
var button = document.querySelector(“#WKAUTOCOMMIT_button”);
if (!button) {
button = document.createElement(“div”);
button.id = “WKAUTOCOMMIT_button”;
button.title = “Toggle Auto Commit Mode”;
button.textContent = “Auto Commit is on”;
button.style.backgroundColor = “#C55”;
button.style.opacity = 1;
button.style.display = “inline-block”;
button.style.fontSize = “0.8125em”;
button.style.color = “#FFF”;
button.style.cursor = “pointer”
button.style.padding = “10px”;
button.style.marginLeft = “10px”;
button.style.verticalAlign = “bottom”;
button.onclick = toggle;

    /* Prepend button to footer */
    var footer = document.querySelector(".quiz-footer");
    footer.appendChild(button);
}

};

/* Load user synonyms. Load them only once. */
var loadSynonyms = function () {
if (loadSynonyms.loaded) return;
const dataUserSynonyms = document.querySelector(‘script[data-quiz-user-synonyms-target]’);
if (!dataUserSynonyms) return;
synonyms = JSON.parse(dataUserSynonyms.innerHTML);
loadSynonyms.loaded = true;
};

function load_script(){
/* Save synonyms added by the user during the quiz session */
window.addEventListener(“didUpdateUserSynonyms”, function(event) {
//console.log(“Received didUpdateUserSynonyms event from WaniKani”, event);
synonyms[event.detail.subjectId] = event.detail.synonyms;
});

/* React on a willShowNextQuestion event, which is triggered by WaniKani when a new question is shown */
window.addEventListener("willShowNextQuestion", function(event) {
    //console.log("Received willShowNextQuestion event from WaniKani", event);
    register_check_input();
    addButton();
    loadSynonyms();

    /* Get expected answers from current item depending on the task (reading or meaning) */
    expected_answers = []
    const item = event.detail;
    const subject = item.subject;
    if (item.questionType === "meaning") {
        expected_answers = expected_answers.concat(subject.meanings);
        const subjectSynonyms = (subject.id in synonyms) ? synonyms[subject.id] : [];
        expected_answers = expected_answers.concat(subjectSynonyms);
    } else if (item.questionType === "reading") {
        if (subject.type === 'Vocabulary') {
            expected_answers = expected_answers.concat(subject.readings.map((e) => e.reading));
        } else if (subject.type === 'Kanji') {
            if (subject.primary_reading_type === 'kunyomi') {
                expected_answers = expected_answers.concat(subject.kunyomi);
            } else if (subject.primary_reading_type === 'onyomi') {
                expected_answers = expected_answers.concat(subject.onyomi);
            }
        }
    }

    // Make the commit function usable again
    commit.usable = true;
});
console.log('WK Auto Commit (a plugin for Wanikani): Initialized');

}

`

Edit: Huh. Looks like the usernames ‘namespace’ and ‘match’ are actually in use. I wonder if posting a codefragment like this also sends notifications?

Thank you for bringing attention to this behavior again and your work on fixing this!

I wasn’t aware that the script only runs when the review page is refreshed. Apparently that’s because of a Wanikani change in July 2024, which is already discussed in this forum thread: Detecting page change in userscripts

I see that your fix uses the Wanikani Open Framework ‘wkof’. I wanted to avoid the dependency on other user scripts, to keep the script easy to install and its footprint small. I think there is a way to directly react on one of the Turbo frameworks events. I will check the next days if this is possible and update the script accordingly. Your fix already points me to the right direction - thank you for that!

Also, as I am not very active on Wanikani anymore, if you or someone else wants to help maintaining this user script, you can reach out to me or directly send me a Pull Request via the user script’s github repository.

I think you need to make sure that you use the “Preformatted text” markdown in your response, the one with three backticks ``` at the start and end, like this:

```
code comes here
```
1 Like

The base solution is to add a listener for the turbo:load event, but that might have already fired before the script starts executing. Using Wkof was the quick and easy fix because it already handled that and other possible turbo details I don’t know about, and it has the same regex syntax as the regular @match statements that it replaces, but you could of course just reimplement the relevant parts directly as well.