// ==UserScript== // @name Twitter media-only filter toggle. // @version 0.6 // @description Toggle non-media tweets on and off, for the power-viewer! // @author Cro // @match https://twitter.com/* // @exclude https://twitter.com/notifications // @run-at document-idle // @grant GM_setValue // @grant GM_getValue // @namespace https://greasyfork.org/users/10865 // @downloadURL none // ==/UserScript== /* jshint esversion: 6 */ (function() { 'use strict'; let program = function(target) { let storageKey = "cro-media-toggle"; // The complexity of determining what is a meaningful image post. let containsImage = function(node) { let res = false; node.querySelectorAll("img").forEach(function (sub) { if (!(sub.src.startsWith("https://abs-0.twimg.com/emoji") || sub.src.startsWith("https://pbs.twimg.com/profile_images") || sub.src.startsWith("https://abs.twimg.com/hashflags"))) { res = true; } }); return res; }; let isTarget = node => node.tagName && node.tagName.toLowerCase() == "article" && !(node.querySelector("video") || containsImage(node)); let hideIfTarget = function(node) { if (isTarget(node)) node.style.display = "none"; }; let show = function(node) { node.style.display = "block"; }; let hideAll = function() { document.body.querySelectorAll("article").forEach(hideIfTarget); }; let showAll = function() { document.body.querySelectorAll("article").forEach(show); }; let running = GM_getValue(storageKey); setInterval(function() { if (running) hideAll(); }, 250); // UI let button = document.createElement("button"); let setButtonState = function() { if (running) { button.innerText = "Only Media Tweets"; } else { button.innerText = "All Tweets"; showAll(); } }; button.onclick = function(event) { running = !running; GM_setValue(storageKey, running); setButtonState(); }; target.prepend(button); setButtonState(); }; // Wait for twitter's react crap finish loading things. let scanInterval = setInterval(function() { let target = document.body.querySelector("h1[role='heading']"); let mainContents = document.body.querySelector("main article"); if (target && mainContents) { clearInterval(scanInterval); program(target); } }, 10); })();