您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
净化Github搜索页,屏蔽cirosantilli等400+人的敏感仓库。
// ==UserScript== // @name Github搜索净化 // @name:zh-CN Github搜索净化 // @name:en Github Search Purification // @namespace https://github.com/BonjourFeng // @version 1.4.0 // @description 净化Github搜索页,屏蔽cirosantilli等400+人的敏感仓库。 // @description:zh-CN 净化Github搜索页,屏蔽cirosantilli等400+人的敏感仓库。 // @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 GPL-3.0 // @author DanicaStar BonjourFeng // @match *://github.com/search* // @match *://github.site/search* // @match *://github.store/search* // @match *://kkgithub.com/search* // @match *://dgithub.xyz/search* // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_deleteValues // @grant unsafeWindow // @run-at document-end // ==/UserScript== (function () { "use strict" // 严格模式 let defaultBanList = ['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', 'b0LBwZ7r5HOeh6CBMuQIhVu3-s-random-fork', 'thethetpvmy', 'wwwswitch520cc', 'shotoanqrob', 'sitempeanhkkwg', 'fukeluo', '1206256980', 'curees', 'yuoppo', 'Createree', 'vghl', 'wholedata', 'dunjian', 'mksshare', 'abshare', 'tpxdat', 'jhdyg', 'changfengqj', 'Dujltqzv', 'xmq1024', 'golade', 'kdjfhd', 'dkjhy', 'junsolg', 'dkjiiu', 'faithhow', 'yamtioy', 'zugzuc', 'lusvont', 'kenyatas', 'koeheu', 'juttama', 'duspub', 'wuqdid', 'visxud', 'suyfic', 'qokkod', 'roepuo', 'purfob', 'gitprocode', 'ynwynw', 'hanguodianying', 'hgyw', '69sm', 'urlapp', 'Augensternhx', 'urlweb', 'fuliso', 'nishjd', '36dshipin', 'hapump', 'zhguoxmw', 'KoreanMovies', 'hanjutv', 'mamadepengyou', 'mamatouyunmuxuan', 'erzideqizi', 'wodeqizidejiejie', 'xiaoyizidemeng', 'qingyuzongheng', 'jiangnanerxi', 'hanguobiaomei', 'djhgy', 'XXOOBY', 'baoyu1024', 'kk234kkkk', '15923-ORIX', 'wutaed', 'webzhibo', 'apptuijian', 'follow666', 'yu90892', 'aconteet', 'getmal', 'itxinfei', 'mingtiana', 'midoushipin', 'paofushipin', 'yinghanshipin', 'GTVapp', 'huangyouquan', 'devlookme', 'audwq', 'jhdgy', 'di6gandh', 'shuangyuzhibo', 'lvchazhibo', 'xiaolanshipin', 'bofangqi', 'yingtaoshipin', 'xiangfeizhibo', 'lvchaApp', 'luoshenzhibo', 'yaojizhibo', 'mudanzhibo', 'aiaizhibo', 'gaochaoqwe', 'jiolde', 'lsdhw', 'kanavdaohang', 'harnh', 'kuadaner', 'wapquan', 'laoyeer', 'reteres', 'haoersn', 'zhengjianzhong0107', 'huaaweiCode', 'jianjian00001', 'm2ak-dev', 'yyzwz', 'froginwe11', 'luanmenglei', 'xijinping0', 'cyqqq', 'qldaisd', 'lTbgykio', 'yao270161651', 'jt0008jt0008', '15625103741', 'sky1234566778', 'chfucao', 'chifuyidaocao', 'updrmeltm', 'alice548', 'yazm000', 'cpnorg', 'tffygbu', 'Liberty-China', '1989CCP', 'liulihaocai', 'RevolutionaryCommitteeCPC', 'LeiyanLu', 'webdao', 'GC4WP', 'tu01', 'ziliao1', 'zzs70', 'ff2017', 'guitu2017', 'tu2017', 'wm001', 'wnel2017', 'dunhlino', 'nelaliox', 'jianjian3219', 'giteecode', '666bears', 'wang-buer', 'id681ilyg316', 'uhjid', 'usdui', 'uhskl', 'uyjks', 'uhskldf', 'itgsi5', 'uifskv', 'uhgask', 'igfkld', 'udsjd', 'ufodk', 'uigsjt', 'ighfrs', 'haivs', 'idrkkld', 'yuisju', 'uldydj', 'uyuek', 'tydfj', 'uuedif', 'ykwsw3', 'uigsi7', 'tyiis', 'ykeik', 'ukvdj', 'uyikl', 'ufzekg', 'yiksure', 'rhksgz', 'rthls', 'rhjaw', 'rehlxs', 'thzsgt', 'tdidst', 'eglct', 'tjkdyu', 'tjlks', 'tjjds', 'rllfs', 'rhkstd', 'yjscdr', 'servisee', 'ufsjzf', 'bvnbvnfgd', 'duliyingshi', 'calendi', 'mayeobey', 'QQMusic-Jay-Chou', 'boylovecomic', 'bt9527', 'FarmerChina', 'Waymon102092', 'baofx', 'biehd', 'moonpas', 'lyqilo', 'liliqh', 'hourv', 'xinfue', 'jijidianying', 'YuyanCai', 'jtdh', 'isdkxr', 'yhildyu', 'ykldyld', 'igsigk', 'uidekj', 'iufskw', 'udsjhf', 'tjkdx', 'rtkist', 'tjlsyh', 'euhf', 'rjzsht', 'rhkdzu', 'ehkkld', 'xzgfsw', 'iofgd', 'yufdk', 'ujkdub', 'iofgdsk', 'dyghikg', 'ugdskf', 'ifwaih', 'oigsiu', 'yjksku', 'yfdkkrf', 'thjsqd', 'yjsyhf', 'ydjsu6', 'igseyf', 'ujudy8', 'tykde', 'ykmdi8', 'yklzrf', 'uijdkd', 'yjkshc', 'tkajc', 'ykdzs', 'jklsx', 'ejldux', 'ifxspo', 'ogsvtf', 'ifdeu', 'yudfdi', 'ofssj', 'igegkx', 'ugfkd', 'ugdsk', 'udskts', 'yjlkdss', 'fkdryl', 'rtuyjsr', 'tus56f', 'yjdsd', 'yuet6h', 'ugtw', 'tlkxt', 'yesrs', 'ykkds', 'yjksu', 'yhyshs', 'xdzfby', 'yujzdh', 'znfl', 'kjiud', 'shijuezhishi', 'hy1980boy', 'ww0304', 'ZXCASD854', 'zfpdh', 'batiyadh', 'yinsedh', 'yyfxz', 'bllpooe', 'joodfer', 'qdmang', 'chaenet', 'mzsyv', 'kzhaoes', 'clnnews', 'kendnes', 'hongnews', 'luokez', 'li721-LY', 'itunsr', 'cctnews', 'htmle', 'xmmj2', 'younownews', '445435213', 'seseClub', 'enewse', 'wsnewse', 'qsnews', 'soasmoughroy', 'adminewhat', 'wsermusic', 'molingfer', 'zhihues', '95movies', '99fuli', 'qnewse', 'tareres', 'hukioip', 'Hochoclate713', 'ervnme', 'greenleaf8888', '93-days', 'doubanm', 'xhydh', 'fvckslvt', 'MDCM-FB', 'b08240', 'm3u8-ekvod', 'huan768468', 'SweeOBC', 'ningmengsuan7788', 'supperqb', 'idskjs', 'ifsird', 'gklksr', 'ifsjxr', 'ifskxt', 'ghjklsd', 'udsskd', 'tgsjk', 'ihgsk', 'ujsjk', 'ijhdf', 'fghhgks', 'udfae4', 'jujwdj', 'ydsdk', 'uyfgsj', 'ykkxrd', 'branono', 'hytcd', 'kjiuo', 'SaolApp', 'lourv', 'uisdlk', 'hutuhai', 'dengminna', 'whmnoe4j', 'txy9704', 'ufsjl', 'udsks', 'uifsjk', 'ygsaj', 'udsts', 'yurdek', 'ghklsr', 'ifsnx', 'ufskd', 'yujst6', 'ifsurjn', 'saoyagma', 'yusyrdk', 'uijhgr', 'geeeeeeeek', 'gfjklk', 'uiskv', 'ccccsp', 'rrrsp', 'udjxs', 'qiezisp', 'egklkd', 't6korf', 'line915577', 'haijv', 'huaxinzhibo', 'haijiaofabuye', 'haijiaoshequ', 'HaijiaoCommunity', 'haijiao-app', 'fulibaike', 'lurmarp', 'entvasa', 'gotwib', 'hghkiiy121', 'gubcem', 'uijssu', 'yjhuk', 'yklsd', 'haijiaoWeb', 'winston779', 'tyukkst', 'ujsnmc', 'ygssk', 'igdkdy', 'qiezishiping', 'kjuhd', 'xiaogongzhuAPP', 'babyzhibo', 'yaojingzhibo', 'balizhibo', 'jiuaizhibo', 'liuyuezhibo', '69live', 'asidw', 'kuaimaoVIP', 'siguaha', 'mizhizhibo', 'lihzd', 'caomeizhibo', '36DAPP', 'luolisheApp', '69zhibo', 'jiejiezhibo', 'k8japan', 'buyaoshan', 'dk111222', 'fanbaovpn', 'HGcrowntiyu', '196tiyu', 'parryno', 'boyiscode', 'moonews', 'kim1528', 'tjqJ62cESiHPj6DdR6vXDAcPp', 'code-help-tutor', 'turbocanary', 'Ifem2BXvz4N4gh1gGn0bkR3Lp', 'R7w726fYrfritM7zPJCO']; let useDefaultList = GM_getValue("useDefaultList", true); // 是否加载默认屏蔽列表,默认为true let showBlockButton = GM_getValue("showBlockButton", true); // 是否显示屏蔽按钮,默认为true let isKeepDiv = GM_getValue("isKeepDiv", false); // 是否保留被屏蔽项目占位,默认为false let isPrecise = GM_getValue("isPrecise", true); // 是否精确匹配,默认为true let detectMode = GM_getValue("detectMode", "mutationobserver"); // 检测模式,默认为mutationobserver let detectDelay = GM_getValue("detectDelay", 100); // 每次检测循环间隔的时间,单位为毫秒,默认为100毫秒 let customBanList = GM_getValue("customBanList", []); // 自定义屏蔽列表 let banList = []; // 最终的屏蔽列表 useDefaultList ? banList = Array.from(new Set([...defaultBanList, ...customBanList])) : banList = customBanList; // 根据是否加载默认屏蔽列表决定最终的屏蔽列表 // 开启设置页面函数 function openMenu() { // 检测是否已经开启设置页面 if (document.getElementsByClassName("settings").length == 0) { let settingMenu = document.createElement("div"); settingMenu.className = "settings"; settingMenu.innerHTML = /*html*/` <h2><span>Github搜索净化 v</span><span id="scriptVersion"></span></h2> <a href="https://github.com/BonjourFeng/Github-Search-Purification" target="_blank"><div class="badge1"></div></a> <a href="https://greasyforks.org/zh-CN/scripts/473912-github%E6%90%9C%E7%B4%A2%E5%87%80%E5%8C%96" target="_blank"><div class="badge2"></div></a> <br> <span class="userLoadNum">已加载屏蔽用户数量:加载中...</span> <hr> <div class="settings-block"> <span>加载默认屏蔽列表</span> <label class="settings-switch"> <input type="checkbox" id="useDefaultList"> <span class="slider round"></span> </label> </div> <div class="settings-block"><span>显示屏蔽按钮</span><label class="settings-switch"><input type="checkbox" id="showBlockButton"><span class="slider round"></span></label> </div> <div class="settings-block"><span>保留被屏蔽项目占位</span><label class="settings-switch"><input type="checkbox" id="isKeepDiv"><span class="slider round"></span></label> </div> <div class="settings-block"><span>精确匹配</span><label class="settings-switch"><input type="checkbox" id="isPrecise"><span class="slider round"></span></label></div> <div class="settings-block"> <span>检测模式</span> <select id="detectMode"> <option value="mutationobserver">MutationObserver(推荐)</option> <option value="loop" title="性能较差,不推荐">Loop</option> <option value="eventListen" title="有可能没有效果">eventListener</option> <option value="navigation" title="Firefox,Safari 不支持">Navigation API</option> <option value="manual" title="需要手动点击按钮进行屏蔽">Manual</option> </select> </div> <div class="settings-block"> <span>检测循环间隔时间(Loop模式)</span> <input type="number" class="settings-input"> </div> <hr> <div class="settings-block"><p class="text-center">自定义屏蔽列表</p></div> <div class="settings-block"> <textarea id="customBanInput" placeholder="在此处输入用户名,用户间以英文逗号分隔" class="settings-textarea"></textarea> </div> <button id="save">保存</button><button id="cancel">取消</button> `; document.body.appendChild(settingMenu); // 更新设置页面 document.getElementById("scriptVersion").innerText = GM_info.script.version; // 更新版本号 if (useDefaultList) { document.getElementsByClassName("userLoadNum")[0].innerText = `已加载默认屏蔽用户数量:${defaultBanList.length},自定义屏蔽用户数量:${customBanList.length}`; } else { document.getElementsByClassName("userLoadNum")[0].innerText = `未加载默认列表,自定义屏蔽用户数量:${customBanList.length}`; } showBlockButton ? document.getElementById("showBlockButton").checked = true : document.getElementById("showBlockButton").checked = false; // 更新是否显示屏蔽按钮 isKeepDiv ? document.getElementById("isKeepDiv").checked = true : document.getElementById("isKeepDiv").checked = false; // 更新是否保留被屏蔽项目占位 isPrecise ? document.getElementById("isPrecise").checked = true : document.getElementById("isPrecise").checked = false; // 更新是否精确匹配 useDefaultList ? document.getElementById("useDefaultList").checked = true : document.getElementById("useDefaultList").checked = false; // 更新是否加载默认屏蔽列表 document.getElementById("detectMode").value = detectMode; // 更新检测模式 // 检测浏览器是否支持 Navigation API if (!window.navigation) { document.querySelector('option[value="navigation"]').disabled = true; } document.getElementsByClassName("settings-input")[0].value = detectDelay; // 更新循环间隔时间输入框 document.getElementsByClassName("settings-input")[0].addEventListener('change', checkDelaytime); // 添加纠正循环间隔监听器 document.getElementById("customBanInput").value = customBanList.join(","); // 更新自定义屏蔽列表 // 背景模糊 backgroungBlur(); // 添加按钮事件——保存 document.getElementById("save").onclick = function () { document.getElementById("showBlockButton").checked == true ? GM_setValue("showBlockButton", true) : GM_setValue("showBlockButton", false); // 保存是否显示屏蔽按钮 document.getElementById("isKeepDiv").checked == true ? GM_setValue("isKeepDiv", true) : GM_setValue("isKeepDiv", false); // 保存是否保留被屏蔽项目占位 document.getElementById("isPrecise").checked == true ? GM_setValue("isPrecise", true) : GM_setValue("isPrecise", false); // 保存是否精确匹配 document.getElementById("useDefaultList").checked == true ? GM_setValue("useDefaultList", true) : GM_setValue("useDefaultList", false); // 保存是否加载默认屏蔽列表 GM_setValue("detectMode", document.getElementById("detectMode").value); // 保存检测模式 let newCustomBanList = document.getElementById("customBanInput").value.split(",").filter(item => item.trim() !== ""); // 去除空字符串 newCustomBanList = newCustomBanList.map(item => item.trim()); // 去除用户名前后空格 newCustomBanList = Array.from(new Set(newCustomBanList).values()); // 用户名去重 GM_setValue("customBanList", newCustomBanList); // 保存自定义屏蔽列表 GM_setValue("detectDelay", parseInt(document.getElementsByClassName("settings-input")[0].value)); // 保存循环间隔时间 closeMenu(); // 关闭设置页面 location.reload(); // 刷新页面以应用设置 } // 添加按钮事件——取消 document.getElementById("cancel").onclick = function () { closeMenu(); // 关闭设置页面 }; } } // 检查循环间隔时间函数 function checkDelaytime() { let val = parseInt(this.value, 10); if (isNaN(val) || val < 10) { this.value = 10; } } // 关闭设置页面函数 function closeMenu() { let settingsWindow = document.getElementsByClassName("settings")[0]; // 获取设置页面元素 settingsWindow.style.opacity = 0; // 设置透明度为0,开始淡出动画 setInterval(() => { settingsWindow.remove() }, 200); // 200毫秒后移除设置页面 backgroungBlur(); // 取消背景模糊 document.getElementsByClassName("settings-input")[0].removeEventListener('change', checkDelaytime) // 删除纠正循环间隔监听器 } // 背景模糊函数,使用try避免因小错误导致脚本失效 function backgroungBlur() { try { let github_area = document.getElementsByClassName("env-production page-responsive")[1]; github_area.style.transition = '0.2s'; // 设置过渡效果 github_area.style.filter == '' ? github_area.style.filter = 'blur(10px)' : github_area.style.filter = ''; // 设置背景模糊 // 设置背景滚动 github_area = document.getElementsByClassName("env-production page-responsive")[0]; github_area.style.overflow == 'hidden' ? github_area.style.overflow = '' : github_area.style.overflow = 'hidden'; // 设置背景滚动 } catch (err) { console.log(GM_info.script.name + ":设置背景模糊或背景滚动失效"); } } // 注册(不可用)菜单——脚本设置 GM_registerMenuCommand( "⚙️脚本设置", function () { openMenu(); } ); // 注册(不可用)菜单——重置设置 GM_registerMenuCommand( "🔄️重置设置", async function () { if (confirm("是否重置脚本设置?") == true) { let keys = await GM.listValues(); // 获取所有设置 GM.deleteValues(keys); // 删除所有设置 location.reload(); // 刷新页面以应用设置 } } ); //** //* 屏蔽处理代码 //** 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 = search_list.length - 1; i >= 0; i--) { // console.log(search_list[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 < banList.length; j++) { if (userName == banList[j]) { return true; } } return false; } else { return false; } } else { for (let j = 0; j < banList.length; j++) { if (target.innerText.includes(banList[j])) { return true; } } return false; } }; //** //* MutationObserver检测代码 //** function cleanByMutationObserver() { const targetNode = document.body; // 观察器的配置(需要观察什么变动) const config = { childList: true, subtree: true }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(clean); // 以上述配置开始观察目标节点 observer.observe(targetNode, config); } //** //* Loop检测代码 //** function cleanByLoop() { console.log("Running:Loop"); setInterval(function () { clean(); }, detectDelay); }; //** //* eventListener检测代码 //** 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() { console.log("Running:EventListener"); setTimeout(() => { clean() }, 1000); clean(); // 重写方法 history.pushState = _wr('pushState'); //监听 window.addEventListener('pushState', function (e) { pageChange(location.href); }) } //** //* Navigation API检测代码 //** function cleanByNavigation() { console.log("Running:Navigation API"); // 初始清理 setTimeout(() => { clean() }, 1000); clean(); // 监听导航事件 window.navigation.addEventListener('navigate', (event) => { if (event.navigationType === 'replace') { setTimeout(() => { clean(); }, 1000); } }); } //** //* 手动屏蔽检测代码 //** function cleanByManual() { console.log("Running:Manual"); // 添加悬浮按钮 const floatingButton = document.createElement("button"); floatingButton.id = "github-purify-button"; floatingButton.innerHTML = "⛔"; floatingButton.title = "点击净化Github搜索结果"; // 添加点击事件 floatingButton.addEventListener("click", () => { clean(); // 添加动画效果表示点击成功 floatingButton.classList.add("button-clicked"); setTimeout(() => { floatingButton.classList.remove("button-clicked"); }, 200); }); // 将按钮添加到页面 document.body.appendChild(floatingButton); } //** //* 入口 //** GM_addStyle(/*css*/` div.settings { transition: 0.2s; position: fixed; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; text-align: center; font-size: large; max-height: 90%; width: 55%; left: 50%; top: 50%; padding: 20px; transform: translate(-50%, -50%); background-color: aliceblue; color: rgba(0, 0, 0, 0.88); border: solid rgb(240, 240, 240) 1px; border-radius: 8px; overflow-y: auto; box-shadow: 0px 0px 10px 5px rgba(0, 0, 0, 0.2); } .text-center { margin: 0 auto; } div.settings h2 { margin: 0; font-size: 1.5em; font-weight: bold; } /* 分隔线样式 */ div.settings hr { border-block-start-color: rgba(5, 5, 5, 0.2); margin: 10px; } /* 设置项block样式 */ div.settings .settings-block { padding: 6px 0; display: flex; align-items: center; justify-content: space-between; } div.settings .settings-block > span { flex: 1; text-align: left; } div.settings .settings-block > label, div.settings .settings-block > input, div.settings .settings-block > textarea { margin-left: auto; } /* 开关样式 */ div.settings label.settings-switch { position: relative; display: inline-block; width: 44px; height: 22px; } div.settings .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: rgb(217, 217, 217); -webkit-transition: .2s; transition: .2s; } div.settings .slider:before { position: absolute; content: ""; height: 14px; width: 14px; left: 4px; bottom: 4px; background-color: white; -webkit-transition: .2s; transition: .2s; } div.settings input:checked+.slider { background-color: #4096ff; } div.settings input:checked+.slider:before { -webkit-transform: translateX(22px); -ms-transform: translateX(22px); transform: translateX(22px); } div.settings .slider.round { border-radius: 34px; } div.settings .slider.round:before { border-radius: 50%; } /* 输入框样式 */ div.settings input[type="number"]{ transition: 0.2s; height: 1.5em; margin: 5px; border: solid rgb(217, 217, 217) 1px; border-radius: 6px; padding: 5px; } div.settings input[type="number"] { width: 5em; } /* 输入框聚焦和悬停样式 */ div.settings input[type="text"]:hover,div.settings input[type="number"]:hover,div.settings input[type="text"]:focus,div.settings input[type="number"]:focus { transition: 0.2s; outline: none; border: solid #4096ff 1px; } /* 文本区域样式 */ div.settings textarea.settings-textarea { transition: 0.2s; height: 3em; width: 100%; border: solid rgb(217, 217, 217) 1px; border-radius: 8px; padding: 5px 10px; resize: both; } /* 文本区域聚焦和悬停样式 */ div.settings textarea.settings-textarea:hover, div.settings textarea.settings-textarea:focus { outline: none; border: solid #4096ff 1px; } /* 按钮样式 */ div.settings button { transition: 0.2s; height: 30px; width: 60px; margin: 20px 10px 0px 10px; background-color: #1677FF; color: white; border: solid rgba(0, 0, 0, 0) 1px; border-radius: 8px; } div.settings button:hover { background-color: #4096ff; } div.settings button:active { transform: scale(0.9); } div.settings select { transition: 0.2s; border: solid rgb(217, 217, 217) 1px; border-radius: 6px; } div.settings select:hover, div.settings select:focus { outline: none; border: solid #4096ff 1px; } /* 深色模式支持 */ @media screen and (prefers-color-scheme: dark) { div.settings, div.settings input,div.settings button,div.settings input[type="number"],div.settings .slider,div.settings textarea.settings-textarea,div.settings select { color: #ccc !important; background-color: #121212 !important; border: solid #ccc 1px !important; } div.settings input:checked+.slider { background-color: #4096ff !important; border: solid #ccc 1px !important; } div.settings textarea.settings-textarea:hover, div.settings textarea.settings-textarea:focus { outline: none; border: solid #4096ff 1px !important; } div.settings input[type="text"]:hover,div.settings input[type="number"]:hover,div.settings input[type="text"]:focus,div.settings input[type="number"]:focus { outline: none !important; border: solid #4096ff 1px !important; } } /* badge */ div.settings div.badge1 { display: inline-block; width: 217px; height: 20px; background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjE3IiBoZWlnaHQ9IjIwIiByb2xlPSJpbWciIGFyaWEtbGFiZWw9IkdpdGh1YjogR2l0aHViIFNlYXJjaCBQdXJpZmljYXRpb24iPjx0aXRsZT5HaXRodWI6IEdpdGh1YiBTZWFyY2ggUHVyaWZpY2F0aW9uPC90aXRsZT48ZyBzaGFwZS1yZW5kZXJpbmc9ImNyaXNwRWRnZXMiPjxyZWN0IHdpZHRoPSI2NCIgaGVpZ2h0PSIyMCIgZmlsbD0iIzU1NSIvPjxyZWN0IHg9IjY0IiB3aWR0aD0iMTUzIiBoZWlnaHQ9IjIwIiBmaWxsPSIjMDA3ZWM2Ii8+PC9nPjxnIGZpbGw9IiNmZmYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtZmFtaWx5PSJWZXJkYW5hLEdlbmV2YSxEZWphVnUgU2FucyxzYW5zLXNlcmlmIiB0ZXh0LXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIiBmb250LXNpemU9IjExMCI+PGltYWdlIHg9IjUiIHk9IjMiIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgeGxpbms6aHJlZj0iZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCbWFXeHNQU0ozYUdsMFpYTnRiMnRsSWlCeWIyeGxQU0pwYldjaUlIWnBaWGRDYjNnOUlqQWdNQ0F5TkNBeU5DSWdlRzFzYm5NOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6SXdNREF2YzNabklqNDhkR2wwYkdVK1IybDBTSFZpUEM5MGFYUnNaVDQ4Y0dGMGFDQmtQU0pOTVRJZ0xqSTVOMk10Tmk0Mk15QXdMVEV5SURVdU16Y3pMVEV5SURFeUlEQWdOUzR6TURNZ015NDBNemdnT1M0NElEZ3VNakExSURFeExqTTROUzQyTGpFeE15NDRNaTB1TWpVNExqZ3lMUzQxTnpjZ01DMHVNamcxTFM0d01TMHhMakEwTFM0d01UVXRNaTR3TkMwekxqTXpPQzQzTWpRdE5DNHdOREl0TVM0Mk1TMDBMakEwTWkweExqWXhRelF1TkRJeUlERTRMakEzSURNdU5qTXpJREUzTGpjZ015NDJNek1nTVRjdU4yTXRNUzR3T0RjdExqYzBOQzR3T0RRdExqY3lPUzR3T0RRdExqY3lPU0F4TGpJd05TNHdPRFFnTVM0NE16Z2dNUzR5TXpZZ01TNDRNemdnTVM0eU16WWdNUzR3TnlBeExqZ3pOU0F5TGpnd09TQXhMak13TlNBekxqUTVOUzQ1T1RndU1UQTRMUzQzTnpZdU5ERTNMVEV1TXpBMUxqYzJMVEV1TmpBMUxUSXVOalkxTFM0ekxUVXVORFkyTFRFdU16TXlMVFV1TkRZMkxUVXVPVE1nTUMweExqTXhMalEyTlMweUxqTTRJREV1TWpNMUxUTXVNakl0TGpFek5TMHVNekF6TFM0MU5DMHhMalV5TXk0eE1EVXRNeTR4TnpZZ01DQXdJREV1TURBMUxTNHpNaklnTXk0eklERXVNak11T1RZdExqSTJOeUF4TGprNExTNHpPVGtnTXkwdU5EQTFJREV1TURJdU1EQTJJREl1TURRdU1UTTRJRE1nTGpRd05TQXlMakk0TFRFdU5UVXlJRE11TWpnMUxURXVNak1nTXk0eU9EVXRNUzR5TXk0Mk5EVWdNUzQyTlRNdU1qUWdNaTQ0TnpNdU1USWdNeTR4TnpZdU56WTFMamcwSURFdU1qTWdNUzQ1TVNBeExqSXpJRE11TWpJZ01DQTBMall4TFRJdU9EQTFJRFV1TmpJMUxUVXVORGMxSURVdU9USXVOREl1TXpZdU9ERWdNUzR3T1RZdU9ERWdNaTR5TWlBd0lERXVOakEyTFM0d01UVWdNaTQ0T1RZdExqQXhOU0F6TGpJNE5pQXdJQzR6TVRVdU1qRXVOamt1T0RJMUxqVTNRekl3TGpVMk5TQXlNaTR3T1RJZ01qUWdNVGN1TlRreUlESTBJREV5TGpJNU4yTXdMVFl1TmpJM0xUVXVNemN6TFRFeUxURXlMVEV5SWk4K1BDOXpkbWMrIi8+PHRleHQgeD0iNDE1IiB5PSIxNDAiIHRyYW5zZm9ybT0ic2NhbGUoLjEpIiBmaWxsPSIjZmZmIiB0ZXh0TGVuZ3RoPSIzNzAiPkdpdGh1YjwvdGV4dD48dGV4dCB4PSIxMzk1IiB5PSIxNDAiIHRyYW5zZm9ybT0ic2NhbGUoLjEpIiBmaWxsPSIjZmZmIiB0ZXh0TGVuZ3RoPSIxNDMwIj5HaXRodWIgU2VhcmNoIFB1cmlmaWNhdGlvbjwvdGV4dD48L2c+PC9zdmc+"); margin: auto; } div.settings div.badge2 { display: inline-block; width: 185px; height: 20px; background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTg1IiBoZWlnaHQ9IjIwIiByb2xlPSJpbWciIGFyaWEtbGFiZWw9IkdyZWFzeSBGb3JrOiBHaXRodWLmkJzntKLlh4DljJYiPjx0aXRsZT5HcmVhc3kgRm9yazogR2l0aHVi5pCc57Si5YeA5YyWPC90aXRsZT48ZyBzaGFwZS1yZW5kZXJpbmc9ImNyaXNwRWRnZXMiPjxyZWN0IHdpZHRoPSI5NCIgaGVpZ2h0PSIyMCIgZmlsbD0iIzU1NSIvPjxyZWN0IHg9Ijk0IiB3aWR0aD0iOTEiIGhlaWdodD0iMjAiIGZpbGw9IiMwMDdlYzYiLz48L2c+PGcgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1mYW1pbHk9IlZlcmRhbmEsR2VuZXZhLERlamFWdSBTYW5zLHNhbnMtc2VyaWYiIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIGZvbnQtc2l6ZT0iMTEwIj48aW1hZ2UgeD0iNSIgeT0iMyIgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiB4bGluazpocmVmPSJkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUJtYVd4c1BTSjNhR2wwWlhOdGIydGxJaUJ5YjJ4bFBTSnBiV2NpSUhacFpYZENiM2c5SWpBZ01DQXlOQ0F5TkNJZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWo0OGRHbDBiR1UrUjNKbFlYTjVJRVp2Y21zOEwzUnBkR3hsUGp4d1lYUm9JR1E5SWswMUxqZzVJREl1TWpJM1lTNHlPQzR5T0NBd0lEQWdNU0F1TWpZMkxqQTNObXcxTGpBMk15QTFMakEyTW1NdU5UUXVOVFF1TlRBNUlERXVOalV5TFM0d016RWdNaTR4T1RKc09DNDNOekVnT0M0M04yTXhMak0xTmlBeExqTTFOUzB1TXpZZ015NHdPVGN0TVM0M015QXhMamN5T0d3dE9DNDNOekl0T0M0M04yTXRMalUwTGpVMExURXVOalV4TGpVM01TMHlMakU1TVM0d016RnNMVFV1TURZekxUVXVNRFpqTFM0ek1EUXRMak13TkM0ek1EUXRMamt4TVM0Mk1EZ3RMall3T0d3ekxqY3hOQ0F6TGpjeE0wdzNMalU1SURndU1qazNJRE11T0RjMUlEUXVOVGd5WXkwdU16QTBMUzR6TURRdU16QTBMUzQ1TVRFdU5qQTNMUzQyTURkc015NDNNVFVnTXk0M01UUWdNUzR3TmpjdE1TNHdOalpNTlM0MU5Ea2dNaTQ1TVdNdExqSXlPQzB1TWpJNExqQTFOeTB1TmpJMkxqTTBNaTB1TmpneldrMHhNaUF3UXpVdU16YzBJREFnTUNBMUxqTTNOU0F3SURFeWN6VXVNemMwSURFeUlERXlJREV5WXpZdU5qSTFJREFnTVRJdE5TNHpOelVnTVRJdE1USlRNVGd1TmpJMUlEQWdNVElnTUZvaUx6NDhMM04yWno0PSIvPjx0ZXh0IHg9IjU2NSIgeT0iMTQwIiB0cmFuc2Zvcm09InNjYWxlKC4xKSIgZmlsbD0iI2ZmZiIgdGV4dExlbmd0aD0iNjcwIj5HcmVhc3kgRm9yazwvdGV4dD48dGV4dCB4PSIxMzg1IiB5PSIxNDAiIHRyYW5zZm9ybT0ic2NhbGUoLjEpIiBmaWxsPSIjZmZmIiB0ZXh0TGVuZ3RoPSI4MTAiPkdpdGh1YuaQnOe0ouWHgOWMljwvdGV4dD48L2c+PC9zdmc+"); margin: auto; } /* 悬浮净化按钮样式 */ #github-purify-button { position: fixed; bottom: 20px; right: 20px; padding: 10px 15px; background-color: #ffffff; border: 1px solid #dddddd; border-radius: 8px; cursor: pointer; z-index: 9999; transition: all 0.3s ease; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } #github-purify-button:hover { background-color: #f0f0f0; } #github-purify-button.button-clicked { transform: scale(0.95); } `); console.log("====================\n脚本:" + GM_info.script.name + " 开始执行\n作者:" + GM_info.script.author + " 版本:" + GM_info.script.version + "\n脚本地址:https://greasyforks.org/zh-CN/scripts/473912-github搜索净化\n====================\n【脚本配置】\nisKeepDiv: " + isKeepDiv + "\nshowBlockButton: " + showBlockButton + "\nisPrecise: " + isPrecise + "\ndetectMode: " + detectMode + "\ndetectDelay: " + detectDelay + "\nuseDefaultList: " + useDefaultList + "\ncustomBanList: " + customBanList); // 如果showBlockButton为true,则添加屏蔽按钮 // 参考 https://greasyforks.org/zh-CN/scripts/493913-github%E5%B1%8F%E8%94%BD%E7%94%A8%E6%88%B7,进行了部分修改,整合了MutationObserver // 作者:Gwen0x4c3, 发布时使用MIT许可证 if (showBlockButton) { const resultListObserver = new MutationObserver((mutations) => { // 创建一个MutationObserver实例,监听DOM变化 const resultList = document.querySelector('div[data-testid="results-list"]'); // 获取搜索结果列表 if (!resultList) return; // 如果没有结果列表则返回 let isButtonAddition = false; // 标记是否为按钮添加操作 for (const mutation of mutations) { // 遍历所有变动 if (mutation.addedNodes.length && mutation.addedNodes[0].querySelector && mutation.addedNodes[0].querySelector('button[data-block-button="true"]')) { // 检查是否有block按钮被添加 isButtonAddition = true; // 如果是,设置标记 break; // 跳出循环 } } if (isButtonAddition) return; // 如果是按钮添加操作则不处理 processResultList(resultList); // 处理结果列表,添加block按钮 }); resultListObserver.observe(document.body, { childList: true, subtree: true }); // 监听整个body的子节点变化 const resultList = document.querySelector('div[data-testid="results-list"]'); // 获取初始的结果列表 if (resultList) { processResultList(resultList); // 如果存在,立即处理一次 } function createElement(tag, clazz, attrs) { // 创建元素的辅助函数 const elem = document.createElement(tag); // 创建指定标签的元素 if (clazz) elem.className = clazz; // 设置类名 if (attrs) { Object.entries(attrs).forEach(([key, value]) => { elem[key] = value; // 设置属性 }); } return elem; // 返回创建的元素 } function processResultList(resultList) { // 处理结果列表,给每个仓库添加block按钮 const repos = resultList.children; // 获取所有仓库节点 for (let i = 0; i < repos.length; i++) { // 遍历每个仓库 const repo = repos[i]; // 当前仓库节点 if (repo.querySelector('button[data-block-button="true"]')) continue; // 如果已经有block按钮则跳过 const exampleButton = repo.querySelector('button'); // 获取一个已有的按钮作为样式参考 if (!exampleButton) continue; // 如果没有按钮则跳过 const span = repo.querySelector('.search-match'); // 获取显示仓库名的span const user = span.innerText.split('/')[0] // 提取用户名 const blockButton = createElement('button', exampleButton.className, { // 创建block按钮,复用样式 innerText: '🚫Block', // 按钮文本 onclick: () => { // 点击事件 customBanList.push(user); // 将用户添加到自定义屏蔽列表 banList.push(user); // 将用户添加到全局屏蔽列表 GM_setValue('customBanList', customBanList); // 保存自定义屏蔽列表 clean(); // 重新清理页面 } }); blockButton.setAttribute('data-size', 'small'); // 设置按钮尺寸属性 blockButton.setAttribute('data-variant', 'default'); // 设置按钮样式属性 blockButton.setAttribute('data-block-button', 'true'); // 添加自定义属性用于识别 const buttonWrapper = createElement('div', exampleButton.parentElement.className); // 创建按钮外层div,复用原按钮父元素的类名 buttonWrapper.appendChild(blockButton); // 将block按钮添加到外层div resultListObserver.disconnect(); // 断开observer,防止递归触发 exampleButton.parentElement.parentElement.prepend(buttonWrapper); // 将block按钮插入到按钮组前面 resultListObserver.observe(document.body, { childList: true, subtree: true }); // 重新监听DOM变化 } } } // 根据选择的模式进行净化 switch (detectMode) { case "mutationobserver": cleanByMutationObserver(); break; case "loop": cleanByLoop(); break; case "eventListen": cleanByEventListener(); break; case "navigation": cleanByNavigation(); break; case "manual": cleanByManual(); break; } })()