Twitter: view more replies and remove useless sections

View more replies and remove shit from twitter

目前為 2021-12-28 提交的版本,檢視 最新版本

// ==UserScript==
// @name          Twitter: view more replies and remove useless sections
// @description   View more replies and remove shit from twitter
// @author        MK
// @namespace     max44
// @homepage      https://gf.qytechs.cn/en/users/309172-max44
// @include       https://twitter.com/*
// @include       https://mobile.twitter.com/*
// @icon          https://www.google.com/s2/favicons?domain=twitter.com
// @version       1.4
// @license       MIT
// @require       https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js
// @grant         none
// @run-at        document-idle
// ==/UserScript==

(function () {
  'use strict';

  function findAndClick(selector, observer) {
    const elem = document.querySelector(selector);
    if (elem != null) {
      elem.click();
      observer.disconnect();
    }
  }

  function isLink(element) {
    return element.getAttribute("role") === "link";
  }

  function isParentLink(element, parentN) {
    if (isLink(element)) return true;

    for (let i = 0; i <= parentN; i++) {
      element = element.parentElement;
      if (isLink(element)) return true;
    }

    return false;
  }

  const config = {childList: true, subtree: true};
  // Replies list
  const repliesSelector = "[aria-labelledby^='accessible-list'][role='region'][class='css-1dbjc4n']";
  // "View more replies" button on preview tweets
  const viewMoreSelector = "[href*='i/status/']" +
          "[role='link']" +
          "[data-focusable='true']" +
          "[class^='css-4rbku5 css-18t94o4 css-1dbjc4n r-1loqt21 r-1ny4l3l'][class$='r-o7ynqc r-6416eg']" +
          " > div > span";
  // "Show additional replies, including those that may contain offensive content" button
  const offensiveSelector = "div[role='button']" +
          "[tabindex='0']" +
          "[class^='css-18t94o4 css-1dbjc4n r-1niwhzg r-42olwf r-sdzlij r-1phboty r-rs99b7'][class$='r-o7ynqc r-6416eg r-lrvibr']" +
          " > div > span > span";
  // "Show more replies" buttons
  const moreRepliesSelector = "div[role='button']" +
          "[tabindex='0']" +
          "[class^='css-18t94o4 css-1dbjc4n r-1777fci r-1pl7oy7 r-1ny4l3l r-o7ynqc r-6416eg r-13qz1uu']" +
          " > div > div > span";
          //"div[class='css-1dbjc4n r-16y2uox r-1wbh5a2 r-1777fci'] " +
          //"div[class^='css-901oao'][class$='r-qvutc0'][dir='auto'] " +
          //"span[class^='css-901oao css-16my406'][class$='r-bcqeeo r-qvutc0']";
  //const refreshAfterFaultSelector = "div[role='button']" +
  //        "[tabindex='0']" +
  //        "[class^='css-18t94o4 css-1dbjc4n r-1kihuf0']" +
  //        "[class$='r-42olwf r-sdzlij r-1phboty r-rs99b7 r-2o02ov r-ero68b r-vkv6oe r-1ny4l3l r-1fneopy r-o7ynqc r-6416eg r-lrvibr']";// " +
  //        //"> div > span > span";

  setTimeout(function () {
    // For preview tweets, tweets that are opened from external sources may has a special format where only a few replies are shown and the rest are replaced
    // by a "More Tweets" section that contains popular tweets from random accounts that may or may not be related to the previewed tweet
    const previewSelector = "[data-testid='primaryColumn'] " +
          "[class='css-1dbjc4n r-yfoy6g r-18bvks7 r-1ljd8xs r-13l2t4g r-1phboty r-1jgb5lz r-11wrixw r-61z16t r-1ye8kvj r-13qz1uu r-184en5c']";
    const preview = document.querySelector(previewSelector);

    if (preview != null) {
      const viewMore = document.querySelector(viewMoreSelector);

      if (viewMore != null) viewMore.click();
    }
  }, 3000);

  const rootCallback = function (mutationsList, observer) {
    const repliesNode = document.querySelector(repliesSelector);

    if (repliesNode != null) {
      const offensiveObserver = new MutationObserver(offensiveCallback);
      const moreRepliesObserver = new MutationObserver(moreRepliesCallback);
      //const refreshAfterFaultObserver = new MutationObserver(refreshAfterFaultCallback);
      offensiveObserver.observe(repliesNode, config);
      moreRepliesObserver.observe(repliesNode, config);
      //refreshAfterFaultObserver.observe(repliesNode, config);
    }

    //Remove useless sections
    $( "aside[aria-label='Who to follow']" ).parent().hide(); //At the newsfeed
    $( "div[style='-webkit-line-clamp: 3;'] > span:contains('Who to follow')" ).parent().parent().parent().parent().parent().hide().next().hide().next().hide().next().hide().next().hide().next().hide(); //At anybody's profile - hide header "Who to follow", then 3 suggestions, "Show more" and divider
    $( "div[aria-label='Timeline: Trending now']" ).parent().parent().parent().parent().hide(); //At the newsfeed
    $( "div[style='-webkit-line-clamp: 3;'] > span:contains('Topics to follow')" ).parent().parent().parent().parent().parent().hide().next().hide().next().hide().next().hide(); //At anybody's profile
    $( "div[style='-webkit-line-clamp: 3;'] > span:contains('Discover new Lists')" ).parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().hide(); //At the newsfeed
    $( "div[aria-label='Open app']" ).parent().hide(); //At any tweet on mobile browser

    //$( "article span:contains('Promoted')" ).parent().parent().parent().parent().parent().hide().next().hide().next().hide();
    //$( "span:contains('Promoted by')" ).parent().parent().parent().parent().hide().next().hide().next().hide();
    //$( "span:contains('Promoted Tweet')" ).parent().parent().parent().hide();
    //$( "span:contains('Promoted')" ).parent().parent().parent().parent().hide();
    //$( "span:contains('Expand your timeline with Topics')" ).parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().hide();
    //$( "div[aria-label='Set as not interested']" ).parent().parent().parent().parent().parent().parent().parent().hide();
  };

  const offensiveCallback = function (mutationsList, observer) {
    findAndClick(offensiveSelector, observer);
  };

  const moreRepliesCallback = function (mutationsList, observer) {
    findAndClick(moreRepliesSelector, observer);
    /*const moreRepliesNodes = document.querySelectorAll(moreRepliesSelector);

    for (let elem of moreRepliesNodes) {
      if (isParentLink(elem, 4)) continue;
      elem.click();
    }*/
  };

  //const refreshAfterFaultCallback = function (mutationsList, observer) {
  //  findAndClick(refreshAfterFaultSelector, observer);
  //};

  const rootNode = document.querySelector("#react-root");
  if (rootNode != null) {
    const rootObserver = new MutationObserver(rootCallback);
    rootObserver.observe(rootNode, config);
  }

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址