// ==UserScript== // @name BDWM-Hide // @namespace http://tampermonkey.net/ // @version 1.1 // @description 北大未名,屏蔽版面或用户 // @author lanvent // @match https://bbs.pku.edu.cn/v2/* // @icon https://www.google.com/s2/favicons?sz=64&domain=pku.edu.cn // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @license MIT // @downloadURL none // ==/UserScript== let blockBlocks = GM_getValue('BDWM_blockBlocks', []); let blockUsers = GM_getValue('BDWM_blockUsers', []); function setblockBlocks(str){ blockBlocks = str.replace(',',',').split(',').map(word => word.trim()).filter(word => word.length > 0); GM_setValue('BDWM_blockBlocks', blockBlocks); if( blockBlocks.length == 0){ return; } removeBoardBlocks(); removeTitles(); } function setblockUsers(str){ blockUsers = str.replace(',',',').split(',').map(word => word.trim()).filter(word => word.length > 0); GM_setValue('BDWM_blockUsers', blockUsers); if( blockUsers.length == 0){ return; } removePostCards(); removePosts(); } function setblockBlocksPrompt() { const userInput = prompt('请输入要屏蔽的版面名称,用逗号分隔:', blockBlocks.join(', ')); if (userInput !== null) { setblockBlocks(userInput); } } function setblockUsersPrompt() { const userInput = prompt('请输入要屏蔽的用户名称,用逗号分隔:', blockUsers.join(', ')); if (userInput !== null) { setblockUsers(userInput); } } function addSettingsButton() { const container = document.querySelector('div.extend-menu.setting-extend-menu > div.content'); if(container == null || container.querySelector('a[name="blockBlocks-button"]')){ return; } const logoutButton = container.querySelector('a.btn-logout'); let settingsButton = document.createElement('a'); settingsButton.textContent = '屏蔽版面设置'; settingsButton.name = 'blockBlocks-button'; settingsButton.addEventListener('click', function(event) { event.preventDefault(); setblockBlocksPrompt(); }); container.insertBefore(settingsButton,logoutButton); settingsButton = document.createElement('a'); settingsButton.textContent = '屏蔽用户设置'; settingsButton.name = 'blockUsers-button'; settingsButton.addEventListener('click', function(event) { event.preventDefault(); setblockUsersPrompt(); }); container.insertBefore(settingsButton,logoutButton); } function addCustomSettingRow() { const form = document.getElementById('preference-form'); if(form==null || form.querySelector('input[name="blockBlocks-keywords"]')){ return; } const submitButtonRow = form.querySelector('.extra-margin-top'); // 版面 let settingRow = document.createElement('div'); settingRow.className = 'form-row'; settingRow.innerHTML = `
`; form.insertBefore(settingRow, submitButtonRow); const blocksKeywordInput = settingRow.querySelector('input[name="blockBlocks-keywords"]'); blocksKeywordInput.value = blockBlocks.join(', '); // 用户 settingRow = document.createElement('div'); settingRow.className = 'form-row'; settingRow.innerHTML = `
`; form.insertBefore(settingRow, submitButtonRow); const usersKeywordInput = settingRow.querySelector('input[name="blockUsers-keywords"]'); usersKeywordInput.value = blockUsers.join(', '); const applyButton = form.querySelector('.orange-large-btn'); applyButton.addEventListener('click', function(event){ setblockBlocks(blocksKeywordInput.value); setblockUsers(usersKeywordInput.value); }); } function removeBoardBlocks() { //版面 let boardBlocks = document.querySelectorAll('.boards-wrapper.list > div.set'); if(boardBlocks!=null){ boardBlocks.forEach(block => { let content = block.querySelector('span.name')?.textContent; if (content && blockBlocks.some(word => word===content)){ console.log("remove block "+content,block); block.remove(); } }); } boardBlocks = document.querySelectorAll('.boards-wrapper.hots > div.board-block'); if(boardBlocks!=null){ boardBlocks.forEach(block => { let content = block.querySelector('span.name')?.textContent; if (content && blockBlocks.some(word => word===content)){ console.log("remove block "+content,block); block.remove(); } }); } } function removeTitles() { //主页榜单 let titles = document.querySelectorAll('li'); if(titles){ titles.forEach(title => { let content = title.querySelector('a.post-link')?.textContent; if (content && blockBlocks.some(word => content.startsWith(word+' '))){ console.log("remove block "+content.substr(0,content.lastIndexOf(' ')),title); title.remove(); } content = title.querySelector('a.topic-link')?.textContent; if (content && blockBlocks.some(word => content.startsWith('['+word+']'))){ console.log("remove block "+content.substr(1,content.lastIndexOf(']')-1),title); title.remove(); } }); } titles = document.querySelectorAll('p > a.topic-link'); if(titles){ titles.forEach(title => { let content = title.textContent; if (blockBlocks.some(word => title.textContent.startsWith('['+word+']'))){ console.log("remove block "+content.substr(1,content.lastIndexOf(']')-1),title); title.remove(); } }); } titles = document.querySelectorAll('a.inline-link'); if(titles){ titles.forEach(title => { let content = title.textContent; if (blockBlocks.some(word => title.textContent.startsWith('['+word+']'))){ console.log("remove block "+content.substr(1,content.lastIndexOf(']')-1),title); title.remove(); } }); } } function removePostCards() { //帖子内 let postCards = document.querySelectorAll('div.card-list > .post-card'); if(postCards){ postCards.forEach(postcard => { let content = postcard.querySelector('p.username > a')?.textContent; if (content && blockUsers.some(word => word===content)){ console.log("remove user " + content ,postcard); postcard.remove(); return; } //删除引用部分 let quote = postcard.querySelector('p.quotehead') content = quote?.attributes['data-username']?.textContent; if (content && blockUsers.some(word => word===content)){ console.log("remove user quote " + content ,postcard); quote.remove(); postcard.querySelector('p.blockquote')?.remove(); } }); } } function removePosts() { //版面帖子列表 let posts = document.querySelectorAll('#list-content > .list-item'); if(posts){ posts.forEach(post => { let content = post.querySelector('.author > .name')?.textContent; if (content && blockUsers.some(word => word===content)){ console.log("remove user " + content ,post); post.remove(); } }); } } (function() { 'use strict'; const config = { childList: true, subtree: true }; const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.type === 'childList') { observer.disconnect(); addSettingsButton(); addCustomSettingRow(); observer.observe(document.body, config); removeBoardBlocks(); removeTitles(); removePostCards(); removePosts(); } }); }); observer.observe(document.body, config); })();