Загрузка данных


// ==UserScript==
// @name         Двач: Анти-Лахта Мод (Умная фильтрация)
// @namespace    http://tampermonkey.net
// @version      2.5
// @description  Скрывает бототреды только в общих лентах досок и никогда не трогает контент внутри самих тредов.
// @author       You
// @match        *://*.2ch.org/*
// @match        *://*.2ch.hk/*
// @match        *://*.m2ch.hk/*
// @match        *://*.2ch.life/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Функция проверки: находимся ли мы внутри треда?
    function isInsideThread() {
        const url = window.location.href;
        // Если в URL есть "/res/" или имя файла заканчивается на ".html" (переход внутрь треда)
        // то скрипт не должен работать
        return url.includes('/res/') || url.includes('.html');
    }

    // Массив ключевых слов
    const botShit = [
        'webm', 'тяноч', 'отношен', 'секс', 'танцуль', 'Воскресной молитвы',
        'фурр', 'почему так', 'девушк', 'лесополос', 'ZASMOBOS', 'Это гуар.',
        'фапочно', 'покажи', 'цуиь', 'аниме', 'mp4', 'banana', 'понитре',
        'анимэ', 'дружботр', 'вацфу', 'вайф', 'тредю', 'зумер', 'тянка', 'тянко',
        'тянок', 'септемба', 'котосуббота', '#пкм', 'пустите в', 'fap', 'РИСОВАЧ',
        'рисовач тред', 'Храмом ГОЛОВЫ', 'храам голов', 'warcraft', 'war c',
        'Главный новостной', 'ШЛИК', 'fap', 'Оцени член', 'оцени', 'писяндрик'
    ];

    // Функция обработки ОП-поста
    function processPost(postElement) {
        // ЕСЛИ МЫ ВНУТРИ ТРЕДА — КАТЕГОРИЧЕСКИ НИЧЕГО НЕ СКРЫВАЕМ
        if (isInsideThread()) return;

        // Защита от повторной обработки одного и того же элемента
        if (postElement.dataset.checkedByLahta) return;
        postElement.dataset.checkedByLahta = "true";

        // Извлекаем текст
        let threadText = postElement.textContent.replace('(OP)', '').toLowerCase();
        threadText = threadText.replace(/\>+(\d+)>/g, '').replace(/\>+(\d+)/g, '');
        threadText = threadText.replace(/\s+/g, ' ').trim();

        // Ищем совпадение
        const triggeredWord = botShit.find(word => {
            const cleanWord = word.trim().toLowerCase();
            return cleanWord !== '' && threadText.includes(cleanWord);
        });

        if (triggeredWord) {
            // Находим контейнер всего треда на доске
            const threadContainer = postElement.closest('.thread') || postElement.closest('[id^="thread-"]') || postElement.closest('.post-wrapper');

            if (threadContainer) {
                // Создаем плашку-заглушку
                const placeholder = document.createElement('div');
                placeholder.className = 'lahta-placeholder';
                placeholder.style.border = '1px dashed #555555';
                placeholder.style.padding = '10px 14px';
                placeholder.style.margin = '12px 0';
                placeholder.style.borderRadius = '4px';
                placeholder.style.background = 'rgba(221, 161, 172, 0.05)';
                placeholder.style.display = 'block';
                placeholder.style.clear = 'both';
                placeholder.innerHTML = `<span style="color: #dda1ac; font-weight: bold; text-decoration: none !important;">УДАЛЕНА БОТОХУЕТА [ ${triggeredWord.trim()} ]</span>`;

                // Вставляем плашку перед скрываемым тредом
                threadContainer.parentNode.insertBefore(placeholder, threadContainer);

                // Скрываем оригинальный тред на главной странице доски
                threadContainer.style.setProperty('display', 'none', 'important');
            }
        }
    }

    // Запуск сканирования
    function scan() {
        if (isInsideThread()) return;

        const opPosts = document.querySelectorAll('.post_type_oppost, .oppost, .post.post_type_oppost');
        opPosts.forEach(post => processPost(post));
    }

    // Первый запуск при инициализации страницы
    scan();

    // Наблюдатель за динамической подгрузкой новых постов/тредов
    const observer = new MutationObserver((mutations) => {
        // Если пользователь перешел внутрь треда (пусть даже по AJAX без перезагрузки), прекращаем обработку
        if (isInsideThread()) return;

        let shouldScan = false;
        for (let mutation of mutations) {
            if (mutation.addedNodes.length > 0) {
                shouldScan = true;
                break;
            }
        }
        if (shouldScan) {
            scan();
        }
    });

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