[UserScript] WaniKani Fast Abridged Wrong/Multiple Answer

Damn, looks like script is loading faster than other files it depends on.
Guess this is a good excuse to rewrite with the open framework, since it needs fixing anyways :stuck_out_tongue:

1 Like

If you do end up using the framework, [Burn Manager] is a good reference example. All the menu-related stuff is at the top of the script. Iā€™ve started putting my scripts under an ā€œOpenā€ or ā€œSettingsā€ sub-menu, depending on what the link actually does. But Iā€™m open to coordinating based on something different if people have other ideas.

1 Like

Actually fighting with settings at the moment. I have two scripts in progress of migration, both using Open Framework, but only the first gets its settings installed into the menu. If I turn that one off, the other does load. Iā€™ll check out the Burn Manager to see if I canā€™t figure out where Iā€™m going wrong.

I can have two scripts settings under the same sub-menu no?

Yeah, I have several installed under Open. Do they each have a different value for ā€˜nameā€™? I may have code in there that prevents duplicating a name since the name is (or was originally going to be) used to create an id attribute.

There we go, thank you.

The sample at wanikani-open-framework/sample_client.js at master Ā· rfindley/wanikani-open-framework Ā· GitHub has script_id instead of name. Was this a renaming, or are they functionally different?

ā€œsettings_dialog = new wkof.Settings({ā€ also utilizes script_id in the example.

Iā€™ll update the example and check if the docs are right. I moved away from ā€˜script_idā€™ in the Menu module because it implies that itā€™s per-script, which doesnā€™t work if a script has more than one menu link. But for sake of not breaking the interface, ā€˜script_idā€™ gets copied into ā€˜nameā€™.

Iā€™m not sure if Settings supports ā€˜nameā€™ yet, but it probably should. Thatā€™s the first module I wrote, and is where script_id originated since I didnā€™t (at the time) think about a script having more than one settings dialog. But things evolve :slight_smile:

That was it, thanks! The one place I forgot to look.

For some reason there seems to be a bug where I canā€™t add synonyms while doing reviews. There also is apparently some buggy stuff happening with synonyms even outside of reviews. It seems to be originating with this script, as turning it off fixes this problem.

dagnabit, I think I borked something real bad. Hang tight fellas.

Edit 1: Went to test the synonyms , and whole entire review was borked (see above statement). Reviews auto-went on after getting right, but didnā€™t mark as right. That seems to be straighted out. Now, back to the synonyms issue. Big failure on my part completely borking it, sorry anyone affected.

Edit 2: Uncaught Error: cannot call methods on autocomplete prior to initialization; attempted to call method 'off' ummā€¦ :flushed:

Edit 3: @rfindley So on review pages, simply calling ā€˜wkof.include(ā€˜Settingsā€™);ā€™ causes the error in Edit 2 when attempting to add a synynom. Any ideas?

Hmmmā€¦ That sounds like a jquery or jqueryUI error (just guessing). I donā€™t call ā€˜offā€™ in my code, though.

Are you certain itā€™s just the wkof.include(), and not creation of a settings dialog? Is there anything useful in the call stack in the console?

Summary
if(window.location.href == "https://www.wanikani.com" || window.location.href == "https://www.wanikani.com/dashboard"){
        wkof.include('Apiv2, Menu, Settings');
        wkof.ready('Menu').then(install_menu);
        wkof.ready('Settings').then(install_settings);
    } else {
        wkof.include('Settings');//shorted to just this
        //A bunch of commented out stuff
    }

clicking the ā€˜add synonymā€™

Summary
Uncaught Error: cannot call methods on autocomplete prior to initialization; attempted to call method 'off'
    at Function.error (application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:1)
    at HTMLInputElement.<anonymous> (<anonymous>:6:5615)
    at Function.each (application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:1)
    at pe.fn.init.each (application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:1)
    at pe.fn.init.t.fn.(anonymous function) [as autocomplete] (<anonymous>:6:5357)
    at new pe.fn.init (application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:2)
    at pe (application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:1)
    at HTMLLIElement.<anonymous> (application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:6)
    at HTMLLIElement.dispatch (application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:2)
    at HTMLLIElement.g.handle (application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:2)

which brings me to application-a9d56fe7838575d6e64bf494c077af35b542a299fc31c1aebc9f33104b08df8b.js:formatted:767

Summary
    pe.extend({
        expando: "jQuery" + (fe + Math.random()).replace(/\D/g, ""),
        isReady: !0,
        error: function(e) {
            throw new Error(e)
        }, 
....

Looking deeper, traces back, partially at least, to ā€œthis.UserSynonyms.addOption = function(e, t, n) {ā€ But, that makes sense

Summary
this.UserSynonyms.addOption = function(e, t, n) {
        var r, i;
        return r = $(".user-synonyms-add-btn"),
        i = UserSynonyms.wrapper(),
        r.off("click"),
        r.on("click", function() {
            var a, o, s, u, c;
            return $(this).hide(),
            s = $("<li></li>", {
                "class": "user-synonyms-add-form"
            }).appendTo(i),
            u = $("<form></form>").appendTo(s),
            c = $("<input></input>", { <-- this line for some reason
                type: "text",
                autocapitalize: "none",
                autocomplete: "off",
                autocorrect: "off",
                spellcheck: "false"
            }).appendTo(u).focus(),

And youā€™re saying if you comment out the include(), you get no error?
Hmm. Can you send me your current code?

I suppose itā€™s possible Iā€™m accidentally overwriting some global variable thatā€™s being used by something else.

is pretty much current, just trying a bunch of things around line 50. Commenting out the entire ā€˜elseā€™ section, error goes away. But just throwing in the include() and error comes.

Okay, Iā€™m able to replicate this. Iā€™ll look into this tonight.

@DaisukeJigen,

I found the problem.
@viet, you might be interested in this, if youā€™re not already aware.

details

It seems jQuery UI is incompatible with one piece of Wanikani code.
In Wanikaniā€™s UserSynonyms.addOption(), it does this:

$("<input></input>", {
    type: "text",
    autocapitalize: "none",
    autocomplete: "off",
    autocorrect: "off",
    spellcheck: "false"
})

The intent is to add each parameter in the object as an attribute on the <input> tag.

The problem is that jQuery checks each parameter to see if it matches a function name in $.fn.
In this case, jQuery UI has an Autocomplete widget that places a constructor at $.fn.autocomplete().
So, instead of adding an autocomplete="off" attribute to the <input> tag, it tries to call $.fn.autocomplete("off").

You can simulate the exact same error by doing this directly (after loading jQuery UI dynamically):

$('<input></input>').autocomplete("off")

Iā€™m going to push a workaround into the framework tonight.

details

Iā€™m going to dynamically remove $.fn.autocomplete after jquery_ui.js loads:

delete $.fn.autocomplete;

Weā€™ll lose the ability to use the Autocomplete widget, but I wasnā€™t using it anyway, so no issue.

This makes the ā€œadd synonymā€ feature work like normal.

4 Likes

Iā€™ll set up some tests today and see if we can avoid the function/attribute collision.

2 Likes

Hi! Iā€™m not sure what Iā€™m doing wrong but I canā€™t get the colors to change. Iā€™m not one with the coding so could you tell me what to change in the code to change the colors? Thanks.

In the showBar function I believe. Not at home, so harder to check. Youā€™d have to make a switch statement based off mode. It was a setting before, but it went away when converted to Open Framework. Itā€™ll be making a return, but took a leave of absence to get the OF version up and running.

@DaisukeJigen,
bonkaholicā€™s issue turned out to be this:

    if(window.location.href == "https://www.wanikani.com" || window.location.href == "https://www.wanikani.com/dashboard"){

The location was actually https://www.wanikani.com/ (i.e. with a slash on the end), so it wasnā€™t installing the menu link.
You can use pathname instead of href, since it automatically adds a "/" if one isnā€™t present:

    if(window.location.pathname == "/" || window.location.pathname == "/dashboard"){
2 Likes

I scooted the attributes out of the short-hand element constructor and added them with a .attr({ā€¦}). The codeā€™s live so we shouldnā€™t have the attribute/function name conflict anymore. (JQuery UI) Autofill away!

2 Likes