☰

Semprot.com Bomber

Hides Semprot replies that lack images or links, keeping the main OP post safe.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

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

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

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

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name         Semprot.com Bomber
// @namespace    Violentmonkey Scripts
// @version      1.1.0
// @description  Hides Semprot replies that lack images or links, keeping the main OP post safe.
// @license      MIT
// @match        https://www.semprot.com/threads/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(async function() {
    'use strict';

    const cleanPath = window.location.pathname.replace(/\/page-\d+.*$/, '');
    const storageKey = 'xf_true_op_' + cleanPath;

    function getPostAuthor(post) {
        if (!post) return null;
        const dataAuthor = post.getAttribute('data-author');
        if (dataAuthor) return dataAuthor.trim();

        // Search for username elements, but explicitly ignore any inside quote blocks
        const usernames = post.querySelectorAll('.username, .message-name');
        for (let el of usernames) {
            if (!el.closest('.bbCodeBlock--quote')) {
                return el.textContent.trim();
            }
        }
        return null;
    }

    async function getOrFetchOpAuthor() {
        let opAuthor = sessionStorage.getItem(storageKey);
        if (opAuthor) return opAuthor;

        const posts = document.querySelectorAll('article.message--post');
        if (posts.length > 0 && !window.location.pathname.includes('/page-')) {
            opAuthor = getPostAuthor(posts[0]);
            if (opAuthor) {
                sessionStorage.setItem(storageKey, opAuthor);
                return opAuthor;
            }
        }

        try {
            const res = await fetch(cleanPath);
            const html = await res.text();
            const doc = new DOMParser().parseFromString(html, 'text/html');
            const firstPost = doc.querySelector('article.message--post');
            if (firstPost) {
                opAuthor = getPostAuthor(firstPost);
                if (opAuthor) {
                    sessionStorage.setItem(storageKey, opAuthor);
                    return opAuthor;
                }
            }
        } catch (err) {
            console.error('Could not fetch root OP:', err);
        }

        if (posts.length > 0) {
            opAuthor = getPostAuthor(posts[0]);
            if (opAuthor) sessionStorage.setItem(storageKey, opAuthor);
        }
        return opAuthor;
    }

    function hasMediaOrLink(post) {
        const messageBody = post.querySelector('.message-body, .bbWrapper');
        if (!messageBody) return false;

        // Check for real images/media, ignoring smilies
        const realImages = messageBody.querySelectorAll('img:not(.smilie), .bbImage, video, iframe, .bbMedia, picture');
        if (realImages.length > 0) return true;

        // Check for links, ignoring quotes and user mentions
        const links = messageBody.querySelectorAll('a');
        for (let a of links) {
            if (a.closest('.bbCodeBlock--quote')) continue;
            if (a.classList.contains('username') || a.hasAttribute('data-user-id')) continue;

            const href = a.getAttribute('href');
            if (href && !href.startsWith('#') && !href.startsWith('javascript:')) {
                return true;
            }
        }

        return false;
    }

    async function filterPosts() {
        const opAuthor = await getOrFetchOpAuthor();
        if (!opAuthor) return;

        const posts = document.querySelectorAll('article.message--post');
        const isPageOne = !window.location.pathname.includes('/page-') || window.location.pathname.endsWith('/page-1');

        posts.forEach((post, index) => {
            if (post.dataset.opProcessed) return;
            post.dataset.opProcessed = 'true';

            const postAuthor = getPostAuthor(post);

            // Nuke anyone who isn't the true OP
            if (postAuthor !== opAuthor) {
                post.style.display = 'none';
                return;
            }

            // Always keep page 1 opening post safe
            if (isPageOne && index === 0) {
                return;
            }

            // Nuke OP text-only replies that lack media or links
            if (!hasMediaOrLink(post)) {
                post.style.display = 'none';
            }
        });
    }

    await filterPosts();

    const observer = new MutationObserver(() => {
        filterPosts();
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();