[Userscript] Wanikani Common Vocab Indicator - Updated

Uses Jisho.org to indicate if the vocabulary item is “common” or not

Install from GreasyFork:
https://greasyfork.org/en/scripts/408339-wanikani-common-vocab-indicator

Installation note: Since it uses Jisho.org, you may be prompted by your user-script manager to allow the script to access Jisho.org to retrieve the is common data. Please click on “always allow from this domain” for Jisho.org when prompted.

Based on the original script by Dtwigs: New User Script: Common Vocabulary Indicator

Changes: I wanted to make some changes to the script and update it a little bit. It is largely the same script as before but:

  1. Move indicator to the right side
  2. Hide indicator when it is not a common word
  3. Add cache to reduce calls to the Jisho API

You can find the code on my GitHub

Development: I’m going to leave this script in “maintenance” mode. There’s no further development or major features that I will contribute to it other than fixing bugs. Please feel free to message me in this thread or send a pull request/issue on this project’s GitHub.

In the previous thread, there was some interest in tying in other sources for the “common” indication (e.g. google search data). I leave it to the community to experiment with that. Hopefully this script may serve as a useful springboard.

11 Likes

Hello, is there new updates on this script?
As for me it doesn’t work anymore…

I wasn’t able to determine where exactly the script is breaking (it’s an awful lot of code for what feels like a pretty straightforward operation), so I ended up writing my own from scratch:

WK x Jisho Common
// ==UserScript==
// @name         WK x Jisho Common
// @version      1.0
// @description  Indicates when the subject under review is common according to jisho.org
// @author       Morikohiki
// @match        https://www.wanikani.com/*
// @require      https://update.greasyfork.org/scripts/421384/1134973/GM_fetch.js
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @connect      jisho.org
// ==/UserScript==

(function() {
  const jic = document.createElement('div');
  jic.setAttribute('style', 'position: relative; bottom: 1.2em; text-align: right; padding-right: 0.2em; height: 0; color: white; font-size: 80%; font-weight: bold;');

  const mo = new MutationObserver(ml => {
    const word = ml[0].addedNodes[0].wholeText;
    const cached = GM_getValue(word);

    if (cached) jic.innerText = cached;
    else {
      GM_fetch(`https://jisho.org/api/v1/search/words?keyword=${word}`).then(r => {
        r.json().then(j => { // not a regular space!  v
          const v = j.data[0].is_common ? 'COMMON' : ' ';
          GM_setValue(word, jic.innerText = v);
        });
      });
    }
  });

  const watch = function() {
    const header = document.querySelector('.character-header');
    if (!header) return mo.disconnect();
    header.append(jic);
    const target = document.querySelector('.character-header__characters');
    mo.observe(target, {childList: true});
    target.innerText = target.innerText; // trigger missed mutation
  };

  const hps = history.pushState;
  history.pushState = function() {
    hps.apply(history, arguments);
    setTimeout(watch, 100);
  };

  watch();
})();

Apologies for taking so long to respond, but I wanted to make sure it worked during reviews, not just extra study. It’d probably be easiest to just go ahead and replace the old code with the new rather than installing mine as a new script; that way it’s already set up to allow cross-origin requests to jisho.org.

Everything (caching, positioning of the indicator, navigation-agnostic activation) seemed to work fine during my testing, but please let me know if you encounter any issues.

Thanks a lot for taking time to write a new code !
You’re a boss.

Unfortunately, it returns an error on line 24 ‘GM_fetch is not defined’
I tried check some vocabs for exemple 家
But nothing indicate it’s a common word on that page. Maybe your code only show the Common tag during the lessons or reviews session?

1 Like

I suspect you’re referring to the little warning triangle (:warning:) that shows up in the editor; this happens because the UI isn’t aware that that function is being provided by an external script (the one referenced in the @require directive in the script’s metadata).

Bummer that it didn’t work for you on the first try, but I don’t think it’s to do with the missing GM_fetch, which again shouldn’t actually be missing at runtime. The only thing I can think it would be is a missing permission somewhere, or else it could be interacting poorly with some other script. I guess I probably should’ve added some error-checking here and there. :sweat_smile:

If it’s not too much trouble, are you able to check whether your browser itself is reporting any errors to the console?

Editing to add that the script does indeed only run during lessons, reviews, and extra study. Somehow it didn’t occur to me that it’d be nice to have the indicator on vocabulary pages as well, but I’ll sort that out.

Uncaught TypeError: Failed to construct 'Response': Invalid name
    at opt.onload (userscript.html?name=WK-x-Jisho-Common.user.js&id=ff5291f9-7301-4aed-8e35-e4f6c7d76083:10:12)
    at Pt (<anonymous>:10:89)
    at <anonymous>:46:242
    at Pt (<anonymous>:10:89)
    at r (<anonymous>:32:484)
    at <anonymous>:33:112
    at <anonymous>:22:300
    at _ (<anonymous>:22:319)

And then if i click on the link i get this

window[“__f__mf3vvmk9.cyp”] = function(){with (this) {(async (u, { p, r, s }) => {try {r(u, s, [undefined,undefined,undefined,p.GM_getValue,p.GM_setValue,p.GM_xmlhttpRequest,p.unsafeWindow,p.GM_info,p.GM]);} catch (e) {if (e.message && e.stack) {console.error("ERROR: Execution of script ‘WK x Jisho Common’ failed! " + e.message);console.log(e.stack);} else {console.error(e);}}})(async function(define,module,exports,GM_getValue,GM_setValue,GM_xmlhttpRequest,unsafeWindow,GM_info,GM) {function GM_fetch(url, opt={}){return new Promise((resolve, reject)=>{// // opt.url = urlopt.data = opt.bodyopt.responseType = “blob”opt.onload = resp=>{resolve(new Response(resp.response, {status: resp.status,// headers: Object.fromEntries(resp.responseHeaders.trim().split(/[\r\n]+/).map(line=>{parts=line.split(': ‘);return [parts.shift(), parts.join(’: ')]}))}))}opt.ontimeout = ()=>reject(“fetch timeout”)opt.onerror   = error=>reject(error)opt.onabort   = ()=>reject(“fetch abort”)GM_xmlhttpRequest(opt)})}

Hope it can help

That would be great :face_holding_back_tears:

I tried to do it myself with AI.

It was kind of a hell to manipulate the code and soooooo long to load, and also too many requests to Jisho.

So i created another script with 3000 most common Japanese words. This list is directly packed in the script.
It triggers during the reviews, lessons, and also on the level pages with a small ‘C’ that indicates that the word is in the list.

Here it is if someone is interested.
WK x 3000 Common Words