您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Hide posts and comments related to politics on Reddit, including dynamic content.
// ==UserScript== // @name Reddit Political Content Filter // @namespace http://tampermonkey.net/ // @version 2.0.1 // @description Hide posts and comments related to politics on Reddit, including dynamic content. // @author Blumsie // @match *://www.reddit.com/* // @grant GM_xmlhttpRequest // @connect raw.githubusercontent.com // ==/UserScript== (function() { 'use strict'; const KEYWORDS_URL = 'https://raw.githubusercontent.com/Blumsie/filter/refs/heads/main/keywords'; let hiddenPostsCount = 0; let hiddenCommentsCount = 0; async function fetchKeywords() { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: KEYWORDS_URL, onload: function(response) { if (response.status === 200) { try { const keywords = response.responseText .match(/"(.*?)"/g) .map(word => word.replace(/"/g, '').trim()); resolve(keywords); } catch (error) { reject(`Error parsing keywords: ${error}`); } } else { reject(`Failed to fetch keywords: ${response.statusText}`); } }, onerror: function(error) { reject(`Request error: ${error}`); } }); }); } function hideContent(keywords) { const keywordRegex = new RegExp('\\b(' + keywords.join('|') + ')\\b', 'i'); const hidePosts = () => { document.querySelectorAll('article').forEach(post => { const titleElement = post.querySelector('a[slot="title"], a[slot="full-post-link"], faceplate-screen-reader-content'); const textContent = titleElement ? titleElement.innerText + ' ' + post.innerText : post.innerText; let triggeredKeywords = new Set(); if (keywordRegex.test(textContent)) { console.debug('Hiding post:', textContent.slice(0, 100)); post.style.display = 'none'; hiddenPostsCount++; keywords.forEach(keyword => { if (new RegExp('\\b' + keyword + '\\b', 'i').test(textContent)) { triggeredKeywords.add(keyword); } }); if (triggeredKeywords.size > 0) { console.log('Keywords that triggered hiding the post:', [...triggeredKeywords].join(', ')); } } }); }; const hideComments = () => { document.querySelectorAll('shreddit-comment').forEach(comment => { const authorElement = comment.getAttribute('author'); const textContent = Array.from(comment.querySelectorAll('p')).map(p => p.innerText).join(' '); let triggeredKeywords = new Set(); const parentElement = comment.closest('div[data-testid="comment"]') || comment; if (keywordRegex.test(textContent)) { console.debug('Hiding comment by:', authorElement); parentElement.style.display = 'none'; hiddenCommentsCount++; keywords.forEach(keyword => { if (new RegExp('\\b' + keyword + '\\b', 'i').test(textContent)) { triggeredKeywords.add(keyword); } }); if (triggeredKeywords.size > 0) { console.log('Keywords that triggered hiding the comment:', [...triggeredKeywords].join(', ')); } } const authorName = comment.querySelector('[aria-label^="Comment from"]'); if (authorName) { authorName.style.display = 'none'; } const replyButton = comment.querySelector('[data-testid="comment-reply-button"]'); if (replyButton) { replyButton.style.display = 'none'; } }); }; hidePosts(); hideComments(); console.log(`${hiddenPostsCount} posts and ${hiddenCommentsCount} comments were hidden because trigger keywords were found.`); } async function initializeFilter() { try { const keywords = await fetchKeywords(); console.log('Fetched Keywords:', keywords); hideContent(keywords); const observer = new MutationObserver(() => { console.debug('DOM changed, reapplying filter'); hideContent(keywords); }); observer.observe(document.body, { childList: true, subtree: true }); } catch (error) { console.error('Error initializing filter:', error); } } window.addEventListener('load', initializeFilter); })();