Mastodon Search External Link Filter

Hides Mastodon Search posts with external links (skipping virtual‑scroll placeholders)

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

You will need to install an extension such as Tampermonkey to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         Mastodon Search External Link Filter
// @description  Hides Mastodon Search posts with external links (skipping virtual‑scroll placeholders)
// @match        https://mastodon.social/search?*
// @version 0.0.1.20250502160211
// @namespace https://greasyfork.org/users/1435046
// ==/UserScript==

(function () {
    // 1) Grab every <article> in the search results panel
    function getPosts() {
        return document.querySelectorAll('.explore__search-results article');
    }

    // 2) Detect links not pointing to this Mastodon instance
    function isExternalLink(a) {
        return a.href && !a.href.includes(location.hostname);
    }

    // 3) Detect virtual‑scroll placeholder articles
    function isPlaceholder(article) {
        const style = getComputedStyle(article);
        return parseFloat(style.opacity) === 0;
    }

    // 4) Hide any fully rendered article containing at least one external link
    function hidePostsWithExternalLinks() {
        getPosts().forEach(article => {
            if (isPlaceholder(article)) return;             // skip placeholders
            const links = article.querySelectorAll('a[href]');
            if (Array.from(links).some(isExternalLink)) {
                article.style.display = 'none';
            }
        });
    }

    // 5) Observe the search-results container for new articles (infinite scroll)
    function observeSearchResults() {
        const container = document.querySelector('.explore__search-results');
        if (!container) return;
        new MutationObserver(hidePostsWithExternalLinks)
            .observe(container, { childList: true, subtree: true });
        hidePostsWithExternalLinks();
    }

    // 6) Kick off: watch the body for the panel to appear, then observe it
    new MutationObserver(observeSearchResults)
        .observe(document.body, { childList: true, subtree: true });
    observeSearchResults();
})();