Monkeying around

I’ve finally got around to writing the Greasemonkey script which I’ve long been threatening.

What it does

The script remembers which comments you’ve seen on LJ (or Dreamwidth) and helps you navigate to new comments. That’s right, I’m finally dragging LiveJournal kicking and screaming into the 1980s.

If you’re on an entry page, pressing “n” skips you to the next new comment, and “p” skips to the previous one. If the style has an “Expand” link, moving to an unexpanded comment with these keys will also expand the thread. If the style has a permanent link or a reply link for each comment in that comment’s header or footer, the script inserts another link next to it, labelled “NEW”. That link shows you that the comment is new at a glance. Clicking the “NEW” link selects the comment so that pressing “n” will go to the next comment from there. On some styles, the currently selected comment will be outlined with a dotted line.

On a journal or friends page, the script will also add the number of new comments to the link text, so that, say, “15 comments” becomes “15 comments (10 new)”, and enable the “n” and “p” keys to move between entries which have new comments, and the “Enter” key to view the selected entry. This only works if you’re looking at a journal which adds “nc=N” to entry links to say there are N comments on an entry (LJ can do this as a trick to confuse your browser’s history function into thinking you’ve not visited that entry whenever there are new comments). If you want to turn this on for your journal then ensure you’re logged in, visit this page, check the box which says “Add &nc=xx to comment URLs” and hit the “Save” button.

How it works

You don’t need to understand this section to use the script. If you don’t care about programming, skip to the next part.

<lj-cut text=”Gory details”> LJ makes it a total pig to do this sort of thing: there’s so little uniformity in journal styles that getting a script like this to work for all of them is impossible. It’s fair enough that LJ allows people to customise their journal’s appearance, but there aren’t even standardised CSS class names for stuff. Not that I’m bitter. So, what the script does is look for anchor tags of the form <a name="tNNNN"> or elements with an id attribute of ljcmtNNNN or tNNNN. NNNN is the comment number, which seems to be unique for each comment on a given user’s journal. It then looks for the permanent link to that comment, which is usually to be found in the header of the comment (or footer, in my current style), and adds a “New” link after that. So, new comments are marked with a link to the next new comment.

The upshot of all this is that if you’re reading a journal with a style which doesn’t use either anchor tags or elements with the given id for all comments, the script won’t work correctly. If the style doesn’t provide each comment with a permanent link in the comment’s header, the comment won’t be marked with a “New” link. Such is life. Please don’t ask me for special case changes to make it work with LJ’s many horribly customised journals. Pick a sensible style of your own and learn to use “style=mine” instead. There’s even another Greasemonkey userscript which will help. On the other hand, if there’s a large class of the standard styles for which it doesn’t work, tell me and I’ll have a look at it.

Using it

If you want to use it, you will need:

  • Firefox, the web browser, version 1.5 or later.
  • Greasemonkey, the extension which lets people write little bits of Javascript to run on certain pages.
  • LJ New Comments, which is what I’ve imaginatively entitled my script. If the userscripts site is down again, you can find a copy on my site.
  • Your flask of weak lemon drink.

After you’ve installed all of the above, visit an entry on LJ and marvel at the “NEW” links on all the new comments (which will be all of them at this point, as the script wasn’t around previously to remember which ones you’d seen before). See above for operating instructions.

Privacy

Note that the script stores a Firefox preference key for each journal entry you visit, listing the IDs of the comments it finds there. The script doesn’t let the database grow without limit: when the script has seen 500 entries, it starts to drop the history for the entries you’ve not visited recently.

Clearing the browser’s history doesn’t affect the script’s list of visited entries. Thus your visits to polybdsmfurries will be recorded for posterity, even if you clear the browser’s history. You can wipe the entire history by using the “Manage User Scripts” entry on the Tools menu to delete the script and its associated preferences (you can re-install it afterwards, but you must clear out the preferences for it to delete the history).

The script does not record the contents of any entry or comment. The script does not transmit any information to LJ or any other website, it merely acts on what it sees when you request journal entries.

Your questions

I’ve given this entry as the homepage for the script on Userscripts.org. That means this entry is intended to serve as a repository for questions about the script, so if you’ve got a question, comment here. I prefer this to commenting on my other entries or to emailing me, unless you already know me. Ta.

To keep up to date with new releases of my greasemonkey scripts, track the tag “greasemonkey” on my journal. This link should enable you to subscribe to that tag and get notified when I post a new entry about greasemonkey scripts.

Revision history

2006-01-02, version 0.1: First version.

