Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save contextnerror/e002ab1968fe68cf75759b84145d2e3b to your computer and use it in GitHub Desktop.
Save contextnerror/e002ab1968fe68cf75759b84145d2e3b to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Media mode for Twitter home
// @name:zh-CN Twitter 主页上的媒体模式
// @name:zh-TW Twitter 主頁上的媒體模式
// @name:zh-HK Twitter 主頁上的媒體模式
// @description Remove text-only tweets on the flow of Twitter home/list. It is currently Beta quality.
// @description:zh-CN 在 Twitter 的主页和列表时间流上删除纯文本 Tweet。当前是 Beta 质量
// @description:zh-TW 在 Twitter 的主頁和列表時間流上刪除純文字 Tweet。當前是 Beta 質量
// @description:zh-HK 在 Twitter 的主頁和列表時間流上刪除純文本 Tweet。當前是 Beta 質量
// @icon https://i.imgur.com/bUIPv1O.jpg
// @namespace https://github.com/UtopicPanther/userscript-twitter-home-media
// @supportURL https://github.com/UtopicPanther/userscript-twitter-home-media/issues
// @version 2021.8.22
// @author UtopicPanther & Bipface
// @license GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// @match https://twitter.com/*
// @match https://mobile.twitter.com/*
// @grant none
// @run-at document-idle
// ==/UserScript==
/*
* Copyright (C) 2020 UtopicPanther
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This script contains an additional exemption. When this script is
* injected into the site with the original setting of `@match`,
* other user scripts running in the same space are not required to
* be compatible with GPL 3.
*
* 这个脚本包含一个附加豁免。当此脚本被注入到原有设置 `@match` 的
* 站点时,不要求同一空间中运行的其他用户脚本与 GPL 3 兼容。
*/
(function() {
'use strict';
let hide = true;
let toggleBtn = null;
const removeTweet = article => {
article.classList.add('mmfth_hide');
const div = article.parentElement.parentElement;
div.style.background = "red";
if (hide)
div.style.display = "none";
}
const showTweet = article => {
console.log("showTweet: %O", article)
article.classList.remove('mmfth_hide');
const div = article.parentElement.parentElement;
div.style.background = "";
div.style.display = "";
}
const isTweetOnlyText = i => {
if (Array.from(i.querySelectorAll('img')).some(img => {
if (!img.src.match(/^[a-z]*:\/\/[^\/]*\/profile_images/) &&
!img.src.match(/^[a-z]*:\/\/[^\/]*\/emoji/)) {
return true;
}
})) return false;
if (i.querySelector('div[data-testid=tweetPhoto]') != null) return false;
if (i.querySelector('div[data-testid^="card.layout"]') != null) return false;
if (Array.from(i.querySelectorAll('a')).some(a => {
if (a.getAttribute('href').match(/^\/[^\/]*\/status\/[0-9]*\/photo\//)) {
return true;
}
})) return false;
if (i.querySelector('video') != null) return false;
if (i.querySelector('div[role=progressbar]') != null) return false;
let emptyMiddle = true;
try {
const tweet = i.querySelector('div[data-testid=tweet]');
const tmp = tweet.children[1].children[1];
const middle = tmp.children[tmp.length - 2];
if (middle.children.length > 0)
emptyMiddle = false;
} catch (e) {}
return emptyMiddle;
}
const findTweetsForRemove = () => {
if (location.pathname.startsWith('/home') ||
location.pathname.startsWith('/i/lists/')) {
document.querySelectorAll('article:not(.mmfth_hide)').forEach(i => {
if (isTweetOnlyText(i)) {
removeTweet(i);
}
});
document.querySelectorAll('.mmfth_hide').forEach(i => {
if (!isTweetOnlyText(i)) {
showTweet(i);
}
});
ensureToggleButton();
}
}
const startObserver = () => {
//const targetNode = document.querySelector('article').parentElement.parentElement.parentElement.parentElement;
const targetNode = document.documentElement || document.body;
findTweetsForRemove();
const config = { childList: true, subtree: true };
const observer = new MutationObserver((mutationsList, observer) => {
findTweetsForRemove();
});
observer.observe(targetNode, config);
}
function ensureToggleButton() {
if (!toggleBtn) {
toggleBtn = document.createElement(`button`);
toggleBtn.type = `button`;
toggleBtn.addEventListener(`click`, performToggle, false);
updateToggleButtonLabel();
}
if (!toggleBtn.isConnected) {
let parent = document.querySelector(`h1[role='heading']`);
if (parent) {
parent.prepend(toggleBtn);
}
}
}
function updateToggleButtonLabel() {
if (toggleBtn) {
toggleBtn.textContent = hide ? `Show All Tweets` : `Only Media Tweets`;
}
}
function performToggle() {
hide = !hide;
alert("Text-only tweets will be " + (hide ? "hidden" : "shown (with red background)"));
document.querySelectorAll('.mmfth_hide').forEach(i => {
i.parentElement.parentElement.style.display = (hide ? "none" : "");
});
updateToggleButtonLabel();
}
//GM_registerMenuCommand("Show/Hide text-only tweets", performToggle);
setTimeout(() => {
startObserver();
}, 6000);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment