Wanikani Open Framework [developer thread]

@rfindley I wanted to get your opinion on how to do something. I might want to reuse one of the filters that I wrote for the Additional Filters script for another purpose. However, the filter itself may not be registered with WKOF if the user has turned it off in the Additional Filter script’s settings. So here are my questions.

  1. My filter has a parameter with a default value. When it’s used in Self Study, it can be on or off and have different settings depending on the item set being used. How can I have a unique setting for overriding the default for my script, just like the Self Study script does for each item filter?
  2. Related to the previous question, how can I use Open Framework to just apply this one filter and none of the others registered with the framework?
  3. Any suggestions for what to do if the user has disabled the requisite filter in the Additional Filters script? I could just force it to be included if the new script is enabled, but I’m not sure if that’s the best approach. Is there any way for my new script to use it without forcing it to show up in Self Study if the user turned it off in the Additional Filters script? (I’m kind of regretting having added the global setting for not registering the filters hehe.)

If it makes sense, feel free to just point me to specific code in the Open Framework or Self Study scripts.

You’re wanting to use this filter in something other than Self-Study, right?

The settings in the Self-Study dialog are stored purely inside of wkof.settings.ss_quiz, and are only used by Self-Study. If you want to keep separate settings (in addition to the default), you can store them in your own script’s settings, and just pass those settings to wkof.ItemData.get_items(). That’s all Self-Study is really doing… a fancy dialog box built dynamically based on the description in the registry, but ultimately just passing the user’s chosen settings to get_items() like this:

wkof.ItemData.get_items({
    wk_items: {
        filters: [
            some_filter: {value: some_filter_value},
            another_filter: {value: another_filter_value},
        ]
    }
})
.then(do_something);

If you want to use a filter without registering it, just apply it manually to the items returned by get_items():

wkof.ItemData.get_items()
.then(additional_filter)
.then(do_something);

function additional_filter(items) {
    // We'll use the Array.prototype.filter() function to iterate through each item.
    // 'your_filter_function()' should return true for each item you want to retain.
    return items.filter(your_filter_function);
}

function your_filter_function(item) {
    // return 'true' if you want to retain the item in the dataset
    // Example:
    var some_date = wkof.settings.my_script.somedate;
    return (item.data.unlocked_at > some_date);
}

function do_something(items) {
    // TODO: Do something with the fully filtered item set.
}

In summary, filters don’t have to be registered. The registry just helps scripts find new filters dynamically, and tells the script any info it needs to know to be able to dynamically create a user interface for such filter.

Are you asking how to set up your Settings dialog in a similar way to Self-Study? Or just how to keep separate settings?

No need for a settings dialog like in Self Study. I’d just put it in the main menu with other script settings.

1 Like

How are these two approaches different? Is it just that the first requires the filters to be registered (if that’s even right)? Anything else?

Yeah, mainly just registered vs non-registered. Internally, the Framework is doing pretty much exactly what the second one is doing, but it’s slightly more efficient since it applies all filters to each item, so it doesn’t have to iterate over all of the items multiple times. But the speed difference it negligible for only 8804 items.

The only other difference is:

  • Registered filter functions are passed two values: the filter value, and the item.
  • The way I set up the non-registered function in my example, it is only passed the item. But you could pass the filter value too, if you want.
1 Like

@rfindley Is there a built in way to get a specific set of items? It would be a shame to have to run a custom filter with each request, especially since I’d have to search through every item to find the right ones.

For testing purposes, I built a ‘slug’ filter that takes a comma-separated string containing the list of slugs. I could post the code later if you want.

For every query, the Framework always grabs the whole list of items from indexedDb (if it’s not already in memory), and just runs the Array filter() function on all items. So, writing a Framework filter is essentially the same as just taking the full items array and just running the array filter() function on it.

@seanblue,
The Settings module now remembers the selected tabs for settings dialogs.

One caveat, though: It remembers if you close the dialog with Save, but not with Cancel, because the state is stored inside the client script’s settings (wkof.settings[script_id]).

1 Like

I’m just writing my first little script using the wkof and it so nice and helpful and does exactly what it is supposed to do according to the documentation. Thanks so much!

And happy cake day to you, @rfindley. 4 years of making WaniKani a better place :heart:

3 Likes

New script!

Looks nice!
Added to the top-post.

1 Like

Thanks for making the WKOF. Writing this script was so much easier with it.

1 Like

Anybody having trouble with Tampermonkey scripts? I apparently got Chrome 68 sometime today, and noticed that all of my scripts are failing to load. Dashboard timeline, WK Undo, etc., all aren’t loading.

Anybody else?

Everything looks fine to me with TM on Chrome 68

OK, thanks. I’ll keep poking at it…

Weirdly, Tampermonkey just blew up on me or something like that. I exported my scripts from the utility menu, removed from Chrome, added it back from the web store, and imported the txt file. After that everything looks fine.

So, just in case anyone sees the same issue with scripts not loading or scripts not running, just remove Tampermonkey and add it back from the store.

1 Like

Not sure about where to post bug reports, but seems like this is the right place.

Browser: Firefox 62.0

So, after coming back to doing some items after a while (~6 months), I upgraded the script, installed the Wanikani Open Framework (executed as #1) and nothing shows up on the lesson screen.

Log says:

13:32:38.969 indexedDB could not open! userscript.html:342:4
13:32:38.970 uncaught exception: undefined
13:32:39.254 WK Auto Commit (a plugin for Wanikani): Initialization started userscript.html:301:5
13:32:39.264 WK Auto Commit: Initialization ended userscript.html:327:5
13:32:39.311 doit session:48:9
13:32:39.312 wrap answerChecker session:55:9
13:32:39.603 START OF WRN userscript.html:18:3
13:32:39.716 Loading failed for the <script> with source "https://js-agent.newrelic.com/nr-1071.min.js". session:1 

Disabling uBlock Origin and Ghostery and turning Firefox’s tracking protection made the final message disappear. List of active scripts:

  • Wanikani Open Framework 1.0.36
  • WaniKani Real Numbers 3
  • Wanikani Reorder Ultimate 2 2.2.4
  • WaniKani Ultimate Timeline 6.5.1
  • WK Auto Commit (edited) 0.42
  • WK But No Cigar 0.9

By putting a console.log() at the beginning of the Reorder script I could verify that it loads after WK Auto Commit. The exception seems to come from Wanikani Open Framework. Usually, I am using a “forgetful” Firefox profile, i.e. permanent private mode, no history recorded, tracking protection enabled, cookies get deleted when closing the browser. But, it seems that setting Firefox to Private Mode automatically disables indexedDB support, although it’s enabled in about:config.

Pretty sure the answer will be “no”, but: Is there a (convenient) way around this? Maybe I am missing somethinghere, but that kinda sucks ^.^ If nothing works, I will have to make a Wanikani profile ._.

Yeah, that was an unfortunate configuration decision by Firefox. IndexedDB is the only non-server-side storage choice for web applications that need a decent amount of storage.

There’s a workaround, though your data will have to load from scratch every time, and it won’t store configuration for userscripts. At the top of the Open Framework script:

	var ignore_missing_indexeddb = false;

Set that to true.

1 Like

Another new script to add to your growing list! :smile:

1 Like