2006-01-03, version 0.2: Added the “p” key. Used javascript to move between comments so doing so does not pollute the browser’s history. Coped with the id=ljcmtNNNN way of marking comments. Made “n” and “p” keys work even in the absence of permalinks on each comment.

2006-01-04, version 0.3: Apparently you can have id=tNNNN, too.

2006-01-04, version 0.4: Broke 0.3, fixed it again. I hope.

2006-01-19, version 0.5: Updated to cope with LJ’s new URL formats. Changed how comments are stored internally so that the database does not grow without limit: the script now remembers comments for the last 500 entries you visited, and forgets the entries you’ve visited least. Also added “New” marker based on reply link as well as thread link, for styles which don’t have a thread link for every comment.

2006-01-19, version 0.6: Convert dashes I find in URLs to underscores internally, to preserve access to history from older versions of the script before LJ’s URL change.

2006-02-09, version 0.7: Work around the fact that Firefox leaks memory like a sieve. Never display negative number of new comments. Change licence to MIT as GPL is overkill for this script.

2006-02-09, version 0.8: There was a bug in the workaround code I got off the Greasemonkey mailing list. Fixed that.

2006-06-04, version 0.9: Enabled the “n” and “p” keys on the friends/journal view. Added the box around the current comment.

2007-02-20, version 1.0, baby: Try harder to draw a box around the current new comment. Applied legolas‘s fix for pressing CTRL at same time as the N or P keys (see comments).

2008-03-31, version 1.1: Make it work faster on entries with lots of comments. Altered behaviour of “NEW” link so it now selects the comment you’re clicking on, as that makes more sense.

2008-09-24, version 1.2: Support Russian keyboards thanks to mumi_0, make threads expand.

2009-01-27, version 1.3: Support for independentminds journals.

2009-05-04, version 1.4: Support for Dreamwidth.

2009-09-22, version 1.5: Amend support for Dreamwidth.

2010-08-09, version 1.6: Made syndicated journals work.

