- // ==UserScript==
- // @name Github屏蔽用户
- // @namespace Violentmonkey Scripts
- // @match https://github.com/*
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant unsafeWindow
- // @grant GM_registerMenuCommand
- // @version 1.0
- // @author Gwen0x4c3
- // @license MIT
- // @description 屏蔽Github搜索页面某些丝麻用户的内容,如cirosantilli发的与代码无关的Shit Repo,我囸你写吗狗罕见
- // ==/UserScript==
- (function() {
- 'use strict';
-
- const log = {
- info(message, obj) {
- if (typeof(message) == 'string') {
- console.log("%c[INFO] " + message, "color:blue;font-weight:bold;", obj);
- } else {
- console.log("%c[INFO] ", "color:blue;font-weight:bold;", arguments);
- }
- },
- error(message, obj) {
- if (typeof(message) == 'string') {
- console.log("%c[ERROR] " + message, "color:red;font-weight:bold;", obj);
- } else {
- console.log("%c[ERROR] ", "color:red;font-weight:bold;", arguments);
- }
- }
- }
-
- const REGEX_SEARCH_REPO = /\/search\?.*?type=repositories.*?/;
- const REGEX_SEARCH_USER = /\/search\?.*?type=users.*?/;
- const REGEX_EXCLUDE_USER = /-user:([a-zA-Z0-9_]+)/g;
-
- const store = {
- blockedUsers: GM_getValue("blocked_users", ['cirosantilli', 'wumaoland']),
- dialog: null
- }
-
- GM_registerMenuCommand("⚙查看屏蔽用户", () => {
- store.dialog.show();
- });
-
- function createElement(tag, clazz, attrs) {
- const elem = document.createElement(tag);
- elem.className = clazz;
- if (attrs) {
- for (let key in attrs) {
- elem[key] = attrs[key];
- }
- }
- return elem;
- }
-
- function blockElem(target) {
- const div = createElement('div', target.className, {
- innerText: `🚫Blocked this shit content by user: ${target.getAttribute('gb_user')}`
- })
- target.replaceWith(div);
- }
-
- function blockRepoSearch() {
- const resultList = document.querySelector('div[data-testid="results-list"]');
- // log.info("获取results list", { resultList });
- if (!resultList || resultList.gb_blocked) {
- setTimeout(blockRepoSearch, 100);
- } else {
- resultList.gb_blocked = true;
- const repos = resultList.children;
- for (let i = 0; i < repos.length; i++) {
- const repo = repos[i];
- const span = repo.querySelector('.search-match');
- log.info({repo, span});
- const user = span.innerText.split('/')[0];
- repo.setAttribute('gb_user', user);
- for (let blockedUser of store.blockedUsers) {
- if (blockedUser == user) {
- log.info("BLOCKED " + span.innerText);
- blockElem(repo);
- break;
- }
- }
- const exampleButton = repo.querySelector('button');
- const blockButton = createElement('button', exampleButton.className, {
- innerText: '🚫Block',
- onclick: e => {
- if (confirm("Are you sure to BLOCK this MF:" + user)) {
- store.blockedUsers.push(user);
- GM_setValue('blocked_users', store.blockedUsers);
- for (let j = 0; j < repos.length; j++) {
- if (repos[j].getAttribute('gb_user') == user) {
- blockElem(repos[j]);
- }
- }
- }
- }
- });
- blockButton.setAttribute('data-size', 'small');
- const buttonWrapper = createElement('div', exampleButton.parentElement.className);
- buttonWrapper.appendChild(blockButton);
- exampleButton.parentElement.parentElement.prepend(buttonWrapper);
- }
- }
- }
-
- function blockUserSearch() {
- const resultList = document.querySelector('div[data-testid="results-list"]');
- // log.info("获取results list", { resultList });
- if (!resultList || resultList.gb_blocked) {
- setTimeout(blockRepoSearch, 100);
- } else {
- resultList.gb_blocked = true;
- const users = resultList.children;
- for (let i = 0; i < users.length; i++) {
- const userElem = users[i];
- const a = user.querySelector('a:last-of-type');
- const user = a.innerText;
- userElem.setAttribute('gb_user', user);
- for (let blockedUser of store.blockedUsers) {
- if (blockedUser == user) {
- log.info("BLOCKED " + span.innerText);
- blockElem(userElem);
- break;
- }
- }
- const exampleButton = user.querySelector('button');
- const blockButton = createElement('button', exampleButton.className, {
- innerText: '🚫Block',
- onclick: e => {
- if (confirm("Are you sure to BLOCK this MF:" + user)) {
- store.blockedUsers.push(user);
- GM_setValue('blocked_users', store.blockedUsers);
- for (let j = 0; j < users.length; j++) {
- if (users[j].getAttribute('gb_user') == user) {
- // users[j].remove();
- // j--;
- blockElem(users[j]);
- }
- }
- }
- }
- });
- blockButton.setAttribute('data-size', 'small');
- const buttonWrapper = createElement('div', exampleButton.parentElement.className);
- buttonWrapper.appendChild(blockButton);
- exampleButton.parentElement.parentElement.prepend(buttonWrapper);
- }
- }
- }
-
- function initDialog() {
- if (document.getElementById('gb_block_dialog')) {
- return;
- }
- const dialog = createElement('dialog', '', {
- id: 'gb_block_dialog',
- style: 'width:50%;position:fixed;left:0;top:50px;'
- });
- store.dialog = dialog;
- const closeBtn = createElement('span', '', {
- innerText: '×',
- style: 'position:absolute;right:5px;top:2px;font-size:18px;cursor:pointer',
- onclick: e => {
- dialog.close();
- }
- })
- const tips = createElement('p', '', {
- innerText: '多个用户使用英文逗号","分隔',
- style: 'text-align: center'
- })
- const textArea = createElement('textarea', '', {
- style: 'width:100%;min-height:200px;font-size:18px;resize:none;',
- value: store.blockedUsers.join(', '),
- onblur: e => {
- const arr = textArea.value.split(',');
- for (let i = 0; i < arr.length; i++) {
- arr[i] = arr[i].trim();
- if (arr[i].length == 0) {
- arr.splice(i, 1);
- i--;
- }
- }
- store.blockedUsers = [...arr];
- GM_setValue('blocked_users', store.blockedUsers);
- textArea.value = arr.join(', ');
- }
- })
- dialog.appendChild(closeBtn);
- dialog.appendChild(tips);
- dialog.appendChild(textArea);
- document.body.append(dialog);
- }
-
- function handleUrlChange(url) {
- initDialog();
- // const _url = new URL(url);
- // if (_url.pathname == '/search') {
- // let q = _url.searchParams.get('q');
- // if (!q) {
- // q = '';
- // }
- // let users = [];
- // let match = null;
- // while ((match = REGEX_EXCLUDE_USER.exec(q)) !== null) {
- // users.push(match[1]);
- // }
- // }
- if (REGEX_SEARCH_REPO.test(lastUrl)) {
- blockRepoSearch();
- } else if (REGEX_SEARCH_USER.test(lastUrl)) {
- blockUserSearch();
- }
- }
-
- let lastUrl = '';
- handleUrlChange(location.href);
- const urlTimer = setInterval(() => {
- if (lastUrl != location.href) {
- log.info("url changed to " + location.href);
- lastUrl = location.href;
- handleUrlChange(lastUrl);
- }
- }, 300);
- })();