Since the new WaniKani UI update this Jitai script is broken. I quickly completely rewrote the logic to make it work with the current version, see code below.
I will provide minimum to no support or help, I just thought it’d be nice to share a quick solution for those that need it.
// ==UserScript==
// @name Jitai
// @version 2.0
// @description Display WaniKani reviews in randomized fonts, for more varied reading training.
// @author rogerxiii (original by obskyr)
// @license MIT
// @icon http://i.imgur.com/qyuR9bD.png
// @include /^https?://(www\.)?wanikani\.com/subjects/review/?$/
// @grant none
// ==/UserScript==
/*
To control which fonts to choose from, edit this list.
If you feel too many fonts of a certain type are showing
up, remove a few of those from the list. If you've got
fonts that aren't in the list that you'd like to be used,
add their names and they'll be in the rotation.
*/
var fonts = [
// Default Windows fonts
"Meiryo, メイリオ",
"MS PGothic, MS Pゴシック, MS Gothic, MS ゴック",
"MS PMincho, MS P明朝, MS Mincho, MS 明朝",
"Yu Gothic, YuGothic",
"Yu Mincho, YuMincho",
// Default OS X fonts
"Hiragino Kaku Gothic Pro, ヒラギノ角ゴ Pro W3",
"Hiragino Maru Gothic Pro, ヒラギノ丸ゴ Pro W3",
"Hiragino Mincho Pro, ヒラギノ明朝 Pro W3",
// Common Linux fonts
"Takao Gothic, TakaoGothic",
"Takao Mincho, TakaoMincho",
"Sazanami Gothic",
"Sazanami Mincho",
"Kochi Gothic",
"Kochi Mincho",
"Dejima Mincho",
"Ume Gothic",
"Ume Mincho",
// Other Japanese fonts people use.
// You might want to try some of these!
"EPSON 行書体M",
"EPSON 正楷書体M",
"EPSON 教科書体M",
"EPSON 太明朝体B",
"EPSON 太行書体B",
"EPSON 丸ゴシック体M",
"cinecaption",
"nagayama_kai",
"A-OTF Shin Maru Go Pro",
"Hosofuwafont",
"ChihayaGothic",
"'chifont+', chifont",
"darts font",
"santyoume-font",
"FC-Flower",
"ArmedBanana", // This one is completely absurd. I recommend it.
"HakusyuKaisyoExtraBold_kk",
"aoyagireisyosimo2, AoyagiKouzanFont2OTF",
"aquafont",
// Add your fonts here!
"Fake font name that you can change",
"Another fake font name",
"Just add them like this!",
"Quotes around the name, comma after."
];
var existingFonts = [];
for (var i = 0; i < fonts.length; ++i)
{
const fontName = fonts[i];
if (fontExists(fontName)) existingFonts.push(fontName);
}
function fontExists(fontName) {
// Approach from kirupa.com/html5/detect_whether_font_is_installed.htm - thanks!
// Will return false for the browser's default monospace font, sadly.
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var text = "wim-—l~ツ亻".repeat(100); // Characters with widths that often vary between fonts.
context.font = "72px monospace";
var defaultWidth = context.measureText(text).width;
// Microsoft Edge raises an error when a context's font is set to a string
// containing certain special characters... so that needs to be handled.
try {
context.font = "72px " + fontName + ", monospace";
} catch (e) {
return false;
}
var testWidth = context.measureText(text).width;
return testWidth != defaultWidth;
}
function isCanvasBlank(canvas) {
return !canvas.getContext('2d')
.getImageData(0, 0, canvas.width, canvas.height).data
.some(channel => channel !== 0);
}
function canRepresentGlyphs(fontName, glyphs) {
var canvas = document.createElement('canvas');
canvas.width = 50;
canvas.height = 50;
var context = canvas.getContext("2d");
context.textBaseline = 'top';
context.font = "24px " + fontName;
var result = true;
for (var i = 0; i < glyphs.length; i++) {
context.fillText(glyphs[i], 0, 0);
if (isCanvasBlank(canvas)) {
result = false;
break;
}
context.clearRect(0, 0, canvas.width, canvas.height);
}
return result;
}
// -----------------------------------------------------------------------------------------------------
const ele = document.getElementsByClassName("character-header__characters")[0];
const default_font = getComputedStyle(ele).fontFamily;
let current_font = default_font;
let style = document.createElement("style");
style.appendChild(document.createTextNode(".character-header__characters:hover { font-family: var(--font-family-japanese-hover); }"));
ele.style.setProperty("--font-family-japanese-hover", current_font);
document.head.appendChild(style);
// On Submit
window.addEventListener("didAnswerQuestion", function()
{
ele.style.setProperty("--font-family-japanese", default_font);
ele.style.setProperty("--font-family-japanese-hover", current_font);
});
// On Next
window.addEventListener("willShowNextQuestion", function(event)
{
const characters = event.detail.subject.characters;
if (typeof(characters) == "string")
{
do current_font = existingFonts[Math.floor(Math.random() * existingFonts.length)];
while (!canRepresentGlyphs(current_font, characters));
ele.style.setProperty("--font-family-japanese", current_font);
ele.style.setProperty("--font-family-japanese-hover", default_font);
}
});