AS mmd cleanup

This script is to clean up the spam in the Anime sharing MMD sharethread.

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

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

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

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.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name        AS mmd cleanup
// @version     1.3
// @namespace   mailto:[email protected]
// @author      perckle
// @description This script is to clean up the spam in the Anime sharing MMD sharethread.
// @license     MIT
// @match       https://www.anime-sharing.com/threads/mmd-discussion-and-sharing.1532636/*
// @grant       none
// @run-at      document-end
// ==/UserScript==

// Configuration flags
const CONFIG = {
    enableWordFilter: true,
    enableLinkCheck: true,
    enableHideBlockCheck: true,
    removeFormatting: false
};

// Function to check if text contains target words (case insensitive)
function containsTargetWords(text) {
    const normalizedText = text.toLowerCase();
    return normalizedText.includes('anyone') ||
           normalizedText.includes('any one') ||
           normalizedText.includes('anybody') ||
           normalizedText.includes('hero') ||
           normalizedText.includes('plz') ||
           normalizedText.includes('pls') ||
           normalizedText.includes('thx') ||
           normalizedText.includes('in advance');
}

// Function to check if element contains a direct child link
function containsLink(bbWrapper) {
    if (!bbWrapper || typeof bbWrapper.children === 'undefined') {
        console.log('Invalid element passed to containsLink');
        return false;
    }

    // Convert children to array and check only direct children
    const children = Array.from(bbWrapper.children);
    return children.some(child => {
        // Check if the child is an 'a' tag with href
        if (child.tagName === 'A' && child.hasAttribute('href')) {
            return true;
        }
        // Check if the child directly contains an 'a' tag (one level deep)
        return child.querySelector(':scope > a[href]') !== null;
    });
}

// Function to check if element contains hideBlock class
function containsHideBlock(bbWrapper) {
    if (!bbWrapper || typeof bbWrapper.querySelector !== 'function') {
        console.log('Invalid element passed to containsHideBlock');
        return false;
    }
    return bbWrapper.querySelector(':scope > .bbCodeBlock--hide, :scope > .hideBlock') !== null;
}

// Function to get text content excluding content within blockquotes
function getTextExcludingQuotes(element) {
    const clone = element.cloneNode(true);
    const blockquotes = clone.querySelectorAll('blockquote');
    blockquotes.forEach(quote => quote.remove());
    return clone.textContent.trim();
}

// Function to remove b and span tags while preserving their content
function removeFormattingTags(element) {
    if (!CONFIG.removeFormatting) return;

    const formattingTags = element.querySelectorAll('b, span');
    formattingTags.forEach(tag => {
        const textContent = document.createTextNode(tag.textContent);
        tag.parentNode.replaceChild(textContent, tag);
    });
}

// Main function to filter forum posts
function filterForumPosts() {
    const container = document.querySelector('.block--messages');
    if (!container) {
        console.log('Forum container not found, retrying...');
        return false;
    }

    const posts = container.querySelectorAll('.message-inner');
    if (posts.length === 0) {
        console.log('No posts found, retrying...');
        return false;
    }

    posts.forEach(post => {
        const bbWrapper = post.querySelector('.bbWrapper');
        if (!bbWrapper) return;

        let shouldRemove = true; // Start with true, set to false if any condition is met




        // Link check
        if (CONFIG.enableLinkCheck && shouldRemove) {
            if (containsLink(bbWrapper)) {
                shouldRemove = false;
            }
        }

        // HideBlock check
        if (CONFIG.enableHideBlockCheck && shouldRemove) {
            if (containsHideBlock(bbWrapper)) {
                shouldRemove = false;
            }
        }
              if (CONFIG.enableWordFilter) {
            const textContent = getTextExcludingQuotes(bbWrapper);
            if (containsTargetWords(textContent)) {
                shouldRemove = true;
            }
        }

        if (shouldRemove) {
            post.remove();
        } else if (CONFIG.removeFormatting) {
            removeFormattingTags(bbWrapper);
        }
    });

    return true;
}

// Function to wait for page to be fully rendered
function waitForPageLoad() {
    const observer = new MutationObserver((mutations, obs) => {
        const success = filterForumPosts();
        if (success) {
            obs.disconnect();
            console.log('Forum filtering complete');
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: false,
        characterData: false
    });

    document.addEventListener('DOMContentLoaded', () => {
        if (filterForumPosts()) {
            observer.disconnect();
            console.log('Forum filtering complete on initial load');
        }
    });

    setTimeout(() => {
        observer.disconnect();
        console.log('Stopped watching for page changes after timeout');
    }, 30000);
}

// Initialize the script
waitForPageLoad();