Does anyone else use this plug-in and have worked out a fix for it? I checked the Auto commit thread but it looks like the original author hasn’t done an update in a long time ![]()
Hey,
I had the same problem. The complete answered actually worked, but synonyms didn’t.
Here’s a fix that worked for me.
// ==UserScript==
// @name WK Auto Commit Fixed
// @namespace WKAUTOCOMMIT
// @version 0.5.2
// @description Auto commit for WaniKani, including user synonyms
// @author Johannes Mikulasch, fix: Lockyard, Plopen
// @match http://www.wanikani.com/subjects/*
// @match https://www.wanikani.com/subjects/*
// @match http://www.wanikani.com/subject-lessons/*
// @match https://www.wanikani.com/subject-lessons/*
// @grant none
// @run-at document-end
// @license
// ==/UserScript==
/*
* WK Auto Commit
*
* Automatically submits an answer when the typed response exactly matches
* one of WaniKani's accepted answers.
*
* Version 0.5.2
* - Fix user synonyms after WaniKani moved them from inline page JSON
* to the study-material database.
* - User synonyms are now read using:
* window.dbManager.getStudyMaterial(subject.id)
* - Protect against an asynchronous synonym lookup modifying the next question.
*
* Version 0.5.1
* - Removed "warned" and "blocked" items from expected answers.
*
* Version 0.5.0 onward by Lockyard
* - Fixed fields renamed by WaniKani.
*
* Version 0.4.8
* - Support /subject-lessons URLs.
*
* Version 0.4.7
* - Restore activation/deactivation button in footer.
*
* Version 0.4.6
* - Revert input detection to onkeyup because input event missed kana input.
*
* Version 0.4.5
* - Support user-defined synonyms.
*
* Version 0.4.4
* - Double-Check lightning mode compatibility fix.
*
* Version 0.4.3
* - Prevent double commits while typing quickly.
*
* Version 0.4.2
* - Adapt to WaniKani's March 27, 2023 review update.
*
* Version 0.4.1
* - Call commit() at most once for each question.
*
* Version 0.4
* - Double-Check Lightning Mode compatibility.
* - Katakana For On'yomi compatibility.
*
* Version 0.3
* - Lessons support.
*
* Version 0.2
* - Greasemonkey / Firefox compatibility.
*
* Version 0.1
* - Initial version.
*/
/* jshint -W097 */
'use strict';
var activated = true;
var click_threshold = 600;
let expected_answers = [];
// Used to prevent an async synonym lookup for the previous question
// from modifying expected_answers after WaniKani has moved on.
let questionGeneration = 0;
// Current subject/question, useful when refreshing synonyms.
let currentSubject = null;
let currentQuestionType = null;
/*
* Detect Lightning Mode from WaniKani Double-Check.
*/
var is_userscript_lightningmode_active = function () {
return Boolean(document.querySelector('.doublecheck-active'));
};
/*
* Toggle Auto Commit.
*/
var toggle = function () {
var button = document.querySelector("#WKAUTOCOMMIT_button");
if (!button) {
return;
}
if (activated) {
button.title = "Switch auto commit on";
button.style.opacity = 0.5;
button.textContent = "Auto Commit is off";
activated = false;
} else {
button.title = "Switch auto commit off";
button.style.opacity = 1.0;
button.textContent = "Auto Commit is on";
activated = true;
}
};
/*
* Normalize answers before comparing them.
*
* Keeps the original behavior:
* - remove whitespace
* - ignore capitalization
*/
var sanitize = function (str) {
if (typeof str !== "string") {
return "";
}
return str
.replace(/\s/g, '')
.toLowerCase();
};
/*
* Submit the current answer.
*/
var commit = function () {
if (!commit.usable) {
return;
}
// Prevent multiple commits for the same question.
commit.usable = false;
const inputbutton =
document.querySelector(".quiz-input__submit-button");
if (!inputbutton) {
return;
}
// First click checks/submits the answer.
inputbutton.click();
/*
* Without Lightning Mode, WaniKani normally requires a second click
* to continue to the next question.
*/
if (!is_userscript_lightningmode_active()) {
setTimeout(function () {
inputbutton.click();
}, click_threshold);
}
};
commit.usable = false;
/*
* Check current input against all known accepted answers.
*/
var check_input = function () {
const userResponseElement =
document.querySelector("#user-response");
if (!userResponseElement) {
return;
}
const currentresponse = userResponseElement.value;
if (!currentresponse) {
return;
}
const sanitizedResponse = sanitize(currentresponse);
for (let i = 0; i < expected_answers.length; i++) {
if (
sanitizedResponse ===
sanitize(expected_answers[i])
) {
commit();
break;
}
}
};
/*
* Register input handler.
*
* onkeyup is intentionally used rather than "input",
* because this has historically worked better with
* WaniKani's kana input handling.
*/
var register_check_input = function () {
var userinput = document.querySelector("#user-response");
if (!userinput) {
return;
}
userinput.onkeyup = function () {
if (activated) {
check_input();
}
};
};
/*
* Add Auto Commit toggle button to the quiz footer.
*/
var addButton = function () {
var button =
document.querySelector("#WKAUTOCOMMIT_button");
if (button) {
return;
}
var footer = document.querySelector(".quiz-footer");
if (!footer) {
return;
}
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;
footer.appendChild(button);
};
/*
* NEW WANIKANI SYNONYM HANDLING
*
* WaniKani no longer exposes user synonyms through:
*
* script[data-quiz-user-synonyms-target]
*
* They are now stored in WaniKani's study-material database.
*/
var getSynonyms = async function (subjectId) {
try {
if (!window.dbManager) {
console.warn(
"WK Auto Commit: window.dbManager is not available"
);
return [];
}
if (
typeof window.dbManager.getStudyMaterial !==
"function"
) {
console.warn(
"WK Auto Commit: dbManager.getStudyMaterial() is not available"
);
return [];
}
const studyMaterial =
await window.dbManager.getStudyMaterial(subjectId);
if (!studyMaterial) {
return [];
}
if (
!Array.isArray(
studyMaterial.meaning_synonyms
)
) {
return [];
}
return studyMaterial.meaning_synonyms;
} catch (error) {
console.warn(
"WK Auto Commit: Could not load user synonyms",
error
);
return [];
}
};
/*
* Load synonyms for the CURRENT meaning question.
*
* This is separated out so we can safely refresh them.
*/
var loadCurrentSynonyms = async function (
subject,
generation
) {
const subjectSynonyms =
await getSynonyms(subject.id);
/*
* We may have moved to another question while IndexedDB
* was being read.
*/
if (generation !== questionGeneration) {
return;
}
/*
* Also make sure this is still the same subject.
*/
if (
!currentSubject ||
currentSubject.id !== subject.id ||
currentQuestionType !== "meaning"
) {
return;
}
expected_answers =
expected_answers.concat(subjectSynonyms);
/*
* Remove duplicates.
*/
expected_answers =
Array.from(new Set(expected_answers));
/*
* The user may already have finished typing the synonym
* while the database lookup was running.
*/
if (activated) {
check_input();
}
};
/*
* WaniKani fires willShowNextQuestion whenever a new quiz
* question is displayed.
*/
window.addEventListener(
"willShowNextQuestion",
function (event) {
const generation = ++questionGeneration;
register_check_input();
addButton();
const item = event.detail;
const subject = item.subject;
currentSubject = subject;
currentQuestionType = item.questionType;
expected_answers = [];
/*
* ============================
* MEANING QUESTION
* ============================
*/
if (item.questionType === "meaning") {
/*
* WaniKani supplied meanings.
*
* Do NOT include:
* - warned
* - blocked
*/
expected_answers =
subject.meanings
.filter(function (meaning) {
return (
meaning?.kind === "primary" ||
meaning?.kind === "alternative" ||
meaning?.kind === "allowed"
);
})
.map(function (meaning) {
return meaning.text;
});
/*
* Normal WaniKani meanings can already be used,
* so enable Auto Commit immediately.
*/
commit.usable = true;
/*
* User synonyms are loaded asynchronously from
* WaniKani's study-material database.
*/
loadCurrentSynonyms(
subject,
generation
);
/*
* ============================
* READING QUESTION
* ============================
*/
} else if (
item.questionType === "reading"
) {
/*
* Vocabulary reading.
*/
if (
subject.type === "Vocabulary" ||
subject.type === "KanaVocabulary"
) {
expected_answers =
subject.readings
.filter(function (reading) {
return (
reading?.kind === "primary" ||
reading?.kind === "alternative" ||
reading?.kind === "allowed"
);
})
.map(function (reading) {
return reading.text;
});
/*
* Kanji reading.
*
* Only accept readings matching WaniKani's
* requested primary reading type.
*/
} else if (
subject.type === "Kanji"
) {
expected_answers =
subject.readings
.filter(function (reading) {
return (
(
reading?.kind === "primary" ||
reading?.kind === "alternative" ||
reading?.kind === "allowed"
) &&
reading.type ===
subject.primary_reading_type
);
})
.map(function (reading) {
return reading.text;
});
}
commit.usable = true;
}
/*
* Remove any duplicate standard answers.
*/
expected_answers =
Array.from(new Set(expected_answers));
}
);
/*
* Initialization.
*/
(function () {
console.log(
"WK Auto Commit 0.5.2: Initialized"
);
})();
Hope it works for you too ![]()
Thank you, it worked perfected