Greasy Fork

Greasy Fork is available in English.

Yandex CleanSearch

Блокировка страниц по домену и заголовкам, рекламы и прочего дерьма в яндекс.

当前为 2024-10-10 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Yandex CleanSearch
// @namespace    http://tampermonkey.net/
// @version      2.9
// @description  Блокировка страниц по домену и заголовкам, рекламы и прочего дерьма в яндекс.
// @author       Zzakhar
// @match        https://yandex.ru/search/*
// @grant        none
// @license      CC BY-NC-ND 
// ==/UserScript==

(function() {
    'use strict';

    // Дб локал
    let blockedSites = JSON.parse(localStorage.getItem('blockedSites')) || [];

    let blockedPropagandaCount = 0;
    let blockedAdsCount = 0;
    let blockedPropaganda = [];
    let isHidden = true;


        // Короч для плавности, т..к когда появляется иконка она сдвигает серчбар
    function movesearchbar() {
        const searchBar = document.querySelector('header.HeaderDesktop-Main .HeaderForm');

        if (!searchBar) {
            console.error('Форма поиска не найдена');
            return;
        }
        searchBar.style.cssText = `
        position: relative;
        left: 34px;
        transition: left 0.7s ease; /* Плавный переход */
    `;
        setTimeout(() => {
            searchBar.style.left = '0px';
        }, 940.87);
    }
    movesearchbar()



    // счетчик
    function updateBlockCounter() {
        const resultsContainer = document.querySelector('.main__center');
        let counterCard = resultsContainer.querySelector('.blocked-counter-card');

        if (!counterCard) {
            counterCard = document.createElement('div');
            counterCard.className = 'blocked-counter-card';
            counterCard.style.backgroundColor = '#300';
            counterCard.style.color = '#ffffff';
            counterCard.style.padding = '10px';
            counterCard.style.marginBottom = '10px';
            counterCard.style.border = '1px solid #600';
            counterCard.style.borderRadius = '5px';
            counterCard.style.maxWidth = '34%';
            counterCard.style.overflow = 'auto';
            resultsContainer.prepend(counterCard);
        }

        const counterText = `Заблокировано: ${blockedPropagandaCount} ненужного мусора и ${blockedAdsCount} рекламы`;
        let textElement = counterCard.querySelector('.counter-text');
        if (!textElement) {
            textElement = document.createElement('div');
            textElement.className = 'counter-text';
            counterCard.appendChild(textElement);
        }
        textElement.textContent = counterText;

        updateButtons(counterCard);
    }

    // смена кнопок
    function updateButtons(counterCard) {
        let showButton = counterCard.querySelector('.show-button');
        let removeButton = counterCard.querySelector('.remove-button');

        if (blockedPropagandaCount > 0 || blockedAdsCount > 0) {
            counterCard.style.display = 'flex';
            counterCard.style.justifyContent = 'space-between';
            counterCard.style.alignItems = 'center';

            if (isHidden) {
                if (!showButton) {
                    showButton = document.createElement('button');
                    showButton.className = 'show-button';
                    showButton.textContent = 'Показать';
                    showButton.style.backgroundColor = '#007bff';
                    showButton.style.color = '#ffffff';
                    showButton.style.border = 'none';
                    showButton.style.borderRadius = '5px';
                    showButton.style.padding = '5px 10px';
                    showButton.style.cursor = 'pointer';
                    showButton.style.marginLeft = '10px';
                    showButton.onclick = showBlockedPropaganda;

                    counterCard.appendChild(showButton);
                }

                if (removeButton) {
                    removeButton.remove();
                }
            } else {
                if (!removeButton) {
                    removeButton = document.createElement('button');
                    removeButton.className = 'remove-button';
                    removeButton.textContent = 'Убрать';
                    removeButton.style.backgroundColor = '#dc3545';
                    removeButton.style.color = '#ffffff';
                    removeButton.style.border = 'none';
                    removeButton.style.borderRadius = '5px';
                    removeButton.style.padding = '5px 10px';
                    removeButton.style.cursor = 'pointer';
                    removeButton.style.marginLeft = '10px';
                    removeButton.onclick = hideBlockedPropaganda;

                    counterCard.appendChild(removeButton);
                }

                if (showButton) {
                    showButton.remove();
                }
            }
        } else {
            if (showButton) {
                showButton.remove();
            }
            if (removeButton) {
                removeButton.remove();
            }
        }
    }
    // Мейн функция поиска
    function blockLinksAndAds() {
        const results = document.querySelectorAll('.serp-item');

        blockedPropagandaCount = 0;
        blockedAdsCount = 0;
        blockedPropaganda = [];

        results.forEach(result => {
            const isAd = checkIfAd(result);
            const link = result.querySelector('a.Link');
            const title = result.querySelector('.OrganicTitle-LinkText');

            if (link && title) {
                const href = link.href.toLowerCase();
                const titleText = title.textContent.toLowerCase();

                const isBlocked = blockedSites.some(site => href.includes(site) || titleText.includes(site));

                if (isAd) {
                    result.style.display = 'none';
                    blockedAdsCount++;
                } else if (isBlocked) {
                    result.style.display = 'none';
                    blockedPropagandaCount++;
                    blockedPropaganda.push(result);
                    console.log("Заблокирована дичь: ", result);
                }
            }
        });

        const containerToHide = document.querySelector("body > main > div > div.main__container > div > div > div.content__left > div.VanillaReact.RelatedBottom");
        if (containerToHide) {
            containerToHide.style.display = 'none';
            console.log("Рекомендациии скрыты.");
        }

        updateBlockCounter();
    }

    //
    function checkIfAd(result) {
        const adTextIndicators = ['реклама', 'баннер',"ad","advertise"];
        return adTextIndicators.some(text => result.textContent.toLowerCase().includes(text));
    }

    // Показать бтн
    function showBlockedPropaganda() {
        console.log("Показать");
        if (isHidden) {
            blockedPropaganda.forEach(prop => {
                prop.style.display = 'block';
            });
            isHidden = false;
            updateButtons(document.querySelector('.blocked-counter-card'));
        }
    }

    // Скрыть бтн
    function hideBlockedPropaganda() {
        console.log("Кнопка 'Убрать' нажата!");
        if (!isHidden) {
            blockedPropaganda.forEach(prop => {
                prop.style.display = 'none';
            });
            isHidden = true;
            updateButtons(document.querySelector('.blocked-counter-card'));
        }
    }

    // дб
     function saveBlockedSites() {
        localStorage.setItem('blockedSites', JSON.stringify(blockedSites));
    }
    window.addEventListener('load', () => {
        blockLinksAndAds();
    });
    //основной цикл
    const observer = new MutationObserver(() => {
        if (isHidden) {
            blockLinksAndAds();
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });

    // настройки


    function resetBlockedSites() {
        blockedSites.length = 0;
        saveBlockedSites();
        updateBlockedSitesList();
        setTimeout(() => {
            location.reload(); // релоад
        }, 2000);
        showNotification('Все заблокированные сайты были очищены.');
    }
    function updateBlockedSitesList() {
        const list = document.getElementById('blockedSitesList');
        list.innerHTML = '';
        blockedSites.forEach(site => {
            const li = document.createElement('li');
            li.textContent = site;
            list.appendChild(li);
        });
    }
    function createPopup() {
        const popup = document.createElement('div');
        popup.className = 'custom-popup';
        popup.style.cssText = `
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: #0e1011;
    border: 2px solid #970e05; /* Цвет рамки */
    border-radius: 10px; /* Скругленные углы */
    box-shadow: 0 0 15px #4c0803, 0 0 30px #8b0903;
    padding: 20px;
    z-index: 9999;
    display: none;
    width: 300px;
    max-width: 90%;
    transition: transform 0.3s ease, opacity 0.3s ease;
    opacity: 0;
`;

        popup.innerHTML = `
    <h3>Yandex CleanSearch</h3>
    <input type="text" id="siteInput" placeholder="Домен или заголовок (Например: rutube.ru)"
           style="width: 90%; padding: 10px; margin-bottom: 10px;">
    <div style="display: flex; justify-content: center; gap: 10px; margin-bottom: 10px;">
        <button id="blockSiteBtn" style="
            background-color: red;
            color: white;
            border: none;
            border-radius: 20px;
            padding: 10px 20px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s ease;
        ">Заблокировать</button>
        <button id="unblockSiteBtn" style="
            background-color: green;
            color: white;
            border: none;
            border-radius: 20px;
            padding: 10px 20px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s ease;
        ">Разблокировать</button>
    </div>
    <div style="display: flex; align-items: center; justify-content: space-between;">
        <h4 style="margin: 0;">Заблокированные сайты:</h4>
        <button id="resetBtn" style="
            background-color: orange;
            color: white;
            border: none;
            border-radius: 10px;
            padding: 5px 10px;
            cursor: pointer;
            font-size: 12px;
            transition: background-color 0.3s ease;
        ">Сбросить</button>
    </div>
    <ul id="blockedSitesList" style="max-height: 80px; overflow-y: auto;"></ul>
    <span id="closePopupBtn" style="
        position: absolute;
        top: 10px;
        right: 10px;
        cursor: pointer;
        font-size: 20px;
        font-weight: bold;
    ">&times;</span>
`;


        document.body.appendChild(popup);

        document.getElementById('blockSiteBtn').addEventListener('click', blockSite);
        document.getElementById('unblockSiteBtn').addEventListener('click', unblockSite);
        document.getElementById('closePopupBtn').addEventListener('click', () => {
            popup.style.display = 'none';
        });
        document.getElementById('resetBtn').addEventListener('click', resetBlockedSites);
    }

    function showPopup() {
        const popup = document.querySelector('.custom-popup');
        popup.style.display = 'block';
        popup.style.opacity = '1';
        popup.style.transform = 'translate(-50%, -50%) scale(1.05)'; // анимация
        updateBlockedSitesList();
    }

   function showNotification(message) {
       const notification = document.createElement('div');
       notification.className = 'notification';
       notification.innerText = message;
       notification.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background-color: #4caf50; /* Зеленый цвет для успешного уведомления */
        color: white;
        padding: 15px;
        border-radius: 5px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
        z-index: 10000;
        opacity: 0;
        transform: translateY(-20px);
        transition: opacity 0.5s, transform 0.5s;
    `;

       document.body.appendChild(notification);
       setTimeout(() => {
           notification.style.opacity = '1';
           notification.style.transform = 'translateY(0)';
       }, 100);
       setTimeout(() => {
           notification.style.opacity = '0';
           notification.style.transform = 'translateY(-20px)';
           setTimeout(() => {
               document.body.removeChild(notification);
           }, 500);
       }, 3000);
   }

    function blockSite() {
        const site = document.getElementById('siteInput').value.toLowerCase();
        if (site && !blockedSites.includes(site)) {
            blockedSites.push(site);
            saveBlockedSites();
            updateBlockedSitesList();
            showNotification(`${site} has been blocked.`);
        } else {
            showNotification('Site is already blocked or input is empty.');
        }
    }

    function unblockSite() {
        const site = document.getElementById('siteInput').value.toLowerCase();
        const index = blockedSites.indexOf(site);

        if (index !== -1) {
            blockedSites.splice(index, 1);
            saveBlockedSites();
            showNotification(`${site} has been unblocked.`);
            setTimeout(() => {
            location.reload();
            }, 2000);
        } else {
            showNotification('Site not found in blocked list.');
        }
    }


    // иконка для настроек
    function createIcon() {
        const headerLogo = document.querySelector('header.HeaderDesktop-Main .HeaderLogo');

        if (!headerLogo) {
            console.error('Логотип не найден');
            return;
        }

        headerLogo.removeAttribute('href'); // Убираем href
        headerLogo.style.cursor = 'default';

        // Создаем иконку внутри логотипа
        const icon = document.createElement('img');
        icon.className = 'custom-icon';
        icon.src = 'https://avatars.mds.yandex.net/i?id=6a46c4318776cd395ef17ab922147471976ebe7d-3569718-images-thumbs&n=13';
        icon.alt = 'FREEINTERNET';
        icon.style.cssText = `
        width: 36px;
        height: 36px;
        border-radius: 50%;
        cursor: pointer;
        position: relative;
        left: 25px;
        vertical-align: middle;
        opacity: 0;
        transform: scale(0.9); /* Начальное уменьшение иконки */
        transition: opacity 0.5s ease, transform 0.5s ease; /* Плавные переходы */
    `;
        headerLogo.appendChild(icon);
        setTimeout(() => {
            icon.style.opacity = '1';
            icon.style.transform = 'scale(1)';
        }, 50);
        icon.addEventListener('click', showPopup);
    }




    createPopup();
    setTimeout(() => {
        createIcon();
    }, 1000);
    console.log(document.querySelector('header.HeaderDesktop-Main .HeaderLogo.HeaderDesktop-Logo'));
})();