Pikabu Advertising Author Blocker

Блокирует статьи рекламных авторов на Pikabu и опционально блокирует блоки с фандрайзингом/играми/Telegram-ссылками в параграфах

// ==UserScript==
// @name         Pikabu Advertising Author Blocker
// @namespace    http://tampermonkey.net/
// @version      1.4.0
// @description  Блокирует статьи рекламных авторов на Pikabu и опционально блокирует блоки с фандрайзингом/играми/Telegram-ссылками в параграфах
// @match        https://pikabu.ru/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // --- Configuration ---
    const blockedAuthorsList = ["rabota.pikabu", "yandex.travel"]; // Список авторов
    const otherSelectorsToHide = ['.feed-games-carousel', '.story-block_type_fundraising']; // Селекторы других блоков для скрытия
    const blockOtherSelectors = true; // Включить/выключить блокировку других блоков

    const blockTelegramLinksInParagraphs = true; // НОВОЕ: Включить/выключить блокировку <p> с Telegram ссылками
    const telegramLinkPattern = /^https:\/\/t\.me\/(\+)?/; // НОВОЕ: Регулярное выражение для поиска Telegram ссылок (t.me/ или t.me/+)

    // Используем Set для быстрой проверки авторов
    const blockedAuthorsSet = new Set(blockedAuthorsList);

    // CSS класс для скрытия элементов
    const hideClassName = 'paab-hidden-element';

    // --- CSS Injection ---
    // Добавляем стиль для скрытия элементов один раз
    function addHideStyle() {
        const styleId = 'paab-hide-style';
        if (document.getElementById(styleId)) {
            return; // Стиль уже добавлен
        }
        const css = `.${hideClassName} { display: none !important; }`;
        const style = document.createElement('style');
        style.id = styleId;
        style.textContent = css;
        // Добавляем в <head> для надежности
        (document.head || document.documentElement).appendChild(style);
    }

    // --- Core Blocking Logic ---
    function hideElements() {
        // 1. Блокировка статей авторов
        // Выбираем только те статьи, которые еще не скрыты
        const articles = document.querySelectorAll(`article[data-author-name]:not(.${hideClassName})`);
        articles.forEach(article => {
            const authorName = article.getAttribute("data-author-name");
            if (blockedAuthorsSet.has(authorName)) {
                article.classList.add(hideClassName);
                // console.log(`PAAB: Hiding article by ${authorName}`); // Для отладки
            }
        });

        // 2. Блокировка других блоков, если включено
        if (blockOtherSelectors) {
            otherSelectorsToHide.forEach(selector => {
                // Находим элементы по селектору, которые еще не скрыты
                const elements = document.querySelectorAll(`${selector}:not(.${hideClassName})`);
                elements.forEach(element => {
                    element.classList.add(hideClassName);
                    // console.log(`PAAB: Hiding element matching selector ${selector}`); // Для отладки
                });
            });
        }

        // 3. НОВОЕ: Блокировка параграфов (<p>) с ссылками на Telegram, если включено
        if (blockTelegramLinksInParagraphs) {
            // Выбираем только те параграфы, которые еще не скрыты
            const paragraphs = document.querySelectorAll(`p:not(.${hideClassName})`);
            paragraphs.forEach(pElement => {
                // Ищем все ссылки внутри текущего параграфа
                const linksInParagraph = pElement.querySelectorAll('a[href]');
                for (const link of linksInParagraph) {
                    const href = link.getAttribute('href');
                    if (href && telegramLinkPattern.test(href)) {
                        pElement.classList.add(hideClassName);
                        // console.log(`PAAB: Hiding paragraph with Telegram link: ${href} in P: ${pElement.textContent.substring(0,50)}...`); // Для отладки
                        break; // Параграф помечен для скрытия, нет нужды проверять другие ссылки в нем
                    }
                }
            });
        }
    }

    // --- Initialization and Observation ---

    // 1. Добавляем CSS стиль
    addHideStyle();

    // 2. Запускаем функцию блокировки сразу и/или по готовности DOM
    if (document.readyState === 'loading') {
        document.addEventListener("DOMContentLoaded", hideElements);
    } else {
        hideElements();
    }

    // 3. Наблюдаем за изменениями в DOM для динамически добавляемого контента
    const observer = new MutationObserver(mutations => {
        let nodesAdded = false;
        for (const mutation of mutations) {
            if (mutation.addedNodes.length > 0) {
                nodesAdded = true;
                break;
            }
        }
        if (nodesAdded) {
             hideElements();
        }
    });

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

})();