Block Facebook Posts with Follow or Join (CSP Safe)

Block posts on Facebook newsfeed that have Follow or Join buttons, bypassing CSP restrictions.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Block Facebook Posts with Follow or Join (CSP Safe)
// @namespace    http://github.com/sarahbarberuk
// @version      1.3
// @description  Block posts on Facebook newsfeed that have Follow or Join buttons, bypassing CSP restrictions.
// @author       Sarah Barber
// @match        https://www.facebook.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
        // Function to find the nearest parent div with exactly one class
        function findNearestParentWithOneClass(element) {
            let parent = element.closest('div');
            while (parent) {
                if (parent.classList.length === 1) {
                    return parent; // Found the div with exactly one class
                }
                parent = parent.parentElement.closest('div'); // Move to the next parent div
            }
            return null; // Return null if no such div is found
        }

        // Function to block posts with "Follow" or "Join" buttons
        function blockPostsWithFollowOrJoin() {
            // Get the main newsfeed div
            const mainDiv = document.querySelector('div[role="main"]');
            if (!mainDiv) return;

            // Get all div elements with role="button" inside the main div
            const buttons = mainDiv.querySelectorAll('div[role="button"]');

            // Loop through each button and check if it contains "Follow" or "Join"
            buttons.forEach(button => {
                const span = button.querySelector('span');

                if (span && (span.innerText === 'Follow' || span.innerText === 'Join')) {
                    // Find the nearest parent div with exactly one class and hide it
                    const postContainer = findNearestParentWithOneClass(button);
                    if (postContainer) {
                        postContainer.style.display = 'none';
                        console.log('Blocked post with:', span.innerText, postContainer);
                    }
                }

                // this bit blocks reels and short videos
                const innerDiv = button.querySelector('div');
                if (innerDiv) {
                    const innerSpan =  innerDiv.querySelector('span');

                    if (innerSpan && (innerSpan.innerText === 'Reels and short videos')) {
                        // Find the nearest parent div with exactly one class and hide it
                        const postContainer = findNearestParentWithOneClass(button);
                        if (postContainer) {
                            postContainer.style.display = 'none';
                            console.log('Blocked post with:', innerSpan.innerText, postContainer);
                        }
                    }
                }  

                   
            });
        }

        // Run the script periodically to catch new posts
        const observer = new MutationObserver(blockPostsWithFollowOrJoin);
        observer.observe(document.body, { childList: true, subtree: true });


})();