Github搜索净化

净化Github搜索页,屏蔽cirosantilli等人的敏感仓库。

26.12.2023 itibariyledir. En son verisyonu görün.

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         Github搜索净化
// @name:zh-CN   Github搜索净化
// @name:en      Github Search Purification
// @namespace    https://github.com/danicastarr
// @version      1.1.0
// @description  净化Github搜索页,屏蔽cirosantilli等人的敏感仓库。
// @description:zh-CN  净化Github搜索页,屏蔽敏感仓库。
// @description:en Clean up Github search page, block sensitive repositories by cirosantilli and others.
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAACEUExURUxpcRgWFhsYGBgWFhcWFh8WFhoYGBgWFiUlJRcVFRkWFhgVFRgWFhgVFRsWFhgWFigeHhkWFv////////////r6+h4eHv///xcVFfLx8SMhIUNCQpSTk/r6+jY0NCknJ97e3ru7u+fn51BOTsPCwqGgoISDg6empmpoaK2srNDQ0FhXV3eXcCcAAAAXdFJOUwCBIZXMGP70BuRH2Ze/LpIMUunHkpQR34sfygAAAVpJREFUOMt1U+magjAMDAVb5BDU3W25b9T1/d9vaYpQKDs/rF9nSNJkArDA9ezQZ8wPbc8FE6eAiQUsOO1o19JolFibKCdHGHC0IJezOMD5snx/yE+KOYYr42fPSufSZyazqDoseTPw4lGJNOu6LBXVUPBG3lqYAOv/5ZwnNUfUifzBt8gkgfgINmjxOpgqUA147QWNaocLniqq3QsSVbQHNp45N/BAwoYQz9oUJEiE4GMGfoBSMj5gjeWRIMMqleD/CAzUHFqTLyjOA5zjNnwa4UCEZ2YK3khEcBXHjVBtEFeIZ6+NxYbPqWp1DLKV42t6Ujn2ydyiPi9nX0TTNAkVVZ/gozsl6FbrktkwaVvL2TRK0C8Ca7Hck7f5OBT6FFbLATkL2ugV0tm0RLM9fedDvhWstl8Wp9AFDjFX7yOY/lJrv8AkYuz7fuP8dv9izCYH+x3/LBnj9fYPBTpJDNzX+7cAAAAASUVORK5CYII=
// @license      GPLv3
// @author       DanicaStar ch3rry
// @match        *://github.com/search*
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-end
// ==/UserScript==
(function (){
    "use strict" // 严格模式
    let ban = ['cirosantilli', 'wumaoland', 'codin-stuffs', 'cheezcharmer', 'gege-circle', 'zhaohmng-outlook-com', 'zaohmeing', 'Daravai1234', 'candice531033938', 'jk-ice-cream', 'jk-ice-cream-250', 'sky8964', 'pxvr-official', 'zpc1314521', 'jjzhang166', 'panbinibn', 'programthink', 'hello-world-1989'];
    let isKeepDiv = GM_getValue("isKeepDiv", false);
    let isPrecise = GM_getValue("isPrecise", false);
    let detectMode = GM_getValue("detectMode", "loop");
    let detectDelay = GM_getValue("detectDelay", 100);
    
    // 注册菜单-是否保留屏蔽项目Div的框,默认false
    GM_registerMenuCommand(
        isKeepDiv ? "✅是否保留屏蔽项目Div的框":"❎是否保留屏蔽项目Div的框",
        function () {
            isKeepDiv ? GM_setValue("isKeepDiv", false):GM_setValue("isKeepDiv", true);
            isKeepDiv = !isKeepDiv;
            location.reload();
      }
    );
    
    // 注册菜单-是否精确匹配,默认false
    GM_registerMenuCommand(
        isPrecise ? "✅是否精确匹配":"❎是否精确匹配",
        function () {
            isPrecise ? GM_setValue("isPrecise", false):GM_setValue("isPrecise", true);
            isPrecise = !isPrecise;
            location.reload();
      }
    );
    
    // 注册菜单-检测模式,默认"loop"
    GM_registerMenuCommand(
        detectMode == "loop" ? "♾️检测模式:loop":"👂检测模式:eventListen",
        function () {
            if (detectMode == "loop") {
                GM_setValue("detectMode", "eventListen");
                detectMode == "eventListen";
            }
            else {
                GM_setValue("detectMode", "loop");
                detectMode == "loop";
            }
            location.reload();
      }
    );
    
    // 注册菜单-detectDelay设置
    if (detectMode == "loop") {
        GM_registerMenuCommand(
        "🕑设置检测间隔时间",
        function () {
            let inputValue = prompt("填入循环间隔时间,单位为毫秒(1000毫秒=1秒),默认为100毫秒", detectDelay); //默认显示detectDelay
            if (inputValue !== null) {
                if (inputValue > 0 && inputValue < 10000) {
                    detectDelay = inputValue;
                    GM_setValue("detectDelay", inputValue);
                    location.reload();
                }
                else {
                    alert("数值错误,请重新输入");
                }
            }
        });
    }
    
    // 注册菜单-设置说明
    GM_registerMenuCommand(
        "❔设置说明",
        function () {
            let message1 = "1. 是否保留屏蔽项目Div的框:若选择不保留,会直接在搜索结果中删除被屏蔽仓库;若选择保留,被屏蔽的仓库会显示一个包含信息'⛔该仓库被脚本屏蔽'的框。\n--------------------\n";
            let message2 = "2. 是否精确匹配:若不精确匹配,则任何innerText包含屏蔽词的仓库都会被屏蔽(.include),可能会有误杀情况;若精确匹配,则只会屏蔽屏蔽词内仓库所有者的仓库(==)\n----------\n";
            let message3 = "3. 检测模式:共有两种模式——循环(loop)和事件监听(eventListener),循环简单暴力,屏蔽效果好,但对性能影响较事件监听大;事件监听性能表现可能较好,但屏蔽效果不及循环\n----------\n";
            let message4 = "4. 每次检测循环间隔的时间,单位为毫秒(1000秒 = 1秒),可根据自身设备性能调整,默认为100毫秒";
            alert(message1 + message2 + message3 + message4);
      }
    );
    
    // 注册菜单-重置设置
    GM_registerMenuCommand(
    "🔄️重置设置",
    function () {
        if (confirm("是否重置脚本设置?") == true) {
            GM_setValue("isKeepDiv", false);
            GM_setValue("isPrecise", false);
            GM_setValue("detectMode", "loop");
            GM_setValue("detectDelay", 100);
            location.reload();
            alert("脚本已重置");
        }
    });
    
    
    // 屏蔽执行
    function clean() {
        if (document.querySelector("div[data-testid='results-list']") !== null) {
        let search_list = document.querySelector("div[data-testid='results-list']").childNodes;
            for (let i = 0; i < search_list.length; i++) {
                if (isBan(search_list[i], isPrecise)) {
                    if (isKeepDiv) {
                        search_list[i].firstChild.remove();
                        search_list[i].append("⛔该仓库被脚本屏蔽");
                    }
                    else {
                        search_list[i].remove();
                    }
                }
            }
        }
    };
    
    
    // 判断是否屏蔽
    function isBan(target ,isPrecise) {
        if (isPrecise) {
            if (target.getElementsByTagName("a").length !== 0) {
                let repositoryName = target.getElementsByTagName("a")[0].innerText;
                let userName = repositoryName.split("/")[0];
                for (let j = 0; j < ban.length; j++) {
                    if (userName == ban[j]) {
                        return true;
                    }
                }
                return false;
            }
            else {return false;}
        }
        else {
            for (let j = 0; j < ban.length; j++) {
                if (target.innerText.includes(ban[j])) {
                    return true;
                }
            }
            return false;
        }
    };
    
    //*********************************************
    //*                                           *
    //*               循环检测代码                *
    //*                                           *
    //*********************************************
    function cleanByLoop() {
        setInterval(function(){
            clean();
        },detectDelay);
    };
    
    //*********************************************
    //*                                           *
    //*               监听检测代码                *
    //*                                           *
    //*********************************************
    // github 路由更新时
    function pageChange(url) {
        // 保证时机
        setTimeout(() => {
        clean()
      }, 1000)
    }
    
    
    // 重写 history event
    let _wr = function(type) {
        let orig = history[type];
        return function() {
            let rv = orig.apply(this, arguments);
            let e = new Event(type);
            e.arguments = arguments;
            window.dispatchEvent(e);
            return rv;
        }
    }
    
    function cleanByEventListener() {
        setTimeout(() => {clean()}, 1000);
        clean();
        // 重写方法
        history.pushState = _wr('pushState');
        //监听
        window.addEventListener('pushState', function(e) {
            pageChange(location.href);
        })
    }
    
    //*********************************************
    //*                                           *
    //*                   入口                    *
    //*                                           *
    //*********************************************
    switch (detectMode) {
        case "loop": cleanByLoop();break;
        case "eventListen": cleanByEventListener();break;
    }
    
    })()