// ==UserScript==
// @name Better Twitter Monkey Edition
// @namespace http://tampermonkey.net/
// @version 0.2
// @description Low effort port of the Better Twitter Chrome Extension.
// @author me, oslego
// @match https://twitter.com/*
// @grant none
// @run-at document-start
// ==/UserScript==
/*
NOT MY WORK.
Code ported over from here with minimal effort lol.
https://github.com/oslego/better-twitter
*/
const userPrefs = {
//CONFIGURE START - Flip the values from true/false depending if you want to enable the feature.
"bt--nofame": {
value: false,
label: "No fame: Hide number of followers and following count",
},
"bt--nopopularity": {
value: true,
label: "No vanity: Hide number of tweet likes, retweets and replies",
},
"bt--nopromoted": {
value: true,
label: "Hide promoted tweets",
},
"bt--noretweets": {
value: false,
label: "Hide retweets"
},
"bt--nolikedtweets": {
value: true,
label: "Hide tweets liked by others"
},
"bt--notrends": {
value: true,
label: "Hide “Trends for you”",
},
"bt--nowtf": {
value: true,
label: "Hide “Who to follow”",
},
"bt--nofooter": {
value: true,
label: "Hide website footer",
},
//CONFIGURE END
}
const contentCSS = `
/* Hide promoted tweets */
.bt--nopromoted [aria-label^="timeline" i][aria-label$="timeline" i] div[bt-promoted],
.bt--nopromoted [aria-label^="timeline" i][aria-label$="tweets" i] div[bt-promoted] {
display: none;
}
/* Hide someone else's liked tweets showing in timelines */
.bt--nolikedtweets [aria-label^="timeline" i][aria-label$="timeline" i] div[bt-likedtweet],
.bt--nolikedtweets [aria-label^="timeline" i][aria-label$="tweets" i] div[bt-likedtweet] {
display: none;
}
/* Hide retweets */
.bt--noretweets [aria-label^="timeline" i][aria-label$="timeline" i] div[bt-retweet],
.bt--noretweets [aria-label^="timeline" i][aria-label$="tweets" i] div[bt-retweet] {
display: none;
}
/* Hide "Who to Follow" from users' timelines aside from search result timelines
https://github.com/oslego/better-twitter/issues/12
*/
.bt--nowtf [aria-label^="timeline" i][aria-label$="timeline" i]:not([aria-label~="search" i]) div[bt-wtf],
.bt--nowtf [aria-label^="timeline" i][aria-label$="tweets" i] div[bt-wtf] {
display: none;
}
/* Find "promoted" icons, then mark their ancestor <div> as a promoted tweet */
.bt--nopromoted path[d^="M20.75"] {
animation: bt-marker-promoted 0s 1;
}
@keyframes bt-marker-promoted { to { outline-color: inherit } }
/* Find "retweeted" icons, then mark their ancestor <div> as a retweet */
.bt--noretweets path[d^="M23.615 15.477c-"] {
animation: bt-marker-retweet 0s 1;
}
@keyframes bt-marker-retweet { to { outline-color: inherit } }
/* Find "liked tweet" icons next to "Someone liked" annotations, then mark their ancestor <div> as a retweet
The path for "filled heart" is identical to the one used when you yourself like a tweet.
When the icon is used in context of the "Someone liked" annotation,
the host <svg> is an only child of its parent so we can differentiate on that. This is fragile.
FIXME: Find a way to match the tweet annotation container for "Someone liked" or "Someone retweeted".
*/
.bt--nolikedtweets svg:only-child path[d="M12 21.638h-.014C9.403 21.59 1.95 14.856 1.95 8.478c0-3.064 2.525-5.754 5.403-5.754 2.29 0 3.83 1.58 4.646 2.73.814-1.148 2.354-2.73 4.645-2.73 2.88 0 5.404 2.69 5.404 5.755 0 6.376-7.454 13.11-10.037 13.157H12z"] {
animation: bt-marker-likedtweet 0s 1;
}
@keyframes bt-marker-likedtweet { to { outline-color: inherit } }
/* Find "Follow" buttons, then mark their ancestor <div> as a who-to-follow prompt */
.bt--nowtf [data-testid$="-follow"] {
animation: bt-marker-wtf 0s 1;
}
@keyframes bt-marker-wtf { to { outline-color: inherit } }
/* Find the "Who to follow" container from the sidebar */
.bt--nowtf [aria-label*="who to follow" i]{
animation: bt-marker-wtf-sidebar 0s 1;
}
@keyframes bt-marker-wtf-sidebar { to { outline-color: inherit } }
.bt--nowtf .bt-marker-wtf-sidebar {
display: none !important;
}
/* Hide "Trends for you" box */
.bt--notrends [aria-label*="trending" i] {
display: none !important;
}
/* Hide "Footer" box */
.bt--nofooter [aria-label="footer" i] {
display: none !important;
}
/* Hide tweet reply count */
.bt--nopopularity [data-testid="reply"] span {
display: none !important;
}
/* Hide tweet retweet count */
.bt--nopopularity [href$="/retweets"] span,
.bt--nopopularity [data-testid="retweet"] span,
.bt--nopopularity [data-testid="unretweet"] span {
display: none !important;
}
/* Hide tweet like count */
.bt--nopopularity [data-testid="like"] span,
.bt--nopopularity [data-testid="unlike"] span,
/* Hide the likes count on a single tweet page, but not the Likes tab on the user profile page */
.bt--nopopularity [href$="/likes"]:not([role="tab"]) span {
display: none !important;
}
/* Hide all profile stats from user cards */
.bt--nofame [href$="/following"],
.bt--nofame [href$="/followers"] {
display: none !important;
}
`;
function applyPrefs() {
Object.entries(userPrefs).forEach(([id, pref]) => {
document.documentElement.classList.toggle(id, pref.value);
})
}
const addGlobalStyle = (css) => {
var head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
}
(function() {
'use strict';
addGlobalStyle(contentCSS);
applyPrefs();
document.addEventListener('animationstart', (e) => {
switch (e.animationName) {
case "bt-marker-likedtweet":
e.target.closest('div:not([class])').setAttribute('bt-likedtweet', true)
break;
case "bt-marker-promoted":
e.target.closest('div:not([class])').setAttribute('bt-promoted', true)
break;
case "bt-marker-retweet":
e.target.closest('div:not([class])').setAttribute('bt-retweet', true)
break;
case "bt-marker-wtf-sidebar":
// Mark the container's parent for the "Who To Follow" in the sidebar.
e.target.parentNode.classList.add(e.animationName)
break;
case "bt-marker-wtf":
const container = e.target.closest('div:not([class])');
container.setAttribute('bt-wtf', true);
// If found, mark the container for the "Who to Follow" heading
const prevContainer = container.previousElementSibling;
if (prevContainer.querySelector('h2')) {
prevContainer.setAttribute('bt-wtf', true);
}
// If found, mark the container for "show more" link
const nextContainer = container.nextElementSibling;
if (nextContainer.querySelector('[href^="/i/connect_people"]')) {
nextContainer.setAttribute('bt-wtf', true);
}
break;
}
});
})();