Greasy Fork is available in English.

2ch tree post

делает треды древовидными

// ==UserScript==
// @name         2ch tree post
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  делает треды древовидными
// @author       You
// @match        http://2ch.hk/*/res/*
// @match        https://2ch.hk/*/res/*
// @match        http://2ch.life/*/res/*
// @match        https://2ch.life/*/res/*
// @grant        none
// @grant        GM_addStyle
// ==/UserScript==

(function () {
  "use strict";
   console.time("tree script");
  //находим все ссылки в постах
  const post = document.querySelectorAll(
    `.post__message > :nth-child(1)[data-num]`
  );

  //функцию вызываем на все посты в треде
  //Перемащает пост и применяет стили для создания дерева
  function postMove(linkPost, newpost = false) {
    const nodePostCurr = linkPost.parentNode.parentNode;
    const nodePostReply = document.querySelector(
      `#post-${linkPost.innerText.match(/\d+/)[0]}`
    );
    //если эта ссылка ведёт на оппост или другой тред или пост не существует - пропускаем
    if (/OP|→/.test(linkPost.innerText) || !nodePostReply) {
      return;
    }
    nodePostReply.append(nodePostCurr);
    if (newpost) {
      nodePostCurr.addEventListener(
        "click",
        () => {
         nodePostCurr.style["border-left"] = "2px dashed";
        },
        { once: true }
      );
    }
  }
  //перебираем и вызываем функцию
  for (const key of post) {
    postMove(key);
  }

  //наблюдаем за появлением новых постов
  const fromThreads = document.querySelector(".thread");

  const observer = new MutationObserver((mutationRecords) => {
    for (const key of mutationRecords) {
      if (key.addedNodes.length > 0) {
        const post = key.addedNodes[0].querySelector(
          `.post__message > :nth-child(1)[data-num]`
        );
        if (post) {
          postMove(post, true);
        }
      }
    }
  });

  observer.observe(fromThreads, { childList: true });
   console.timeEnd("tree script");

    function GM_addStyle(css) {
  const style = document.getElementById("GM_addStyleBy8626") || (function() {
    const style = document.createElement('style');
    style.type = 'text/css';
    style.id = "GM_addStyleBy8626";
    document.head.appendChild(style);
    return style;
  })();
  const sheet = style.sheet;
  sheet.insertRule(css, (sheet.rules || sheet.cssRules || []).length);
}

   GM_addStyle('.post .post_type_reply { border-left-color: white; }');
})();