33 votes

Tildes UserScript: Comment Link Fix

I joined Tildes a couple of days ago, and I'm absolutely loving the interface and community.

In the last few days of using Tildes, I noticed a particular problem that was mildly annoying; if you have the "Collapse old comments when I return to a topic" setting on, and you click on a link that is supposed to lead to a comment in a topic you have already visited, it won't jump to that comment.

Searching around, I found a post about it from a day ago, in which long-time users have mentioned that it's been a known problem for a while now. In those comments, someone mentioned permalinks as a solution, but it appears that's still in the works.

For now, I've made a quick userscript that will address this issue (and adds some slight related functionality). It hasn't been thoroughly tested yet, so if any issues occur, please let me know. This userscript is designed to be used with Tampermonkey (a privacy-friendly alternate that should work is ViolentMonkey), which is available in all popular desktop browsers. Installation instructions for Tampermonkey are available on their site (it's installed like any other extension).

To install the script, you can head to this GitHub Gist which contains the code (click "Raw" to open the TamperMonkey install prompt), or you can copy and paste the code from the following dropdown block into a "New script" on the TamperMonkey dashboard. The dropdown is not guaranteed to contain the latest version.

Code
// ==UserScript==
// @name         Tildes Comment Link Fix
// @namespace    https://gist.github.com/blankdvth/6da89fff580e8cf6e50f88847ddb5729
// @version      1.2.0
// @description  Fixes comment links (anchors) not working as a result of Tildes' comment collapsing feature.
// @author       blank_dvth
// @match        https://tildes.net/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tildes.net
// @grant        none
// ==/UserScript==

/* 
    USER SETTINGS
    This script is not big enough to warrant a visual settings menu, so adjust settings here.
    true = enable, false = disable
*/
const alwaysRun_S = false; // If enabled, will always run the script, even if the comment was not collapsed (site works fine in this case). This is useful if you want to make use of the other settings.
const smoothScroll_S = false; // If enabled, will smoothly (animated) scroll to the comment. If disabled, will jump to the comment.
const uncollapseIndividual_S = true; // If enabled will uncollapse parent comments into one line instead of fully uncollapsing them.
const uncollapseChildren_S = true; // If enabled, will uncollapse all children of the comment. If disabled, will leave them collapsed.
const collapseIrrelevant_S = true; // The script uncollapses all parents to ensure the comment is visible. This will collapse irrelevant (not direct parent) comments again.
// END OF USER SETTINGS

/**
 * Uncollapses the comment if it is collapsed.
 * @param {HTMLElement} element Article element of the actual comment
 * @param {boolean} individual If true, will "uncollapse" into one line instead of fully uncollapsing
 * @returns {boolean} True if the comment was collapsed, false if it was not
 */
function uncollapse(element, individual = false) {
    if (element.nodeName !== "ARTICLE") return false;
    var removed = false;
    if (
        !individual &&
        element.classList.contains("is-comment-collapsed-individual")
    ) {
        element.classList.remove("is-comment-collapsed-individual");
        removed = true;
    }
    if (element.classList.contains("is-comment-collapsed")) {
        if (individual)
            element.classList.add("is-comment-collapsed-individual");
        element.classList.remove("is-comment-collapsed");
        removed = true;
    }
    return removed;
}

/**
 * Uncollapses all direct parents of the comment.
 * @param {HTMLElement} element Article element of the actual comment
 * @param {boolean} collapseIrrelevant If true, will collapse irrelevant comments again
 * @param {boolean} individual If true, will "uncollapse" into one line instead of fully uncollapsing
 * @returns {boolean} True if any parent was collapsed, false if none were
 */
function uncollapseParents(element, collapseIrrelevant, individual) {
    const relevant = []; // List of relevant elements (direct parents)
    var wasCollapsed = false; // Whether any parent was collapsed
    while (
        element.parentElement &&
        element.parentElement.nodeName !== "SECTION"
    ) {
        element = element.parentElement;
        relevant.push(element); // Add parent to relevant list
        if (uncollapse(element, individual)) wasCollapsed = true;
        // Collapse all irrelevant sibling comments (if feature enabled)
        if (collapseIrrelevant && element.nodeName === "ARTICLE") {
            element
                .querySelectorAll(
                    `article#${element.id} > ol.comment-tree > li.comment-tree-item > article:not(.is-comment-collapsed)`
                )
                .forEach((child) => {
                    if (!relevant.includes(child))
                        child.classList.add("is-comment-collapsed");
                });
        }
    }
    return wasCollapsed;
}

/**
 * Uncollapses all direct children of the comment.
 * @param {HTMLElement} element Article element of the actual comment
 */
function uncollapseChildren(element) {
    element
        .querySelectorAll("article.is-comment-collapsed article.is-comment-collapsed-individual")
        .forEach(uncollapse);
}

(function () {
    if (!location.hash.startsWith("#comment-")) return; // Not a comment hash
    const comment = document.getElementById(location.hash.substring(1)); // Get comment element
    if (!comment) return; // Comment does not exist
    // Uncollapse the comment itself, and it's parents, then perform other actions if needed/enabled
    if (
        uncollapse(comment) |
            uncollapseParents(
                comment,
                collapseIrrelevant_S,
                uncollapseIndividual_S
            ) ||
        alwaysRun_S
    ) {
        // Uncollapse all children (if feature enabled)
        if (uncollapseChildren_S) uncollapseChildren(comment);
        // Scroll to the comment
        if (smoothScroll_S) comment.scrollIntoView({ behavior: "smooth" });
        else comment.scrollIntoView();
    }
})();
Settings Description

There are comments that already contain short descriptions for each setting in the code, but here are more in-depth descriptions.

  • alwaysRun: By default, the script does not run if the comment and its parents are already uncollapsed (this means the in-built anchor will work as expected). However, when this setting is enabled, the script will still perform the additional options (such as uncollapsing children and collapsing irrelevant).
  • smoothScroll: When enabled, will use a smooth animated scroll. When disabled, will jump directly.
  • uncollapseIndividual: Parent comments need to be uncollapsed in some shape or form in order for the script to work. This allows you to choose what type of uncollapse is used. When enabled, it will uncollapse the parent comments into a single line (shows a short preview). When disabled, it will fully uncollapse the parent comments (everything is visible).
  • uncollapseChildren: When enabled, will automatically uncollapse all child comments (replies) to the linked comment.
  • collapseIrrelevant: When enabled, it will automatically collapse all sibling/cousin comments (comments that have a shared parent but are not directly ancestors of the linked comment)
Changelog (Last Updated 2023-06-12 22:55 EST)
  • v1.2.0:
    • Prevent entire sibling/cousin chains from being collapsed, only collapse toplevel
    • Ensure individually collapsed children are uncollapsed properly
    • Ensure proper exiting if comment does not exist
  • v1.1.0:
    • First public release

11 comments

  1. [6]
    honestbleeps
    Link
    Listen, buddy, I've got dibs on Tildes Enhancement Suite - don't you .... I'm kidding. I do not have the energy to do another one of those. (I don't expect 99.9% of people to get this reference,...

    Listen, buddy, I've got dibs on Tildes Enhancement Suite - don't you ....

    I'm kidding. I do not have the energy to do another one of those.

    (I don't expect 99.9% of people to get this reference, so I'll spell it out: I am the goofball who created Reddit Enhancement Suite many years ago)

    17 votes
    1. [2]
      honestbleeps
      Link Parent
      also, given it appears Tildes links its own source code at the footer of the site - I wonder if it makes sense to contribute a PR as opposed to start getting people installing userscripts?

      also, given it appears Tildes links its own source code at the footer of the site - I wonder if it makes sense to contribute a PR as opposed to start getting people installing userscripts?

      8 votes
      1. blank_dvth
        (edited )
        Link Parent
        I do agree that it's much better to have a fix actually in the site itself, rather than needing people to install user scripts. Sadly, I just don't currently have the free time (at least for this...

        I do agree that it's much better to have a fix actually in the site itself, rather than needing people to install user scripts. Sadly, I just don't currently have the free time (at least for this month) to do that, although I do plan to as soon as I get the time. The script is more meant as a quick patch for now, before I get the time to work on an actual fix. It appears the last PR action taken was 2 years ago as well, there's a large backlog of PRs right now -- it will probably take some time for the PR to get reviewed anyhow, so a script is a good temporary fix.

        6 votes
    2. cfabbro
      (edited )
      Link Parent
      Actually, you're already late to the party, @honestbleeps. @Bauke has you beat by a few years with Tildes ReExtended. ;) But awesome to see you on here. I've used RES for so long that I genuinely...

      Actually, you're already late to the party, @honestbleeps. @Bauke has you beat by a few years with Tildes ReExtended. ;)

      But awesome to see you on here. I've used RES for so long that I genuinely forget what is and isn't even on the base site anymore. :P

      6 votes
    3. blank_dvth
      Link Parent
      Oh wow, RES has made my life so much better through the years. Thanks for making it, it's truly an amazing extension.

      Oh wow, RES has made my life so much better through the years. Thanks for making it, it's truly an amazing extension.

      4 votes
    4. zoroa
      Link Parent
      Thank you for making RES, which made Reddit a place I felt comfortable spending time in.

      Thank you for making RES, which made Reddit a place I felt comfortable spending time in.

      1 vote
  2. [2]
    Barney
    (edited )
    Link
    That is so good! Thank you so much!! I would like to add something for those whom this might concern. Tampermonkey is closed source and its privacy policy leaves many, many things to be desired. I...

    That is so good! Thank you so much!!

    I would like to add something for those whom this might concern. Tampermonkey is closed source and its privacy policy leaves many, many things to be desired.

    I suggest using Violentmonkey instead (Homepage, Firefox, Chrome, Github Source). Unlike Tampermonkey, they do not collect any data whatsoever.

    I know this is a non-issue for most people, but if you care about your privacy, use Violentmonkey instead of Tampermonkey. The script and the installation method described in @blank_dvth's post work exactly the same :)

    Thank you again for this script!

    11 votes
    1. blank_dvth
      Link Parent
      Thanks for the link to Violentmonkey! It seems like a great choice, didn't even know it existed before this.

      Thanks for the link to Violentmonkey! It seems like a great choice, didn't even know it existed before this.

      1 vote
  3. cfabbro
    Link
    Oh, wow this is awesome. Thanks you so much for making this!!!!! And also thanks for including some additional configuration for it too, that is above and beyond. If we could exemplary topics, you...

    Oh, wow this is awesome. Thanks you so much for making this!!!!! And also thanks for including some additional configuration for it too, that is above and beyond. If we could exemplary topics, you would definitely be getting one from me for this.

    8 votes
  4. streblo
    Link
    Wow, this is awesome. Thank-you!

    Wow, this is awesome.

    Thank-you!

    7 votes