Using TamperMonkey for my recent post about messing with the Pepsi ROTY vote had me kind of on the lookout for other scripts to write.
Automating Things for the Sake of Automating
Today I got around to thinking about a minor improvement to my life that 100% conforms to the “why do something mildly inconvenient in six seconds when I could spend 30 minutes automating” mindset.
I’m a fogie, by which I mean I still use old.reddit.com. I hate the new design for a lot of reasons, especially visually, but I specifically love the old design because it works with
Reddit Enhancement Suite (RES).
One thing I really love about RES is its keyboard shortcuts. I’m a big fan of Vimium but RES works way better, so I disable Vimium on Reddit. One of the best keyboard shortcuts is the one that lets you jump to a subreddit from r/all. However, 99.9% of the time when I use that keyboard shortcut it’s to go to a sub I just found and the first thing I have to do is use my mouse to the top of the page to select
top of all time. Can’t have that.
Back to UserScripts
So I decided to write a little script in Tampermonkey that makes it so that all the subreddit links link in a new page to the top of all time in a subreddit.
I started by trying to do it in jQuery. Or rather, thinking of trying to do it in jQuery. I remember almost 0% of the jQuery I learned 3 years ago when I was using JS and React regularly.
$.ajax() is still a thing, right?
Whatever. Vanilla JS is fine, honestly. I don’t get enough chances to write fat arrow functions (which are honestly one of my favorite. I way prefer them over Python’s Lambdas)
The first thing I tried was to add another link next to the subreddit links so I’d have the option to go to either top all time OR just the regular sub.
but I immediately encountered a goofy problem.
See, when you use
Array, it returns an
HTMLCollection. Which I assumed would behave close enough, but first of all
forEach is not defined on it so I have to use a
for of loop, and second, when I do loop over it for my first trip it hangs… and by adding a cap on the number of iterations I can see why.
See, it turns out that
HTMLCollection is live updated. So when I add a new anchor tag with the class
subreddit, it gets inserted into the
HTMLCollection and comes up on the next iteration, gets a new anchor tag added after it, and so on, infinitely.
The lazy workaround is to modify my goal and just change the links to point to the subreddit’s top all time, rather than adding an additional link.
and this does work
but it leaves something to be desired. Now if I actually just want to go to the subreddit, that’s a pain.
Back to Basics with querySelectors
With a quick search I was able to find other people encountering the same problem as I did with
HTMLCollection being dynamic. This blog post has a great explanation of a workaround, which is to use
document.querySelectorAll which returns a
NodeList instead, and
NodeLists are static.
It looks like nothing changed, but actually, it has! There’s two links there, smushed right next to each other. And by clicking on either of them, I can tell that one does indeed go to
r/gaming and the second goes to
r/gaming/top which is great.
By adding a 3px
marginRight to the
style of the original element I can split the two apart so that it looks a little nicer.
The one thing that’s missing is that on line 16 I added
"/top" to the end of the
textContent of the original element for the new element. So I expected it to be
r/gaming/top, not just
It turns out that
HTMLElement.cloneNode() has a parameter,
deep that defaults to
true, which means the textContent isn’t getting copied. So with one final change, here’s the final script
Cool! And as a final bonus, now that I’m working with a
NodeList I get