81 thoughts on “Monkeying around”

  1. This is an excellent script, thank you!

    I do have one problem with it though. I can’t navigate to the “next” and “previous” new comments when I use “begin finding as you begin typing” option in Firefox, because it brings up the find dialog instead.

    How can I modify the script to use for example the Alt-n and Alt-p combinations instead?

    1. Funny: my Firefox doesn’t do the search thing unless I press “/” and then start typing. Maybe it’s a configuration thing. Anyway…

      If you’re happy changing a bit of Javascript, the part you’re interested in is the keypress_handler function near the bottom of the script. The event has event.altKey set true if the Alt key was pressed along with the key, event.ctrlKey set if the Ctrl key was pressed, and so on. So you’d want to change the test for each key to something like: if (event.which == 112 && event.altKey), I think, that is, you’d say “press p and alt key at the same time”.

      Hope this helps.

      1. Now that you mentioned it, yes, I think I actually have changed a preference somewhere (or was it an extension?) which enabled find as you type without the “/”. Anyway, I’m going to try to change the script to work with the Alt key. Thanks again :).

      2. I have run into another problem. I have the “nc=N” turned on, but the number of new comments does not work with the Generator layout. I have temporarily taken out all my overrides and switched to the default theme, and the number of new comments is still not showing. However, as soon as I switch to another layout, the number of new comments is displayed.

        (And there’s no coincidence of somebody just adding a new comment–I’m not clicking on the comments, just switching between various layouts.)

        Curiously, all the other layouts are showing the number of new comments, it’s only the Generator that doesn’t. Any ideas what might be the problem?

        1. I just switched to the Generator style and back again, and It Works For MeTM.

          One thing it does require: if you’ve got an “nc=N” link, the text inside the link must contain the number N somewhere for the script to modify it. People often copy the nc=N part when they link to someone else’s entry, and I didn’t want to start peppering “here’s a great entry” links with “(10 new comments)”, so it’s looking for something it’s pretty sure is a friends/entries page link to that entry. So if you’ve customised your style not to have the number of comments in the link text somewhere, the friends/entries page functionality won’t work.

          The other thing to note is that it doesn’t fire on any of the special URLs that paid users get (user.livejournal.com or livejournal.com/~user/), at the moment, although some code to do that is partially in the script.

  2. This is a really handy script; thanks. Are you interested in new-feature suggestions? You could make “n” on a journal page find the first journal entry on the page with unread comments, load it and point the browser at either the top of the entry (if all comments are unread) or the first unread comment.

  3. Oh, and in the ‘bug report’ category, after hitting ‘back’ to return from an entry page to my friends page the link was updated to say “(13 comments (-1 new)” — note the negative number. Unfortunately it doesn’t seem to be reliably reproducible 🙁

    1. I’ve seen that on entries with deleted comments, as the number of comments goes down but the markers for the comments are still there (and anyway, there’s no way to know the comment was deleted before opening the entry). I think the best thing for the script to do is not modify the link text when it comes up with a negative number.

      1. I don’t think deleted comments are involved here. I think that what happens is that:

        (1) you load your friends page and it says for a particular entry “13 comments (2 new)”
        (2) at this point somebody else replies to that entry
        (3) you visit the page for that entry and read the new comments (the 2 you knew about and the third one that was just added); so the script knows there are 14 read comments now
        (4) you press the back button — this page hasn’t been refreshed so it still says “13 comments”; your script then updates the “n new” text to 13-14 == -1

        [But I haven’t actually looked at the script so this is just speculation.]

        So I think that you could either refresh the page or just make it change the text to “14 comments (0 new)” by adjusting the comments count if the new count would otherwise be negative. But I hadn’t thought about the deleted comments aspect.

        1. Yes, I bet that’s what’s going on: I’d not considered the cache.

          I think refreshing the page is probably a bad thing, as it generates more traffic for LJ. Giving zero out as the answer seems cleaner. There’s not much I can do about deleted comments as AFAIK there’s no way to recognise that a comment has been deleted without a lot of faff which probably won’t work for some styles, so I think I’ll just put that down as a known “feature” of the script.

    2. I’ve fixed it so it doesn’t do that, and also so it works around various memory leaks in Firefox 1.5.

      The negative numbers fix is not ideal, as the logic is merely “if the number comes out negative, don’t display it”, whereas it ought to be “if you loaded the friends page more recently than the entry page and the number of new comments is negative, some have been deleted: never compare the nc value with the script’s notion of newness again, just compare the last nc with the new one each time you see it.” But that’s more work than I want for a late-night hack.

  4. Another bug, although I’m not sure what provokes this: sometimes my friends page ends up with links like this: “8 comments (1 new) (1 new)”…

    (I’m still using 0.6.)

    1. Hmmm… I’d hope that Greasemonkey did its own idempotency checks to prevent that sort of thing. I’ve never seen that one with GM 0.6.4 on FF 1.5. Any more ideas on how to reproduce it?

  5. Hello! I’ve been using your script before, but I switched OS and lost it. As Userscripts.org is down right now, I can’t access it. Have you made it available elsewhere?

    1. Hi. Userscripts is a bit unreliable at the moment, so I’ve placed a copy of the script on my site (and also uploaded the new version I’ve had kicking around on my hard drive for a while).

  6. I didn’t realize how much I relied on this script until I changed my style to use .permalink_url?format=light instead of $.comments.read_url (so that the killfile script would work properly) and found that losing ?nc=xx also lost me the new comment notes. Fortunately, using $.comments.read_url&format=light appears to work. Thanks for a great script!

    1. Thanks for the comment: I’m glad to know that people find it useful.

      I keep thinking I’ll generalise its knowledge of where comments are in various styles to extend the killfiling and thread unfolding functions that other people have implemented for the default comment style, but I’ve been a bit busy lately. Maybe now I’ve got some more free time I’ll give it a go.

    1. It sort-of works, but they don’t know about each other, so they don’t interoperate properly. What happens on my machine is that on pages with the default comment style, if I unfold a thread, LJ New Comments will fail for the comments on that thread, but if I keep pressing “n”, I will eventually reach the bottom of the thread.

      This makes sense: LJ Thread Unfolder destroys a piece of the DOM and replaces it with the comments it loaded, so Firefox refuses to scrollIntoView the objects which LJ New Comments has cached (the folded up comments, which are just the header without the text). Making LJ New Comments recache its idea of where each comment is (without updating its idea of newness) whenever LJ Thread Unfolder unfolds a thread would make things work, but I don’t know of a good way for two GM scripts to communicate like that.

      My master plan is to use LJ New Comment’s ability to recognise a comment in a variety of styles to make a better thread unfolder (the current one only really works in the default style, useful though that is) and possibly a kill-file (I want my Usenet). Don’t hold your breath, though.

  7. Bugreport: installing this script and then opening a new window with ctrl+n makes my friends page jump to whatever ‘n’ would jump to. I’m trying to fix this, I’ll let you know if I do.

    1. Ok, I fixed it like this: I added these lines to the keypress handler:

         //return if any modifier is active, so we don't handle e.g. ctrl+n
         if(event.ctrlKey || event.altKey  || event.ctrlKey  || event.metaKey  || event.shiftKey)
         return;
         

      Just under the already existing

         if (event.which != 110 && event.which != 112)
         return;
         
  8. Of all the userscripts out there, yours is probably the most useful and most reliable userscript out there. There’s a few system styles out there that it doesn’t work on. But no biggie.

    1. er, I spoke slightly too soon. I *also* had to put an if block around
      all the entry-specific stuff.

      if (userName) {

      }

      *then* I find it is storing too long a comment list: it is storing a
      string of comment ids, plus “extend, override, init, destroy” so the
      list is four items too long. I thought this was a style issue but I
      poked some more and it turns out to be something to do with the js
      objects because they show up even with

      commentHash = new Object();
      for (commentNumber in commentHash) {

      so I blame opera, and I fix that loop to ignore those items….

      *then* I realise that (??) because the gm emulating thing works by
      storing document cookies, it’s not working properly because of post and
      friends page being in different domains. So I have to edit the gm
      emulator to take the domain as an argument to its value storing thing,
      and edit your script to send that.

      *now*, now it works.

        1. Looks like the comment you replied to is quite old. You might have some luck emailing Mair: there’s an address on her site. I don’t use Opera myself, but I’ve no problem making the script compatible with it, so if you do manage to get an updated script, let me know and I’ll merge it in with the standard one.

          From the thread here, it looks like getting it going also requires changes to the compatibility script for Opera as well as to my script, which the maintainer of that script might also be interested in.

        1. Looking at that script, it does a search and replace on the entire HTML source of the page and then set the innerHTML for the page back to the replaced text. I think that throws away all the stuff LJ New Comments has put in, so if that script runs after LJ New Comments, it’ll wipe out the stuff that my script puts in. I claim this is a bug in how the other script works, since it’s going to chuck away anything else another Greasemonkey script has done to the DOM.

    1. I could do. Looks like Javascript can detect the locale with navigator.language. If the only differences are which keys do what, it should be fairly easy to fold your changes in, with a Greasemonkey menu option to select between Russian and English, defaulting to Russian if that’s the navigator.language. Can I see your code?

      1. Here are my changes, starting from line 535:
        [code]
        if (event.which != 110 && event.which != 112 && event.which != 1090 && event.which != 1079)
        return;
        var isComment = (newCommentAnchors[nextComment][0] != “”);
        var obj;

        if (event.which == 110 || event.which == 1090) // ‘n’
        {
        obj = newCommentAnchors[nextComment][1];
        nextComment = (nextComment + 1) % newCommentAnchors.length;
        }
        else if (event.which == 112 || event.which == 1079) // ‘p’
        [/code]

        It doesn’t matter for me now which keyboard layout is turned on.

        1. Thanks. How do I tell people which keys to press? Will they have Cyrillic characters on the keys (I don’t know what a Russian keyboard looks like), and if so which ones?

  9. Hi! Awesome script, but I’m having some troubles with it. (I’m using Firefox v.3.05 on Windows XP.) At first when I installed the script, it worked like it was supposed to. Now, for some reason, all comments are labelled NEW, no matter how many times I view the page.

    I haven’t really changed anything/installed anything new, but my antivirus (AVG, free edition) did clean out some tracking cookies, could this have anything to do with it?

    1. The script doesn’t store the comments you’ve seen as cookies, it stores them as preference settings in Firefox (because that’s how Greasemonkey does it). Firefox only writes preference settings to disk when the browser closes down properly, so if Firefox crashes it’ll lose its memory of the comments you’ve seen since you started Firefox.

      It sounds like that’s not what you’re seeing here, though. If you keep hitting reload on a page, do you get NEW comments all the time, or is it just when you go back to a page after restarting Firefox?

      1. If you keep hitting reload on a page, do you get NEW comments all the time
        Yeah. It doesn’t matter how many times I reload, they still show up as NEW to me. I don’t understand why it stopped working so suddenly, I haven’t really changed anything.

        1. Hmm… I suppose a non-standard style on a journal might confuse it, but I’d expect it not to mark things as NEW if that was happening.

          One thing you could try is telling Greasemonkey to uninstall the script and the associated preferences (as that’ll clear out everything) and then re-installing that latest version. On the Firefox on the Mac, that’s Tools->Greasemonkey->Manage User Scripts, select “LJ New Comments” and tick the “Also uninstall associated preferences” box, and then hit “Uninstall”. The latest version is on userscripts.org in the usual place.

  10. I’ve been using your script for ages, and it’s a great help. Thank you very much.

    I was wondering whether you were planning on making a version for Dreamwidth? It’s one of those clever things you don’t realise how much you miss, until you don’t have access to it any more.

    1. Glad you like the script.

      I do intend to make it compatible with Dreamwidth (and with other popular LJ clones) but I’ve been waiting for DW’s official launch as they’ve been changing styles and suchlike as they’ve been developing it. It looks like the way the script detects comments will work just as it did on LJ, so I hope to have something fairly soon.

      1. Thank you very much for getting to it so promptly. 🙂

        At first, it worked to mark comments as NEW but didn’t give the number of unread comments on my friends page, which is what I mostly use it for.

        But then I read your original entry properly, and found this link on Dreamwidth, which does the same thing as the LJ setting you link to. So now it seems to work absolutely fine, with all three of the basic styles.

        Thanks again.

  11. It doesn’t seem to be working on dreamwidth for me — I’ve tried looking at several different journals.

    I removed and reinstalled the script, just in case I had an old one.

  12. Hello, thanks for the great script! It doesn’t seem to be working on posts in syndicated feeds, though – either the “X new” on your friends page or on individual comments in a syndicated post. I’ve tried disabling and reenabling the script, un/reinstalling it, and checked the included and excluded pages (both default). I’m pretty sure it was working a couple weeks ago, not sure why it stopped.

    1. Looking at it, I don’t think it should ever have worked for syndicated accounts, because it doesn’t recognise the URL of the page as being a LiveJournal entry. I’ll try to fix it this weekend, hopefully.

  13. Thanks for the script!

    Question/comment: as far as you know, is this compatible with Insanejournal? Figured I’d check in case there’s something messed up on my end and it’s supposed to actually work. I just use the default entry views (not customized) and the comment URL structure is ljcmtNNNN, but it doesn’t seem to be working for me.

    1. It partially works on IJ if you just tell it to run on *.insanejournal.com using the Greasemonkey configuration. Under Windows, that’s Tools, GreaseMonkey, Manage User Scripts, Options (on the script), Included Pages, Add, then add http://*.insanejournal.com/*

      What doesn’t work is comments on communities, because IJ has changed the URL for that. I’ll have a look at fixing that when I get a moment.

  14. Hi there. I’m not sure if you’re still maintaining this script, but lately when I’ve been clicking on the Expand link on an entry that has lots and lots of comments, the page view sometimes jumps to a higher point on the page and then I have to scroll down again to find the comment I expanded. It’s not happening in IE, only Firefox, and when I contacted LJ Support about it, they recommended disabling all my add-ons and then re-enabling them one at a time to find out if one of them is causing the problem. It looks like your script is the culprit. Do you have any suggestions for a workaround? I love your script and I don’t want to disable it.

        1. Hmmm. It Works For Me™. One thing that will make it jump is if you press the N or P key as it’ll then take you to the next or previous unread comment starting from the top (this used to work even in expanded threads and now doesn’t, something else I should look at).

          Another thing: what are you disabling? Greasemonkey, or the LJ New Comments script itself within Greasemonkey’s menu? If the former, do you have any other Greasemonkey scripts installed?

          1. Thanks for looking into it. I had a feeling it may have been something unique to my system since I haven’t seen anyone else complaining about it.

            I have been having the problem with the view jumping even when using the N key.

            I didn’t disable Greasemonkey, just the script. I had LJ Twitterless and Expand All installed until last week, then I removed them because I don’t use them anymore anyway. I removed them after the problem with the jumping view started, so they aren’t responsible for the problem. The only script I’m still using is yours.

            Thanks again.

  15. Hi, I have this on my main computer and it works fine. However, I’ve been trying to get it to work on my laptop for a few days now, but whenever I click to install it, I get the error ‘Script could not be installed TypeError : lines is null.’ Any idea what the problem is?

    1. I Googled for the error message and people seem to think it’s a problem with Firefox and Greasemonkey, as it’s been seen with various different Greasemonkey scripts. Suggestions include making sure you’ve got the latest Firefox and Greasemonkey, and uninstalling and reinstalling Greasemonkey.

      1. I’ve got the most up to date Firefox and reinstalling Greasemonkey didn’t work. I did install it on the PC a long time ago, so I’m wondering if it’s incompatible with a new version of one of those.

Leave a Reply

Your email address will not be published. Required fields are marked *