Mastodon Search External Link Filter

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

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==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();
})();