View more replies and remove shit from twitter
当前为
// ==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://greasyfork.org/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.3.9
// @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
$( "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
//$( "span:contains('Trends for you')" ).parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().hide();
$( "span:contains('Topics to follow')" ).parent().parent().parent().parent().parent().hide().next().hide().next().hide().next().hide(); //At anybody's profile
$( "span:contains('Discover new Lists')" ).parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().hide(); //At the newsfeed
//$( "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();
$( "span:contains('Open app')" ).parent().parent().hide();
/*$( "span:contains('Who to follow')" ).parent().parent().parent().parent().parent().hide().next().hide().next().hide().next().hide().next().hide().next().hide();
$( "span:contains('Topics to follow')" ).parent().parent().parent().parent().parent().hide().next().hide().next().hide().next().hide();
$( "article span:contains('Promoted')" ).parent().parent().parent().parent().parent().hide().next().hide().next().hide().next().hide();
$( "span:contains('Promoted by')" ).parent().parent().parent().parent().hide().next().hide().next().hide().next().hide();
$( "span:contains('Promoted Tweet')" ).parent().parent().parent().parent().hide();
$( "span:contains('Promoted')" ).parent().parent().parent().parent().parent().hide();
$( "span:contains('Trends for you')" ).parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().hide();
$( "span:contains('Expand your timeline with Topics')" ).parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().hide();
$( "span:contains('Discover new Lists')" ).parent().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().parent().parent().parent().parent().parent().parent().parent().parent().remove();
$( "div[aria-label='Set as not interested']" ).parent().parent().parent().parent().parent().parent().parent().parent().remove();
$( "span:contains('Open app')" ).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);
}
})();