I have the exact same issue on my side, the script does not work until after I refresh the page one time after I started my reviews. Nothing in the browser console either. Thanks a lot for your work on the script btw
Iāve posted another update for Open Framework. It addresses some issues with navigation, but probably not the āretypeā button issue yet. I havenāt been able to replicate that issue yet.
so donāt know who needs to see this, but i use WK on two different computers (desktop and laptop), and i guess i never bothered looking how to sync tampermonkey across the two devices (despite being logged into the same chrome profile and having everything else sync, tampermonkey does not). thus i had two piles of minorly different extensions. except on my laptop, double check actually worked and on my desktop it did not.
so i took a few minutes and manually matched up the list and even order of scripts on both computers. after all was said and done, i found three differences in regards to different script versions.
i tried the easiest first: i updated ConfusionGuesser which was outdated on my desktop to the current version (1.21). and voila! double-check randomly worked on my desktop. iām very happy now.
again, everyone has their own pile of script goop, but this is what worked for me, maybe itāll work for others.
tl;dr: i updated a separate extension (ConfusionGuesser) to the current version and double-check started to work again
I noticed that the page is not yet populated when the turbo:load event fires, and I havenāt yet found an event that actually does wait until everything is populated (turbo:render and turbo:frame-render both fire beforeturbo:load). So, what I did in Open Framework is: add a zero-millisecond delay after turbo:load, which basically just allows the current round of events to be fully processed before Open Framework starts calling scriptsā pageload handlers, presumably allowing Turbo to finish rendering the page firstā¦ and that seemed to work 100% of the time for me. But Iāve always hated resorting to that kind of trickery because it only works by circumstance, not by design. And, as is now obvious, itās not 100% successful for everyone, so I think there is still a race condition. The easy solution is to add a larger delay, but thatās still not a solution-by-design, and it adds unwanted delay, so unless someone has a better idea, I think Iām going to have to resort to something that I always dread: mutation observers.
If this turns out to be a common solution for scripts, Iāll add it to Open Framework. But for now, Iāll just put it in Double-Check.
When working on the Sow Total Lesson Count script we found that Turbo events fire randomly and sometimes donāt fire at all on a page load. You cannot rely on an event to always be there when you need it.
I didnāt work on the solution. @LupoMikti did. IIRC they rework the script to detect and handle page change even in the absence of events. How this was done I have no idea. You may look at the code for the Show Total Lesson Count script.
I just realizedā¦ was this maybe because not all of the pages were converted to Turbo yet? I know the dashboard was pretty much the last page the be converted.
As a temporary fix, Iāve just added a half-second delay in Double-Checkās startup to hopefully get it working on more peopleās PCs. Please upgrade and let me know if it works.
As you can see below, I updated OF last night and DC the day before and this morning DC is WORKING AGAIN with no āreloadingā required!!! So that half second delay was not needed for me.
But as you can see at the bottom, I still have to do a āreloadā in order to get SSQ to activate. Hope you can fix this at some point in the future when you have the time
I keep saying thisā¦but then again you KEEP DESERVING THISā¦thanks again for all your hard work!
I semi-recently watched some detailed videos about the JavaScript event loop and better understand why the setTimeout solution works the way it does. If it makes you sleep better at night, you can think of it as a peculiarity/limitation of the JavaScript engine. You already properly explained how it works, though. Essentially, using setTimeout(callback, 0) adds the callback to the task queue (often called macrotasks), which gets resolved after the current call stack and the microtask queue are all finished resolving.
Tangentially, there is apparently an upcoming API for a scheduler.yield() function, that does almost the same thing as setTimeout(callback, 0), but in a more inline fashion and also the position in which it is placed in the task queue is better handled. [Quite unfortunate that compatibility makes this a moot point for this conversationā¦]
Circling back, in other words, the method of handling the callbacks by adding them to the task queue via setTimeoutis a perfectly appropriate way of handling it. As for the instance of the events not always being reliable, that (from what I could tell) boils down to the implementation. For example, turbo:before-visit does not fire for history navigation.
Also, the reason I used that window.Turbo?.session.history.pageLoaded solution was to handle the case in which āturbo:loadā has already fired for the current page by the time the script runs, in which case, I got the current URL via window.Turbo.session.history.location.href (which might be overkill, but since I was already confirming Turboās existence, I figured I might as well use it). I think this was the issue that the Show Total Lesson Count script was dealing with, so I added a basic āloadā listener (similar to how you had started doing it before) that would call the callback immediately if-and-only-if the page had already finished loading by the time the listener was attempting to be added.
As far as I could tell when I was working on fixing my script for Proleauās issues, every page navigation I did was a turbo one; I only ever got full page refreshes by using the browser refresh button.
In my script, to address the various scenarios of events not firing in order or not firing at all, I needed to introduce a script-global state management system so I could keep track of where in the loading/injecting process the script was. I needed to know when it entered the āstartingā state, when it entered an initial load rather than a subsequent load, when the turbo-frames I needed to be loaded were successfully detected as loaded, a retry counter for attempts at injecting what I needed, and a variable to track the state of my turbo event handlers being ābusyā or not to try and introduce pseudo-blocking context for async callbacks.
Itās all very messy as itās the product of troubleshooting rather than architecting, but maybe the ideas can be helpful in addition to what Inserio has provided above: Show Total Lesson Count
Thanks! This resolved the issue for me about 70% of the time. However, I noticed that sometimes the turbo:load event listener doesnāt get registered, as briefly mentioned above.
I spent some time reviewing the code, though I should note that I donāt have experience with scripting and Iām not familiar with the API. I observed that the turbo:load event is added as early as possible in the Open Framework script with // @run-at document-start. However, in some cases, the document body isnāt initialized at this point, which causes an exception to be thrown (although itās hidden because the catch block is empty).
To fix this, I replaced // @run-at document-start with // @run-at document-body. According to the Tampermonkey documentation, this ensures that the script is injected only when the body element is available. After making this change and refreshing the page several times, the issue with the event not triggering seems to be resolved.
Again, Iām inexperienced with scripts, so there might be other factors Iām missing, but I hope this can help